summaryrefslogtreecommitdiff
path: root/app/views
diff options
context:
space:
mode:
Diffstat (limited to 'app/views')
-rw-r--r--app/views/admin/abuse_reports/index.html.haml18
-rw-r--r--app/views/admin/application_settings/_ci_cd.html.haml6
-rw-r--r--app/views/admin/application_settings/_eks.html.haml31
-rw-r--r--app/views/admin/application_settings/_outbound.html.haml4
-rw-r--r--app/views/admin/application_settings/_plantuml.html.haml41
-rw-r--r--app/views/admin/application_settings/_repository_mirrors_form.html.haml4
-rw-r--r--app/views/admin/application_settings/_snowplow.html.haml11
-rw-r--r--app/views/admin/application_settings/_sourcegraph.html.haml38
-rw-r--r--app/views/admin/application_settings/_third_party_offers.html.haml28
-rw-r--r--app/views/admin/application_settings/integrations.html.haml33
-rw-r--r--app/views/admin/application_settings/network.html.haml2
-rw-r--r--app/views/admin/application_settings/repository.html.haml4
-rw-r--r--app/views/admin/dashboard/index.html.haml37
-rw-r--r--app/views/admin/sessions/_new_base.html.haml2
-rw-r--r--app/views/admin/sessions/_signin_box.html.haml2
-rw-r--r--app/views/admin/sessions/_tabs_normal.html.haml2
-rw-r--r--app/views/admin/sessions/new.html.haml2
-rw-r--r--app/views/admin/users/show.html.haml2
-rw-r--r--app/views/ci/group_variables/_content.html.haml1
-rw-r--r--app/views/ci/group_variables/_header.html.haml5
-rw-r--r--app/views/ci/group_variables/_index.html.haml13
-rw-r--r--app/views/ci/group_variables/_variable_header.html.haml5
-rw-r--r--app/views/ci/variables/_header.html.haml2
-rw-r--r--app/views/ci/variables/_index.html.haml5
-rw-r--r--app/views/ci/variables/_url_query_variable_row.html.haml28
-rw-r--r--app/views/clusters/clusters/_advanced_settings.html.haml21
-rw-r--r--app/views/clusters/clusters/_banner.html.haml6
-rw-r--r--app/views/clusters/clusters/_gcp_signup_offer_banner.html.haml2
-rw-r--r--app/views/clusters/clusters/aws/_new.html.haml20
-rw-r--r--app/views/clusters/clusters/cloud_providers/_cloud_provider_button.html.haml6
-rw-r--r--app/views/clusters/clusters/cloud_providers/_cloud_provider_selector.html.haml6
-rw-r--r--app/views/clusters/clusters/eks/_index.html.haml2
-rw-r--r--app/views/clusters/clusters/gcp/_form.html.haml13
-rw-r--r--app/views/clusters/clusters/gcp/_new.html.haml7
-rw-r--r--app/views/clusters/clusters/index.html.haml2
-rw-r--r--app/views/clusters/clusters/new.html.haml33
-rw-r--r--app/views/clusters/clusters/show.html.haml2
-rw-r--r--app/views/clusters/clusters/user/_form.html.haml8
-rw-r--r--app/views/clusters/clusters/user/_header.html.haml2
-rw-r--r--app/views/dashboard/projects/_zero_authorized_projects.html.haml2
-rw-r--r--app/views/devise/sessions/new.html.haml6
-rw-r--r--app/views/devise/shared/_signin_box.html.haml2
-rw-r--r--app/views/devise/shared/_tabs_ldap.html.haml2
-rw-r--r--app/views/errors/not_found.html.haml2
-rw-r--r--app/views/groups/issues.html.haml8
-rw-r--r--app/views/groups/milestones/show.html.haml2
-rw-r--r--app/views/groups/settings/ci_cd/show.html.haml3
-rw-r--r--app/views/help/_shortcuts.html.haml2
-rw-r--r--app/views/import/manifest/_form.html.haml2
-rw-r--r--app/views/layouts/_flash.html.haml2
-rw-r--r--app/views/layouts/_head.html.haml4
-rw-r--r--app/views/layouts/_mailer.html.haml72
-rw-r--r--app/views/layouts/_page.html.haml2
-rw-r--r--app/views/layouts/header/_current_user_dropdown.html.haml9
-rw-r--r--app/views/layouts/header/_default.html.haml4
-rw-r--r--app/views/layouts/header/_help_dropdown.html.haml4
-rw-r--r--app/views/layouts/nav/_dashboard.html.haml27
-rw-r--r--app/views/layouts/nav/sidebar/_group.html.haml10
-rw-r--r--app/views/layouts/nav/sidebar/_project.html.haml12
-rw-r--r--app/views/notify/member_access_denied_email.html.haml11
-rw-r--r--app/views/notify/member_access_granted_email.html.haml16
-rw-r--r--app/views/notify/member_access_requested_email.html.haml9
-rw-r--r--app/views/notify/member_invite_accepted_email.html.haml13
-rw-r--r--app/views/notify/member_invite_declined_email.html.haml11
-rw-r--r--app/views/notify/member_invited_email.html.haml27
-rw-r--r--app/views/profiles/preferences/_sourcegraph.html.haml26
-rw-r--r--app/views/profiles/preferences/show.html.haml3
-rw-r--r--app/views/profiles/show.html.haml2
-rw-r--r--app/views/projects/_export.html.haml2
-rw-r--r--app/views/projects/_files.html.haml6
-rw-r--r--app/views/projects/_home_panel.html.haml2
-rw-r--r--app/views/projects/_merge_request_merge_options_settings.html.haml6
-rw-r--r--app/views/projects/blame/show.html.haml2
-rw-r--r--app/views/projects/blob/_header.html.haml13
-rw-r--r--app/views/projects/blob/_markdown_buttons.html.haml2
-rw-r--r--app/views/projects/buttons/_clone.html.haml2
-rw-r--r--app/views/projects/buttons/_download.html.haml13
-rw-r--r--app/views/projects/buttons/_download_links.html.haml6
-rw-r--r--app/views/projects/compare/_form.html.haml10
-rw-r--r--app/views/projects/deployments/_confirm_rollback_modal.html.haml2
-rw-r--r--app/views/projects/environments/empty_logs.html.haml14
-rw-r--r--app/views/projects/environments/empty_metrics.html.haml (renamed from app/views/projects/environments/empty.html.haml)4
-rw-r--r--app/views/projects/error_tracking/details.html.haml4
-rw-r--r--app/views/projects/graphs/show.html.haml28
-rw-r--r--app/views/projects/issues/_issue.html.haml3
-rw-r--r--app/views/projects/labels/index.html.haml2
-rw-r--r--app/views/projects/merge_requests/_how_to_merge.html.haml2
-rw-r--r--app/views/projects/merge_requests/creations/_new_submit.html.haml10
-rw-r--r--app/views/projects/merge_requests/edit.html.haml1
-rw-r--r--app/views/projects/milestones/show.html.haml53
-rw-r--r--app/views/projects/mirrors/_authentication_method.html.haml10
-rw-r--r--app/views/projects/mirrors/_mirror_repos_form.html.haml4
-rw-r--r--app/views/projects/pages/_access.html.haml6
-rw-r--r--app/views/projects/pages/_list.html.haml4
-rw-r--r--app/views/projects/pages/show.html.haml36
-rw-r--r--app/views/projects/pages_domains/_certificate.html.haml79
-rw-r--r--app/views/projects/pages_domains/_dns.html.haml33
-rw-r--r--app/views/projects/pages_domains/_form.html.haml71
-rw-r--r--app/views/projects/pages_domains/_lets_encrypt_callout.html.haml13
-rw-r--r--app/views/projects/pages_domains/edit.html.haml15
-rw-r--r--app/views/projects/pages_domains/new.html.haml1
-rw-r--r--app/views/projects/pages_domains/show.html.haml2
-rw-r--r--app/views/projects/pipelines/_with_tabs.html.haml14
-rw-r--r--app/views/projects/pipelines/new.html.haml7
-rw-r--r--app/views/projects/pipelines/show.html.haml3
-rw-r--r--app/views/projects/protected_branches/shared/_branches_list.html.haml3
-rw-r--r--app/views/projects/services/_form.html.haml1
-rw-r--r--app/views/projects/services/_index.html.haml2
-rw-r--r--app/views/projects/services/edit.html.haml3
-rw-r--r--app/views/projects/settings/ci_cd/_form.html.haml2
-rw-r--r--app/views/projects/settings/ci_cd/show.html.haml3
-rw-r--r--app/views/projects/settings/operations/_grafana_integration.html.haml2
-rw-r--r--app/views/projects/settings/operations/show.html.haml1
-rw-r--r--app/views/projects/show.html.haml2
-rw-r--r--app/views/projects/tree/_readme.html.haml2
-rw-r--r--app/views/projects/tree/_tree_header.html.haml12
-rw-r--r--app/views/projects/tree/show.html.haml3
-rw-r--r--app/views/registrations/welcome.html.haml15
-rw-r--r--app/views/search/_category.html.haml2
-rw-r--r--app/views/search/_results.html.haml1
-rw-r--r--app/views/search/results/_blob.html.haml4
-rw-r--r--app/views/search/results/_blob_data.html.haml2
-rw-r--r--app/views/search/results/_snippet_blob.html.haml2
-rw-r--r--app/views/search/results/_snippet_title.html.haml5
-rw-r--r--app/views/search/results/_wiki_blob.html.haml2
-rw-r--r--app/views/shared/_clone_panel.html.haml3
-rw-r--r--app/views/shared/_field.html.haml4
-rw-r--r--app/views/shared/_group_form.html.haml7
-rw-r--r--app/views/shared/_mobile_clone_panel.html.haml2
-rw-r--r--app/views/shared/_personal_access_tokens_form.html.haml1
-rw-r--r--app/views/shared/_service_settings.html.haml2
-rw-r--r--app/views/shared/form_elements/_description.html.haml3
-rw-r--r--app/views/shared/issuable/_form.html.haml4
-rw-r--r--app/views/shared/issuable/_search_bar.html.haml307
-rw-r--r--app/views/shared/issuable/_sidebar.html.haml8
-rw-r--r--app/views/shared/issuable/form/_branch_chooser.html.haml31
-rw-r--r--app/views/shared/issuable/form/_merge_params.html.haml14
-rw-r--r--app/views/shared/members/_access_request_links.html.haml2
-rw-r--r--app/views/shared/milestones/_description.html.haml8
-rw-r--r--app/views/shared/milestones/_header.html.haml38
-rw-r--r--app/views/shared/milestones/_milestone.html.haml14
-rw-r--r--app/views/shared/milestones/_sidebar.html.haml21
-rw-r--r--app/views/shared/milestones/_tabs.html.haml47
-rw-r--r--app/views/shared/milestones/_top.html.haml56
-rw-r--r--app/views/shared/notifications/_button.html.haml6
-rw-r--r--app/views/shared/notifications/_custom_notifications.html.haml3
-rw-r--r--app/views/shared/notifications/_new_button.html.haml2
-rw-r--r--app/views/shared/projects/_list.html.haml2
-rw-r--r--app/views/shared/runners/_runner_description.html.haml2
-rw-r--r--app/views/shared/snippets/_blob.html.haml3
-rw-r--r--app/views/shared/snippets/_embed.html.haml2
-rw-r--r--app/views/shared/snippets/_header.html.haml2
-rw-r--r--app/views/shared/snippets/_snippet.html.haml5
153 files changed, 1113 insertions, 791 deletions
diff --git a/app/views/admin/abuse_reports/index.html.haml b/app/views/admin/abuse_reports/index.html.haml
index cc29657a439..e3d78b3058f 100644
--- a/app/views/admin/abuse_reports/index.html.haml
+++ b/app/views/admin/abuse_reports/index.html.haml
@@ -1,6 +1,18 @@
-- page_title 'Abuse Reports'
-%h3.page-title Abuse Reports
-%hr
+- page_title _('Abuse Reports')
+
+%h3.page-title= _('Abuse Reports')
+
+.row-content-block.second-block
+ = form_tag admin_abuse_reports_path, method: :get, class: 'filter-form' do
+ .filter-categories.flex-fill
+ .filter-item.inline
+ = dropdown_tag(user_dropdown_label(params[:user_id], 'User'),
+ options: { toggle_class: 'js-filter-submit js-user-search',
+ title: _('Filter by user'), filter: true, filterInput: 'input#user-search',
+ dropdown_class: 'dropdown-menu-selectable dropdown-menu-user js-filter-submit',
+ placeholder: _('Search users'),
+ data: { current_user: true, field_name: 'user_id' }})
+
.abuse-reports
- if @abuse_reports.present?
.table-holder
diff --git a/app/views/admin/application_settings/_ci_cd.html.haml b/app/views/admin/application_settings/_ci_cd.html.haml
index 1f5bce19bc6..9806090c1a6 100644
--- a/app/views/admin/application_settings/_ci_cd.html.haml
+++ b/app/views/admin/application_settings/_ci_cd.html.haml
@@ -53,5 +53,11 @@
= s_('AdminSettings|Environment variables are protected by default')
.form-text.text-muted
= s_('AdminSettings|When creating a new environment variable it will be protected by default.')
+ .form-group
+ = f.label :ci_config_path, _('Default CI configuration path'), class: 'label-bold'
+ = f.text_field :default_ci_config_path, class: 'form-control', placeholder: '.gitlab-ci.yml'
+ %p.form-text.text-muted
+ = _("The default CI configuration path for new projects.").html_safe
+ = link_to icon('question-circle'), help_page_path('user/project/pipelines/settings', anchor: 'custom-ci-config-path'), target: '_blank'
= f.submit _('Save changes'), class: "btn btn-success"
diff --git a/app/views/admin/application_settings/_eks.html.haml b/app/views/admin/application_settings/_eks.html.haml
new file mode 100644
index 00000000000..b1f7ed76281
--- /dev/null
+++ b/app/views/admin/application_settings/_eks.html.haml
@@ -0,0 +1,31 @@
+- expanded = integration_expanded?('eks_')
+%section.settings.as-eks.no-animate#js-eks-settings{ class: ('expanded' if expanded) }
+ .settings-header
+ %h4
+ = _('Amazon EKS')
+ %button.btn.js-settings-toggle{ type: 'button' }
+ = expanded ? 'Collapse' : 'Expand'
+ %p
+ = _('Amazon EKS integration allows you to provision EKS clusters from GitLab.')
+
+ .settings-content
+ = form_for @application_setting, url: integrations_admin_application_settings_path(anchor: 'js-eks-settings'), html: { class: 'fieldset-form' } do |f|
+ = form_errors(@application_setting)
+
+ %fieldset
+ .form-group
+ .form-check
+ = f.check_box :eks_integration_enabled, class: 'form-check-input'
+ = f.label :eks_integration_enabled, class: 'form-check-label' do
+ Enable Amazon EKS integration
+ .form-group
+ = f.label :eks_account_id, 'Account ID', class: 'label-bold'
+ = f.text_field :eks_account_id, class: 'form-control'
+ .form-group
+ = f.label :eks_access_key_id, 'Access key ID', class: 'label-bold'
+ = f.text_field :eks_access_key_id, class: 'form-control'
+ .form-group
+ = f.label :eks_secret_access_key, 'Secret access key', class: 'label-bold'
+ = f.password_field :eks_secret_access_key, value: @application_setting.eks_secret_access_key, class: 'form-control'
+
+ = f.submit 'Save changes', class: "btn btn-success"
diff --git a/app/views/admin/application_settings/_outbound.html.haml b/app/views/admin/application_settings/_outbound.html.haml
index ad26f52aea7..42528f40123 100644
--- a/app/views/admin/application_settings/_outbound.html.haml
+++ b/app/views/admin/application_settings/_outbound.html.haml
@@ -4,7 +4,7 @@
%fieldset
.form-group
.form-check
- = f.check_box :allow_local_requests_from_web_hooks_and_services, class: 'form-check-input'
+ = f.check_box :allow_local_requests_from_web_hooks_and_services, class: 'form-check-input', data: { qa_selector: 'allow_requests_from_services_checkbox' }
= f.label :allow_local_requests_from_web_hooks_and_services, class: 'form-check-label' do
= _('Allow requests to the local network from web hooks and services')
.form-check
@@ -27,4 +27,4 @@
%span.form-text.text-muted
= _('Resolves IP addresses once and uses them to submit requests')
- = f.submit 'Save changes', class: "btn btn-success"
+ = f.submit 'Save changes', class: "btn btn-success", data: { qa_selector: 'save_changes_button' }
diff --git a/app/views/admin/application_settings/_plantuml.html.haml b/app/views/admin/application_settings/_plantuml.html.haml
index 86dc289dd7c..d35774d330d 100644
--- a/app/views/admin/application_settings/_plantuml.html.haml
+++ b/app/views/admin/application_settings/_plantuml.html.haml
@@ -1,18 +1,27 @@
-= form_for @application_setting, url: integrations_admin_application_settings_path(anchor: 'js-plantuml-settings'), html: { class: 'fieldset-form' } do |f|
- = form_errors(@application_setting)
+- expanded = integration_expanded?('plantuml_')
+%section.settings.as-plantuml.no-animate#js-plantuml-settings{ class: ('expanded' if expanded) }
+ .settings-header
+ %h4
+ = _('PlantUML')
+ %button.btn.btn-default.js-settings-toggle{ type: 'button' }
+ = expanded ? _('Collapse') : _('Expand')
+ %p
+ = _('Allow rendering of PlantUML diagrams in Asciidoc documents.')
+ .settings-content
+ = form_for @application_setting, url: integrations_admin_application_settings_path(anchor: 'js-plantuml-settings'), html: { class: 'fieldset-form' } do |f|
+ = form_errors(@application_setting) if expanded
- %fieldset
- .form-group
- .form-check
- = f.check_box :plantuml_enabled, class: 'form-check-input'
- = f.label :plantuml_enabled, class: 'form-check-label' do
- Enable PlantUML
- .form-group
- = f.label :plantuml_url, 'PlantUML URL', class: 'label-bold'
- = f.text_field :plantuml_url, class: 'form-control', placeholder: 'http://gitlab.your-plantuml-instance.com:8080'
- .form-text.text-muted
- Allow rendering of
- = link_to "PlantUML", "http://plantuml.com"
- diagrams in Asciidoc documents using an external PlantUML service.
+ %fieldset
+ .form-group
+ .form-check
+ = f.check_box :plantuml_enabled, class: 'form-check-input'
+ = f.label :plantuml_enabled, _('Enable PlantUML'), class: 'form-check-label'
+ .form-group
+ = f.label :plantuml_url, 'PlantUML URL', class: 'label-bold'
+ = f.text_field :plantuml_url, class: 'form-control', placeholder: 'http://gitlab.your-plantuml-instance.com:8080'
+ .form-text.text-muted
+ Allow rendering of
+ = link_to "PlantUML", "http://plantuml.com"
+ diagrams in Asciidoc documents using an external PlantUML service.
- = f.submit 'Save changes', class: "btn btn-success"
+ = f.submit _('Save changes'), class: "btn btn-success"
diff --git a/app/views/admin/application_settings/_repository_mirrors_form.html.haml b/app/views/admin/application_settings/_repository_mirrors_form.html.haml
index 362f4a42464..6e5fa6eb62c 100644
--- a/app/views/admin/application_settings/_repository_mirrors_form.html.haml
+++ b/app/views/admin/application_settings/_repository_mirrors_form.html.haml
@@ -7,9 +7,9 @@
.form-check
= f.check_box :mirror_available, class: 'form-check-input'
= f.label :mirror_available, class: 'form-check-label' do
- = _('Allow mirrors to be set up for projects')
+ = _('Allow repository mirroring to be configured by project maintainers')
%span.form-text.text-muted
- = _('If disabled, only admins will be able to set up mirrors in projects.')
+ = _('If disabled, only admins will be able to configure repository mirroring.')
= link_to icon('question-circle'), help_page_path('workflow/repository_mirroring')
= render_if_exists 'admin/application_settings/mirror_settings', form: f
diff --git a/app/views/admin/application_settings/_snowplow.html.haml b/app/views/admin/application_settings/_snowplow.html.haml
index 31fd12d191e..a2597433270 100644
--- a/app/views/admin/application_settings/_snowplow.html.haml
+++ b/app/views/admin/application_settings/_snowplow.html.haml
@@ -1,4 +1,4 @@
-- expanded = true if !@application_setting.valid? && @application_setting.errors.any? { |k| k.to_s.start_with?('snowplow_') }
+- expanded = integration_expanded?('snowplow_')
%section.settings.as-snowplow.no-animate#js-snowplow-settings{ class: ('expanded' if expanded) }
.settings-header
%h4
@@ -10,7 +10,7 @@
.settings-content
= form_for @application_setting, url: integrations_admin_application_settings_path(anchor: 'js-snowplow-settings'), html: { class: 'fieldset-form' } do |f|
- = form_errors(@application_setting)
+ = form_errors(@application_setting) if expanded
%fieldset
.form-group
@@ -21,10 +21,13 @@
= f.label :snowplow_collector_hostname, _('Collector hostname'), class: 'label-light'
= f.text_field :snowplow_collector_hostname, class: 'form-control', placeholder: 'snowplow.example.com'
.form-group
- = f.label :snowplow_site_id, _('Site ID'), class: 'label-light'
- = f.text_field :snowplow_site_id, class: 'form-control'
+ = f.label :snowplow_app_id, _('App ID'), class: 'label-light'
+ = f.text_field :snowplow_app_id, class: 'form-control'
.form-group
= f.label :snowplow_cookie_domain, _('Cookie domain'), class: 'label-light'
= f.text_field :snowplow_cookie_domain, class: 'form-control'
+ .form-group
+ = f.label :snowplow_iglu_registry_url, _('Iglu registry URL (optional)'), class: 'label-light'
+ = f.text_field :snowplow_iglu_registry_url, class: 'form-control'
= f.submit _('Save changes'), class: 'btn btn-success'
diff --git a/app/views/admin/application_settings/_sourcegraph.html.haml b/app/views/admin/application_settings/_sourcegraph.html.haml
new file mode 100644
index 00000000000..23cda0334a2
--- /dev/null
+++ b/app/views/admin/application_settings/_sourcegraph.html.haml
@@ -0,0 +1,38 @@
+- return unless Gitlab::Sourcegraph.feature_available?
+- expanded = integration_expanded?('sourcegraph_')
+
+%section.settings.as-sourcegraph.no-animate#js-sourcegraph-settings{ class: ('expanded' if expanded) }
+ .settings-header
+ %h4
+ = _('Sourcegraph')
+ %button.btn.btn-default.js-settings-toggle{ type: 'button' }
+ = expanded ? _('Collapse') : _('Expand')
+ %p
+ - link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: 'https://sourcegraph.com/' }
+ - link_end = "#{sprite_icon('external-link', size: 12, css_class: 'ml-1 vertical-align-center')}</a>".html_safe
+ = s_('SourcegraphAdmin|Enable code intelligence powered by %{link_start}Sourcegraph%{link_end} on your GitLab instance\'s code views and merge requests.').html_safe % { link_start: link_start, link_end: link_end }
+ %span
+ = link_to s_('SourcegraphAdmin|More information'), help_page_path('integration/sourcegraph.md'), target: '_blank'
+
+
+ .settings-content
+ = form_for @application_setting, url: integrations_admin_application_settings_path(anchor: 'js-sourcegraph-settings'), html: { class: 'fieldset-form' } do |f|
+ = form_errors(@application_setting)
+
+ %fieldset
+ .form-group
+ .form-check
+ = f.check_box :sourcegraph_enabled, class: 'form-check-input'
+ = f.label :sourcegraph_enabled, s_('SourcegraphAdmin|Enable Sourcegraph'), class: 'form-check-label'
+ .form-group
+ .form-check
+ = f.check_box :sourcegraph_public_only, class: 'form-check-input'
+ = f.label :sourcegraph_public_only, s_('SourcegraphAdmin|Block on private and internal projects'), class: 'form-check-label'
+ .form-text.text-muted
+ = s_('SourcegraphAdmin|If checked, only public projects will have code intelligence and communicate with Sourcegraph.')
+ .form-group
+ = f.label :sourcegraph_url, s_('SourcegraphAdmin|Sourcegraph URL'), class: 'label-bold'
+ = f.text_field :sourcegraph_url, class: 'form-control', placeholder: s_('SourcegraphAdmin|e.g. https://sourcegraph.example.com')
+ .form-text.text-muted
+ = s_('SourcegraphAdmin|Configure the URL to a Sourcegraph instance which can read your GitLab projects.')
+ = f.submit s_('SourcegraphAdmin|Save changes'), class: 'btn btn-success'
diff --git a/app/views/admin/application_settings/_third_party_offers.html.haml b/app/views/admin/application_settings/_third_party_offers.html.haml
index adde09f75e4..256b1f74bfa 100644
--- a/app/views/admin/application_settings/_third_party_offers.html.haml
+++ b/app/views/admin/application_settings/_third_party_offers.html.haml
@@ -1,13 +1,21 @@
-- application_setting = local_assigns.fetch(:application_setting)
+- expanded = integration_expanded?('hide_third_party_')
+%section.settings.as-third-party-offers.no-animate#js-third-party-offers-settings{ class: ('expanded' if expanded) }
+ .settings-header
+ %h4
+ = _('Third party offers')
+ %button.btn.btn-default.js-settings-toggle{ type: 'button' }
+ = expanded ? _('Collapse') : _('Expand')
+ %p
+ = _('Control the display of third party offers.')
+ .settings-content
-= form_for application_setting, url: integrations_admin_application_settings_path(anchor: 'js-third-party-offers-settings'), html: { class: 'fieldset-form' } do |f|
- = form_errors(application_setting)
+ = form_for @application_setting, url: integrations_admin_application_settings_path(anchor: 'js-third-party-offers-settings'), html: { class: 'fieldset-form' } do |f|
+ = form_errors(@application_setting) if expanded
- %fieldset
- .form-group
- .form-check
- = f.check_box :hide_third_party_offers, class: 'form-check-input'
- = f.label :hide_third_party_offers, class: 'form-check-label' do
- Do not display offers from third parties within GitLab
+ %fieldset
+ .form-group
+ .form-check
+ = f.check_box :hide_third_party_offers, class: 'form-check-input'
+ = f.label :hide_third_party_offers, _('Do not display offers from third parties within GitLab'), class: 'form-check-label'
- = f.submit 'Save changes', class: "btn btn-success"
+ = f.submit _('Save changes'), class: "btn btn-success"
diff --git a/app/views/admin/application_settings/integrations.html.haml b/app/views/admin/application_settings/integrations.html.haml
index 310e86b1377..0aa833e49a8 100644
--- a/app/views/admin/application_settings/integrations.html.haml
+++ b/app/views/admin/application_settings/integrations.html.haml
@@ -2,30 +2,11 @@
- page_title _("Integrations")
- @content_class = "limit-container-width" unless fluid_layout
-= render_if_exists 'admin/application_settings/elasticsearch_form', expanded: expanded_by_default?
+= render_if_exists 'admin/application_settings/elasticsearch_form'
+= render 'admin/application_settings/plantuml'
+= render 'admin/application_settings/sourcegraph'
+= render_if_exists 'admin/application_settings/slack'
+= render 'admin/application_settings/third_party_offers'
+= render 'admin/application_settings/snowplow'
+= render 'admin/application_settings/eks' if Feature.enabled?(:create_eks_clusters)
-%section.settings.as-plantuml.no-animate#js-plantuml-settings{ class: ('expanded' if expanded_by_default?) }
- .settings-header
- %h4
- = _('PlantUML')
- %button.btn.btn-default.js-settings-toggle{ type: 'button' }
- = expanded_by_default? ? _('Collapse') : _('Expand')
- %p
- = _('Allow rendering of PlantUML diagrams in Asciidoc documents.')
- .settings-content
- = render 'plantuml'
-
-= render_if_exists 'admin/application_settings/slack', expanded: expanded_by_default?
-
-%section.settings.as-third-party-offers.no-animate#js-third-party-offers-settings{ class: ('expanded' if expanded_by_default?) }
- .settings-header
- %h4
- = _('Third party offers')
- %button.btn.btn-default.js-settings-toggle{ type: 'button' }
- = expanded_by_default? ? _('Collapse') : _('Expand')
- %p
- = _('Control the display of third party offers.')
- .settings-content
- = render 'third_party_offers', application_setting: @application_setting
-
-= render_if_exists 'admin/application_settings/snowplow', expanded: expanded_by_default?
diff --git a/app/views/admin/application_settings/network.html.haml b/app/views/admin/application_settings/network.html.haml
index 092834b993c..7bd51172195 100644
--- a/app/views/admin/application_settings/network.html.haml
+++ b/app/views/admin/application_settings/network.html.haml
@@ -24,7 +24,7 @@
.settings-content
= render 'ip_limits'
-%section.settings.as-outbound.no-animate#js-outbound-settings{ class: ('expanded' if expanded_by_default?) }
+%section.settings.as-outbound.no-animate#js-outbound-settings{ class: ('expanded' if expanded_by_default?), data: { qa_selector: 'outbound_requests_section' } }
.settings-header
%h4
= _('Outbound requests')
diff --git a/app/views/admin/application_settings/repository.html.haml b/app/views/admin/application_settings/repository.html.haml
index 25f8b6541b5..b0934a9d9fb 100644
--- a/app/views/admin/application_settings/repository.html.haml
+++ b/app/views/admin/application_settings/repository.html.haml
@@ -5,11 +5,11 @@
%section.settings.as-mirror.no-animate#js-mirror-settings{ class: ('expanded' if expanded_by_default?) }
.settings-header
%h4
- = _('Repository mirror')
+ = _('Repository mirroring')
%button.btn.js-settings-toggle{ type: 'button' }
= expanded_by_default? ? 'Collapse' : 'Expand'
%p
- = _('Configure push mirrors.')
+ = _('Configure repository mirroring.')
.settings-content
= render partial: 'repository_mirrors_form'
diff --git a/app/views/admin/dashboard/index.html.haml b/app/views/admin/dashboard/index.html.haml
index 41147950c40..e5a3c0df9bf 100644
--- a/app/views/admin/dashboard/index.html.haml
+++ b/app/views/admin/dashboard/index.html.haml
@@ -41,17 +41,38 @@
.info-well
.well-segment.admin-well.admin-well-features
%h4 Features
- = feature_entry(_('Sign up'), href: admin_application_settings_path(anchor: 'js-signup-settings'), enabled: allow_signup?)
- = feature_entry(_('LDAP'), enabled: Gitlab.config.ldap.enabled)
- = feature_entry(_('Gravatar'), href: admin_application_settings_path(anchor: 'js-account-settings'), enabled: gravatar_enabled?)
- = feature_entry(_('OmniAuth'), href: admin_application_settings_path(anchor: 'js-signin-settings'), enabled: Gitlab::Auth.omniauth_enabled?)
- = feature_entry(_('Reply by email'), enabled: Gitlab::IncomingEmail.enabled?)
+ = feature_entry(_('Sign up'),
+ href: admin_application_settings_path(anchor: 'js-signup-settings'),
+ enabled: allow_signup?)
+
+ = feature_entry(_('LDAP'),
+ enabled: Gitlab.config.ldap.enabled)
+
+ = feature_entry(_('Gravatar'),
+ href: admin_application_settings_path(anchor: 'js-account-settings'),
+ enabled: gravatar_enabled?)
+
+ = feature_entry(_('OmniAuth'),
+ href: admin_application_settings_path(anchor: 'js-signin-settings'),
+ enabled: Gitlab::Auth.omniauth_enabled?)
+
+ = feature_entry(_('Reply by email'),
+ enabled: Gitlab::IncomingEmail.enabled?)
= render_if_exists 'admin/dashboard/elastic_and_geo'
- = feature_entry(_('Container Registry'), href: ci_cd_admin_application_settings_path(anchor: 'js-registry-settings'), enabled: Gitlab.config.registry.enabled)
- = feature_entry(_('Gitlab Pages'), href: help_instance_configuration_url, enabled: Gitlab.config.pages.enabled)
- = feature_entry(_('Shared Runners'), href: admin_runners_path, enabled: Gitlab.config.gitlab_ci.shared_runners_enabled)
+ = feature_entry(_('Container Registry'),
+ href: ci_cd_admin_application_settings_path(anchor: 'js-registry-settings'),
+ enabled: Gitlab.config.registry.enabled,
+ doc_href: help_page_path('user/packages/container_registry/index'))
+
+ = feature_entry(_('Gitlab Pages'),
+ enabled: Gitlab.config.pages.enabled,
+ doc_href: help_instance_configuration_url)
+
+ = feature_entry(_('Shared Runners'),
+ href: admin_runners_path,
+ enabled: Gitlab.config.gitlab_ci.shared_runners_enabled)
.col-md-4
.info-well
.well-segment.admin-well
diff --git a/app/views/admin/sessions/_new_base.html.haml b/app/views/admin/sessions/_new_base.html.haml
index 55aea0296e7..3d77a439d61 100644
--- a/app/views/admin/sessions/_new_base.html.haml
+++ b/app/views/admin/sessions/_new_base.html.haml
@@ -4,4 +4,4 @@
= password_field_tag :password, nil, class: 'form-control', required: true, title: _('This field is required.'), data: { qa_selector: 'password_field' }
.submit-container.move-submit-down
- = submit_tag _('Enter admin mode'), class: 'btn btn-success', data: { qa_selector: 'sign_in_button' }
+ = submit_tag _('Enter Admin Mode'), class: 'btn btn-success', data: { qa_selector: 'sign_in_button' }
diff --git a/app/views/admin/sessions/_signin_box.html.haml b/app/views/admin/sessions/_signin_box.html.haml
index 69baa76060e..1d19915d3c5 100644
--- a/app/views/admin/sessions/_signin_box.html.haml
+++ b/app/views/admin/sessions/_signin_box.html.haml
@@ -1,4 +1,4 @@
-- if form_based_providers.any?
+- if any_form_based_providers_enabled?
- if password_authentication_enabled_for_web?
.login-box.tab-pane{ id: 'login-pane', role: 'tabpanel' }
diff --git a/app/views/admin/sessions/_tabs_normal.html.haml b/app/views/admin/sessions/_tabs_normal.html.haml
index f5dedb5ad76..20830051d31 100644
--- a/app/views/admin/sessions/_tabs_normal.html.haml
+++ b/app/views/admin/sessions/_tabs_normal.html.haml
@@ -1,3 +1,3 @@
%ul.nav-links.new-session-tabs.nav-tabs.nav{ role: 'tablist' }
%li.nav-item{ role: 'presentation' }
- %a.nav-link.active{ href: '#login-pane', data: { toggle: 'tab', qa_selector: 'sign_in_tab' }, role: 'tab' }= _('Enter admin mode')
+ %a.nav-link.active{ href: '#login-pane', data: { toggle: 'tab', qa_selector: 'sign_in_tab' }, role: 'tab' }= _('Enter Admin Mode')
diff --git a/app/views/admin/sessions/new.html.haml b/app/views/admin/sessions/new.html.haml
index ee06b4a1741..73028e78ea5 100644
--- a/app/views/admin/sessions/new.html.haml
+++ b/app/views/admin/sessions/new.html.haml
@@ -1,5 +1,5 @@
- @hide_breadcrumbs = true
-- page_title _('Enter admin mode')
+- page_title _('Enter Admin Mode')
.row.justify-content-center
.col-6.new-session-forms-container
diff --git a/app/views/admin/users/show.html.haml b/app/views/admin/users/show.html.haml
index 706fa033c51..cd07fee8e59 100644
--- a/app/views/admin/users/show.html.haml
+++ b/app/views/admin/users/show.html.haml
@@ -152,7 +152,7 @@
- email = " (#{@user.unconfirmed_email})"
%p This user has an unconfirmed email address#{email}. You may force a confirmation.
%br
- = link_to 'Confirm user', confirm_admin_user_path(@user), method: :put, class: "btn btn-info", data: { confirm: 'Are you sure?' }
+ = link_to 'Confirm user', confirm_admin_user_path(@user), method: :put, class: "btn btn-info", data: { confirm: 'Are you sure?', qa_selector: 'confirm_user_button' }
= render_if_exists 'admin/users/user_detail_note'
diff --git a/app/views/ci/group_variables/_content.html.haml b/app/views/ci/group_variables/_content.html.haml
new file mode 100644
index 00000000000..db5f1021f57
--- /dev/null
+++ b/app/views/ci/group_variables/_content.html.haml
@@ -0,0 +1 @@
+= _("These variables are configured in the parent group settings, and will be active in the current project in addition to the project variables.")
diff --git a/app/views/ci/group_variables/_header.html.haml b/app/views/ci/group_variables/_header.html.haml
new file mode 100644
index 00000000000..71d123ec9f2
--- /dev/null
+++ b/app/views/ci/group_variables/_header.html.haml
@@ -0,0 +1,5 @@
+%h5
+ = _('Group variables (inherited)')
+
+%p
+ = render "ci/group_variables/content"
diff --git a/app/views/ci/group_variables/_index.html.haml b/app/views/ci/group_variables/_index.html.haml
new file mode 100644
index 00000000000..c350ba5caf7
--- /dev/null
+++ b/app/views/ci/group_variables/_index.html.haml
@@ -0,0 +1,13 @@
+- variables = @project.group.self_and_ancestors.map(&:variables).flatten
+
+.row
+ .col-lg-12
+ .group-variable-list
+ = render 'ci/group_variables/variable_header'
+ - variables.each do |variable|
+ .group-variable-row.d-flex.w-100.border-bottom.pt-2.pb-2
+ .table-section.section-40.append-right-10.key
+ = variable.key
+ .table-section.section-40.append-right-10
+ %a.group-origin-link{ href: group_settings_ci_cd_path(variable.group) }
+ = variable.group.name
diff --git a/app/views/ci/group_variables/_variable_header.html.haml b/app/views/ci/group_variables/_variable_header.html.haml
new file mode 100644
index 00000000000..1a3168cf781
--- /dev/null
+++ b/app/views/ci/group_variables/_variable_header.html.haml
@@ -0,0 +1,5 @@
+.group-variable-keys.d-flex.w-100.align-items-center.pb-2.border-bottom
+ .bold.table-section.section-40.append-right-10
+ = s_('Key')
+ .bold.table-section.section-40.append-right-10
+ = s_('Origin')
diff --git a/app/views/ci/variables/_header.html.haml b/app/views/ci/variables/_header.html.haml
index dbfa0a9e5a1..ce4dd5a4877 100644
--- a/app/views/ci/variables/_header.html.haml
+++ b/app/views/ci/variables/_header.html.haml
@@ -7,5 +7,5 @@
%button.btn.btn-default.js-settings-toggle{ type: 'button' }
= expanded ? _('Collapse') : _('Expand')
-%p.append-bottom-0
+%p
= render "ci/variables/content"
diff --git a/app/views/ci/variables/_index.html.haml b/app/views/ci/variables/_index.html.haml
index 94102b4dcd0..7ae5c48b93c 100644
--- a/app/views/ci/variables/_index.html.haml
+++ b/app/views/ci/variables/_index.html.haml
@@ -24,3 +24,8 @@
= n_('Hide value', 'Hide values', @variables.size)
- else
= n_('Reveal value', 'Reveal values', @variables.size)
+ - if !@group && @project.group
+ .settings-header.border-top.prepend-top-20
+ = render 'ci/group_variables/header'
+ .settings-content.pr-0
+ = render 'ci/group_variables/index'
diff --git a/app/views/ci/variables/_url_query_variable_row.html.haml b/app/views/ci/variables/_url_query_variable_row.html.haml
new file mode 100644
index 00000000000..6672a8e5ea0
--- /dev/null
+++ b/app/views/ci/variables/_url_query_variable_row.html.haml
@@ -0,0 +1,28 @@
+- form_field = local_assigns.fetch(:form_field, nil)
+- variable = local_assigns.fetch(:variable, nil)
+
+- key = variable[0]
+- value = variable[1]
+- variable_type = variable[2] || "env_var"
+
+- destroy_input_name = "#{form_field}[variables_attributes][][_destroy]"
+- variable_type_input_name = "#{form_field}[variables_attributes][][variable_type]"
+- key_input_name = "#{form_field}[variables_attributes][][key]"
+- value_input_name = "#{form_field}[variables_attributes][][secret_value]"
+
+%li.js-row.ci-variable-row
+ .ci-variable-row-body.border-bottom
+ %input.js-ci-variable-input-destroy{ type: "hidden", name: destroy_input_name }
+ %select.js-ci-variable-input-variable-type.ci-variable-body-item.form-control.select-control.custom-select.table-section.section-15{ name: variable_type_input_name }
+ = options_for_select(ci_variable_type_options, variable_type)
+ %input.js-ci-variable-input-key.ci-variable-body-item.qa-ci-variable-input-key.form-control.table-section.section-15{ type: "text",
+ name: key_input_name,
+ value: key,
+ placeholder: s_('CiVariables|Input variable key') }
+ .ci-variable-body-item.gl-show-field-errors.table-section.section-15.border-top-0.p-0
+ %textarea.js-ci-variable-input-value.js-secret-value.qa-ci-variable-input-value.form-control{ rows: 1,
+ name: value_input_name,
+ placeholder: s_('CiVariables|Input variable value') }
+ = value
+ %button.js-row-remove-button.ci-variable-row-remove-button.table-section.section-5.border-top-0{ type: 'button', 'aria-label': s_('CiVariables|Remove variable row') }
+ = icon('minus-circle')
diff --git a/app/views/clusters/clusters/_advanced_settings.html.haml b/app/views/clusters/clusters/_advanced_settings.html.haml
index 8005dcbf65f..493d7a00854 100644
--- a/app/views/clusters/clusters/_advanced_settings.html.haml
+++ b/app/views/clusters/clusters/_advanced_settings.html.haml
@@ -1,3 +1,9 @@
+- group_id = @cluster.group.id if @cluster.group_type?
+
+- if @cluster.project_type?
+ - group_id = @cluster.project.group.id if @cluster.project.group
+ - user_id = @cluster.project.namespace.owner_id unless group_id
+
- if can?(current_user, :admin_cluster, @cluster)
- unless @cluster.provided_by_user?
.append-bottom-20
@@ -7,6 +13,21 @@
- link_gke = link_to(s_('ClusterIntegration|Google Kubernetes Engine'), @cluster.gke_cluster_url, target: '_blank', rel: 'noopener noreferrer')
= s_('ClusterIntegration|Manage your Kubernetes cluster by visiting %{link_gke}').html_safe % { link_gke: link_gke }
+ = form_for @cluster, url: clusterable.cluster_path(@cluster), as: :cluster, html: { class: 'cluster_management_form' } do |field|
+
+ %h5
+ = s_('ClusterIntegration|Cluster management project (alpha)')
+
+ .form-group
+ .form-text.text-muted
+ = project_select_tag('cluster[management_project_id]', class: 'hidden-filter-value', toggle_class: 'js-project-search js-project-filter js-filter-submit', dropdown_class: 'dropdown-menu-selectable dropdown-menu-project js-filter-submit',
+ placeholder: _('Select project'), idAttribute: 'id', data: { order_by: 'last_activity_at', idattribute: 'id', simple_filter: true, allow_clear: true, include_groups: false, include_projects_in_subgroups: true, group_id: group_id, user_id: user_id }, value: @cluster.management_project_id)
+ .text-muted
+ = s_('ClusterIntegration|A cluster management project can be used to run deployment jobs with Kubernetes <code>cluster-admin</code> privileges.').html_safe
+ = link_to _('More information'), help_page_path('user/clusters/management_project.md'), target: '_blank'
+ .form-group
+ = field.submit _('Save changes'), class: 'btn btn-success qa-save-domain'
+
.sub-section.form-group
%h4.text-danger
= s_('ClusterIntegration|Remove Kubernetes cluster integration')
diff --git a/app/views/clusters/clusters/_banner.html.haml b/app/views/clusters/clusters/_banner.html.haml
index 4b4278075a6..7d97aaccbcf 100644
--- a/app/views/clusters/clusters/_banner.html.haml
+++ b/app/views/clusters/clusters/_banner.html.haml
@@ -1,10 +1,10 @@
.hidden.js-cluster-error.bs-callout.bs-callout-danger{ role: 'alert' }
- = s_('ClusterIntegration|Something went wrong while creating your Kubernetes cluster on Google Kubernetes Engine')
+ = s_('ClusterIntegration|Something went wrong while creating your Kubernetes cluster')
%p.js-error-reason
.hidden.js-cluster-creating.bs-callout.bs-callout-info{ role: 'alert' }
%span.spinner.spinner-dark.spinner-sm{ 'aria-label': 'Loading' }
- %span.prepend-left-4= s_('ClusterIntegration|Kubernetes cluster is being created on Google Kubernetes Engine...')
+ %span.prepend-left-4= s_('ClusterIntegration|Kubernetes cluster is being created...')
.hidden.row.js-cluster-api-unreachable.bs-callout.bs-callout-warning{ role: 'alert' }
.col-11
@@ -19,4 +19,4 @@
%button.js-close-banner.close.cluster-application-banner-close.h-100.m-0= "×"
.hidden.js-cluster-success.bs-callout.bs-callout-success{ role: 'alert' }
- = s_("ClusterIntegration|Kubernetes cluster was successfully created on Google Kubernetes Engine.")
+ = s_("ClusterIntegration|Kubernetes cluster was successfully created.")
diff --git a/app/views/clusters/clusters/_gcp_signup_offer_banner.html.haml b/app/views/clusters/clusters/_gcp_signup_offer_banner.html.haml
index a9299af8d78..617e5d1d5d3 100644
--- a/app/views/clusters/clusters/_gcp_signup_offer_banner.html.haml
+++ b/app/views/clusters/clusters/_gcp_signup_offer_banner.html.haml
@@ -7,6 +7,6 @@
.gcp-signup-offer--copy
%h4= s_('ClusterIntegration|Did you know?')
%p= s_('ClusterIntegration|Every new Google Cloud Platform (GCP) account receives $300 in credit upon %{sign_up_link}. In partnership with Google, GitLab is able to offer an additional $200 for both new and existing GCP accounts to get started with GitLab\'s Google Kubernetes Engine Integration.').html_safe % { sign_up_link: link }
- %a.btn.btn-default{ href: 'https://goo.gl/AaJzRW', target: '_blank', rel: 'noopener noreferrer' }
+ %a.btn.btn-default{ href: 'https://cloud.google.com/partners/partnercredit/?pcn_code=0014M00001h35gDQAQ#contact-form', target: '_blank', rel: 'noopener noreferrer' }
= s_("ClusterIntegration|Apply for credit")
diff --git a/app/views/clusters/clusters/aws/_new.html.haml b/app/views/clusters/clusters/aws/_new.html.haml
new file mode 100644
index 00000000000..48467f88f52
--- /dev/null
+++ b/app/views/clusters/clusters/aws/_new.html.haml
@@ -0,0 +1,20 @@
+- if !Gitlab::CurrentSettings.eks_integration_enabled?
+ - documentation_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: help_page_path("integration/amazon") }
+ = s_('Amazon authentication is not %{link_start}correctly configured%{link_end}. Ask your GitLab administrator if you want to use this service.').html_safe % { link_start: documentation_link_start, link_end: '<a/>'.html_safe }
+- else
+ .js-create-eks-cluster-form-container{ data: { 'gitlab-managed-cluster-help-path' => help_page_path('user/project/clusters/index.md', anchor: 'gitlab-managed-clusters'),
+ 'create-role-path' => clusterable.authorize_aws_role_path,
+ 'sign-out-path' => clusterable.revoke_aws_role_path,
+ 'create-cluster-path' => clusterable.create_aws_clusters_path,
+ 'get-roles-path' => clusterable.aws_api_proxy_path('roles'),
+ 'get-regions-path' => clusterable.aws_api_proxy_path('regions'),
+ 'get-key-pairs-path' => clusterable.aws_api_proxy_path('key_pairs'),
+ 'get-vpcs-path' => clusterable.aws_api_proxy_path('vpcs'),
+ 'get-subnets-path' => clusterable.aws_api_proxy_path('subnets'),
+ 'get-security-groups-path' => clusterable.aws_api_proxy_path('security_groups'),
+ 'get-instance-types-path' => clusterable.aws_api_proxy_path('instance_types'),
+ 'account-id' => Gitlab::CurrentSettings.eks_account_id,
+ 'external-id' => @aws_role.role_external_id,
+ 'kubernetes-integration-help-path' => help_page_path('user/project/clusters/index'),
+ 'external-link-icon' => icon('external-link'),
+ 'has-credentials' => @aws_role.role_arn.present?.to_s } }
diff --git a/app/views/clusters/clusters/cloud_providers/_cloud_provider_button.html.haml b/app/views/clusters/clusters/cloud_providers/_cloud_provider_button.html.haml
index d4999798c19..56d46580b9e 100644
--- a/app/views/clusters/clusters/cloud_providers/_cloud_provider_button.html.haml
+++ b/app/views/clusters/clusters/cloud_providers/_cloud_provider_button.html.haml
@@ -1,8 +1,10 @@
- provider = local_assigns.fetch(:provider)
- logo_path = local_assigns.fetch(:logo_path)
- label = local_assigns.fetch(:label)
+- last = local_assigns.fetch(:last, false)
+- classes = ['btn btn-light btn-outline flex-fill d-inline-flex flex-column justify-content-center align-items-center', ('mr-3' unless last)]
-= link_to clusterable.new_path(provider: provider), class: 'btn gl-button btn-outline flex-fill d-inline-flex flex-column mr-3 justify-content-center align-items-center' do
- .svg-content= image_tag logo_path, alt: label, class: 'gl-w-13 gl-h-13'
+= link_to clusterable.new_path(provider: provider), class: classes do
+ .svg-content.p-2= image_tag logo_path, alt: label, class: 'gl-w-64 gl-h-64'
%span
= label
diff --git a/app/views/clusters/clusters/cloud_providers/_cloud_provider_selector.html.haml b/app/views/clusters/clusters/cloud_providers/_cloud_provider_selector.html.haml
index 7a93a7604f5..91925f5f96f 100644
--- a/app/views/clusters/clusters/cloud_providers/_cloud_provider_selector.html.haml
+++ b/app/views/clusters/clusters/cloud_providers/_cloud_provider_selector.html.haml
@@ -2,10 +2,10 @@
- eks_label = s_('ClusterIntegration|Amazon EKS')
- create_cluster_label = s_('ClusterIntegration|Create cluster on')
.d-flex.flex-column
- %h5
+ %h5.mb-3
= create_cluster_label
.d-flex
= render partial: 'clusters/clusters/cloud_providers/cloud_provider_button',
- locals: { provider: 'eks', label: eks_label, logo_path: 'illustrations/logos/amazon_eks.svg' }
+ locals: { provider: 'aws', label: eks_label, logo_path: 'illustrations/logos/amazon_eks.svg' }
= render partial: 'clusters/clusters/cloud_providers/cloud_provider_button',
- locals: { provider: 'gke', label: gke_label, logo_path: 'illustrations/logos/google_gke.svg' }
+ locals: { provider: 'gcp', label: gke_label, logo_path: 'illustrations/logos/google_gke.svg', last: true }
diff --git a/app/views/clusters/clusters/eks/_index.html.haml b/app/views/clusters/clusters/eks/_index.html.haml
deleted file mode 100644
index db64698a7f2..00000000000
--- a/app/views/clusters/clusters/eks/_index.html.haml
+++ /dev/null
@@ -1,2 +0,0 @@
-.js-create-eks-cluster-form-container{ data: { 'gitlab-managed-cluster-help-path' => help_page_path('user/project/clusters/index.md', anchor: 'gitlab-managed-clusters'),
-'kubernetes-integration-help-path' => help_page_path('user/project/clusters/index') } }
diff --git a/app/views/clusters/clusters/gcp/_form.html.haml b/app/views/clusters/clusters/gcp/_form.html.haml
index cca16ce7eda..95670a2ec87 100644
--- a/app/views/clusters/clusters/gcp/_form.html.haml
+++ b/app/views/clusters/clusters/gcp/_form.html.haml
@@ -64,12 +64,13 @@
%p.form-text.text-muted
= s_('ClusterIntegration|Learn more about %{help_link_start_machine_type}machine types%{help_link_end} and %{help_link_start_pricing}pricing%{help_link_end}.').html_safe % { help_link_start_machine_type: help_link_start % { url: machine_type_link_url }, help_link_start_pricing: help_link_start % { url: pricing_link_url }, help_link_end: help_link_end }
- .form-group
- = provider_gcp_field.check_box :cloud_run, { label: s_('ClusterIntegration|Enable Cloud Run on GKE (beta)'),
- label_class: 'label-bold' }
- .form-text.text-muted
- = s_('ClusterIntegration|Uses the Cloud Run, Istio, and HTTP Load Balancing addons for this cluster.')
- = link_to _('More information'), help_page_path('user/project/clusters/index.md', anchor: 'cloud-run-on-gke'), target: '_blank'
+ - if Feature.enabled?(:create_cloud_run_clusters, clusterable)
+ .form-group
+ = provider_gcp_field.check_box :cloud_run, { label: s_('ClusterIntegration|Enable Cloud Run on GKE (beta)'),
+ label_class: 'label-bold' }
+ .form-text.text-muted
+ = s_('ClusterIntegration|Uses the Cloud Run, Istio, and HTTP Load Balancing addons for this cluster.')
+ = link_to _('More information'), help_page_path('user/project/clusters/index.md', anchor: 'cloud-run-on-gke'), target: '_blank'
.form-group
= field.check_box :managed, { label: s_('ClusterIntegration|GitLab-managed cluster'),
diff --git a/app/views/clusters/clusters/gcp/_new.html.haml b/app/views/clusters/clusters/gcp/_new.html.haml
new file mode 100644
index 00000000000..3d47f4bf2c3
--- /dev/null
+++ b/app/views/clusters/clusters/gcp/_new.html.haml
@@ -0,0 +1,7 @@
+= render 'clusters/clusters/gcp/header'
+- if @valid_gcp_token
+ = render 'clusters/clusters/gcp/form'
+- elsif @authorize_url
+ = render 'clusters/clusters/gcp/signin_with_google_button'
+- else
+ = render 'clusters/clusters/gcp/gcp_not_configured'
diff --git a/app/views/clusters/clusters/index.html.haml b/app/views/clusters/clusters/index.html.haml
index 9bab3bf56aa..049010cadf4 100644
--- a/app/views/clusters/clusters/index.html.haml
+++ b/app/views/clusters/clusters/index.html.haml
@@ -16,7 +16,7 @@
.bs-callout.bs-callout-info
= s_('ClusterIntegration|Clusters are utilized by selecting the nearest ancestor with a matching environment scope. For example, project clusters will override group clusters.')
%strong
- = link_to _('More information'), help_page_path('user/group/clusters/', anchor: 'cluster-precedence')
+ = link_to _('More information'), help_page_path('user/group/clusters/index', anchor: 'cluster-precedence')
.clusters-table.js-clusters-list
.gl-responsive-table-row.table-row-header{ role: "row" }
diff --git a/app/views/clusters/clusters/new.html.haml b/app/views/clusters/clusters/new.html.haml
index 2c23426aaf9..cb8cbe4e6f2 100644
--- a/app/views/clusters/clusters/new.html.haml
+++ b/app/views/clusters/clusters/new.html.haml
@@ -2,9 +2,6 @@
- page_title _('Kubernetes Cluster')
- create_eks_enabled = Feature.enabled?(:create_eks_clusters)
- active_tab = local_assigns.fetch(:active_tab, 'create')
-- create_on_gke_tab_label = s_('ClusterIntegration|Create new Cluster on GKE')
-- create_on_eks_tab_label = s_('ClusterIntegration|Create new Cluster on EKS')
-- create_new_cluster_label = s_('ClusterIntegration|Create new Cluster')
= javascript_include_tag 'https://apis.google.com/js/api.js'
= render_gcp_signup_offer
@@ -18,14 +15,9 @@
%a.nav-link{ href: '#create-cluster-pane', id: 'create-cluster-tab', class: active_when(active_tab == 'create'), data: { toggle: 'tab' }, role: 'tab' }
%span
- if create_eks_enabled
- - if @gke_selected
- = create_on_gke_tab_label
- - elsif @eks_selected
- = create_on_eks_tab_label
- - else
- = create_new_cluster_label
+ = create_new_cluster_label(provider: params[:provider])
- else
- = create_on_gke_tab_label
+ = create_new_cluster_label(provider: 'gcp')
%li.nav-item{ role: 'presentation' }
%a.nav-link{ href: '#add-cluster-pane', id: 'add-cluster-tab', class: active_when(active_tab == 'add'), data: { toggle: 'tab' }, role: 'tab' }
%span Add existing cluster
@@ -33,27 +25,10 @@
.tab-content.gitlab-tab-content
- if create_eks_enabled
.tab-pane{ id: 'create-cluster-pane', class: active_when(active_tab == 'create'), role: 'tabpanel' }
- - if @gke_selected
- = render 'clusters/clusters/gcp/header'
- - if @valid_gcp_token
- = render 'clusters/clusters/gcp/form'
- - elsif @authorize_url
- = render 'clusters/clusters/gcp/signin_with_google_button'
- - else
- = render 'clusters/clusters/gcp/gcp_not_configured'
- - elsif @eks_selected
- = render 'clusters/clusters/eks/index'
- - else
- = render 'clusters/clusters/cloud_providers/cloud_provider_selector'
+ = render new_cluster_partial(provider: params[:provider])
- else
.tab-pane{ id: 'create-cluster-pane', class: active_when(active_tab == 'create'), role: 'tabpanel' }
- = render 'clusters/clusters/gcp/header'
- - if @valid_gcp_token
- = render 'clusters/clusters/gcp/form'
- - elsif @authorize_url
- = render 'clusters/clusters/gcp/signin_with_google_button'
- - else
- = render 'clusters/clusters/gcp/gcp_not_configured'
+ = render new_cluster_partial(provider: 'gcp')
.tab-pane{ id: 'add-cluster-pane', class: active_when(active_tab == 'add'), role: 'tabpanel' }
= render 'clusters/clusters/user/header'
diff --git a/app/views/clusters/clusters/show.html.haml b/app/views/clusters/clusters/show.html.haml
index 31d5f592d75..5beeaf7259a 100644
--- a/app/views/clusters/clusters/show.html.haml
+++ b/app/views/clusters/clusters/show.html.haml
@@ -12,11 +12,13 @@
install_helm_path: clusterable.install_applications_cluster_path(@cluster, :helm),
install_ingress_path: clusterable.install_applications_cluster_path(@cluster, :ingress),
install_cert_manager_path: clusterable.install_applications_cluster_path(@cluster, :cert_manager),
+ install_crossplane_path: clusterable.install_applications_cluster_path(@cluster, :crossplane),
install_prometheus_path: clusterable.install_applications_cluster_path(@cluster, :prometheus),
install_runner_path: clusterable.install_applications_cluster_path(@cluster, :runner),
install_jupyter_path: clusterable.install_applications_cluster_path(@cluster, :jupyter),
install_knative_path: clusterable.install_applications_cluster_path(@cluster, :knative),
update_knative_path: clusterable.update_applications_cluster_path(@cluster, :knative),
+ install_elastic_stack_path: clusterable.install_applications_cluster_path(@cluster, :elastic_stack),
cluster_environments_path: cluster_environments_path,
toggle_status: @cluster.enabled? ? 'true': 'false',
has_rbac: has_rbac_enabled?(@cluster) ? 'true': 'false',
diff --git a/app/views/clusters/clusters/user/_form.html.haml b/app/views/clusters/clusters/user/_form.html.haml
index a6acf948ed4..39b6d74d9f9 100644
--- a/app/views/clusters/clusters/user/_form.html.haml
+++ b/app/views/clusters/clusters/user/_form.html.haml
@@ -1,7 +1,7 @@
-- more_info_link = link_to _('More information'), help_page_path('user/project/clusters/index.md',
- anchor: 'add-existing-kubernetes-cluster'), target: '_blank'
-- rbac_help_link = link_to _('More information'), help_page_path('user/project/clusters/index.md',
- anchor: 'role-based-access-control-rbac-core-only'), target: '_blank'
+- more_info_link = link_to _('More information'), help_page_path('user/project/clusters/add_remove_clusters.md',
+ anchor: 'add-existing-cluster'), target: '_blank'
+- rbac_help_link = link_to _('More information'), help_page_path('user/project/clusters/add_remove_clusters.md',
+ anchor: 'access-controls'), target: '_blank'
- api_url_help_text = s_('ClusterIntegration|The URL used to access the Kubernetes API.')
- ca_cert_help_text = s_('ClusterIntegration|The Kubernetes certificate used to authenticate to the cluster.')
diff --git a/app/views/clusters/clusters/user/_header.html.haml b/app/views/clusters/clusters/user/_header.html.haml
index 3b9ceaa2b8a..b0a24ee464f 100644
--- a/app/views/clusters/clusters/user/_header.html.haml
+++ b/app/views/clusters/clusters/user/_header.html.haml
@@ -1,5 +1,5 @@
%h4
= s_('ClusterIntegration|Enter the details for your Kubernetes cluster')
%p
- - link_to_help_page = link_to(s_('ClusterIntegration|documentation'), help_page_path('user/project/clusters/index', anchor: 'add-existing-kubernetes-cluster'), target: '_blank', rel: 'noopener noreferrer')
+ - link_to_help_page = link_to(s_('ClusterIntegration|documentation'), help_page_path('user/project/clusters/add_remove_clusters', anchor: 'add-existing-cluster'), target: '_blank', rel: 'noopener noreferrer')
= s_('ClusterIntegration|Please enter access information for your Kubernetes cluster. If you need help, you can read our %{link_to_help_page} on Kubernetes').html_safe % { link_to_help_page: link_to_help_page }
diff --git a/app/views/dashboard/projects/_zero_authorized_projects.html.haml b/app/views/dashboard/projects/_zero_authorized_projects.html.haml
index a2b1f0d9298..b5f5025b581 100644
--- a/app/views/dashboard/projects/_zero_authorized_projects.html.haml
+++ b/app/views/dashboard/projects/_zero_authorized_projects.html.haml
@@ -3,7 +3,7 @@
.container.section-body
.row
.blank-state-welcome.w-100
- %h2.blank-state-welcome-title
+ %h2.blank-state-welcome-title{ data: { qa_selector: 'welcome_title_content' } }
= _('Welcome to GitLab')
%p.blank-state-text
= _('Faster releases. Better code. Less pain.')
diff --git a/app/views/devise/sessions/new.html.haml b/app/views/devise/sessions/new.html.haml
index 8f6c3ecbe58..fd6d8f3f769 100644
--- a/app/views/devise/sessions/new.html.haml
+++ b/app/views/devise/sessions/new.html.haml
@@ -1,13 +1,13 @@
- page_title "Sign in"
#signin-container
- - if form_based_providers.any?
+ - if any_form_based_providers_enabled?
= render 'devise/shared/tabs_ldap'
- else
- unless experiment_enabled?(:signup_flow)
= render 'devise/shared/tabs_normal'
.tab-content
- - if password_authentication_enabled_for_web? || ldap_enabled? || crowd_enabled?
+ - if password_authentication_enabled_for_web? || ldap_sign_in_enabled? || crowd_enabled?
= render 'devise/shared/signin_box'
-# Signup only makes sense if you can also sign-in
@@ -15,7 +15,7 @@
= render 'devise/shared/signup_box'
-# Show a message if none of the mechanisms above are enabled
- - if !password_authentication_enabled_for_web? && !ldap_enabled? && !(omniauth_enabled? && devise_mapping.omniauthable?)
+ - if !password_authentication_enabled_for_web? && !ldap_sign_in_enabled? && !(omniauth_enabled? && devise_mapping.omniauthable?)
%div
No authentication methods configured.
diff --git a/app/views/devise/shared/_signin_box.html.haml b/app/views/devise/shared/_signin_box.html.haml
index 746d43edbad..6ddb7e1ac48 100644
--- a/app/views/devise/shared/_signin_box.html.haml
+++ b/app/views/devise/shared/_signin_box.html.haml
@@ -1,4 +1,4 @@
-- if form_based_providers.any?
+- if any_form_based_providers_enabled?
- if crowd_enabled?
.login-box.tab-pane{ id: "crowd", role: 'tabpanel', class: active_when(form_based_auth_provider_has_active_class?(:crowd)) }
.login-body
diff --git a/app/views/devise/shared/_tabs_ldap.html.haml b/app/views/devise/shared/_tabs_ldap.html.haml
index db54c166a53..b8f0cd2a91a 100644
--- a/app/views/devise/shared/_tabs_ldap.html.haml
+++ b/app/views/devise/shared/_tabs_ldap.html.haml
@@ -1,4 +1,4 @@
-%ul.nav-links.new-session-tabs.nav-tabs.nav{ class: ('custom-provider-tabs' if form_based_providers.any?) }
+%ul.nav-links.new-session-tabs.nav-tabs.nav{ class: ('custom-provider-tabs' if any_form_based_providers_enabled?) }
- if crowd_enabled?
%li.nav-item
= link_to "Crowd", "#crowd", class: "nav-link #{active_when(form_based_auth_provider_has_active_class?(:crowd))}", 'data-toggle' => 'tab'
diff --git a/app/views/errors/not_found.html.haml b/app/views/errors/not_found.html.haml
index ae055f398ac..13f07e2f5d5 100644
--- a/app/views/errors/not_found.html.haml
+++ b/app/views/errors/not_found.html.haml
@@ -11,5 +11,5 @@
= form_tag search_path, method: :get, class: 'form-inline-flex' do |f|
.field
= search_field_tag :search, '', placeholder: _('Search for projects, issues, etc.'), class: 'form-control'
- = button_tag 'Search', class: 'btn btn-success', name: nil, type: 'submit'
+ = button_tag _('Search'), class: 'btn btn-sm btn-success', name: nil, type: 'submit'
= render 'errors/footer'
diff --git a/app/views/groups/issues.html.haml b/app/views/groups/issues.html.haml
index bf077eb09d2..1cb1cc45bdb 100644
--- a/app/views/groups/issues.html.haml
+++ b/app/views/groups/issues.html.haml
@@ -22,4 +22,10 @@
- if @can_bulk_update
= render_if_exists 'shared/issuable/group_bulk_update_sidebar', group: @group, type: :issues
- = render 'shared/issues'
+ - if Feature.enabled?(:vue_issuables_list, @group)
+ .js-issuables-list{ data: { endpoint: expose_url(api_v4_groups_issues_path(id: @group.id)),
+ 'can-bulk-edit': @can_bulk_update.to_json,
+ 'empty-svg-path': image_path('illustrations/issues.svg'),
+ 'sort-key': @sort } }
+ - else
+ = render 'shared/issues'
diff --git a/app/views/groups/milestones/show.html.haml b/app/views/groups/milestones/show.html.haml
index 23b1a22240f..33e68bc766e 100644
--- a/app/views/groups/milestones/show.html.haml
+++ b/app/views/groups/milestones/show.html.haml
@@ -1,4 +1,4 @@
= render "header_title"
= render 'shared/milestones/top', milestone: @milestone, group: @group
-= render 'shared/milestones/tabs', milestone: @milestone, show_project_name: true if @milestone.legacy_group_milestone?
+= render 'shared/milestones/tabs', milestone: @milestone, show_project_name: true
= render 'shared/milestones/sidebar', milestone: @milestone, affix_offset: 102
diff --git a/app/views/groups/settings/ci_cd/show.html.haml b/app/views/groups/settings/ci_cd/show.html.haml
index a3f35b72cc6..81bd15ed287 100644
--- a/app/views/groups/settings/ci_cd/show.html.haml
+++ b/app/views/groups/settings/ci_cd/show.html.haml
@@ -31,7 +31,8 @@
%button.btn.btn-default.js-settings-toggle{ type: "button" }
= expanded ? _('Collapse') : _('Expand')
%p
- = _('Register and see your runners for this group.')
+ = _("Runners are processes that pick up and execute jobs for GitLab. Here you can register and see your Runners for this project.")
+ = link_to s_('More information'), help_page_path('ci/runners/README')
.settings-content
= render 'groups/runners/index'
diff --git a/app/views/help/_shortcuts.html.haml b/app/views/help/_shortcuts.html.haml
index f1ba804f920..5f8f2333e40 100644
--- a/app/views/help/_shortcuts.html.haml
+++ b/app/views/help/_shortcuts.html.haml
@@ -218,7 +218,7 @@
%tr
%td.shortcut
%kbd esc
- %td= _('Go back (while searching for files')
+ %td= _('Go back (while searching for files)')
%tr
%td.shortcut
%kbd y
diff --git a/app/views/import/manifest/_form.html.haml b/app/views/import/manifest/_form.html.haml
index 78c7fadb019..b515ce084e4 100644
--- a/app/views/import/manifest/_form.html.haml
+++ b/app/views/import/manifest/_form.html.haml
@@ -13,7 +13,7 @@
.form-group
= label_tag :manifest, class: 'label-bold' do
= _('Manifest')
- = file_field_tag :manifest, class: 'form-control-file', required: true
+ = file_field_tag :manifest, class: 'form-control-file w-auto', required: true
.form-text.text-muted
= _('Import multiple repositories by uploading a manifest file.')
= link_to icon('question-circle'), help_page_path('user/project/import/manifest')
diff --git a/app/views/layouts/_flash.html.haml b/app/views/layouts/_flash.html.haml
index 92572f0308c..a0b030fa3b2 100644
--- a/app/views/layouts/_flash.html.haml
+++ b/app/views/layouts/_flash.html.haml
@@ -3,7 +3,7 @@
- flash.each do |key, value|
-# Don't show a flash message if the message is nil
- if value
- %div{ class: "flash-content flash-#{key} rounded" }
+ %div{ class: "flash-#{key} mb-2" }
%span= value
%div{ class: "close-icon-wrapper js-close-icon" }
= sprite_icon('close', size: 16, css_class: 'close-icon')
diff --git a/app/views/layouts/_head.html.haml b/app/views/layouts/_head.html.haml
index b8c9f0ae1e8..0060d8323b0 100644
--- a/app/views/layouts/_head.html.haml
+++ b/app/views/layouts/_head.html.haml
@@ -57,7 +57,7 @@
= yield :library_javascripts
= javascript_include_tag locale_path unless I18n.locale == :en
- = webpack_bundle_tag "raven" if Gitlab.config.sentry.enabled
+ = webpack_bundle_tag "sentry" if Gitlab.config.sentry.enabled
- if content_for?(:page_specific_javascripts)
= yield :page_specific_javascripts
@@ -89,4 +89,4 @@
= render 'layouts/google_analytics' if extra_config.has_key?('google_analytics_id')
= render 'layouts/piwik' if extra_config.has_key?('piwik_url') && extra_config.has_key?('piwik_site_id')
- = render_if_exists 'layouts/snowplow'
+ = render 'layouts/snowplow'
diff --git a/app/views/layouts/_mailer.html.haml b/app/views/layouts/_mailer.html.haml
index 6e8294d6adc..24b8138078d 100644
--- a/app/views/layouts/_mailer.html.haml
+++ b/app/views/layouts/_mailer.html.haml
@@ -1,80 +1,48 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional //EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
%html{ lang: "en" }
%head
%meta{ content: "text/html; charset=UTF-8", "http-equiv" => "Content-Type" }/
%meta{ content: "width=device-width, initial-scale=1", name: "viewport" }/
%meta{ content: "IE=edge", "http-equiv" => "X-UA-Compatible" }/
%title= message.subject
- :css
- /* CLIENT-SPECIFIC STYLES */
- body, table, td, a { -webkit-text-size-adjust: 100%; -ms-text-size-adjust: 100%; }
- table, td { mso-table-lspace: 0pt; mso-table-rspace: 0pt; }
- img { -ms-interpolation-mode: bicubic; }
- .hidden {
- display: none !important;
- visibility: hidden !important;
- }
- /* iOS BLUE LINKS */
- a[x-apple-data-detectors] {
- color: inherit !important;
- text-decoration: none !important;
- font-size: inherit !important;
- font-family: inherit !important;
- font-weight: inherit !important;
- line-height: inherit !important;
- }
+ -# Avoid premailer processing of client-specific styles (@media tag not supported)
+ -# We need to inline the contents here because mail clients (e.g. iOS Mail, Outlook)
+ -# do not support linked stylesheets.
+ %style{ type: 'text/css', 'data-premailer': 'ignore' }
+ = asset_to_string('mailer_client_specific.css').html_safe
- /* ANDROID MARGIN HACK */
- body { margin:0 !important; }
- div[style*="margin: 16px 0"] { margin:0 !important; }
-
- @media only screen and (max-width: 639px) {
- body, #body {
- min-width: 320px !important;
- }
- table.wrapper {
- width: 100% !important;
- min-width: 320px !important;
- }
- table.wrapper > tbody > tr > td {
- border-left: 0 !important;
- border-right: 0 !important;
- border-radius: 0 !important;
- padding-left: 10px !important;
- padding-right: 10px !important;
- }
- }
- %body{ style: "background-color:#fafafa;margin:0;padding:0;text-align:center;min-width:640px;width:100%;height:100%;font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;" }
- %table#body{ border: "0", cellpadding: "0", cellspacing: "0", style: "background-color:#fafafa;margin:0;padding:0;text-align:center;min-width:640px;width:100%;" }
+ = stylesheet_link_tag 'mailer.css'
+ %body
+ %table#body{ border: "0", cellpadding: "0", cellspacing: "0" }
%tbody
%tr.line
- %td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;background-color:#6b4fbb;height:4px;font-size:4px;line-height:4px;" }
+ %td
%tr.header
- %td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;padding:25px 0;font-size:13px;line-height:1.6;color:#5c5c5c;" }
+ %td
= html_header_message
= header_logo
%tr
- %td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;" }
- %table.wrapper{ border: "0", cellpadding: "0", cellspacing: "0", style: "width:640px;margin:0 auto;border-collapse:separate;border-spacing:0;" }
+ %td
+ %table.wrapper{ border: "0", cellpadding: "0", cellspacing: "0" }
%tbody
%tr
- %td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;background-color:#ffffff;text-align:left;padding:18px 25px;border:1px solid #ededed;border-radius:3px;overflow:hidden;" }
- %table.content{ border: "0", cellpadding: "0", cellspacing: "0", style: "width:100%;border-collapse:separate;border-spacing:0;" }
+ %td.wrapper-cell
+ %table.content{ border: "0", cellpadding: "0", cellspacing: "0" }
%tbody
= yield
= render_if_exists 'layouts/mailer/additional_text'
%tr.footer
- %td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;padding:25px 0;font-size:13px;line-height:1.6;color:#5c5c5c;" }
- %img{ alt: "GitLab", height: "33", src: image_url('mailers/gitlab_footer_logo.gif'), style: "display:block;margin:0 auto 1em;", width: "90" }/
+ %td
+ %img{ alt: "GitLab", height: "33", width: "90", src: image_url('mailers/gitlab_footer_logo.gif') }
%div
- - manage_notifications_link = link_to(_("Manage all notifications"), profile_notifications_url, style: "color:#3777b0;text-decoration:none;")
- - help_link = link_to(_("Help"), help_url, style: "color:#3777b0;text-decoration:none;")
+ - manage_notifications_link = link_to(_("Manage all notifications"), profile_notifications_url, class: 'mng-notif-link')
+ - help_link = link_to(_("Help"), help_url, class: 'help-link')
= _("You're receiving this email because of your account on %{host}. %{manage_notifications_link} &middot; %{help_link}").html_safe % { host: Gitlab.config.gitlab.host, manage_notifications_link: manage_notifications_link, help_link: help_link }
= yield :additional_footer
%tr
- %td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;padding:25px 0;font-size:13px;line-height:1.6;color:#5c5c5c;" }
+ %td.footer-message
= html_footer_message
diff --git a/app/views/layouts/_page.html.haml b/app/views/layouts/_page.html.haml
index 6cdb85456c3..443a73f5cce 100644
--- a/app/views/layouts/_page.html.haml
+++ b/app/views/layouts/_page.html.haml
@@ -17,6 +17,4 @@
%div{ class: "#{(container_class unless @no_container)} #{@content_class}" }
.content{ id: "content-body" }
= render "layouts/flash", extra_flash_class: 'limit-container-width'
- - if Gitlab.com?
- = render_if_exists "layouts/privacy_policy_update_callout"
= yield
diff --git a/app/views/layouts/header/_current_user_dropdown.html.haml b/app/views/layouts/header/_current_user_dropdown.html.haml
index efe74ddd902..d15f0ae3228 100644
--- a/app/views/layouts/header/_current_user_dropdown.html.haml
+++ b/app/views/layouts/header/_current_user_dropdown.html.haml
@@ -18,6 +18,11 @@
- if current_user_menu?(:profile)
%li
= link_to s_("CurrentUser|Profile"), current_user, class: 'profile-link', data: { user: current_user.username }
+ - if current_user_menu?(:start_trial)
+ %li
+ %a.profile-link{ href: trials_link_url }
+ = s_("CurrentUser|Start a Gold trial")
+ = emoji_icon('rocket')
- if current_user_menu?(:settings)
%li
= link_to s_("CurrentUser|Settings"), profile_path, data: { qa_selector: 'settings_link' }
@@ -35,8 +40,8 @@
%li.d-md-none
= render 'shared/user_dropdown_contributing_link'
= render_if_exists 'shared/user_dropdown_instance_review'
- - if Gitlab.com?
- %li.js-canary-link.d-md-none
+ - if Gitlab.com_but_not_canary?
+ %li.d-md-none
= link_to _("Switch to GitLab Next"), "https://next.gitlab.com/"
- if current_user_menu?(:sign_out)
diff --git a/app/views/layouts/header/_default.html.haml b/app/views/layouts/header/_default.html.haml
index d8697be7f7a..5719fb24b89 100644
--- a/app/views/layouts/header/_default.html.haml
+++ b/app/views/layouts/header/_default.html.haml
@@ -18,8 +18,8 @@
- if logo_text.present?
%span.logo-text.d-none.d-lg-block.prepend-left-8
= logo_text
- - if Gitlab.com?
- = link_to 'https://next.gitlab.com', class: 'label-link js-canary-badge canary-badge bg-transparent hidden', target: :_blank do
+ - if Gitlab.com_and_canary?
+ = link_to 'https://next.gitlab.com', class: 'label-link canary-badge bg-transparent', target: :_blank do
%span.color-label.has-tooltip.badge.badge-pill.green-badge
= _('Next')
diff --git a/app/views/layouts/header/_help_dropdown.html.haml b/app/views/layouts/header/_help_dropdown.html.haml
index 71977b23481..93854c212df 100644
--- a/app/views/layouts/header/_help_dropdown.html.haml
+++ b/app/views/layouts/header/_help_dropdown.html.haml
@@ -12,6 +12,6 @@
%li
= render 'shared/user_dropdown_contributing_link'
= render_if_exists 'shared/user_dropdown_instance_review'
- - if Gitlab.com?
- %li.js-canary-link
+ - if Gitlab.com_but_not_canary?
+ %li
= link_to _("Switch to GitLab Next"), "https://next.gitlab.com/"
diff --git a/app/views/layouts/nav/_dashboard.html.haml b/app/views/layouts/nav/_dashboard.html.haml
index 5122c2517aa..d339751848b 100644
--- a/app/views/layouts/nav/_dashboard.html.haml
+++ b/app/views/layouts/nav/_dashboard.html.haml
@@ -55,15 +55,15 @@
= nav_link(controller: 'admin/dashboard') do
= link_to admin_root_path, class: 'admin-icon qa-admin-area-link d-xl-none' do
= _('Admin Area')
- - if Feature.enabled?(:user_mode_in_session)
- - if header_link?(:admin_mode)
- = nav_link(controller: 'admin/sessions') do
- = link_to destroy_admin_session_path, class: 'd-lg-none lock-open-icon' do
- = _('Leave admin mode')
- - elsif current_user.admin?
- = nav_link(controller: 'admin/sessions') do
- = link_to new_admin_session_path, class: 'd-lg-none lock-icon' do
- = _('Enter admin mode')
+ - if Feature.enabled?(:user_mode_in_session)
+ - if header_link?(:admin_mode)
+ = nav_link(controller: 'admin/sessions') do
+ = link_to destroy_admin_session_path, class: 'd-lg-none lock-open-icon' do
+ = _('Leave Admin Mode')
+ - elsif current_user.admin?
+ = nav_link(controller: 'admin/sessions') do
+ = link_to new_admin_session_path, class: 'd-lg-none lock-icon' do
+ = _('Enter Admin Mode')
- if Gitlab::Sherlock.enabled?
%li
= link_to sherlock_transactions_path, class: 'admin-icon' do
@@ -74,6 +74,15 @@
= link_to admin_root_path, class: 'admin-icon qa-admin-area-link', title: _('Admin Area'), aria: { label: _('Admin Area') }, data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do
= sprite_icon('admin', size: 18)
+ - if Feature.enabled?(:user_mode_in_session)
+ - if header_link?(:admin_mode)
+ = nav_link(controller: 'admin/sessions', html_options: { class: "d-none d-lg-block d-xl-block"}) do
+ = link_to destroy_admin_session_path, title: _('Leave Admin Mode'), aria: { label: _('Leave Admin Mode') }, data: { toggle: 'tooltip', placement: 'bottom', container: 'body' } do
+ = sprite_icon('lock-open', size: 18)
+ - elsif current_user.admin?
+ = nav_link(controller: 'admin/sessions', html_options: { class: "d-none d-lg-block d-xl-block"}) do
+ = link_to new_admin_session_path, title: _('Enter Admin Mode'), aria: { label: _('Enter Admin Mode') }, data: { toggle: 'tooltip', placement: 'bottom', container: 'body' } do
+ = sprite_icon('lock', size: 18)
-# Shortcut to Dashboard > Projects
- if dashboard_nav_link?(:projects)
diff --git a/app/views/layouts/nav/sidebar/_group.html.haml b/app/views/layouts/nav/sidebar/_group.html.haml
index 4930c6cf5f7..a6d2c894185 100644
--- a/app/views/layouts/nav/sidebar/_group.html.haml
+++ b/app/views/layouts/nav/sidebar/_group.html.haml
@@ -16,13 +16,19 @@
.nav-icon-container
= sprite_icon('home')
%span.nav-item-name
- = _('Overview')
+ - if @group.subgroup?
+ = _('Subgroup overview')
+ - else
+ = _('Group overview')
%ul.sidebar-sub-level-items
= nav_link(path: ['groups#show', 'groups#details', 'groups#activity', 'groups#subgroups'], html_options: { class: "fly-out-top-item" } ) do
= link_to group_path(@group) do
%strong.fly-out-top-item-name
- = _('Overview')
+ - if @group.subgroup?
+ = _('Subgroup overview')
+ - else
+ = _('Group overview')
%li.divider.fly-out-top-item
= nav_link(path: ['groups#show', 'groups#details', 'groups#subgroups'], html_options: { class: 'home' }) do
diff --git a/app/views/layouts/nav/sidebar/_project.html.haml b/app/views/layouts/nav/sidebar/_project.html.haml
index c84bc0b5cd4..9b3ad05d0c0 100644
--- a/app/views/layouts/nav/sidebar/_project.html.haml
+++ b/app/views/layouts/nav/sidebar/_project.html.haml
@@ -13,13 +13,13 @@
.nav-icon-container
= sprite_icon('home')
%span.nav-item-name
- = _('Project')
+ = _('Project overview')
%ul.sidebar-sub-level-items
= nav_link(path: 'projects#show', html_options: { class: "fly-out-top-item" } ) do
= link_to project_path(@project) do
%strong.fly-out-top-item-name
- = _('Project')
+ = _('Project overview')
%li.divider.fly-out-top-item
= nav_link(path: 'projects#show') do
= link_to project_path(@project), title: _('Project details'), class: 'shortcuts-project' do
@@ -163,7 +163,7 @@
- if project_nav_tab? :pipelines
= nav_link(controller: [:pipelines, :builds, :jobs, :pipeline_schedules, :artifacts]) do
- = link_to project_pipelines_path(@project), class: 'shortcuts-pipelines qa-link-pipelines rspec-link-pipelines' do
+ = link_to project_pipelines_path(@project), class: 'shortcuts-pipelines qa-link-pipelines rspec-link-pipelines', data: { qa_selector: 'ci_cd_link' } do
.nav-icon-container
= sprite_icon('rocket')
%span.nav-item-name#js-onboarding-pipelines-link
@@ -247,6 +247,8 @@
%span
= _('Serverless')
+ = render_if_exists 'layouts/nav/sidebar/pod_logs_link' # EE-specific
+
- if project_nav_tab? :clusters
- show_cluster_hint = show_gke_cluster_integration_callout?(@project)
= nav_link(controller: [:clusters, :user, :gcp]) do
@@ -264,7 +266,7 @@
dismiss_endpoint: user_callouts_path } }
- if show_cluster_hint
.feature-highlight-popover-content
- = image_tag 'illustrations/cluster_popover.svg', class: 'feature-highlight-illustration'
+ = image_tag 'illustrations/cluster_popover.svg', class: 'feature-highlight-illustration', lazy: false, alt: _('Kubernetes popover')
.feature-highlight-popover-sub-content
%p= _('Allows you to add and manage Kubernetes clusters.')
%p
@@ -347,7 +349,7 @@
= _('Members')
- if can_edit
= nav_link(controller: [:integrations, :services, :hooks, :hook_logs]) do
- = link_to project_settings_integrations_path(@project), title: _('Integrations') do
+ = link_to project_settings_integrations_path(@project), title: _('Integrations'), data: { qa_selector: 'integrations_settings_link' } do
%span
= _('Integrations')
= nav_link(controller: :repository) do
diff --git a/app/views/notify/member_access_denied_email.html.haml b/app/views/notify/member_access_denied_email.html.haml
index 71c9c50071a..11661a423dd 100644
--- a/app/views/notify/member_access_denied_email.html.haml
+++ b/app/views/notify/member_access_denied_email.html.haml
@@ -1,4 +1,7 @@
-%p
- Your request to join the
- #{link_to member_source.human_name, member_source.web_url} #{member_source.model_name.singular}
- has been denied.
+%tr
+ %td.text-content
+ %p
+ Your request to join the
+ #{link_to member_source.human_name, member_source.web_url, class: :highlight} #{member_source.model_name.singular}
+ has been #{content_tag :span, 'denied', class: :highlight}.
+
diff --git a/app/views/notify/member_access_granted_email.html.haml b/app/views/notify/member_access_granted_email.html.haml
index 1c50dba9c97..e28a10a243f 100644
--- a/app/views/notify/member_access_granted_email.html.haml
+++ b/app/views/notify/member_access_granted_email.html.haml
@@ -1,10 +1,14 @@
- link_end = '</a>'.html_safe
- source_type = member_source.model_name.singular
- leave_link = polymorphic_url([member_source], leave: 1)
-- source_link = link_to(member_source.human_name, member_source.web_url, target: '_blank', rel: 'noopener noreferrer')
+- source_link = link_to(member_source.human_name, member_source.web_url, target: '_blank', rel: 'noopener noreferrer', class: :highlight)
+- access_level = content_tag(:span, member.human_access, class: :highlight)
+
+%tr
+ %td.text-content
+ %p
+ = _('You have been granted %{access_level} access to the %{source_link} %{source_type}.').html_safe % { access_level: access_level, source_link: source_link, source_type: source_type }
+ %p
+ - leave_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: leave_link }
+ = _('If this was a mistake you can %{leave_link_start}leave the %{source_type}%{link_end}.').html_safe % { source_type: source_type, leave_link_start: leave_link_start, link_end: link_end }
-%p
- = _('You have been granted %{access_level} access to the %{source_link} %{source_type}.').html_safe % { access_level: member.human_access, source_link: source_link, source_type: source_type }
-%p
- - leave_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: leave_link }
- = _('If this was a mistake you can %{leave_link_start}leave the %{source_type}%{link_end}.').html_safe % { source_type: source_type, leave_link_start: leave_link_start, link_end: link_end }
diff --git a/app/views/notify/member_access_requested_email.html.haml b/app/views/notify/member_access_requested_email.html.haml
index 76f1f08a0cb..43f25af3dba 100644
--- a/app/views/notify/member_access_requested_email.html.haml
+++ b/app/views/notify/member_access_requested_email.html.haml
@@ -1,3 +1,6 @@
-%p
- #{link_to member.user.name, member.user} requested #{member.human_access}
- access to the #{link_to member_source.human_name, polymorphic_url([member_source, :members])} #{member_source.model_name.singular}.
+%tr
+ %td.text-content
+ %p
+ #{link_to member.user.name, member.user, class: :highlight} requested #{content_tag :span, member.human_access, class: :highlight}
+ access to the #{link_to member_source.human_name, polymorphic_url([member_source, :members]), class: :highlight} #{member_source.model_name.singular}.
+
diff --git a/app/views/notify/member_invite_accepted_email.html.haml b/app/views/notify/member_invite_accepted_email.html.haml
index 2d1d40881eb..0abb79000e0 100644
--- a/app/views/notify/member_invite_accepted_email.html.haml
+++ b/app/views/notify/member_invite_accepted_email.html.haml
@@ -1,5 +1,8 @@
-%p
- #{member.invite_email}, now known as
- #{link_to member.user.name, user_url(member.user)},
- has accepted your invitation to join the
- #{link_to member_source.human_name, member_source.web_url} #{member_source.model_name.singular}.
+%tr
+ %td.text-content
+ %p
+ #{content_tag :span, member.invite_email, class: :highlight}, now known as
+ #{link_to member.user.name, user_url(member.user)},
+ has accepted your invitation to join the
+ #{link_to member_source.human_name, member_source.web_url, class: :highlight} #{member_source.model_name.singular}.
+
diff --git a/app/views/notify/member_invite_declined_email.html.haml b/app/views/notify/member_invite_declined_email.html.haml
index aa1b373d1a6..5e626767235 100644
--- a/app/views/notify/member_invite_declined_email.html.haml
+++ b/app/views/notify/member_invite_declined_email.html.haml
@@ -1,4 +1,7 @@
-%p
- #{@invite_email}
- has declined your invitation to join the
- #{link_to member_source.human_name, member_source.web_url} #{member_source.model_name.singular}.
+%tr
+ %td.text-content
+ %p
+ #{content_tag :span, @invite_email, class: :highlight}
+ has #{content_tag :span, 'declined', class: :highlight} your invitation to join the
+ #{link_to member_source.human_name, member_source.web_url, class: :highlight} #{member_source.model_name.singular}.
+
diff --git a/app/views/notify/member_invited_email.html.haml b/app/views/notify/member_invited_email.html.haml
index 6730172242b..ae3fecf404a 100644
--- a/app/views/notify/member_invited_email.html.haml
+++ b/app/views/notify/member_invited_email.html.haml
@@ -1,13 +1,16 @@
-%p
- You have been invited
- - if member.created_by
- by
- = link_to member.created_by.name, user_url(member.created_by)
- to join the
- = link_to member_source.human_name, member_source.public? ? member_source.web_url : invite_url(@token)
- #{member_source.model_name.singular} as #{member.human_access}.
+%tr
+ %td.text-content
+ %p
+ You have been invited
+ - if member.created_by
+ by
+ = link_to member.created_by.name, user_url(member.created_by)
+ to join the
+ = link_to member_source.human_name, member_source.public? ? member_source.web_url : invite_url(@token), class: :highlight
+ #{member_source.model_name.singular} as #{content_tag :span, member.human_access, class: :highlight}.
+
+ %p
+ = link_to 'Accept invitation', invite_url(@token)
+ or
+ = link_to 'decline', decline_invite_url(@token)
-%p
- = link_to 'Accept invitation', invite_url(@token)
- or
- = link_to 'decline', decline_invite_url(@token)
diff --git a/app/views/profiles/preferences/_sourcegraph.html.haml b/app/views/profiles/preferences/_sourcegraph.html.haml
new file mode 100644
index 00000000000..20a904694ca
--- /dev/null
+++ b/app/views/profiles/preferences/_sourcegraph.html.haml
@@ -0,0 +1,26 @@
+- return unless Gitlab::Sourcegraph::feature_available? && Gitlab::CurrentSettings.sourcegraph_enabled
+- sourcegraph_url = Gitlab::CurrentSettings.sourcegraph_url
+
+.col-sm-12
+ %hr
+
+.col-lg-4.profile-settings-sidebar
+ %h4.prepend-top-0
+ = s_('Preferences|Integrations')
+ %p
+ = s_('Preferences|Customize integrations with third party services.')
+ = succeed '.' do
+ = link_to _('Learn more'), help_page_path('user/profile/preferences.md', anchor: 'integrations'), target: '_blank'
+.col-lg-8
+ %label.label-bold
+ = s_('Preferences|Sourcegraph')
+ = link_to icon('question-circle'), help_page_path('user/profile/preferences.md', anchor: 'sourcegraph'), target: '_blank', class: 'has-tooltip', title: _('More information')
+ .form-group.form-check
+ = f.check_box :sourcegraph_enabled, class: 'form-check-input'
+ = f.label :sourcegraph_enabled, class: 'form-check-label' do
+ - link_start = '<a href="%{url}">'.html_safe % { url: sourcegraph_url }
+ - link_end = '</a>'.html_safe
+ = s_('Preferences|Enable integrated code intelligence on code views').html_safe % { link_start: link_start, link_end: link_end }
+ .form-text.text-muted
+ = sourcegraph_url_message
+ = sourcegraph_experimental_message
diff --git a/app/views/profiles/preferences/show.html.haml b/app/views/profiles/preferences/show.html.haml
index 84657592cd8..bf76b7379dd 100644
--- a/app/views/profiles/preferences/show.html.haml
+++ b/app/views/profiles/preferences/show.html.haml
@@ -111,6 +111,9 @@
= time_display_label
.form-text.text-muted
= s_('Preferences|For example: 30 mins ago.')
+
+ = render 'sourcegraph', f: f
+
.col-lg-4.profile-settings-sidebar
.col-lg-8
.form-group
diff --git a/app/views/profiles/show.html.haml b/app/views/profiles/show.html.haml
index 68b7efc6fb4..cfad274f91d 100644
--- a/app/views/profiles/show.html.haml
+++ b/app/views/profiles/show.html.haml
@@ -94,7 +94,7 @@
- else
= f.text_field :name, label: s_('Profiles|Full name'), required: true, title: s_("Profiles|Using emojis in names seems fun, but please try to set a status message instead"), wrapper: { class: 'col-md-9 qa-full-name rspec-full-name' }, help: s_("Profiles|Enter your name, so people you know can recognize you")
= f.text_field :id, readonly: true, label: s_('Profiles|User ID'), wrapper: { class: 'col-md-3' }
- = f.select :role, ::User.roles.keys.map { |role| [role.titleize, role] }, {}, class: 'input-md'
+ = f.select :role, ::User.roles.keys.map { |role| [role.titleize, role] }, { prompt: _('Select your role') }, required: true, class: 'input-md'
= render_if_exists 'profiles/email_settings', form: f
= f.text_field :skype, class: 'input-md', placeholder: s_("Profiles|username")
diff --git a/app/views/projects/_export.html.haml b/app/views/projects/_export.html.haml
index e4129a91daf..2e00632892b 100644
--- a/app/views/projects/_export.html.haml
+++ b/app/views/projects/_export.html.haml
@@ -14,7 +14,7 @@
%li= desc
%p= _('The following items will NOT be exported:')
%ul
- %li= _('Job traces and artifacts')
+ %li= _('Job logs and artifacts')
%li= _('Container registry images')
%li= _('CI variables')
%li= _('Webhooks')
diff --git a/app/views/projects/_files.html.haml b/app/views/projects/_files.html.haml
index 95fdad125a7..20d4084f428 100644
--- a/app/views/projects/_files.html.haml
+++ b/app/views/projects/_files.html.haml
@@ -15,15 +15,13 @@
= render 'shared/commit_well', commit: commit, ref: ref, project: project
- if is_project_overview
- .project-buttons.append-bottom-default{ class: ("js-keep-hidden-on-navigation" if vue_file_list_enabled?) }
+ .project-buttons.append-bottom-default{ class: ("js-show-on-project-root" if vue_file_list_enabled?) }
= render 'stat_anchor_list', anchors: @project.statistics_buttons(show_auto_devops_callout: show_auto_devops_callout)
- if vue_file_list_enabled?
- #js-tree-list{ data: { project_path: @project.full_path, project_short_path: @project.path, ref: ref, full_name: @project.name_with_namespace } }
+ #js-tree-list{ data: vue_file_list_data(project, ref) }
- if can_edit_tree?
= render 'projects/blob/upload', title: _('Upload New File'), placeholder: _('Upload New File'), button_title: _('Upload file'), form_path: project_create_blob_path(@project, @id), method: :post
= render 'projects/blob/new_dir'
- - if @tree.readme
- = render "projects/tree/readme", readme: @tree.readme
- else
= render 'projects/tree/tree_content', tree: @tree, content_url: content_url
diff --git a/app/views/projects/_home_panel.html.haml b/app/views/projects/_home_panel.html.haml
index 4783b10cf6d..b7c4114d485 100644
--- a/app/views/projects/_home_panel.html.haml
+++ b/app/views/projects/_home_panel.html.haml
@@ -3,7 +3,7 @@
- max_project_topic_length = 15
- emails_disabled = @project.emails_disabled?
-.project-home-panel{ class: [("empty-project" if empty_repo), ("js-keep-hidden-on-navigation" if vue_file_list_enabled?)] }
+.project-home-panel{ class: [("empty-project" if empty_repo), ("js-show-on-project-root" if vue_file_list_enabled?)] }
.row.append-bottom-8
.home-panel-title-row.col-md-12.col-lg-6.d-flex
.avatar-container.rect-avatar.s64.home-panel-avatar.append-right-default.float-none
diff --git a/app/views/projects/_merge_request_merge_options_settings.html.haml b/app/views/projects/_merge_request_merge_options_settings.html.haml
index 5ab475822de..047b4dafbfc 100644
--- a/app/views/projects/_merge_request_merge_options_settings.html.haml
+++ b/app/views/projects/_merge_request_merge_options_settings.html.haml
@@ -12,3 +12,9 @@
= form.check_box :printing_merge_request_link_enabled, class: 'form-check-input'
= form.label :printing_merge_request_link_enabled, class: 'form-check-label' do
= s_('ProjectSettings|Show link to create/view merge request when pushing from the command line')
+ .form-check.mb-2
+ = form.check_box :remove_source_branch_after_merge, class: 'form-check-input'
+ = form.label :remove_source_branch_after_merge, class: 'form-check-label' do
+ = s_("ProjectSettings|Enable 'Delete source branch' option by default")
+ .descr.text-secondary
+ = s_('ProjectSettings|Existing merge requests and protected branches are not affected')
diff --git a/app/views/projects/blame/show.html.haml b/app/views/projects/blame/show.html.haml
index f2215765974..30fe5622ebd 100644
--- a/app/views/projects/blame/show.html.haml
+++ b/app/views/projects/blame/show.html.haml
@@ -19,7 +19,7 @@
= author_avatar(commit, size: 36, has_tooltip: false)
.commit-row-title
%span.item-title.str-truncated-100
- = link_to_markdown commit.title, project_commit_path(@project, commit.id), class: "cdark", title: commit.title
+ = link_to commit.title, project_commit_path(@project, commit.id), class: "cdark", title: commit.title
.float-right
= link_to commit.short_id, project_commit_path(@project, commit), class: "commit-sha"
&nbsp;
diff --git a/app/views/projects/blob/_header.html.haml b/app/views/projects/blob/_header.html.haml
index 84ccd816d80..77245114772 100644
--- a/app/views/projects/blob/_header.html.haml
+++ b/app/views/projects/blob/_header.html.haml
@@ -6,17 +6,18 @@
= render 'projects/blob/viewer_switcher', blob: blob unless blame
.btn-group{ role: "group" }<
- = copy_blob_source_button(blob) unless blame
- = open_raw_blob_button(blob)
- = download_blob_button(blob)
- = view_on_environment_button(@commit.sha, @path, @environment) if @environment
- .btn-group{ role: "group" }<
- = render_if_exists 'projects/blob/header_file_locks_link'
= edit_blob_button
= ide_edit_button
+ .btn-group{ role: "group" }<
+ = render_if_exists 'projects/blob/header_file_locks_link'
- if current_user
= replace_blob_link
= delete_blob_link
+ .btn-group{ role: "group" }<
+ = copy_blob_source_button(blob) unless blame
+ = open_raw_blob_button(blob)
+ = download_blob_button(blob)
+ = view_on_environment_button(@commit.sha, @path, @environment) if @environment
= render 'projects/fork_suggestion'
= render_if_exists 'projects/blob/header_file_locks', project: @project, path: @path
diff --git a/app/views/projects/blob/_markdown_buttons.html.haml b/app/views/projects/blob/_markdown_buttons.html.haml
index 28d1ff97825..44ec2fa69cb 100644
--- a/app/views/projects/blob/_markdown_buttons.html.haml
+++ b/app/views/projects/blob/_markdown_buttons.html.haml
@@ -6,7 +6,7 @@
= markdown_toolbar_button({ icon: "link", data: { "md-tag" => "[{text}](url)", "md-select" => "url" }, title: _("Add a link") })
= markdown_toolbar_button({ icon: "list-bulleted", data: { "md-tag" => "* ", "md-prepend" => true }, title: _("Add a bullet list") })
= markdown_toolbar_button({ icon: "list-numbered", data: { "md-tag" => "1. ", "md-prepend" => true }, title: _("Add a numbered list") })
- = markdown_toolbar_button({ icon: "task-done", data: { "md-tag" => "* [ ] ", "md-prepend" => true }, title: _("Add a task list") })
+ = markdown_toolbar_button({ icon: "list-task", data: { "md-tag" => "* [ ] ", "md-prepend" => true }, title: _("Add a task list") })
= markdown_toolbar_button({ icon: "table", data: { "md-tag" => "| header | header |\n| ------ | ------ |\n| cell | cell |\n| cell | cell |", "md-prepend" => true }, title: _("Add a table") })
- if show_fullscreen_button
%button.toolbar-btn.toolbar-fullscreen-btn.js-zen-enter.has-tooltip{ type: "button", tabindex: -1, "aria-label": "Go full screen", title: _("Go full screen"), data: { container: "body" } }
diff --git a/app/views/projects/buttons/_clone.html.haml b/app/views/projects/buttons/_clone.html.haml
index abef33ca01c..ed22573b23e 100644
--- a/app/views/projects/buttons/_clone.html.haml
+++ b/app/views/projects/buttons/_clone.html.haml
@@ -25,5 +25,3 @@
= clipboard_button(target: '#http_project_clone', title: _("Copy URL"), class: "input-group-text btn-default btn-clipboard")
= render_if_exists 'projects/buttons/geo'
= render_if_exists 'projects/buttons/kerberos_clone_field'
-
-= render_if_exists 'shared/geo_info_modal', project: project
diff --git a/app/views/projects/buttons/_download.html.haml b/app/views/projects/buttons/_download.html.haml
index 96df3cd18fe..e8aff58b505 100644
--- a/app/views/projects/buttons/_download.html.haml
+++ b/app/views/projects/buttons/_download.html.haml
@@ -12,11 +12,14 @@
%h5.m-0.dropdown-bold-header= _('Download source code')
.dropdown-menu-content
= render 'projects/buttons/download_links', project: project, ref: ref, archive_prefix: archive_prefix, path: nil
- - if directory? && Feature.enabled?(:git_archive_path, default_enabled: true)
- %section.border-top.pt-1.mt-1
- %h5.m-0.dropdown-bold-header= _('Download this directory')
- .dropdown-menu-content
- = render 'projects/buttons/download_links', project: project, ref: ref, archive_prefix: archive_prefix, path: @path
+ - if Feature.enabled?(:git_archive_path, default_enabled: true)
+ - if vue_file_list_enabled?
+ #js-directory-downloads{ data: { links: directory_download_links(project, ref, archive_prefix).to_json } }
+ - elsif directory?
+ %section.border-top.pt-1.mt-1
+ %h5.m-0.dropdown-bold-header= _('Download this directory')
+ .dropdown-menu-content
+ = render 'projects/buttons/download_links', project: project, ref: ref, archive_prefix: archive_prefix, path: @path
- if pipeline && pipeline.latest_builds_with_artifacts.any?
%section.border-top.pt-1.mt-1
%h5.m-0.dropdown-bold-header= _('Download artifacts')
diff --git a/app/views/projects/buttons/_download_links.html.haml b/app/views/projects/buttons/_download_links.html.haml
index b256d94065b..990f3ff526b 100644
--- a/app/views/projects/buttons/_download_links.html.haml
+++ b/app/views/projects/buttons/_download_links.html.haml
@@ -1,6 +1,4 @@
-- formats = [['zip', 'btn-primary'], ['tar.gz'], ['tar.bz2'], ['tar']]
-
.btn-group.ml-0.w-100
- - formats.each do |(fmt, extra_class)|
+ - Gitlab::Workhorse::ARCHIVE_FORMATS.each_with_index do |fmt, index|
- archive_path = project_archive_path(project, id: tree_join(ref, archive_prefix), path: path, format: fmt)
- = link_to fmt, external_storage_url_or_path(archive_path), rel: 'nofollow', download: '', class: "btn btn-xs #{extra_class}"
+ = link_to fmt, external_storage_url_or_path(archive_path), rel: 'nofollow', download: '', class: "btn btn-xs #{"btn-primary" if index == 0}"
diff --git a/app/views/projects/compare/_form.html.haml b/app/views/projects/compare/_form.html.haml
index 9744d293c8b..c8c96297672 100644
--- a/app/views/projects/compare/_form.html.haml
+++ b/app/views/projects/compare/_form.html.haml
@@ -8,8 +8,9 @@
.input-group-text
= s_("CompareBranches|Source")
= hidden_field_tag :to, params[:to]
- = button_tag type: 'button', title: params[:to], class: "form-control compare-dropdown-toggle js-compare-dropdown has-tooltip monospace", required: true, data: { refs_url: refs_project_path(@project), toggle: "dropdown", target: ".js-compare-to-dropdown", selected: params[:to], field_name: :to } do
- .dropdown-toggle-text.str-truncated= params[:to] || _("Select branch/tag")
+ = button_tag type: 'button', title: params[:to], class: "btn form-control compare-dropdown-toggle js-compare-dropdown has-tooltip", required: true, data: { refs_url: refs_project_path(@project), toggle: "dropdown", target: ".js-compare-to-dropdown", selected: params[:to], field_name: :to } do
+ .dropdown-toggle-text.str-truncated.monospace.float-left= params[:to] || _("Select branch/tag")
+ = sprite_icon('arrow-down', size: 16, css_class: 'float-right')
= render 'shared/ref_dropdown'
.compare-ellipsis.inline ...
.form-group.dropdown.compare-form-group.from.js-compare-from-dropdown
@@ -18,8 +19,9 @@
.input-group-text
= s_("CompareBranches|Target")
= hidden_field_tag :from, params[:from]
- = button_tag type: 'button', title: params[:from], class: "form-control compare-dropdown-toggle js-compare-dropdown has-tooltip monospace", required: true, data: { refs_url: refs_project_path(@project), toggle: "dropdown", target: ".js-compare-from-dropdown", selected: params[:from], field_name: :from } do
- .dropdown-toggle-text.str-truncated= params[:from] || _("Select branch/tag")
+ = button_tag type: 'button', title: params[:from], class: "btn form-control compare-dropdown-toggle js-compare-dropdown has-tooltip", required: true, data: { refs_url: refs_project_path(@project), toggle: "dropdown", target: ".js-compare-from-dropdown", selected: params[:from], field_name: :from } do
+ .dropdown-toggle-text.str-truncated.monospace.float-left= params[:from] || _("Select branch/tag")
+ = sprite_icon('arrow-down', size: 16, css_class: 'float-right')
= render 'shared/ref_dropdown'
&nbsp;
= button_tag s_("CompareBranches|Compare"), class: "btn btn-success commits-compare-btn"
diff --git a/app/views/projects/deployments/_confirm_rollback_modal.html.haml b/app/views/projects/deployments/_confirm_rollback_modal.html.haml
index ff40e404e5f..9162827b501 100644
--- a/app/views/projects/deployments/_confirm_rollback_modal.html.haml
+++ b/app/views/projects/deployments/_confirm_rollback_modal.html.haml
@@ -13,7 +13,7 @@
%p= s_('Environments|This action will relaunch the job for commit %{commit_id}, putting the environment in a previous version. Are you sure you want to continue?').html_safe % {commit_id: commit_sha}
- else
%p
- = s_('Environments|This action will run the job defined by staging for commit %{commit_id}, putting the environment in a previous version. You can revert it by re-deploying the latest version of your application. Are you sure you want to continue?').html_safe % {commit_id: commit_sha}
+ = s_('Environments|This action will run the job defined by %{environment_name} for commit %{commit_id}, putting the environment in a previous version. You can revert it by re-deploying the latest version of your application. Are you sure you want to continue?').html_safe % {commit_id: commit_sha, environment_name: @environment.name}
.modal-footer
= button_tag _('Cancel'), type: 'button', class: 'btn btn-cancel', data: { dismiss: 'modal' }
= link_to [:retry, @project.namespace.becomes(Namespace), @project, deployment.deployable], method: :post, class: 'btn btn-danger' do
diff --git a/app/views/projects/environments/empty_logs.html.haml b/app/views/projects/environments/empty_logs.html.haml
new file mode 100644
index 00000000000..602dc908b75
--- /dev/null
+++ b/app/views/projects/environments/empty_logs.html.haml
@@ -0,0 +1,14 @@
+- page_title _('Pod logs')
+
+.row.empty-state
+ .col-sm-12
+ .svg-content
+ = image_tag 'illustrations/operations_log_pods_empty.svg'
+ .col-12
+ .text-content
+ %h4.text-center
+ = s_('Environments|No deployed environments')
+ %p.state-description.text-center
+ = s_('Logs|To see the pod logs, deploy your code to an environment.')
+ .text-center
+ = link_to s_('Environments|Learn about environments'), help_page_path('ci/environments'), class: 'btn btn-success'
diff --git a/app/views/projects/environments/empty.html.haml b/app/views/projects/environments/empty_metrics.html.haml
index 129dbbf4e56..dad93290fbd 100644
--- a/app/views/projects/environments/empty.html.haml
+++ b/app/views/projects/environments/empty_metrics.html.haml
@@ -7,8 +7,8 @@
.col-12
.text-content
%h4.text-center
- = s_('Metrics|No deployed environments')
+ = s_('Environments|No deployed environments')
%p.state-description
= s_('Metrics|Check out the CI/CD documentation on deploying to an environment')
.text-center
- = link_to s_("Metrics|Learn about environments"), help_page_path('ci/environments'), class: 'btn btn-success'
+ = link_to s_("Environments|Learn about environments"), help_page_path('ci/environments'), class: 'btn btn-success'
diff --git a/app/views/projects/error_tracking/details.html.haml b/app/views/projects/error_tracking/details.html.haml
new file mode 100644
index 00000000000..640746ad8f6
--- /dev/null
+++ b/app/views/projects/error_tracking/details.html.haml
@@ -0,0 +1,4 @@
+- page_title _('Error Details')
+- add_to_breadcrumbs 'Errors', project_error_tracking_index_path(@project)
+
+#js-error_details{ data: error_details_data(@current_user, @project) }
diff --git a/app/views/projects/graphs/show.html.haml b/app/views/projects/graphs/show.html.haml
index 6e5e4607232..a952db0eea3 100644
--- a/app/views/projects/graphs/show.html.haml
+++ b/app/views/projects/graphs/show.html.haml
@@ -1,26 +1,8 @@
- page_title _('Contributors')
-.js-graphs-show{ 'data-project-graph-path': project_graph_path(@project, current_ref, format: :json) }
- .sub-header-block
- .tree-ref-holder.inline.vertical-align-middle
- = render 'shared/ref_switcher', destination: 'graphs'
- = link_to s_('Commits|History'), project_commits_path(@project, current_ref), class: 'btn'
+.sub-header-block.bg-gray-light.gl-p-3
+ .tree-ref-holder.inline.vertical-align-middle
+ = render 'shared/ref_switcher', destination: 'graphs'
+ = link_to s_('Commits|History'), project_commits_path(@project, current_ref), class: 'btn'
- .loading-graph
- .center
- %h3.page-title
- %i.fa.fa-spinner.fa-spin
- = s_('ContributorsPage|Building repository graph.')
- %p.slead
- = s_('ContributorsPage|Please wait a moment, this page will automatically refresh when ready.')
-
- .stat-graph.hide
- .header.clearfix
- %h3#date_header.page-title
- %p.light
- = s_('ContributorsPage|Commits to %{branch_name}, excluding merge commits. Limited to 6,000 commits.') % { branch_name: @ref }
- %input#brush_change{ :type => "hidden" }
- .graphs.row
- #contributors-master.svg-w-100
- #contributors.clearfix
- %ol.contributors-list.svg-w-100.row
+.js-contributors-graph{ class: container_class, 'data-project-graph-path': project_graph_path(@project, current_ref, format: :json),'data-project-branch': current_ref }
diff --git a/app/views/projects/issues/_issue.html.haml b/app/views/projects/issues/_issue.html.haml
index 367b8c1138e..c8ab47888d0 100644
--- a/app/views/projects/issues/_issue.html.haml
+++ b/app/views/projects/issues/_issue.html.haml
@@ -1,4 +1,5 @@
-%li{ id: dom_id(issue), class: issue_css_classes(issue), url: issue_path(issue), data: { labels: issue.label_ids, id: issue.id } }
+-# DANGER: Any changes to this file need to be reflected in issuables_list/components/issuable.vue!
+%li{ id: dom_id(issue), class: issue_css_classes(issue), url: issue_path(issue), data: { labels: issue.label_ids, id: issue.id, qa_selector: 'issue', qa_issue_title: issue.title } }
.issue-box
- if @can_bulk_update
.issue-check.hidden
diff --git a/app/views/projects/labels/index.html.haml b/app/views/projects/labels/index.html.haml
index 0328751c68c..0373e37818d 100644
--- a/app/views/projects/labels/index.html.haml
+++ b/app/views/projects/labels/index.html.haml
@@ -26,7 +26,7 @@
= render partial: 'shared/label', collection: @prioritized_labels, as: :label, locals: { force_priority: true, subject: @project }
- elsif search.present?
.nothing-here-block
- = _('No prioritised labels with such name or description')
+ = _('No prioritized labels with such name or description')
- if @labels.present?
.other-labels
diff --git a/app/views/projects/merge_requests/_how_to_merge.html.haml b/app/views/projects/merge_requests/_how_to_merge.html.haml
index 57205682bda..9cdbbe7204b 100644
--- a/app/views/projects/merge_requests/_how_to_merge.html.haml
+++ b/app/views/projects/merge_requests/_how_to_merge.html.haml
@@ -12,8 +12,8 @@
= clipboard_button(target: "pre#merge-info-1", title: _("Copy commands"))
%pre.dark#merge-info-1
- if @merge_request.for_fork?
+ -# All repo/branch refs have been quoted to allow support for special characters (such as #my-branch)
:preserve
- -# All repo/branch refs have been quoted to allow support for special characters (such as #my-branch)
git fetch "#{h default_url_to_repo(@merge_request.source_project)}" "#{h @merge_request.source_branch}"
git checkout -b "#{h @merge_request.source_project_path}-#{h @merge_request.source_branch}" FETCH_HEAD
- else
diff --git a/app/views/projects/merge_requests/creations/_new_submit.html.haml b/app/views/projects/merge_requests/creations/_new_submit.html.haml
index 543441b9479..15c83f92474 100644
--- a/app/views/projects/merge_requests/creations/_new_submit.html.haml
+++ b/app/views/projects/merge_requests/creations/_new_submit.html.haml
@@ -1,15 +1,5 @@
%h3.page-title
New Merge Request
-%p.slead
- - source_title, target_title = format_mr_branch_names(@merge_request)
- From
- %strong.ref-name= source_title
- %span into
- %strong.ref-name= target_title
-
- %span.float-right
- = link_to 'Change branches', mr_change_branches_path(@merge_request)
-%hr
= form_for [@project.namespace.becomes(Namespace), @project, @merge_request], html: { class: 'merge-request-form common-note-form js-requires-input js-quick-submit' } do |f|
= render 'shared/issuable/form', f: f, issuable: @merge_request, commits: @commits, presenter: @mr_presenter
= f.hidden_field :source_project_id
diff --git a/app/views/projects/merge_requests/edit.html.haml b/app/views/projects/merge_requests/edit.html.haml
index 03159f123f3..318c9d809c1 100644
--- a/app/views/projects/merge_requests/edit.html.haml
+++ b/app/views/projects/merge_requests/edit.html.haml
@@ -2,5 +2,4 @@
%h3.page-title
Edit Merge Request #{@merge_request.to_reference}
-%hr
= render 'form'
diff --git a/app/views/projects/milestones/show.html.haml b/app/views/projects/milestones/show.html.haml
index 49d3039d0c9..5f244d3a6c3 100644
--- a/app/views/projects/milestones/show.html.haml
+++ b/app/views/projects/milestones/show.html.haml
@@ -3,57 +3,8 @@
- page_title @milestone.title, _('Milestones')
- page_description @milestone.description
-.detail-page-header.milestone-page-header
- .status-box{ class: status_box_class(@milestone) }
- - if @milestone.closed?
- = _('Closed')
- - elsif @milestone.expired?
- = _('Past due')
- - elsif @milestone.upcoming?
- = _('Upcoming')
- - else
- = _('Open')
- .header-text-content
- %span.identifier
- %strong
- = _('Milestone')
- - if @milestone.due_date || @milestone.start_date
- = milestone_date_range(@milestone)
- .milestone-buttons
- - if can?(current_user, :admin_milestone, @project)
- = link_to edit_project_milestone_path(@project, @milestone), class: 'btn btn-grouped btn-nr' do
- = _('Edit')
-
- - if @project.group
- %button.js-promote-project-milestone-button.btn.btn-grouped{ data: { toggle: 'modal',
- target: '#promote-milestone-modal',
- milestone_title: @milestone.title,
- group_name: @project.group.name,
- url: promote_project_milestone_path(@milestone.project, @milestone),
- container: 'body' },
- disabled: true,
- type: 'button' }
- = _('Promote')
- #promote-milestone-modal
-
- - if @milestone.active?
- = link_to _('Close milestone'), project_milestone_path(@project, @milestone, milestone: {state_event: :close }), method: :put, class: 'btn btn-close btn-nr btn-grouped'
- - else
- = link_to _('Reopen milestone'), project_milestone_path(@project, @milestone, milestone: {state_event: :activate }), method: :put, class: 'btn btn-reopen btn-nr btn-grouped'
-
- = render 'shared/milestones/delete_button'
-
- %a.btn.btn-default.btn-grouped.float-right.d-block.d-sm-none.js-sidebar-toggle{ href: '#' }
- = icon('angle-double-left')
-
-.detail-page-description.milestone-detail
- %h2.title.qa-milestone-title
- = markdown_field(@milestone, :title)
-
- %div
- - if @milestone.description.present?
- .description.md
- = markdown_field(@milestone, :description)
+= render 'shared/milestones/header', milestone: @milestone
+= render 'shared/milestones/description', milestone: @milestone
= render_if_exists 'shared/milestones/burndown', milestone: @milestone, project: @project
diff --git a/app/views/projects/mirrors/_authentication_method.html.haml b/app/views/projects/mirrors/_authentication_method.html.haml
index ee82d68d398..a6978cba495 100644
--- a/app/views/projects/mirrors/_authentication_method.html.haml
+++ b/app/views/projects/mirrors/_authentication_method.html.haml
@@ -3,10 +3,12 @@
.form-group
= f.label :auth_method, _('Authentication method'), class: 'label-bold'
- = f.select :auth_method,
- options_for_select(auth_options, mirror.auth_method),
- {}, { class: "form-control js-mirror-auth-type qa-authentication-method" }
- = f.hidden_field :auth_method, value: "password", class: "js-hidden-mirror-auth-type"
+ .select-wrapper
+ = f.select :auth_method,
+ options_for_select(auth_options, mirror.auth_method),
+ {}, { class: "form-control select-control js-mirror-auth-type qa-authentication-method" }
+ = icon('chevron-down')
+ = f.hidden_field :auth_method, value: "password", class: "js-hidden-mirror-auth-type"
.form-group
.collapse.js-well-changing-auth
diff --git a/app/views/projects/mirrors/_mirror_repos_form.html.haml b/app/views/projects/mirrors/_mirror_repos_form.html.haml
index b49f1d9315e..dd794e03f48 100644
--- a/app/views/projects/mirrors/_mirror_repos_form.html.haml
+++ b/app/views/projects/mirrors/_mirror_repos_form.html.haml
@@ -1,5 +1,7 @@
.form-group
= label_tag :mirror_direction, _('Mirror direction'), class: 'label-light'
- = select_tag :mirror_direction, options_for_select([[_('Push'), 'push']]), class: 'form-control js-mirror-direction qa-mirror-direction', disabled: true
+ .select-wrapper
+ = select_tag :mirror_direction, options_for_select([[_('Push'), 'push']]), class: 'form-control select-control js-mirror-direction qa-mirror-direction', disabled: true
+ = icon('chevron-down')
= render partial: "projects/mirrors/mirror_repos_push", locals: { f: f }
diff --git a/app/views/projects/pages/_access.html.haml b/app/views/projects/pages/_access.html.haml
index 178f0acc5b9..08dcba2afd7 100644
--- a/app/views/projects/pages/_access.html.haml
+++ b/app/views/projects/pages/_access.html.haml
@@ -13,5 +13,11 @@
- @project.pages_domains.each do |domain|
%p
= external_link(domain.url, domain.url)
+ - unless @project.public_pages?
+ .card-footer.alert-warning
+ - help_page = help_page_path('/user/project/pages/pages_access_control')
+ - link_start = '<a href="%{url}" target="_blank" class="alert-link" rel="noopener noreferrer">'.html_safe % { url: help_page }
+ - link_end = '</a>'.html_safe
+ = s_('GitLabPages|Access Control is enabled for this Pages website; only authorized users will be able to access it. To make your website publicly available, navigate to your project\'s %{strong_start}Settings > General > Visibility%{strong_end} and select %{strong_start}Everyone%{strong_end} in pages section. Read the %{link_start}documentation%{link_end} for more information.').html_safe % { link_start: link_start, link_end: link_end, strong_start: '<strong>'.html_safe, strong_end: '</strong>'.html_safe }
.card-footer.alert-primary
= s_('GitLabPages|It may take up to 30 minutes before the site is available after the first deployment.')
diff --git a/app/views/projects/pages/_list.html.haml b/app/views/projects/pages/_list.html.haml
index b05491f2c6e..4676c7399f1 100644
--- a/app/views/projects/pages/_list.html.haml
+++ b/app/views/projects/pages/_list.html.haml
@@ -21,11 +21,11 @@
%span.badge.badge-danger
= s_('GitLabPages|Expired')
%div
- = link_to s_('GitLabPages|Details'), project_pages_domain_path(@project, domain), class: "btn btn-sm btn-grouped"
+ = link_to s_('GitLabPages|Edit'), edit_project_pages_domain_path(@project, domain), class: "btn btn-sm btn-grouped btn-success btn-inverted"
= link_to s_('GitLabPages|Remove'), project_pages_domain_path(@project, domain), data: { confirm: s_('GitLabPages|Are you sure?')}, method: :delete, class: "btn btn-remove btn-sm btn-grouped"
- if verification_enabled && domain.unverified?
%li.list-group-item.bs-callout-warning
- - details_link_start = "<a href='#{project_pages_domain_path(@project, domain)}'>".html_safe
+ - details_link_start = "<a href='#{edit_project_pages_domain_path(@project, domain)}'>".html_safe
- details_link_end = '</a>'.html_safe
= s_('GitLabPages|%{domain} is not verified. To learn how to verify ownership, visit your %{link_start}domain details%{link_end}.').html_safe % { domain: domain.domain,
link_start: details_link_start,
diff --git a/app/views/projects/pages/show.html.haml b/app/views/projects/pages/show.html.haml
index 0e1f281410a..3ec87597849 100644
--- a/app/views/projects/pages/show.html.haml
+++ b/app/views/projects/pages/show.html.haml
@@ -1,23 +1,27 @@
- page_title 'Pages'
-%h3.page-title.with-button
- = s_('GitLabPages|Pages')
+- if @project.pages_enabled?
+ %h3.page-title.with-button
+ = s_('GitLabPages|Pages')
- - if can?(current_user, :update_pages, @project) && (Gitlab.config.pages.external_http || Gitlab.config.pages.external_https)
- = link_to new_project_pages_domain_path(@project), class: 'btn btn-success float-right', title: s_('GitLabPages|New Domain') do
- = s_('GitLabPages|New Domain')
+ - if can?(current_user, :update_pages, @project) && (Gitlab.config.pages.external_http || Gitlab.config.pages.external_https)
+ = link_to new_project_pages_domain_path(@project), class: 'btn btn-success float-right', title: s_('GitLabPages|New Domain') do
+ = s_('GitLabPages|New Domain')
-%p.light
- = s_('GitLabPages|With GitLab Pages you can host your static websites on GitLab. Combined with the power of GitLab CI and the help of GitLab Runner you can deploy static pages for your individual projects, your user or your group.')
-- if Gitlab.config.pages.external_https
- = render 'https_only'
+ %p.light
+ = s_('GitLabPages|With GitLab Pages you can host your static websites on GitLab. Combined with the power of GitLab CI and the help of GitLab Runner you can deploy static pages for your individual projects, your user or your group.')
+ - if Gitlab.config.pages.external_https
+ = render 'https_only'
-%hr.clearfix
+ %hr.clearfix
-= render 'access'
-= render 'use'
-- if Gitlab.config.pages.external_http || Gitlab.config.pages.external_https
- = render 'list'
+ = render 'access'
+ = render 'use'
+ - if Gitlab.config.pages.external_http || Gitlab.config.pages.external_https
+ = render 'list'
+ - else
+ = render 'no_domains'
+ = render 'destroy'
- else
- = render 'no_domains'
-= render 'destroy'
+ .bs-callout.bs-callout-warning
+ = s_('GitLabPages|GitLab Pages are disabled for this project. You can enable them on your project\'s %{strong_start}Settings > General > Visibility%{strong_end} page.').html_safe % { strong_start: '<strong>'.html_safe, strong_end: '</strong>'.html_safe }
diff --git a/app/views/projects/pages_domains/_certificate.html.haml b/app/views/projects/pages_domains/_certificate.html.haml
index 42631fca5e8..92d30e0b056 100644
--- a/app/views/projects/pages_domains/_certificate.html.haml
+++ b/app/views/projects/pages_domains/_certificate.html.haml
@@ -1,18 +1,63 @@
-- if @domain.auto_ssl_enabled?
- - if @domain.enabled?
- - if @domain.certificate_text
- %pre
- = @domain.certificate_text
- - else
- .bs-callout.bs-callout-info
- = _("GitLab is obtaining a Let's Encrypt SSL certificate for this domain. This process can take some time. Please try again later.")
+- auto_ssl_available = ::Gitlab::LetsEncrypt.enabled?
+- auto_ssl_enabled = @domain.auto_ssl_enabled?
+- auto_ssl_available_and_enabled = auto_ssl_available && auto_ssl_enabled
+- has_user_defined_certificate = @domain.certificate && @domain.certificate_user_provided?
+
+- if auto_ssl_available
+ .form-group.border-section
+ .row
+ .col-sm-2
+ = _('Certificate')
+ .col-sm-10.js-auto-ssl-toggle-container
+ %label{ for: "pages_domain_auto_ssl_enabled_button" }
+ - lets_encrypt_link_url = "https://letsencrypt.org/"
+ - lets_encrypt_link_start = "<a href=\"%{lets_encrypt_link_url}\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"text-nowrap\">".html_safe % { lets_encrypt_link_url: lets_encrypt_link_url }
+ - lets_encrypt_link_end = "</a>".html_safe
+ = _("Automatic certificate management using %{lets_encrypt_link_start}Let's Encrypt%{lets_encrypt_link_end}").html_safe % { lets_encrypt_link_start: lets_encrypt_link_start, lets_encrypt_link_end: lets_encrypt_link_end }
+ %button{ type: "button", id: "pages_domain_auto_ssl_enabled_button",
+ class: "js-project-feature-toggle project-feature-toggle mt-2 #{"is-checked" if auto_ssl_available_and_enabled}",
+ "aria-label": _("Automatic certificate management using Let's Encrypt") }
+ = f.hidden_field :auto_ssl_enabled?, class: "js-project-feature-toggle-input"
+ %span.toggle-icon
+ = sprite_icon("status_success_borderless", size: 16, css_class: "toggle-icon-svg toggle-status-checked")
+ = sprite_icon("status_failed_borderless", size: 16, css_class: "toggle-icon-svg toggle-status-unchecked")
+ %p.text-secondary.mt-3
+ - docs_link_url = help_page_path("user/project/pages/custom_domains_ssl_tls_certification/lets_encrypt_integration.md")
+ - docs_link_start = "<a href=\"%{docs_link_url}\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"text-nowrap\">".html_safe % { docs_link_url: docs_link_url }
+ - docs_link_end = "</a>".html_safe
+ = _("Let's Encrypt is a free, automated, and open certificate authority (CA) that gives digital certificates in order to enable HTTPS (SSL/TLS) for websites. Learn more about Let's Encrypt configuration by following the %{docs_link_start}documentation on GitLab Pages%{docs_link_end}.").html_safe % { docs_link_url: docs_link_url, docs_link_start: docs_link_start, docs_link_end: docs_link_end }
+
+.form-group.border-section.js-shown-unless-auto-ssl{ class: ("d-none" if auto_ssl_available_and_enabled) }
+ - if has_user_defined_certificate
+ .row
+ .col-sm-10.offset-sm-2
+ .card
+ .card-header
+ = _('Certificate')
+ .d-flex.justify-content-between.align-items-center.p-3
+ %span
+ = @domain.subject || _('missing')
+ = link_to _('Remove'),
+ clean_certificate_project_pages_domain_path(@project, @domain),
+ data: { confirm: _('Are you sure?') },
+ class: 'btn btn-remove btn-sm',
+ method: :delete
- else
- .bs-callout.bs-callout-warning
- = _("A Let's Encrypt SSL certificate can not be obtained until your domain is verified.")
-- else
- - if @domain.certificate_text
- %pre
- = @domain.certificate_text
- - else
- .light
- = _("missing")
+ .row
+ .col-sm-10.offset-sm-2
+ = f.label :user_provided_certificate, _("Certificate (PEM)")
+ = f.text_area :user_provided_certificate,
+ rows: 5,
+ class: "form-control js-enabled-unless-auto-ssl",
+ disabled: auto_ssl_available_and_enabled
+ %span.help-inline.text-muted= _("Upload a certificate for your domain with all intermediates")
+ .row
+ .col-sm-10.offset-sm-2
+ = f.label :user_provided_key, _("Key (PEM)")
+ = f.text_area :user_provided_key,
+ rows: 5,
+ class: "form-control js-enabled-unless-auto-ssl",
+ disabled: auto_ssl_available_and_enabled
+ %span.help-inline.text-muted= _("Upload a private key for your certificate")
+
+= render 'lets_encrypt_callout', auto_ssl_available_and_enabled: auto_ssl_available_and_enabled
diff --git a/app/views/projects/pages_domains/_dns.html.haml b/app/views/projects/pages_domains/_dns.html.haml
new file mode 100644
index 00000000000..e4e590f0a98
--- /dev/null
+++ b/app/views/projects/pages_domains/_dns.html.haml
@@ -0,0 +1,33 @@
+- verification_enabled = Gitlab::CurrentSettings.pages_domain_verification_enabled?
+- dns_record = "#{@domain.domain} CNAME #{@domain.project.pages_subdomain}.#{Settings.pages.host}."
+
+.form-group.border-section
+ .row
+ .col-sm-2
+ = _("DNS")
+ .col-sm-10
+ .input-group
+ = text_field_tag :domain_dns, dns_record , class: "monospace js-select-on-focus form-control", readonly: true
+ .input-group-append
+ = clipboard_button(target: '#domain_dns', class: 'btn-default input-group-text d-none d-sm-block')
+ %p.form-text.text-muted
+ = _("To access this domain create a new DNS record")
+- if verification_enabled
+ - verification_record = "#{@domain.verification_domain} TXT #{@domain.keyed_verification_code}"
+ .form-group.border-section
+ .row
+ .col-sm-2
+ = _("Verification status")
+ .col-sm-10
+ .status-badge
+ - text, status = @domain.unverified? ? [_('Unverified'), 'badge-danger'] : [_('Verified'), 'badge-success']
+ .badge{ class: status }
+ = text
+ = link_to sprite_icon("redo"), verify_project_pages_domain_path(@project, @domain), method: :post, class: "btn has-tooltip", title: _("Retry verification")
+ .input-group
+ = text_field_tag :domain_verification, verification_record, class: "monospace js-select-on-focus form-control", readonly: true
+ .input-group-append
+ = clipboard_button(target: '#domain_verification', class: 'btn-default d-none d-sm-block')
+ %p.form-text.text-muted
+ - link_to_help = link_to(_('verify ownership'), help_page_path('user/project/pages/custom_domains_ssl_tls_certification/index.md', anchor: '4-verify-the-domains-ownership'))
+ = _("To %{link_to_help} of your domain, add the above key to a TXT record within to your DNS configuration.").html_safe % { link_to_help: link_to_help }
diff --git a/app/views/projects/pages_domains/_form.html.haml b/app/views/projects/pages_domains/_form.html.haml
index 4aa1e574d93..e06dab9be06 100644
--- a/app/views/projects/pages_domains/_form.html.haml
+++ b/app/views/projects/pages_domains/_form.html.haml
@@ -3,62 +3,25 @@
- @domain.errors.full_messages.each do |msg|
= msg
-.form-group.row
- .col-sm-2.col-form-label
- = f.label :domain, _("Domain")
- .col-sm-10
- = f.text_field :domain, required: true, autocomplete: "off", class: "form-control", disabled: @domain.persisted?
-
-- if Gitlab.config.pages.external_https
-
- - auto_ssl_available = ::Gitlab::LetsEncrypt.enabled?
- - auto_ssl_enabled = @domain.auto_ssl_enabled?
- - auto_ssl_available_and_enabled = auto_ssl_available && auto_ssl_enabled
-
- - if auto_ssl_available
- .form-group.row
- .col-sm-2.col-form-label
- %label{ for: "pages_domain_auto_ssl_enabled_button" }
- - lets_encrypt_link_url = "https://letsencrypt.org/"
- - lets_encrypt_link_start = "<a href=\"%{lets_encrypt_link_url}\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"text-nowrap\">".html_safe % { lets_encrypt_link_url: lets_encrypt_link_url }
- - lets_encrypt_link_end = "</a>".html_safe
- = _("Automatic certificate management using %{lets_encrypt_link_start}Let's Encrypt%{lets_encrypt_link_end}").html_safe % { lets_encrypt_link_start: lets_encrypt_link_start, lets_encrypt_link_end: lets_encrypt_link_end }
-
- .col-sm-10.js-auto-ssl-toggle-container
- %button{ type: "button", id: "pages_domain_auto_ssl_enabled_button",
- class: "js-project-feature-toggle project-feature-toggle mt-2 #{"is-checked" if auto_ssl_available_and_enabled}",
- "aria-label": _("Automatic certificate management using Let's Encrypt") }
- = f.hidden_field :auto_ssl_enabled?, class: "js-project-feature-toggle-input"
- %span.toggle-icon
- = sprite_icon("status_success_borderless", size: 16, css_class: "toggle-icon-svg toggle-status-checked")
- = sprite_icon("status_failed_borderless", size: 16, css_class: "toggle-icon-svg toggle-status-unchecked")
- %p.text-secondary.mt-3
- - docs_link_url = help_page_path("user/project/pages/custom_domains_ssl_tls_certification/lets_encrypt_integration.md")
- - docs_link_start = "<a href=\"%{docs_link_url}\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"text-nowrap\">".html_safe % { docs_link_url: docs_link_url }
- - docs_link_end = "</a>".html_safe
- = _("Let's Encrypt is a free, automated, and open certificate authority (CA) that gives digital certificates in order to enable HTTPS (SSL/TLS) for websites. Learn more about Let's Encrypt configuration by following the %{docs_link_start}documentation on GitLab Pages%{docs_link_end}.").html_safe % { docs_link_url: docs_link_url, docs_link_start: docs_link_start, docs_link_end: docs_link_end }
-
- .js-shown-unless-auto-ssl{ class: ("d-none" if auto_ssl_available_and_enabled) }
- .form-group.row
- .col-sm-2.col-form-label
- = f.label :user_provided_certificate, _("Certificate (PEM)")
+.form-group.border-section
+ .row
+ - if @domain.persisted?
+ .col-sm-2
+ = _("Domain")
.col-sm-10
- = f.text_area :user_provided_certificate,
- rows: 5,
- class: "form-control js-enabled-unless-auto-ssl",
- disabled: auto_ssl_available_and_enabled
- %span.help-inline.text-muted= _("Upload a certificate for your domain with all intermediates")
-
- .form-group.row
- .col-sm-2.col-form-label
- = f.label :user_provided_key, _("Key (PEM)")
+ = external_link(@domain.url, @domain.url)
+ - else
+ .col-sm-2
+ = f.label :domain, _("Domain")
.col-sm-10
- = f.text_area :user_provided_key,
- rows: 5,
- class: "form-control js-enabled-unless-auto-ssl",
- disabled: auto_ssl_available_and_enabled
- %span.help-inline.text-muted= _("Upload a private key for your certificate")
+ .input-group
+ = f.text_field :domain, required: true, autocomplete: "off", class: "form-control"
+- if @domain.persisted?
+ = render 'dns'
+
+- if Gitlab.config.pages.external_https
+ = render 'certificate', f: f
- else
- .nothing-here-block
+ .border-section.nothing-here-block
= _("Support for custom certificates is disabled. Ask your system's administrator to enable it.")
diff --git a/app/views/projects/pages_domains/_lets_encrypt_callout.html.haml b/app/views/projects/pages_domains/_lets_encrypt_callout.html.haml
new file mode 100644
index 00000000000..d6406a78fca
--- /dev/null
+++ b/app/views/projects/pages_domains/_lets_encrypt_callout.html.haml
@@ -0,0 +1,13 @@
+- if @domain.enabled?
+ - if @domain.auto_ssl_enabled && !@domain.certificate
+ .form-group.border-section.js-shown-if-auto-ssl{ class: ("d-none" unless auto_ssl_available_and_enabled) }
+ .row
+ .col-sm-10.offset-sm-2
+ .bs-callout.bs-callout-info.mt-0
+ = _("GitLab is obtaining a Let's Encrypt SSL certificate for this domain. This process can take some time. Please try again later.")
+- else
+ .form-group.border-section.js-shown-if-auto-ssl{ class: ("d-none" unless auto_ssl_available_and_enabled) }
+ .row
+ .col-sm-10.offset-sm-2
+ .bs-callout.bs-callout-warning.mt-0
+ = _("A Let's Encrypt SSL certificate can not be obtained until your domain is verified.")
diff --git a/app/views/projects/pages_domains/edit.html.haml b/app/views/projects/pages_domains/edit.html.haml
index 7c0777e5496..a08be65d7e4 100644
--- a/app/views/projects/pages_domains/edit.html.haml
+++ b/app/views/projects/pages_domains/edit.html.haml
@@ -1,12 +1,21 @@
- add_to_breadcrumbs _("Pages"), project_pages_path(@project)
- breadcrumb_title @domain.domain
- page_title @domain.domain
+
+- verification_enabled = Gitlab::CurrentSettings.pages_domain_verification_enabled?
+
+- if verification_enabled && @domain.unverified?
+ = content_for :flash_message do
+ .alert.alert-warning
+ .container-fluid.container-limited
+ = _("This domain is not verified. You will need to verify ownership before access is enabled.")
+
%h3.page-title
- = @domain.domain
+ = _('Pages Domain')
= render 'projects/pages_domains/helper_text'
-%hr.clearfix
%div
= form_for [@project.namespace.becomes(Namespace), @project, @domain], html: { class: 'fieldset-form' } do |f|
= render 'form', { f: f }
- .form-actions
+ .form-actions.d-flex.justify-content-between
= f.submit _('Save Changes'), class: "btn btn-success"
+ = link_to _('Cancel'), project_pages_path(@project), class: 'btn btn-default btn-inverse'
diff --git a/app/views/projects/pages_domains/new.html.haml b/app/views/projects/pages_domains/new.html.haml
index e23ccb5d4c6..3210bfe9231 100644
--- a/app/views/projects/pages_domains/new.html.haml
+++ b/app/views/projects/pages_domains/new.html.haml
@@ -3,7 +3,6 @@
%h3.page-title
= _("New Pages Domain")
= render 'projects/pages_domains/helper_text'
-%hr.clearfix
%div
= form_for [@project.namespace.becomes(Namespace), @project, @domain], html: { class: 'fieldset-form' } do |f|
= render 'form', { f: f }
diff --git a/app/views/projects/pages_domains/show.html.haml b/app/views/projects/pages_domains/show.html.haml
index 33837e21c8d..8eec3d51835 100644
--- a/app/views/projects/pages_domains/show.html.haml
+++ b/app/views/projects/pages_domains/show.html.haml
@@ -58,4 +58,4 @@
%td
= _("Certificate")
%td
- = render 'certificate'
+ = render 'lets_encrypt_callout', auto_ssl_available_and_enabled: false
diff --git a/app/views/projects/pipelines/_with_tabs.html.haml b/app/views/projects/pipelines/_with_tabs.html.haml
index 8c3518e3a29..4d8cba5168d 100644
--- a/app/views/projects/pipelines/_with_tabs.html.haml
+++ b/app/views/projects/pipelines/_with_tabs.html.haml
@@ -1,3 +1,5 @@
+- test_reports_enabled = Feature.enabled?(:junit_pipeline_view)
+
.tabs-holder
%ul.pipelines-tabs.nav-links.no-top.no-bottom.mobile-separator.nav.nav-tabs
%li.js-pipeline-tab-link
@@ -12,6 +14,11 @@
= link_to failures_project_pipeline_path(@project, @pipeline), data: { target: '#js-tab-failures', action: 'failures', toggle: 'tab' }, class: 'failures-tab' do
= _('Failed Jobs')
%span.badge.badge-pill.js-failures-counter= @pipeline.failed_builds.count
+ - if test_reports_enabled
+ %li.js-tests-tab-link
+ = link_to test_report_project_pipeline_path(@project, @pipeline), data: { target: '#js-tab-tests', action: 'test_report', toggle: 'tab' }, class: 'test-tab' do
+ = s_('TestReports|Tests')
+ %span.badge.badge-pill= pipeline.test_reports.total_count
= render_if_exists "projects/pipelines/tabs_holder", pipeline: @pipeline, project: @project
.tab-content
@@ -32,10 +39,6 @@
%th
= render partial: "projects/stage/stage", collection: pipeline.legacy_stages, as: :stage
- - elsif pipeline.project.builds_enabled? && !pipeline.ci_yaml_file
- .bs-callout.bs-callout-warning
- = _("%{gitlab_ci_yml} not found in this commit") % { gitlab_ci_yml: ".gitlab-ci.yml" }
-
- if @pipeline.failed_builds.present?
#js-tab-failures.build-failures.tab-pane.build-page
%table.table.responsive-table.ci-table.responsive-table-sm-rounded
@@ -71,4 +74,7 @@
%pre.build-trace.build-trace-rounded
%code.bash.js-build-output
= build_summary(build)
+
+ #js-tab-tests.tab-pane
+ #js-pipeline-tests-detail
= render_if_exists "projects/pipelines/tabs_content", pipeline: @pipeline, project: @project
diff --git a/app/views/projects/pipelines/new.html.haml b/app/views/projects/pipelines/new.html.haml
index bfcaa09ae8c..a3e46a0939c 100644
--- a/app/views/projects/pipelines/new.html.haml
+++ b/app/views/projects/pipelines/new.html.haml
@@ -23,6 +23,13 @@
%label
= s_('Pipeline|Variables')
%ul.ci-variable-list
+ - if params[:var]
+ - params[:var].each do |variable|
+ = render 'ci/variables/url_query_variable_row', form_field: 'pipeline', variable: variable
+ - if params[:file_var]
+ - params[:file_var].each do |variable|
+ - variable.push("file")
+ = render 'ci/variables/url_query_variable_row', form_field: 'pipeline', variable: variable
= render 'ci/variables/variable_row', form_field: 'pipeline', only_key_value: true
.form-text.text-muted
= (s_("Pipeline|Specify variable values to be used in this run. The values specified in %{settings_link} will be used by default.") % {settings_link: settings_link}).html_safe
diff --git a/app/views/projects/pipelines/show.html.haml b/app/views/projects/pipelines/show.html.haml
index 2b2133b8296..f0b3ab24ea0 100644
--- a/app/views/projects/pipelines/show.html.haml
+++ b/app/views/projects/pipelines/show.html.haml
@@ -20,4 +20,5 @@
- else
= render "projects/pipelines/with_tabs", pipeline: @pipeline
-.js-pipeline-details-vue{ data: { endpoint: project_pipeline_path(@project, @pipeline, format: :json) } }
+.js-pipeline-details-vue{ data: { endpoint: project_pipeline_path(@project, @pipeline, format: :json),
+ test_report_endpoint: test_report_project_pipeline_path(@project, @pipeline, format: :json) } }
diff --git a/app/views/projects/protected_branches/shared/_branches_list.html.haml b/app/views/projects/protected_branches/shared/_branches_list.html.haml
index 9dff251101b..f07de81d7fd 100644
--- a/app/views/projects/protected_branches/shared/_branches_list.html.haml
+++ b/app/views/projects/protected_branches/shared/_branches_list.html.haml
@@ -5,6 +5,7 @@
%p.settings-message.text-center
= s_("ProtectedBranch|There are currently no protected branches, protect a branch with the form above.")
- else
+ .flash-container
%table.table.table-bordered
%colgroup
%col{ width: "20%" }
@@ -27,8 +28,6 @@
- if can_admin_project
%th
%tbody
- %tr
- %td.flash-container{ colspan: 5 }
= yield
= paginate @protected_branches, theme: 'gitlab'
diff --git a/app/views/projects/services/_form.html.haml b/app/views/projects/services/_form.html.haml
index 959a2423e02..582f3d6fce4 100644
--- a/app/views/projects/services/_form.html.haml
+++ b/app/views/projects/services/_form.html.haml
@@ -6,7 +6,6 @@
- hide_class = 'd-none' if @service.activated? != value
%span.js-service-active-status{ class: hide_class, data: { value: value.to_s } }
= boolean_to_icon value
- %p= #{@service.description}.
- if @service.respond_to?(:detailed_description)
%p= @service.detailed_description
diff --git a/app/views/projects/services/_index.html.haml b/app/views/projects/services/_index.html.haml
index 7748a7a6a8e..3f33d72d3ec 100644
--- a/app/views/projects/services/_index.html.haml
+++ b/app/views/projects/services/_index.html.haml
@@ -21,7 +21,7 @@
%td{ "aria-label" => (service.activated? ? s_("ProjectService|%{service_title}: status on") : s_("ProjectService|%{service_title}: status off")) % { service_title: service.title } }
= boolean_to_icon service.activated?
%td
- = link_to edit_project_service_path(@project, service.to_param) do
+ = link_to edit_project_service_path(@project, service.to_param), { data: { qa_selector: "#{service.title.downcase.gsub(/[\s\(\)]/,'_')}_link" } } do
%strong= service.title
%td.d-none.d-sm-block
= service.description
diff --git a/app/views/projects/services/edit.html.haml b/app/views/projects/services/edit.html.haml
index fc20bc52d1c..1e7903535c6 100644
--- a/app/views/projects/services/edit.html.haml
+++ b/app/views/projects/services/edit.html.haml
@@ -1,6 +1,7 @@
-- breadcrumb_title s_("ProjectService|Integrations")
+- breadcrumb_title @service.title
- page_title @service.title, s_("ProjectService|Services")
- add_to_breadcrumbs(s_("ProjectService|Settings"), edit_project_path(@project))
+- add_to_breadcrumbs(s_("ProjectService|Integrations"), namespace_project_settings_integrations_path)
= render 'deprecated_message' if @service.deprecation_message
diff --git a/app/views/projects/settings/ci_cd/_form.html.haml b/app/views/projects/settings/ci_cd/_form.html.haml
index 66ed1cadf6a..ea815be23c1 100644
--- a/app/views/projects/settings/ci_cd/_form.html.haml
+++ b/app/views/projects/settings/ci_cd/_form.html.haml
@@ -98,7 +98,7 @@
%span.input-group-append
.input-group-text /
%p.form-text.text-muted
- = _("A regular expression that will be used to find the test coverage output in the job trace. Leave blank to disable")
+ = _("A regular expression that will be used to find the test coverage output in the job log. Leave blank to disable")
= link_to icon('question-circle'), help_page_path('user/project/pipelines/settings', anchor: 'test-coverage-parsing'), target: '_blank'
.bs-callout.bs-callout-info
%p= _("Below are examples of regex for existing tools:")
diff --git a/app/views/projects/settings/ci_cd/show.html.haml b/app/views/projects/settings/ci_cd/show.html.haml
index 87000e8270b..862db23e856 100644
--- a/app/views/projects/settings/ci_cd/show.html.haml
+++ b/app/views/projects/settings/ci_cd/show.html.haml
@@ -37,7 +37,8 @@
%button.btn.js-settings-toggle{ type: 'button' }
= expanded ? _('Collapse') : _('Expand')
%p
- = _("Register and see your runners for this project.")
+ = _("Runners are processes that pick up and execute jobs for GitLab. Here you can register and see your Runners for this project.")
+ = link_to s_('More information'), help_page_path('ci/runners/README')
.settings-content
= render 'projects/runners/index'
diff --git a/app/views/projects/settings/operations/_grafana_integration.html.haml b/app/views/projects/settings/operations/_grafana_integration.html.haml
new file mode 100644
index 00000000000..cd5b5abd9ce
--- /dev/null
+++ b/app/views/projects/settings/operations/_grafana_integration.html.haml
@@ -0,0 +1,2 @@
+.js-grafana-integration{ data: { operations_settings_endpoint: project_settings_operations_path(@project),
+ grafana_integration: { url: grafana_integration_url, token: grafana_integration_token, enabled: grafana_integration_enabled?.to_s } } }
diff --git a/app/views/projects/settings/operations/show.html.haml b/app/views/projects/settings/operations/show.html.haml
index 0a7a155bc12..3c955e5f558 100644
--- a/app/views/projects/settings/operations/show.html.haml
+++ b/app/views/projects/settings/operations/show.html.haml
@@ -5,4 +5,5 @@
= render_if_exists 'projects/settings/operations/incidents'
= render 'projects/settings/operations/error_tracking'
= render 'projects/settings/operations/external_dashboard'
+= render 'projects/settings/operations/grafana_integration'
= render_if_exists 'projects/settings/operations/tracing'
diff --git a/app/views/projects/show.html.haml b/app/views/projects/show.html.haml
index b58af545439..c5653c3dd5a 100644
--- a/app/views/projects/show.html.haml
+++ b/app/views/projects/show.html.haml
@@ -6,7 +6,7 @@
= render partial: 'flash_messages', locals: { project: @project }
-- if !@project.empty_repo? && can?(current_user, :download_code, @project)
+- if !@project.empty_repo? && can?(current_user, :download_code, @project) && !vue_file_list_enabled?
- signatures_path = project_signatures_path(@project, @project.default_branch)
.js-signature-container{ data: { 'signatures-path': signatures_path } }
diff --git a/app/views/projects/tree/_readme.html.haml b/app/views/projects/tree/_readme.html.haml
index 4f6c7e1f9a6..fef019e1b69 100644
--- a/app/views/projects/tree/_readme.html.haml
+++ b/app/views/projects/tree/_readme.html.haml
@@ -1,5 +1,5 @@
- if readme.rich_viewer
- %article.file-holder.readme-holder{ id: 'readme', class: [("limited-width-container" unless fluid_layout), ("js-hide-on-navigation" if vue_file_list_enabled?)] }
+ %article.file-holder.readme-holder{ id: 'readme', class: [("limited-width-container" unless fluid_layout), ("js-show-on-root" if vue_file_list_enabled?)] }
.js-file-title.file-title
= blob_icon readme.mode, readme.name
= link_to project_blob_path(@project, tree_join(@ref, readme.path)) do
diff --git a/app/views/projects/tree/_tree_header.html.haml b/app/views/projects/tree/_tree_header.html.haml
index 38422d4533d..127734ddfd7 100644
--- a/app/views/projects/tree/_tree_header.html.haml
+++ b/app/views/projects/tree/_tree_header.html.haml
@@ -77,15 +77,21 @@
.tree-controls
= render_if_exists 'projects/tree/lock_link'
- = link_to s_('Commits|History'), project_commits_path(@project, @id), class: 'btn'
+ - if vue_file_list_enabled?
+ #js-tree-history-link.d-inline-block{ data: { history_link: project_commits_path(@project, @ref) } }
+ - else
+ = link_to s_('Commits|History'), project_commits_path(@project, @id), class: 'btn'
= render 'projects/find_file_link'
- if can_create_mr_from_fork
= succeed " " do
- if can_collaborate || current_user&.already_forked?(@project)
- = link_to ide_edit_path(@project, @ref, @path), class: 'btn btn-default qa-web-ide-button' do
- = _('Web IDE')
+ - if vue_file_list_enabled?
+ #js-tree-web-ide-link.d-inline-block
+ - else
+ = link_to ide_edit_path(@project, @ref, @path), class: 'btn btn-default qa-web-ide-button' do
+ = _('Web IDE')
- else
= link_to '#modal-confirm-fork', class: 'btn btn-default qa-web-ide-button', data: { target: '#modal-confirm-fork', toggle: 'modal'} do
= _('Web IDE')
diff --git a/app/views/projects/tree/show.html.haml b/app/views/projects/tree/show.html.haml
index 39b29a20df6..65f5bc31d2e 100644
--- a/app/views/projects/tree/show.html.haml
+++ b/app/views/projects/tree/show.html.haml
@@ -6,7 +6,8 @@
= content_for :meta_tags do
= auto_discovery_link_tag(:atom, project_commits_url(@project, @ref, rss_url_options), title: "#{@project.name}:#{@ref} commits")
-.js-signature-container{ data: { 'signatures-path': signatures_path } }
+- unless vue_file_list_enabled?
+ .js-signature-container{ data: { 'signatures-path': signatures_path } }
= render 'projects/last_push'
= render 'projects/files', commit: @last_commit, project: @project, ref: @ref, content_url: project_tree_path(@project, @id)
diff --git a/app/views/registrations/welcome.html.haml b/app/views/registrations/welcome.html.haml
index 02ab974ecc0..7b92f5070df 100644
--- a/app/views/registrations/welcome.html.haml
+++ b/app/views/registrations/welcome.html.haml
@@ -1,10 +1,10 @@
-- content_for(:page_title, _('Welcome to GitLab<br>%{username}!' % { username: html_escape(current_user.username) }).html_safe)
+- content_for(:page_title, _('Welcome to GitLab @%{username}!') % { username: current_user.username })
- max_name_length = 128
.text-center.mb-3
- = _('In order to tailor your experience with GitLab<br>we would like to know a bit more about you.').html_safe
+ = _('In order to tailor your experience with GitLab we<br>would like to know a bit more about you.').html_safe
.signup-box.p-3.mb-2
.signup-body
- = form_for(current_user, url: users_sign_up_update_role_path, html: { class: 'new_new_user gl-show-field-errors', 'aria-live' => 'assertive' }) do |f|
+ = form_for(current_user, url: users_sign_up_update_registration_path, html: { class: 'new_new_user gl-show-field-errors', 'aria-live' => 'assertive' }) do |f|
.devise-errors.mt-0
= render 'devise/shared/error_messages', resource: current_user
.name.form-group
@@ -13,5 +13,14 @@
.form-group
= f.label :role, _('Role'), class: 'label-bold'
= f.select :role, ::User.roles.keys.map { |role| [role.titleize, role] }, {}, class: 'form-control'
+ .form-group
+ = f.label :setup_for_company, _('Are you setting up GitLab for a company?'), class: 'label-bold'
+ .d-flex.justify-content-center
+ .w-25
+ = f.radio_button :setup_for_company, true
+ = f.label :setup_for_company, _('Yes'), value: 'true'
+ .w-25
+ = f.radio_button :setup_for_company, false
+ = f.label :setup_for_company, _('No'), value: 'false'
.submit-container.mt-3
= f.submit _('Get started!'), class: 'btn-register btn btn-block mb-0 p-2'
diff --git a/app/views/search/_category.html.haml b/app/views/search/_category.html.haml
index eae2a491ceb..84198489e41 100644
--- a/app/views/search/_category.html.haml
+++ b/app/views/search/_category.html.haml
@@ -1,5 +1,5 @@
- users = capture_haml do
- - if search_tabs?(:members)
+ - if show_user_search_tab?
= search_filter_link 'users', _("Users")
.scrolling-tabs-container.inner-page-scroll-tabs.is-smaller
diff --git a/app/views/search/_results.html.haml b/app/views/search/_results.html.haml
index de9947528cf..629a5a045b1 100644
--- a/app/views/search/_results.html.haml
+++ b/app/views/search/_results.html.haml
@@ -1,6 +1,7 @@
- if @search_objects.to_a.empty?
= render partial: "search/results/empty"
= render_if_exists 'shared/promotions/promote_advanced_search'
+ = render_if_exists 'search/form_revert_to_basic'
- else
.row-content-block.d-md-flex.text-left.align-items-center
- unless @search_objects.is_a?(Kaminari::PaginatableWithoutCount)
diff --git a/app/views/search/results/_blob.html.haml b/app/views/search/results/_blob.html.haml
index bdad07f36d1..4fb72b26955 100644
--- a/app/views/search/results/_blob.html.haml
+++ b/app/views/search/results/_blob.html.haml
@@ -2,6 +2,6 @@
- return unless project
- blob = parse_search_result(blob)
-- blob_link = project_blob_path(project, tree_join(blob.ref, blob.filename))
+- blob_link = project_blob_path(project, tree_join(blob.ref, blob.path))
-= render partial: 'search/results/blob_data', locals: { blob: blob, project: project, file_name: blob.filename, blob_link: blob_link }
+= render partial: 'search/results/blob_data', locals: { blob: blob, project: project, path: blob.path, blob_link: blob_link }
diff --git a/app/views/search/results/_blob_data.html.haml b/app/views/search/results/_blob_data.html.haml
index 36b6ea7bd37..01e42224428 100644
--- a/app/views/search/results/_blob_data.html.haml
+++ b/app/views/search/results/_blob_data.html.haml
@@ -4,7 +4,7 @@
= link_to blob_link do
%i.fa.fa-file
%strong
- = search_blob_title(project, file_name)
+ = search_blob_title(project, path)
- if blob.data
.file-content.code.term{ data: { qa_selector: 'file_text_content' } }
= render 'shared/file_highlight', blob: blob, first_line_number: blob.startline
diff --git a/app/views/search/results/_snippet_blob.html.haml b/app/views/search/results/_snippet_blob.html.haml
index f17dae0a94c..37f4efee9d2 100644
--- a/app/views/search/results/_snippet_blob.html.haml
+++ b/app/views/search/results/_snippet_blob.html.haml
@@ -1,6 +1,7 @@
- snippet_blob = chunk_snippet(snippet_blob, @search_term)
- snippet = snippet_blob[:snippet_object]
- snippet_chunks = snippet_blob[:snippet_chunks]
+- snippet_path = reliable_snippet_path(snippet)
.search-result-row
%span
@@ -11,7 +12,6 @@
= snippet.author_name
%span.light= time_ago_with_tooltip(snippet.created_at)
%h4.snippet-title
- - snippet_path = reliable_snippet_path(snippet)
.file-holder
.js-file-title.file-title
= link_to snippet_path do
diff --git a/app/views/search/results/_snippet_title.html.haml b/app/views/search/results/_snippet_title.html.haml
index 1e01088d9e6..7280146720e 100644
--- a/app/views/search/results/_snippet_title.html.haml
+++ b/app/views/search/results/_snippet_title.html.haml
@@ -2,10 +2,7 @@
%h4.snippet-title.term
= link_to reliable_snippet_path(snippet_title) do
= truncate(snippet_title.title, length: 60)
- - if snippet_title.private?
- %span.badge.badge-gray
- %i.fa.fa-lock
- = _("private")
+ = snippet_badge(snippet_title)
%span.cgray.monospace.tiny.float-right.term
= snippet_title.file_name
diff --git a/app/views/search/results/_wiki_blob.html.haml b/app/views/search/results/_wiki_blob.html.haml
index b351ecd4edf..9afed2bbecc 100644
--- a/app/views/search/results/_wiki_blob.html.haml
+++ b/app/views/search/results/_wiki_blob.html.haml
@@ -2,4 +2,4 @@
- wiki_blob = parse_search_result(wiki_blob)
- wiki_blob_link = project_wiki_path(project, wiki_blob.basename)
-= render partial: 'search/results/blob_data', locals: { blob: wiki_blob, project: project, file_name: wiki_blob.filename, blob_link: wiki_blob_link }
+= render partial: 'search/results/blob_data', locals: { blob: wiki_blob, project: project, path: wiki_blob.path, blob_link: wiki_blob_link }
diff --git a/app/views/shared/_clone_panel.html.haml b/app/views/shared/_clone_panel.html.haml
index cb834878276..3e805189055 100644
--- a/app/views/shared/_clone_panel.html.haml
+++ b/app/views/shared/_clone_panel.html.haml
@@ -22,6 +22,3 @@
.input-group-append
= clipboard_button(target: '#project_clone', title: _("Copy URL"), class: "input-group-text btn-default btn-clipboard")
- = render_if_exists 'shared/geo_modal_button'
-
-= render_if_exists 'shared/geo_modal', project: project
diff --git a/app/views/shared/_field.html.haml b/app/views/shared/_field.html.haml
index 606d0f241aa..a7ad6d6f2c4 100644
--- a/app/views/shared/_field.html.haml
+++ b/app/views/shared/_field.html.haml
@@ -16,7 +16,7 @@
= form.label name, title, class: "col-form-label col-sm-2"
.col-sm-10
- if type == 'text'
- = form.text_field name, class: "form-control", placeholder: placeholder, required: required, disabled: disabled
+ = form.text_field name, class: "form-control", placeholder: placeholder, required: required, disabled: disabled, data: { qa_selector: "#{name.downcase.gsub('\s', '')}_field" }
- elsif type == 'textarea'
= form.text_area name, rows: 5, class: "form-control", placeholder: placeholder, required: required, disabled: disabled
- elsif type == 'checkbox'
@@ -24,6 +24,6 @@
- elsif type == 'select'
= form.select name, options_for_select(choices, value ? value : default_choice), {}, { class: "form-control", disabled: disabled}
- elsif type == 'password'
- = form.password_field name, autocomplete: "new-password", placeholder: placeholder, class: "form-control", required: value.blank? && required, disabled: disabled
+ = form.password_field name, autocomplete: "new-password", placeholder: placeholder, class: "form-control", required: value.blank? && required, disabled: disabled, data: { qa_selector: "#{name.downcase.gsub('\s', '')}_field" }
- if help
%span.form-text.text-muted= help
diff --git a/app/views/shared/_group_form.html.haml b/app/views/shared/_group_form.html.haml
index 959792718ca..9a65981ed58 100644
--- a/app/views/shared/_group_form.html.haml
+++ b/app/views/shared/_group_form.html.haml
@@ -22,11 +22,16 @@
- if parent
%strong= parent.full_path + '/'
= f.hidden_field :parent_id
- = f.text_field :path, placeholder: 'my-awesome-group', class: 'form-control',
+ = f.text_field :path, placeholder: 'my-awesome-group', class: 'form-control js-validate-group-path',
autofocus: local_assigns[:autofocus] || false, required: true,
pattern: Gitlab::PathRegex::NAMESPACE_FORMAT_REGEX_JS,
title: _('Please choose a group URL with no special characters.'),
"data-bind-in" => "#{'create_chat_team' if Gitlab.config.mattermost.enabled}"
+ %p.validation-error.gl-field-error.field-validation.hide
+ = _('Group path is already taken. Suggestions: ')
+ %span.gl-path-suggestions
+ %p.validation-success.gl-field-success.field-validation.hide= _('Group path is available.')
+ %p.validation-pending.gl-field-error-ignore.field-validation.hide= _('Checking group path availability...')
- if @group.persisted?
.alert.alert-warning.prepend-top-10
diff --git a/app/views/shared/_mobile_clone_panel.html.haml b/app/views/shared/_mobile_clone_panel.html.haml
index 1e6b6f7c79b..2887acf7cd7 100644
--- a/app/views/shared/_mobile_clone_panel.html.haml
+++ b/app/views/shared/_mobile_clone_panel.html.haml
@@ -4,7 +4,7 @@
.btn-group.mobile-git-clone.js-mobile-git-clone.btn-block
= clipboard_button(button_text: default_clone_label, text: default_url_to_repo(project), hide_button_icon: true, class: "btn-primary flex-fill bold justify-content-center input-group-text clone-dropdown-btn js-clone-dropdown-label")
- %button.btn.btn-primary.dropdown-toggle.js-dropdown-toggle{ type: "button", data: { toggle: "dropdown" } }
+ %button.btn.btn-primary.dropdown-toggle.js-dropdown-toggle.flex-grow-0.d-flex-center{ type: "button", data: { toggle: "dropdown" } }
= sprite_icon("arrow-down", css_class: "dropdown-btn-icon icon")
%ul.dropdown-menu.dropdown-menu-selectable.dropdown-menu-right.clone-options-dropdown{ data: { dropdown: true } }
- if ssh_enabled?
diff --git a/app/views/shared/_personal_access_tokens_form.html.haml b/app/views/shared/_personal_access_tokens_form.html.haml
index 1d96feda3b0..ca0b473addf 100644
--- a/app/views/shared/_personal_access_tokens_form.html.haml
+++ b/app/views/shared/_personal_access_tokens_form.html.haml
@@ -19,7 +19,6 @@
= f.label :expires_at, _('Expires at'), class: 'label-bold'
.input-icon-wrapper
= f.text_field :expires_at, class: "datepicker form-control", placeholder: 'YYYY-MM-DD'
- = icon('calendar', { class: 'input-icon-right' })
.form-group
= f.label :scopes, _('Scopes'), class: 'label-bold'
diff --git a/app/views/shared/_service_settings.html.haml b/app/views/shared/_service_settings.html.haml
index 6fa61c15493..627a1eb6eae 100644
--- a/app/views/shared/_service_settings.html.haml
+++ b/app/views/shared/_service_settings.html.haml
@@ -12,7 +12,7 @@
.form-group.row
= form.label :active, "Active", class: "col-form-label col-sm-2"
.col-sm-10
- = form.check_box :active, disabled: disable_fields_service?(@service)
+ = form.check_box :active, disabled: disable_fields_service?(@service), data: { qa_selector: 'active_checkbox' }
- if @service.configurable_events.present?
.form-group.row
diff --git a/app/views/shared/form_elements/_description.html.haml b/app/views/shared/form_elements/_description.html.haml
index be78fd0ccfb..9db6184ebca 100644
--- a/app/views/shared/form_elements/_description.html.haml
+++ b/app/views/shared/form_elements/_description.html.haml
@@ -2,6 +2,7 @@
- model = local_assigns.fetch(:model)
- form = local_assigns.fetch(:form)
+- placeholder = model.is_a?(MergeRequest) ? _('Describe the goal of the changes and what reviewers should be aware of.') : _('Write a comment or drag your files here…')
- supports_quick_actions = model.new_record?
- if supports_quick_actions
@@ -16,7 +17,7 @@
= render layout: 'projects/md_preview', locals: { url: preview_url, referenced_users: true } do
= render 'projects/zen', f: form, attr: :description,
classes: 'note-textarea qa-issuable-form-description rspec-issuable-form-description',
- placeholder: "Write a comment or drag your files here…",
+ placeholder: placeholder,
supports_quick_actions: supports_quick_actions
= render 'shared/notes/hints', supports_quick_actions: supports_quick_actions
.clearfix
diff --git a/app/views/shared/issuable/_form.html.haml b/app/views/shared/issuable/_form.html.haml
index 5e2b5f95ee3..0fb23adc31f 100644
--- a/app/views/shared/issuable/_form.html.haml
+++ b/app/views/shared/issuable/_form.html.haml
@@ -12,6 +12,8 @@
= link_to "the #{issuable.class.model_name.human.downcase}", polymorphic_path([@project.namespace.becomes(Namespace), @project, issuable]), target: "_blank", rel: 'noopener noreferrer'
and make sure your changes will not unintentionally remove theirs
+= render 'shared/issuable/form/branch_chooser', issuable: issuable, form: form
+
.form-group.row
= form.label :title, class: 'col-form-label col-sm-2'
@@ -34,8 +36,6 @@
= render_if_exists 'shared/issuable/approvals', issuable: issuable, presenter: presenter, form: form
-= render 'shared/issuable/form/branch_chooser', issuable: issuable, form: form
-
= render 'shared/issuable/form/merge_params', issuable: issuable
= render 'shared/issuable/form/contribution', issuable: issuable, form: form
diff --git a/app/views/shared/issuable/_search_bar.html.haml b/app/views/shared/issuable/_search_bar.html.haml
index 9d580930fb8..d341520e4a2 100644
--- a/app/views/shared/issuable/_search_bar.html.haml
+++ b/app/views/shared/issuable/_search_bar.html.haml
@@ -5,155 +5,170 @@
- user_can_admin_list = board && can?(current_user, :admin_list, board.resource_parent)
.issues-filters{ class: ("w-100" if type == :boards_modal) }
- .issues-details-filters.filtered-search-block.d-flex.flex-column.flex-md-row{ class: block_css_class, "v-pre" => type == :boards_modal }
- - if type == :boards
- = render "shared/boards/switcher", board: board
- = form_tag page_filter_path, method: :get, class: 'filter-form js-filter-form w-100' do
- - if params[:search].present?
- = hidden_field_tag :search, params[:search]
- - if @can_bulk_update
- .check-all-holder.d-none.d-sm-block.hidden
- = check_box_tag "check-all-issues", nil, false, class: "check-all-issues left"
- .issues-other-filters.filtered-search-wrapper.d-flex.flex-column.flex-md-row
- .filtered-search-box
- - if type != :boards_modal && type != :boards
- = dropdown_tag(_('Recent searches'),
- options: { wrapper_class: "filtered-search-history-dropdown-wrapper",
- toggle_class: "filtered-search-history-dropdown-toggle-button",
- dropdown_class: "filtered-search-history-dropdown",
- content_class: "filtered-search-history-dropdown-content" }) do
- .js-filtered-search-history-dropdown{ data: { full_path: search_history_storage_prefix } }
- .filtered-search-box-input-container.droplab-dropdown
- .scroll-container
- %ul.tokens-container.list-unstyled
- %li.input-token
- %input.form-control.filtered-search{ search_filter_input_options(type) }
- #js-dropdown-hint.filtered-search-input-dropdown-menu.dropdown-menu.hint-dropdown
- %ul{ data: { dropdown: true } }
- %li.filter-dropdown-item{ data: { action: 'submit' } }
- %button.btn.btn-link{ type: 'button' }
- = sprite_icon('search')
- %span
- = _('Press Enter or click to search')
- %ul.filter-dropdown{ data: { dynamic: true, dropdown: true } }
- %li.filter-dropdown-item
- %button.btn.btn-link{ type: 'button' }
- -# Encapsulate static class name `{{icon}}` inside #{} to bypass
- -# haml lint's ClassAttributeWithStaticValue
- %svg
- %use{ 'xlink:href': "#{'{{icon}}'}" }
- %span.js-filter-hint
- {{hint}}
- %span.js-filter-tag.dropdown-light-content
- {{tag}}
- #js-dropdown-author.filtered-search-input-dropdown-menu.dropdown-menu
- - if current_user
+ .issues-details-filters.filtered-search-block.d-flex.flex-column.flex-lg-row{ class: block_css_class, "v-pre" => type == :boards_modal }
+ .d-flex.flex-column.flex-md-row.flex-grow-1.mb-lg-0.mb-md-2.mb-sm-0
+ - if type == :boards
+ = render "shared/boards/switcher", board: board
+ = form_tag page_filter_path, method: :get, class: 'filter-form js-filter-form w-100' do
+ - if params[:search].present?
+ = hidden_field_tag :search, params[:search]
+ - if @can_bulk_update
+ .check-all-holder.d-none.d-sm-block.hidden
+ = check_box_tag "check-all-issues", nil, false, class: "check-all-issues left"
+ .issues-other-filters.filtered-search-wrapper.d-flex.flex-column.flex-md-row
+ .filtered-search-box
+ - if type != :boards_modal && type != :boards
+ = dropdown_tag(_('Recent searches'),
+ options: { wrapper_class: "filtered-search-history-dropdown-wrapper",
+ toggle_class: "filtered-search-history-dropdown-toggle-button",
+ dropdown_class: "filtered-search-history-dropdown",
+ content_class: "filtered-search-history-dropdown-content" }) do
+ .js-filtered-search-history-dropdown{ data: { full_path: search_history_storage_prefix } }
+ .filtered-search-box-input-container.droplab-dropdown
+ .scroll-container
+ %ul.tokens-container.list-unstyled
+ %li.input-token
+ %input.form-control.filtered-search{ search_filter_input_options(type) }
+ #js-dropdown-hint.filtered-search-input-dropdown-menu.dropdown-menu.hint-dropdown
%ul{ data: { dropdown: true } }
- = render 'shared/issuable/user_dropdown_item',
- user: current_user
- %ul.filter-dropdown{ data: { dynamic: true, dropdown: true } }
- = render 'shared/issuable/user_dropdown_item',
- user: User.new(username: '{{username}}', name: '{{name}}'),
- avatar: { lazy: true, url: '{{avatar_url}}' }
- #js-dropdown-assignee.filtered-search-input-dropdown-menu.dropdown-menu
- %ul{ data: { dropdown: true } }
- %li.filter-dropdown-item{ data: { value: 'None' } }
- %button.btn.btn-link{ type: 'button' }
- = _('None')
- %li.filter-dropdown-item{ data: { value: 'Any' } }
- %button.btn.btn-link{ type: 'button' }
- = _('Any')
- %li.divider.droplab-item-ignore
+ %li.filter-dropdown-item{ data: { action: 'submit' } }
+ %button.btn.btn-link{ type: 'button' }
+ = sprite_icon('search')
+ %span
+ = _('Press Enter or click to search')
+ %ul.filter-dropdown{ data: { dynamic: true, dropdown: true } }
+ %li.filter-dropdown-item
+ %button.btn.btn-link{ type: 'button' }
+ -# Encapsulate static class name `{{icon}}` inside #{} to bypass
+ -# haml lint's ClassAttributeWithStaticValue
+ %svg
+ %use{ 'xlink:href': "#{'{{icon}}'}" }
+ %span.js-filter-hint
+ {{hint}}
+ %span.js-filter-tag.dropdown-light-content
+ {{tag}}
+ #js-dropdown-author.filtered-search-input-dropdown-menu.dropdown-menu
- if current_user
+ %ul{ data: { dropdown: true } }
+ = render 'shared/issuable/user_dropdown_item',
+ user: current_user
+ %ul.filter-dropdown{ data: { dynamic: true, dropdown: true } }
+ = render 'shared/issuable/user_dropdown_item',
+ user: User.new(username: '{{username}}', name: '{{name}}'),
+ avatar: { lazy: true, url: '{{avatar_url}}' }
+ #js-dropdown-assignee.filtered-search-input-dropdown-menu.dropdown-menu
+ %ul{ data: { dropdown: true } }
+ %li.filter-dropdown-item{ data: { value: 'None' } }
+ %button.btn.btn-link{ type: 'button' }
+ = _('None')
+ %li.filter-dropdown-item{ data: { value: 'Any' } }
+ %button.btn.btn-link{ type: 'button' }
+ = _('Any')
+ %li.divider.droplab-item-ignore
+ - if current_user
+ = render 'shared/issuable/user_dropdown_item',
+ user: current_user
+ %ul.filter-dropdown{ data: { dynamic: true, dropdown: true } }
= render 'shared/issuable/user_dropdown_item',
- user: current_user
- %ul.filter-dropdown{ data: { dynamic: true, dropdown: true } }
- = render 'shared/issuable/user_dropdown_item',
- user: User.new(username: '{{username}}', name: '{{name}}'),
- avatar: { lazy: true, url: '{{avatar_url}}' }
- = render_if_exists 'shared/issuable/approver_dropdown'
- #js-dropdown-milestone.filtered-search-input-dropdown-menu.dropdown-menu
- %ul{ data: { dropdown: true } }
- %li.filter-dropdown-item{ data: { value: 'None' } }
- %button.btn.btn-link{ type: 'button' }
- = _('None')
- %li.filter-dropdown-item{ data: { value: 'Any' } }
- %button.btn.btn-link{ type: 'button' }
- = _('Any')
- %li.filter-dropdown-item{ data: { value: 'Upcoming' } }
- %button.btn.btn-link{ type: 'button' }
- = _('Upcoming')
- %li.filter-dropdown-item{ data: { value: 'Started' } }
- %button.btn.btn-link{ type: 'button' }
- = _('Started')
- %li.divider.droplab-item-ignore
- %ul.filter-dropdown{ data: { dynamic: true, dropdown: true } }
- %li.filter-dropdown-item
- %button.btn.btn-link.js-data-value{ type: 'button' }
- {{title}}
- #js-dropdown-label.filtered-search-input-dropdown-menu.dropdown-menu
- %ul{ data: { dropdown: true } }
- %li.filter-dropdown-item{ data: { value: 'None' } }
- %button.btn.btn-link{ type: 'button' }
- = _('None')
- %li.filter-dropdown-item{ data: { value: 'Any' } }
- %button.btn.btn-link{ type: 'button' }
- = _('Any')
- %li.divider.droplab-item-ignore
- %ul.filter-dropdown{ data: { dynamic: true, dropdown: true } }
- %li.filter-dropdown-item
- %button.btn.btn-link{ type: 'button' }
- %span.dropdown-label-box{ style: 'background: {{color}}' }
- %span.label-title.js-data-value
+ user: User.new(username: '{{username}}', name: '{{name}}'),
+ avatar: { lazy: true, url: '{{avatar_url}}' }
+ = render_if_exists 'shared/issuable/approver_dropdown'
+ #js-dropdown-milestone.filtered-search-input-dropdown-menu.dropdown-menu
+ %ul{ data: { dropdown: true } }
+ %li.filter-dropdown-item{ data: { value: 'None' } }
+ %button.btn.btn-link{ type: 'button' }
+ = _('None')
+ %li.filter-dropdown-item{ data: { value: 'Any' } }
+ %button.btn.btn-link{ type: 'button' }
+ = _('Any')
+ %li.filter-dropdown-item{ data: { value: 'Upcoming' } }
+ %button.btn.btn-link{ type: 'button' }
+ = _('Upcoming')
+ %li.filter-dropdown-item{ data: { value: 'Started' } }
+ %button.btn.btn-link{ type: 'button' }
+ = _('Started')
+ %li.divider.droplab-item-ignore
+ %ul.filter-dropdown{ data: { dynamic: true, dropdown: true } }
+ %li.filter-dropdown-item
+ %button.btn.btn-link.js-data-value{ type: 'button' }
+ {{title}}
+ #js-dropdown-release.filtered-search-input-dropdown-menu.dropdown-menu
+ %ul{ data: { dropdown: true } }
+ %li.filter-dropdown-item{ data: { value: 'None' } }
+ %button.btn.btn-link{ type: 'button' }
+ = _('None')
+ %li.filter-dropdown-item{ data: { value: 'Any' } }
+ %button.btn.btn-link{ type: 'button' }
+ = _('Any')
+ %li.divider.droplab-item-ignore
+ %ul.filter-dropdown{ data: { dynamic: true, dropdown: true } }
+ %li.filter-dropdown-item
+ %button.btn.btn-link.js-data-value{ type: 'button' }
+ {{title}}
+ #js-dropdown-label.filtered-search-input-dropdown-menu.dropdown-menu
+ %ul{ data: { dropdown: true } }
+ %li.filter-dropdown-item{ data: { value: 'None' } }
+ %button.btn.btn-link{ type: 'button' }
+ = _('None')
+ %li.filter-dropdown-item{ data: { value: 'Any' } }
+ %button.btn.btn-link{ type: 'button' }
+ = _('Any')
+ %li.divider.droplab-item-ignore
+ %ul.filter-dropdown{ data: { dynamic: true, dropdown: true } }
+ %li.filter-dropdown-item
+ %button.btn.btn-link{ type: 'button' }
+ %span.dropdown-label-box{ style: 'background: {{color}}' }
+ %span.label-title.js-data-value
+ {{title}}
+ #js-dropdown-my-reaction.filtered-search-input-dropdown-menu.dropdown-menu
+ %ul{ data: { dropdown: true } }
+ %li.filter-dropdown-item{ data: { value: 'None' } }
+ %button.btn.btn-link{ type: 'button' }
+ = _('None')
+ %li.filter-dropdown-item{ data: { value: 'Any' } }
+ %button.btn.btn-link{ type: 'button' }
+ = _('Any')
+ %li.divider.droplab-item-ignore
+ %ul.filter-dropdown{ data: { dynamic: true, dropdown: true } }
+ %li.filter-dropdown-item
+ %button.btn.btn-link{ type: 'button' }
+ %gl-emoji
+ %span.js-data-value.prepend-left-10
+ {{name}}
+ #js-dropdown-wip.filtered-search-input-dropdown-menu.dropdown-menu
+ %ul.filter-dropdown{ data: { dropdown: true } }
+ %li.filter-dropdown-item{ data: { value: 'yes', capitalize: true } }
+ %button.btn.btn-link{ type: 'button' }
+ = _('Yes')
+ %li.filter-dropdown-item{ data: { value: 'no', capitalize: true } }
+ %button.btn.btn-link{ type: 'button' }
+ = _('No')
+ #js-dropdown-confidential.filtered-search-input-dropdown-menu.dropdown-menu
+ %ul.filter-dropdown{ data: { dropdown: true } }
+ %li.filter-dropdown-item{ data: { value: 'yes', capitalize: true } }
+ %button.btn.btn-link{ type: 'button' }
+ = _('Yes')
+ %li.filter-dropdown-item{ data: { value: 'no', capitalize: true } }
+ %button.btn.btn-link{ type: 'button' }
+ = _('No')
+ #js-dropdown-target-branch.filtered-search-input-dropdown-menu.dropdown-menu
+ %ul.filter-dropdown{ data: { dynamic: true, dropdown: true } }
+ %li.filter-dropdown-item
+ %button.btn.btn-link.js-data-value.monospace
{{title}}
- #js-dropdown-my-reaction.filtered-search-input-dropdown-menu.dropdown-menu
- %ul{ data: { dropdown: true } }
- %li.filter-dropdown-item{ data: { value: 'None' } }
- %button.btn.btn-link{ type: 'button' }
- = _('None')
- %li.filter-dropdown-item{ data: { value: 'Any' } }
- %button.btn.btn-link{ type: 'button' }
- = _('Any')
- %li.divider.droplab-item-ignore
- %ul.filter-dropdown{ data: { dynamic: true, dropdown: true } }
- %li.filter-dropdown-item
- %button.btn.btn-link{ type: 'button' }
- %gl-emoji
- %span.js-data-value.prepend-left-10
- {{name}}
- #js-dropdown-wip.filtered-search-input-dropdown-menu.dropdown-menu
- %ul.filter-dropdown{ data: { dropdown: true } }
- %li.filter-dropdown-item{ data: { value: 'yes', capitalize: true } }
- %button.btn.btn-link{ type: 'button' }
- = _('Yes')
- %li.filter-dropdown-item{ data: { value: 'no', capitalize: true } }
- %button.btn.btn-link{ type: 'button' }
- = _('No')
- #js-dropdown-confidential.filtered-search-input-dropdown-menu.dropdown-menu
- %ul.filter-dropdown{ data: { dropdown: true } }
- %li.filter-dropdown-item{ data: { value: 'yes', capitalize: true } }
- %button.btn.btn-link{ type: 'button' }
- = _('Yes')
- %li.filter-dropdown-item{ data: { value: 'no', capitalize: true } }
- %button.btn.btn-link{ type: 'button' }
- = _('No')
- #js-dropdown-target-branch.filtered-search-input-dropdown-menu.dropdown-menu
- %ul.filter-dropdown{ data: { dynamic: true, dropdown: true } }
- %li.filter-dropdown-item
- %button.btn.btn-link.js-data-value.monospace
- {{title}}
- = render_if_exists 'shared/issuable/filter_weight', type: type
+ = render_if_exists 'shared/issuable/filter_weight', type: type
- %button.clear-search.hidden{ type: 'button' }
- = icon('times')
- .filter-dropdown-container.d-flex.flex-column.flex-md-row
- - if type == :boards
- .js-board-config{ data: { can_admin_list: user_can_admin_list, has_scope: board.scoped? } }
- - if user_can_admin_list
- = render 'shared/issuable/board_create_list_dropdown', board: board
- - if @project
- #js-add-issues-btn.prepend-left-10{ data: { can_admin_list: can?(current_user, :admin_list, @project) } }
- #js-toggle-focus-btn
- - elsif is_not_boards_modal_or_productivity_analytics
- = render 'shared/issuable/sort_dropdown'
+ %button.clear-search.hidden{ type: 'button' }
+ = icon('times')
+ .filter-dropdown-container.d-flex.flex-column.flex-md-row
+ #js-board-labels-toggle
+ - if type == :boards
+ .js-board-config{ data: { can_admin_list: user_can_admin_list, has_scope: board.scoped? } }
+ - if user_can_admin_list
+ = render 'shared/issuable/board_create_list_dropdown', board: board
+ - if @project
+ #js-add-issues-btn.prepend-left-10{ data: { can_admin_list: can?(current_user, :admin_list, @project) } }
+ #js-toggle-focus-btn
+ - elsif is_not_boards_modal_or_productivity_analytics
+ = render 'shared/issuable/sort_dropdown'
diff --git a/app/views/shared/issuable/_sidebar.html.haml b/app/views/shared/issuable/_sidebar.html.haml
index c8b2adcf084..2170b88c7c3 100644
--- a/app/views/shared/issuable/_sidebar.html.haml
+++ b/app/views/shared/issuable/_sidebar.html.haml
@@ -141,13 +141,7 @@
.js-sidebar-participants-entry-point
- if signed_in
- - if issuable_sidebar[:project_emails_disabled]
- .block.js-emails-disabled
- .sidebar-collapsed-icon.has-tooltip{ title: notification_description(:owner_disabled), data: { placement: "left", container: "body", boundary: 'viewport' } }
- = notification_setting_icon
- .hide-collapsed= notification_description(:owner_disabled)
- - else
- .js-sidebar-subscriptions-entry-point
+ .js-sidebar-subscriptions-entry-point
- project_ref = issuable_sidebar[:reference]
.block.project-reference
diff --git a/app/views/shared/issuable/form/_branch_chooser.html.haml b/app/views/shared/issuable/form/_branch_chooser.html.haml
index fbc96baa0f7..29ac17c43b9 100644
--- a/app/views/shared/issuable/form/_branch_chooser.html.haml
+++ b/app/views/shared/issuable/form/_branch_chooser.html.haml
@@ -4,21 +4,20 @@
- return unless issuable.is_a?(MergeRequest)
- return if issuable.closed_without_fork?
-%hr
-- if issuable.new_record?
- .form-group.row
- = form.label :source_branch, class: 'col-form-label col-sm-2'
- .col-sm-10
- .issuable-form-select-holder
- = form.select(:source_branch, [issuable.source_branch], {}, { class: 'source_branch select2 ref-name', disabled: true })
-.form-group.row
- = form.label :target_branch, class: 'col-form-label col-sm-2'
- .col-sm-10.target-branch-select-dropdown-container
- .issuable-form-select-holder
- = form.hidden_field(:target_branch,
- { class: 'target_branch js-target-branch-select ref-name',
- disabled: issuable.new_record?,
- data: { placeholder: "Select branch", endpoint: refs_project_path(@project, sort: 'updated_desc', find: 'branches') }})
+- source_title, target_title = format_mr_branch_names(@merge_request)
+
+.form-group.row.d-flex.gl-pl-3.gl-pr-3.branch-selector
+ .align-self-center
+ %span= s_('From %{source_title} into').html_safe % { source_title: "<code>#{source_title}</code>".html_safe }
- if issuable.new_record?
+ %code= target_title
&nbsp;
- = link_to 'Change branches', mr_change_branches_path(issuable)
+ = link_to _('Change branches'), mr_change_branches_path(issuable)
+ - elsif issuable.for_fork?
+ %code= issuable.target_project_path + ":"
+ - unless issuable.new_record?
+ %span.dropdown.prepend-left-5.d-inline-block
+ = form.hidden_field(:target_branch,
+ { class: 'target_branch js-target-branch-select ref-name mw-xl',
+ data: { placeholder: _('Select branch'), endpoint: refs_project_path(@project, sort: 'updated_desc', find: 'branches') }})
+%hr
diff --git a/app/views/shared/issuable/form/_merge_params.html.haml b/app/views/shared/issuable/form/_merge_params.html.haml
index f0c4acdd07f..1b557214e02 100644
--- a/app/views/shared/issuable/form/_merge_params.html.haml
+++ b/app/views/shared/issuable/form/_merge_params.html.haml
@@ -3,17 +3,17 @@
- return unless issuable.is_a?(MergeRequest)
- return if issuable.closed_without_fork?
-- if issuable.can_remove_source_branch?(current_user)
- .form-group.row
- .col-sm-10.offset-sm-2
- .form-check
+.form-group.row
+ .col-sm-2.col-form-label.pt-sm-0
+ %label
+ = _('Merge options')
+ .col-sm-10
+ - if issuable.can_remove_source_branch?(current_user)
+ .form-check.append-bottom-default
= hidden_field_tag 'merge_request[force_remove_source_branch]', '0', id: nil
= check_box_tag 'merge_request[force_remove_source_branch]', '1', issuable.force_remove_source_branch?, class: 'form-check-input'
= label_tag 'merge_request[force_remove_source_branch]', class: 'form-check-label' do
Delete source branch when merge request is accepted.
-
-.form-group.row
- .col-sm-10.offset-sm-2
.form-check
= hidden_field_tag 'merge_request[squash]', '0', id: nil
= check_box_tag 'merge_request[squash]', '1', issuable.squash, class: 'form-check-input'
diff --git a/app/views/shared/members/_access_request_links.html.haml b/app/views/shared/members/_access_request_links.html.haml
index eac743b5206..b4b06640bd9 100644
--- a/app/views/shared/members/_access_request_links.html.haml
+++ b/app/views/shared/members/_access_request_links.html.haml
@@ -4,7 +4,7 @@
- link_text = source.is_a?(Group) ? _('Leave group') : _('Leave project')
= link_to link_text, polymorphic_path([:leave, source, :members]),
method: :delete,
- data: { confirm: leave_confirmation_message(source) },
+ data: { confirm: leave_confirmation_message(source), qa_selector: 'leave_group_link' },
class: 'access-request-link js-leave-link'
- elsif requester = source.requesters.find_by(user_id: current_user.id) # rubocop: disable CodeReuse/ActiveRecord
= link_to _('Withdraw Access Request'), polymorphic_path([:leave, source, :members]),
diff --git a/app/views/shared/milestones/_description.html.haml b/app/views/shared/milestones/_description.html.haml
new file mode 100644
index 00000000000..5ff110bf94b
--- /dev/null
+++ b/app/views/shared/milestones/_description.html.haml
@@ -0,0 +1,8 @@
+.detail-page-description.milestone-detail
+ %h2.title
+ = markdown_field(milestone, :title)
+
+ - if milestone.try(:description).present?
+ %div
+ .description.md
+ = markdown_field(milestone, :description)
diff --git a/app/views/shared/milestones/_header.html.haml b/app/views/shared/milestones/_header.html.haml
new file mode 100644
index 00000000000..2da857261d1
--- /dev/null
+++ b/app/views/shared/milestones/_header.html.haml
@@ -0,0 +1,38 @@
+.detail-page-header.milestone-page-header
+ .status-box{ class: status_box_class(milestone) }
+ = milestone_status_string(milestone)
+
+ .header-text-content
+ %span.identifier
+ %strong
+ = _('Milestone')
+ - if milestone.due_date || milestone.start_date
+ = milestone_date_range(milestone)
+
+ .milestone-buttons
+ - if can?(current_user, :admin_milestone, @group || @project)
+ - unless milestone.legacy_group_milestone?
+ = link_to _('Edit'), edit_milestone_path(milestone), class: 'btn btn-grouped'
+
+ - if milestone.project_milestone? && milestone.project.group
+ %button.js-promote-project-milestone-button.btn.btn-grouped{ data: { toggle: 'modal',
+ target: '#promote-milestone-modal',
+ milestone_title: milestone.title,
+ group_name: milestone.project.group.name,
+ url: promote_project_milestone_path(milestone.project, milestone),
+ container: 'body' },
+ disabled: true,
+ type: 'button' }
+ = _('Promote')
+ #promote-milestone-modal
+
+ - if milestone.active?
+ = link_to _('Close milestone'), update_milestone_path(milestone, { state_event: :close }), method: :put, class: 'btn btn-grouped btn-close'
+ - else
+ = link_to _('Reopen milestone'), update_milestone_path(milestone, { state_event: :activate }), method: :put, class: 'btn btn-grouped btn-reopen'
+
+ - unless milestone.legacy_group_milestone?
+ = render 'shared/milestones/delete_button'
+
+ %button.btn.btn-default.btn-grouped.float-right.d-block.d-sm-none.js-sidebar-toggle{ type: 'button' }
+ = icon('angle-double-left')
diff --git a/app/views/shared/milestones/_milestone.html.haml b/app/views/shared/milestones/_milestone.html.haml
index e99aa3f1ee4..b324f35c338 100644
--- a/app/views/shared/milestones/_milestone.html.haml
+++ b/app/views/shared/milestones/_milestone.html.haml
@@ -12,8 +12,20 @@
- if @project || milestone.is_a?(GlobalMilestone) || milestone.group_milestone?
- if milestone.due_date || milestone.start_date
- .milestone-range.append-bottom-5
+ .text-tertiary.append-bottom-5
= milestone_date_range(milestone)
+ - recent_releases, total_count, more_count = recent_releases_with_counts(milestone)
+ - unless total_count.zero?
+ .text-tertiary.append-bottom-5.milestone-release-links
+ = icon('rocket')
+ = n_('Release', 'Releases', total_count)
+ - recent_releases.each do |release|
+ = link_to release.name, project_releases_path(release.project, anchor: release.tag)
+ - unless release == recent_releases.last
+ &bull;
+ - if total_count > recent_releases.count
+ &bull;
+ = link_to n_('%{count} more release', '%{count} more releases', more_count) % { count: more_count }, project_releases_path(milestone.project)
%div
= render('shared/milestone_expired', milestone: milestone)
- if milestone.group_milestone?
diff --git a/app/views/shared/milestones/_sidebar.html.haml b/app/views/shared/milestones/_sidebar.html.haml
index 22a6d5e33f0..b6656e6283c 100644
--- a/app/views/shared/milestones/_sidebar.html.haml
+++ b/app/views/shared/milestones/_sidebar.html.haml
@@ -138,6 +138,27 @@
Merged:
= milestone.merge_requests.merged.count
+ - if project
+ - recent_releases, total_count, more_count = recent_releases_with_counts(milestone)
+ .block.releases
+ .sidebar-collapsed-icon.has-tooltip{ title: milestone_releases_tooltip_text(milestone), data: { container: 'body', placement: 'left', boundary: 'viewport' } }
+ %strong
+ = icon('rocket')
+ %span= total_count
+ .title.hide-collapsed= n_('Release', 'Releases', total_count)
+ .hide-collapsed
+ - if total_count.zero?
+ .no-value= _('None')
+ - else
+ .font-weight-bold
+ - recent_releases.each do |release|
+ = link_to release.name, project_releases_path(project, :anchor => release.tag)
+ - unless release == recent_releases.last
+ %span.font-weight-normal &bull;
+ - if more_count > 0
+ %span.font-weight-normal &bull;
+ = link_to n_('%{count} more release', '%{count} more releases', more_count) % { count: more_count }, project_releases_path(project), class: 'font-weight-normal'
+
- milestone_ref = milestone.try(:to_reference, full: true)
- if milestone_ref.present?
.block.reference
diff --git a/app/views/shared/milestones/_tabs.html.haml b/app/views/shared/milestones/_tabs.html.haml
index b877f66c71e..f718c5767d1 100644
--- a/app/views/shared/milestones/_tabs.html.haml
+++ b/app/views/shared/milestones/_tabs.html.haml
@@ -1,30 +1,22 @@
-- issues_accessible = milestone.is_a?(GlobalMilestone) || can?(current_user, :read_issue, @project)
-
.scrolling-tabs-container.inner-page-scroll-tabs.is-smaller
.fade-left= icon('angle-left')
.fade-right= icon('angle-right')
%ul.nav-links.scrolling-tabs.js-milestone-tabs.nav.nav-tabs
- - if issues_accessible
- %li.nav-item
- = link_to '#tab-issues', class: 'nav-link active', 'data-toggle' => 'tab', 'data-show' => '.tab-issues-buttons' do
- Issues
- %span.badge.badge-pill= milestone.issues_visible_to_user(current_user).size
- %li.nav-item
- = link_to '#tab-merge-requests', class: 'nav-link', 'data-toggle' => 'tab', 'data-endpoint': milestone_merge_request_tab_path(milestone) do
- Merge Requests
- %span.badge.badge-pill= milestone.merge_requests_visible_to_user(current_user).size
- - else
- %li.nav-item
- = link_to '#tab-merge-requests', class: 'nav-link active', 'data-toggle' => 'tab', 'data-endpoint': milestone_merge_request_tab_path(milestone) do
- Merge Requests
- %span.badge.badge-pill= milestone.merge_requests.size
%li.nav-item
- = link_to '#tab-participants', class: 'nav-link', 'data-toggle' => 'tab', 'data-endpoint': milestone_participants_tab_path(milestone) do
- Participants
+ = link_to '#tab-issues', class: 'nav-link active', data: { toggle: 'tab', show: '.tab-issues-buttons' } do
+ = _('Issues')
+ %span.badge.badge-pill= milestone.issues_visible_to_user(current_user).size
+ %li.nav-item
+ = link_to '#tab-merge-requests', class: 'nav-link', data: { toggle: 'tab', endpoint: milestone_tab_path(milestone, 'merge_requests') } do
+ = _('Merge Requests')
+ %span.badge.badge-pill= milestone.merge_requests_visible_to_user(current_user).size
+ %li.nav-item
+ = link_to '#tab-participants', class: 'nav-link', data: { toggle: 'tab', endpoint: milestone_tab_path(milestone, 'participants') } do
+ = _('Participants')
%span.badge.badge-pill= milestone.issue_participants_visible_by_user(current_user).count
%li.nav-item
- = link_to '#tab-labels', class: 'nav-link', 'data-toggle' => 'tab', 'data-endpoint': milestone_labels_tab_path(milestone) do
- Labels
+ = link_to '#tab-labels', class: 'nav-link', data: { toggle: 'tab', endpoint: milestone_tab_path(milestone, 'labels') } do
+ = _('Labels')
%span.badge.badge-pill= milestone.issue_labels_visible_by_user(current_user).count
- issues = milestone.sorted_issues(current_user)
@@ -32,16 +24,11 @@
- show_full_project_name = local_assigns.fetch(:show_full_project_name, false)
.tab-content.milestone-content
- - if issues_accessible
- .tab-pane.active#tab-issues{ data: { sort_endpoint: (sort_issues_project_milestone_path(@project, @milestone) if @project && current_user) } }
- = render 'shared/milestones/issues_tab', issues: issues, show_project_name: show_project_name, show_full_project_name: show_full_project_name
- .tab-pane#tab-merge-requests
- -# loaded async
- = render "shared/milestones/tab_loading"
- - else
- .tab-pane.active#tab-merge-requests
- -# loaded async
- = render "shared/milestones/tab_loading"
+ .tab-pane.active#tab-issues{ data: { sort_endpoint: (sort_issues_project_milestone_path(@project, @milestone) if @project && current_user) } }
+ = render 'shared/milestones/issues_tab', issues: issues, show_project_name: show_project_name, show_full_project_name: show_full_project_name
+ .tab-pane#tab-merge-requests
+ -# loaded async
+ = render "shared/milestones/tab_loading"
.tab-pane#tab-participants
-# loaded async
= render "shared/milestones/tab_loading"
diff --git a/app/views/shared/milestones/_top.html.haml b/app/views/shared/milestones/_top.html.haml
index fd3317341f6..12575b30a6c 100644
--- a/app/views/shared/milestones/_top.html.haml
+++ b/app/views/shared/milestones/_top.html.haml
@@ -4,54 +4,15 @@
- group = local_assigns[:group]
- is_dynamic_milestone = milestone.legacy_group_milestone? || milestone.dashboard_milestone?
-.detail-page-header.milestone-page-header
- .status-box{ class: "status-box-#{milestone.closed? ? 'closed' : 'open'}" }
- - if milestone.closed?
- Closed
- - elsif milestone.expired?
- Expired
- - else
- Open
-
- .header-text-content
- %span.identifier
- Milestone #{milestone.title}
- - if milestone.due_date || milestone.start_date
- %span.creator
- &nbsp;&middot;
- = milestone_date_range(milestone)
-
- .milestone-buttons
- - if group
- - if can?(current_user, :admin_milestone, group)
- - if milestone.group_milestone?
- = link_to edit_group_milestone_path(group, milestone), class: "btn btn btn-grouped" do
- Edit
- - if milestone.active?
- = link_to 'Close Milestone', group_milestone_route(milestone, {state_event: :close }), method: :put, class: "btn btn-grouped btn-close"
- - else
- = link_to 'Reopen Milestone', group_milestone_route(milestone, {state_event: :activate }), method: :put, class: "btn btn-grouped btn-reopen"
-
- - unless is_dynamic_milestone
- = render 'shared/milestones/delete_button'
-
- %a.btn.btn-default.btn-grouped.float-right.d-block.d-sm-none.js-sidebar-toggle{ href: "#" }
- = icon('angle-double-left')
-
+= render 'shared/milestones/header', milestone: milestone
= render 'shared/milestones/deprecation_message' if is_dynamic_milestone
-
-.detail-page-description.milestone-detail
- %h2.title
- = markdown_field(milestone, :title)
- - if milestone.group_milestone? && milestone.description.present?
- %div
- .description.md
- = markdown_field(milestone, :description)
+= render 'shared/milestones/description', milestone: milestone
- if milestone.complete?(current_user) && milestone.active?
.alert.alert-success.prepend-top-default
- - close_msg = group ? 'You may close the milestone now.' : 'Navigate to the project to close the milestone.'
- %span All issues for this milestone are closed. #{close_msg}
+ %span
+ = _('All issues for this milestone are closed.')
+ = group ? _('You may close the milestone now.') : _('Navigate to the project to close the milestone.')
= render_if_exists 'shared/milestones/burndown', milestone: milestone, project: @project
@@ -77,10 +38,3 @@
Open
%td
= milestone.expires_at
-- elsif milestone.group_milestone?
- %br
- View
- = link_to 'Issues', issues_group_path(@group, milestone_title: milestone.title)
- or
- = link_to 'Merge Requests', merge_requests_group_path(@group, milestone_title: milestone.title)
- in this milestone
diff --git a/app/views/shared/notifications/_button.html.haml b/app/views/shared/notifications/_button.html.haml
index 441abd57334..2b3e986a841 100644
--- a/app/views/shared/notifications/_button.html.haml
+++ b/app/views/shared/notifications/_button.html.haml
@@ -17,14 +17,14 @@
.js-notification-toggle-btns
%div{ class: ("btn-group" if notification_setting.custom?) }
- if notification_setting.custom?
- %button.dropdown-new.btn.btn-default.btn-xs.has-tooltip.notifications-btn.text-left#notifications-button{ type: "button", title: button_title, class: "#{btn_class}", "aria-label" => aria_label, data: { container: "body", toggle: "modal", target: "#" + notifications_menu_identifier("modal", notification_setting), display: 'static' } }
+ %button.dropdown-new.btn.btn-default.has-tooltip.notifications-btn.text-left#notifications-button{ type: "button", title: button_title, class: "#{btn_class}", "aria-label" => aria_label, data: { container: "body", toggle: "modal", target: "#" + notifications_menu_identifier("modal", notification_setting), display: 'static' } }
= icon("bell", class: "js-notification-loading")
= notification_title(notification_setting.level)
- %button.btn.dropdown-toggle{ data: { toggle: "dropdown", target: notifications_menu_identifier("dropdown", notification_setting), flip: "false" } }
+ %button.btn.dropdown-toggle.d-flex{ data: { toggle: "dropdown", target: notifications_menu_identifier("dropdown", notification_setting), flip: "false" } }
= icon('caret-down')
.sr-only Toggle dropdown
- else
- %button.dropdown-new.btn.btn-default.btn-xs.has-tooltip.notifications-btn#notifications-button{ type: "button", title: button_title, class: "#{btn_class}", "aria-label" => aria_label, data: { container: "body", toggle: "dropdown", target: notifications_menu_identifier("dropdown", notification_setting), flip: "false" } }
+ %button.dropdown-new.btn.btn-default.has-tooltip.notifications-btn#notifications-button{ type: "button", title: button_title, class: "#{btn_class}", "aria-label" => aria_label, data: { container: "body", toggle: "dropdown", target: notifications_menu_identifier("dropdown", notification_setting), flip: "false" } }
.float-left
= icon("bell", class: "js-notification-loading")
= notification_title(notification_setting.level)
diff --git a/app/views/shared/notifications/_custom_notifications.html.haml b/app/views/shared/notifications/_custom_notifications.html.haml
index 43a87fd8397..1fef43c0c37 100644
--- a/app/views/shared/notifications/_custom_notifications.html.haml
+++ b/app/views/shared/notifications/_custom_notifications.html.haml
@@ -1,3 +1,5 @@
+- hide_label = local_assigns.fetch(:hide_label, false)
+
.modal.fade{ tabindex: "-1", role: "dialog", id: notifications_menu_identifier("modal", notification_setting), "aria-labelledby": "custom-notifications-title" }
.modal-dialog
.modal-content
@@ -11,6 +13,7 @@
.container-fluid
= form_for notification_setting, html: { class: "custom-notifications-form" } do |f|
= hidden_setting_source_input(notification_setting)
+ = hidden_field_tag("hide_label", true) if hide_label
.row
.col-lg-4
%h4.prepend-top-0= _('Notification events')
diff --git a/app/views/shared/notifications/_new_button.html.haml b/app/views/shared/notifications/_new_button.html.haml
index 3c8cc023848..363053b5e35 100644
--- a/app/views/shared/notifications/_new_button.html.haml
+++ b/app/views/shared/notifications/_new_button.html.haml
@@ -31,4 +31,4 @@
= render "shared/notifications/notification_dropdown", notification_setting: notification_setting
= content_for :scripts_body do
- = render "shared/notifications/custom_notifications", notification_setting: notification_setting
+ = render "shared/notifications/custom_notifications", notification_setting: notification_setting, hide_label: true
diff --git a/app/views/shared/projects/_list.html.haml b/app/views/shared/projects/_list.html.haml
index d70a1631010..59b4facdbe5 100644
--- a/app/views/shared/projects/_list.html.haml
+++ b/app/views/shared/projects/_list.html.haml
@@ -32,7 +32,7 @@
- explore_groups_button_label = _('Explore groups')
- explore_groups_button_link = explore_groups_path
-.js-projects-list-holder
+.js-projects-list-holder{ data: { qa_selector: 'projects_list' } }
- if any_projects?(projects)
- load_pipeline_status(projects) if pipeline_status
%ul.projects-list{ class: css_classes }
diff --git a/app/views/shared/runners/_runner_description.html.haml b/app/views/shared/runners/_runner_description.html.haml
index 5935750ca06..a47bbd55325 100644
--- a/app/views/shared/runners/_runner_description.html.haml
+++ b/app/views/shared/runners/_runner_description.html.haml
@@ -1,6 +1,6 @@
.light.prepend-top-default
%p
- = _("A 'Runner' is a process which runs a job. You can set up as many Runners as you need.")
+ = _("You can set up as many Runners as you need to run your jobs.")
%br
= _('Runners can be placed on separate users, servers, and even on your local machine.')
diff --git a/app/views/shared/snippets/_blob.html.haml b/app/views/shared/snippets/_blob.html.haml
index 2132fcbccc5..6a5e777706c 100644
--- a/app/views/shared/snippets/_blob.html.haml
+++ b/app/views/shared/snippets/_blob.html.haml
@@ -8,7 +8,6 @@
.btn-group{ role: "group" }<
= copy_blob_source_button(blob)
= open_raw_blob_button(blob)
-
- = link_to icon('download'), download_snippet_path(@snippet), target: '_blank', class: "btn btn-sm has-tooltip", title: 'Download', data: { container: 'body' }
+ = download_raw_snippet_button(@snippet)
= render 'projects/blob/content', blob: blob
diff --git a/app/views/shared/snippets/_embed.html.haml b/app/views/shared/snippets/_embed.html.haml
index c7f0511d1de..d2e35511b32 100644
--- a/app/views/shared/snippets/_embed.html.haml
+++ b/app/views/shared/snippets/_embed.html.haml
@@ -17,7 +17,7 @@
.file-actions.d-none.d-sm-block
.btn-group{ role: "group" }<
- = embedded_snippet_raw_button
+ = embedded_raw_snippet_button
= embedded_snippet_download_button
%article.file-holder.snippet-file-content
diff --git a/app/views/shared/snippets/_header.html.haml b/app/views/shared/snippets/_header.html.haml
index 8d94a87a775..67f177288f0 100644
--- a/app/views/shared/snippets/_header.html.haml
+++ b/app/views/shared/snippets/_header.html.haml
@@ -44,7 +44,7 @@
%li
%button.js-share-btn.btn.btn-transparent{ type: 'button' }
%strong.embed-toggle-list-item= _("Share")
- %input.js-snippet-url-area.snippet-embed-input.form-control{ type: "text", autocomplete: 'off', value: snippet_embed }
+ %input.js-snippet-url-area.snippet-embed-input.form-control{ type: "text", autocomplete: 'off', value: snippet_embed_tag(@snippet) }
.input-group-append
= clipboard_button(title: _('Copy'), class: 'js-clipboard-btn snippet-clipboard-btn btn btn-default', target: '.js-snippet-url-area')
.clearfix
diff --git a/app/views/shared/snippets/_snippet.html.haml b/app/views/shared/snippets/_snippet.html.haml
index 0ef626868a2..5602ea37b5c 100644
--- a/app/views/shared/snippets/_snippet.html.haml
+++ b/app/views/shared/snippets/_snippet.html.haml
@@ -7,8 +7,9 @@
.title
= link_to reliable_snippet_path(snippet) do
= snippet.title
- - if snippet.file_name
- %span.snippet-filename.monospace.d-none.d-sm-inline-block
+ - if snippet.file_name.present?
+ %span.snippet-filename.d-none.d-sm-inline-block.ml-2
+ = sprite_icon('doc-code', size: 16, css_class: 'file-icon align-text-bottom')
= snippet.file_name
%ul.controls