summaryrefslogtreecommitdiff
path: root/app/views
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2019-10-22 11:31:16 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2019-10-22 11:31:16 +0000
commit905c1110b08f93a19661cf42a276c7ea90d0a0ff (patch)
tree756d138db422392c00471ab06acdff92c5a9b69c /app/views
parent50d93f8d1686950fc58dda4823c4835fd0d8c14b (diff)
downloadgitlab-ce-905c1110b08f93a19661cf42a276c7ea90d0a0ff.tar.gz
Add latest changes from gitlab-org/gitlab@12-4-stable-ee
Diffstat (limited to 'app/views')
-rw-r--r--app/views/admin/application_settings/_ci_cd.html.haml2
-rw-r--r--app/views/admin/application_settings/_influx.html.haml2
-rw-r--r--app/views/admin/application_settings/_pages.html.haml2
-rw-r--r--app/views/admin/application_settings/_performance.html.haml10
-rw-r--r--app/views/admin/application_settings/_protected_paths.html.haml31
-rw-r--r--app/views/admin/application_settings/_repository_storage.html.haml27
-rw-r--r--app/views/admin/application_settings/_snowplow.html.haml2
-rw-r--r--app/views/admin/application_settings/_visibility_and_access.html.haml5
-rw-r--r--app/views/admin/application_settings/network.html.haml13
-rw-r--r--app/views/admin/applications/show.html.haml4
-rw-r--r--app/views/admin/dashboard/index.html.haml5
-rw-r--r--app/views/admin/impersonation_tokens/index.html.haml2
-rw-r--r--app/views/admin/labels/destroy.js.haml4
-rw-r--r--app/views/admin/labels/index.html.haml4
-rw-r--r--app/views/admin/projects/index.html.haml32
-rw-r--r--app/views/admin/runners/index.html.haml7
-rw-r--r--app/views/admin/sessions/_new_base.html.haml7
-rw-r--r--app/views/admin/sessions/_signin_box.html.haml11
-rw-r--r--app/views/admin/sessions/_tabs_normal.html.haml3
-rw-r--r--app/views/admin/sessions/new.html.haml15
-rw-r--r--app/views/admin/system_info/show.html.haml44
-rw-r--r--app/views/admin/users/_head.html.haml4
-rw-r--r--app/views/admin/users/_modals.html.haml30
-rw-r--r--app/views/admin/users/_user.html.haml37
-rw-r--r--app/views/admin/users/_user_activation_effects.html.haml6
-rw-r--r--app/views/admin/users/_user_block_effects.html.haml11
-rw-r--r--app/views/admin/users/_user_deactivation_effects.html.haml18
-rw-r--r--app/views/admin/users/_user_detail.html.haml2
-rw-r--r--app/views/admin/users/index.html.haml9
-rw-r--r--app/views/admin/users/show.html.haml48
-rw-r--r--app/views/ci/runner/_how_to_setup_runner.html.haml4
-rw-r--r--app/views/ci/runner/_how_to_setup_runner_automatically.html.haml22
-rw-r--r--app/views/ci/variables/_variable_row.html.haml2
-rw-r--r--app/views/clusters/clusters/cloud_providers/_cloud_provider_button.html.haml2
-rw-r--r--app/views/clusters/clusters/cloud_providers/_cloud_provider_selector.html.haml4
-rw-r--r--app/views/clusters/clusters/eks/_index.html.haml3
-rw-r--r--app/views/clusters/clusters/gcp/_form.html.haml12
-rw-r--r--app/views/clusters/clusters/gcp/_gcp_not_configured.html.haml3
-rw-r--r--app/views/clusters/clusters/gcp/_signin_with_google_button.html.haml4
-rw-r--r--app/views/clusters/clusters/new.html.haml32
-rw-r--r--app/views/clusters/clusters/show.html.haml5
-rw-r--r--app/views/dashboard/projects/_blank_state_admin_welcome.html.haml61
-rw-r--r--app/views/dashboard/projects/_blank_state_welcome.html.haml72
-rw-r--r--app/views/dashboard/projects/_zero_authorized_projects.html.haml21
-rw-r--r--app/views/dashboard/snippets/index.html.haml4
-rw-r--r--app/views/devise/registrations/new.html.haml5
-rw-r--r--app/views/devise/sessions/new.html.haml3
-rw-r--r--app/views/devise/shared/_experimental_separate_sign_up_flow_box.html.haml31
-rw-r--r--app/views/devise/shared/_sign_in_link.html.haml2
-rw-r--r--app/views/devise/shared/_signin_box.html.haml5
-rw-r--r--app/views/doorkeeper/applications/show.html.haml4
-rw-r--r--app/views/events/event/_push.html.haml12
-rw-r--r--app/views/groups/_activities.html.haml2
-rw-r--r--app/views/groups/_create_chat_team.html.haml2
-rw-r--r--app/views/groups/edit.html.haml4
-rw-r--r--app/views/groups/new.html.haml4
-rw-r--r--app/views/groups/projects.html.haml41
-rw-r--r--app/views/groups/registry/repositories/index.html.haml12
-rw-r--r--app/views/groups/runners/_group_runners.html.haml4
-rw-r--r--app/views/groups/settings/_advanced.html.haml24
-rw-r--r--app/views/groups/settings/ci_cd/_form.html.haml13
-rw-r--r--app/views/groups/settings/ci_cd/show.html.haml15
-rw-r--r--app/views/groups/show.html.haml2
-rw-r--r--app/views/groups/sidebar/_packages.html.haml16
-rw-r--r--app/views/help/instance_configuration/_ssh_info.html.haml27
-rw-r--r--app/views/help/show.html.haml2
-rw-r--r--app/views/help/ui.html.haml3
-rw-r--r--app/views/import/bitbucket/status.html.haml11
-rw-r--r--app/views/import/bitbucket_server/status.html.haml2
-rw-r--r--app/views/layouts/_flash.html.haml3
-rw-r--r--app/views/layouts/_head.html.haml12
-rw-r--r--app/views/layouts/_page.html.haml2
-rw-r--r--app/views/layouts/devise_experimental_separate_sign_up_flow.html.haml26
-rw-r--r--app/views/layouts/header/_current_user_dropdown.html.haml18
-rw-r--r--app/views/layouts/header/_default.html.haml8
-rw-r--r--app/views/layouts/header/_help_dropdown.html.haml3
-rw-r--r--app/views/layouts/nav/_dashboard.html.haml77
-rw-r--r--app/views/layouts/nav/sidebar/_admin.html.haml10
-rw-r--r--app/views/layouts/nav/sidebar/_group.html.haml2
-rw-r--r--app/views/layouts/nav/sidebar/_profile.html.haml4
-rw-r--r--app/views/layouts/nav/sidebar/_project.html.haml8
-rw-r--r--app/views/notify/new_release_email.html.haml18
-rw-r--r--app/views/notify/new_release_email.text.erb12
-rw-r--r--app/views/notify/pipeline_failed_email.html.haml2
-rw-r--r--app/views/notify/pipeline_failed_email.text.erb2
-rw-r--r--app/views/notify/pipeline_success_email.html.haml2
-rw-r--r--app/views/notify/pipeline_success_email.text.erb2
-rw-r--r--app/views/profiles/emails/index.html.haml8
-rw-r--r--app/views/profiles/notifications/_group_settings.html.haml2
-rw-r--r--app/views/profiles/passwords/edit.html.haml8
-rw-r--r--app/views/profiles/show.html.haml1
-rw-r--r--app/views/projects/_export.html.haml8
-rw-r--r--app/views/projects/_new_project_push_tip.html.haml2
-rw-r--r--app/views/projects/artifacts/_artifact.html.haml61
-rw-r--r--app/views/projects/artifacts/_table.html.haml16
-rw-r--r--app/views/projects/artifacts/index.html.haml10
-rw-r--r--app/views/projects/blob/_editor.html.haml8
-rw-r--r--app/views/projects/blob/_template_selectors.html.haml17
-rw-r--r--app/views/projects/blob/edit.html.haml1
-rw-r--r--app/views/projects/blob/new.html.haml1
-rw-r--r--app/views/projects/blob/show.html.haml2
-rw-r--r--app/views/projects/blob/viewers/_audio.html.haml2
-rw-r--r--app/views/projects/branches/_branch.html.haml3
-rw-r--r--app/views/projects/buttons/_clone.html.haml4
-rw-r--r--app/views/projects/commit/_commit_box.html.haml2
-rw-r--r--app/views/projects/commits/_commit.html.haml7
-rw-r--r--app/views/projects/cycle_analytics/_overview.html.haml2
-rw-r--r--app/views/projects/cycle_analytics/show.html.haml2
-rw-r--r--app/views/projects/deploy_tokens/_new_deploy_token.html.haml4
-rw-r--r--app/views/projects/deployments/_deployment.html.haml38
-rw-r--r--app/views/projects/deployments/_rollback.haml2
-rw-r--r--app/views/projects/diffs/_diffs.html.haml2
-rw-r--r--app/views/projects/diffs/_stats.html.haml4
-rw-r--r--app/views/projects/environments/show.html.haml9
-rw-r--r--app/views/projects/find_file/show.html.haml8
-rw-r--r--app/views/projects/issues/_issue.html.haml5
-rw-r--r--app/views/projects/issues/import_csv/_button.html.haml2
-rw-r--r--app/views/projects/issues/index.html.haml3
-rw-r--r--app/views/projects/merge_requests/_how_to_merge.html.haml6
-rw-r--r--app/views/projects/merge_requests/show.html.haml1
-rw-r--r--app/views/projects/mirrors/_mirror_repos.html.haml6
-rw-r--r--app/views/projects/mirrors/_ssh_host_keys.html.haml4
-rw-r--r--app/views/projects/notes/_more_actions_dropdown.html.haml2
-rw-r--r--app/views/projects/pages/_access.html.haml6
-rw-r--r--app/views/projects/pages/_destroy.haml10
-rw-r--r--app/views/projects/pages/_https_only.html.haml5
-rw-r--r--app/views/projects/pages/_list.html.haml19
-rw-r--r--app/views/projects/pages/_no_domains.html.haml5
-rw-r--r--app/views/projects/pages/_use.html.haml10
-rw-r--r--app/views/projects/pages/show.html.haml11
-rw-r--r--app/views/projects/pipelines/_info.html.haml10
-rw-r--r--app/views/projects/protected_branches/shared/_branches_list.html.haml17
-rw-r--r--app/views/projects/protected_branches/shared/_create_protected_branch.html.haml19
-rw-r--r--app/views/projects/protected_branches/shared/_protected_branch.html.haml21
-rw-r--r--app/views/projects/registry/repositories/index.html.haml5
-rw-r--r--app/views/projects/releases/edit.html.haml3
-rw-r--r--app/views/projects/runners/_specific_runners.html.haml25
-rw-r--r--app/views/projects/settings/ci_cd/_autodevops_form.html.haml4
-rw-r--r--app/views/projects/settings/ci_cd/_form.html.haml13
-rw-r--r--app/views/projects/tags/_tag.html.haml12
-rw-r--r--app/views/projects/tags/new.html.haml2
-rw-r--r--app/views/projects/tree/_tree_header.html.haml13
-rw-r--r--app/views/projects/triggers/_trigger.html.haml2
-rw-r--r--app/views/registrations/welcome.html.haml17
-rw-r--r--app/views/search/_form.html.haml1
-rw-r--r--app/views/search/results/_empty.html.haml3
-rw-r--r--app/views/search/show.html.haml3
-rw-r--r--app/views/shared/_allow_request_access.html.haml4
-rw-r--r--app/views/shared/_auto_devops_implicitly_enabled_banner.html.haml2
-rw-r--r--app/views/shared/_clone_panel.html.haml2
-rw-r--r--app/views/shared/_confirm_fork_modal.html.haml12
-rw-r--r--app/views/shared/_confirm_modal.html.haml5
-rw-r--r--app/views/shared/_event_filter.html.haml4
-rw-r--r--app/views/shared/_group_form.html.haml4
-rw-r--r--app/views/shared/_personal_access_tokens_created_container.html.haml2
-rw-r--r--app/views/shared/_remote_mirror_update_button.html.haml2
-rw-r--r--app/views/shared/_user_dropdown_contributing_link.html.haml5
-rw-r--r--app/views/shared/boards/_switcher.html.haml2
-rw-r--r--app/views/shared/deploy_keys/_form.html.haml2
-rw-r--r--app/views/shared/empty_states/_issues.html.haml3
-rw-r--r--app/views/shared/form_elements/_apply_template_warning.html.haml14
-rw-r--r--app/views/shared/issuable/_assignees.html.haml2
-rw-r--r--app/views/shared/issuable/_board_create_list_dropdown.html.haml2
-rw-r--r--app/views/shared/issuable/_feed_buttons.html.haml6
-rw-r--r--app/views/shared/issuable/_form.html.haml1
-rw-r--r--app/views/shared/issuable/_search_bar.html.haml7
-rw-r--r--app/views/shared/issuable/_sidebar.html.haml330
-rw-r--r--app/views/shared/issuable/_sidebar_assignees.html.haml2
-rw-r--r--app/views/shared/milestones/_sidebar.html.haml4
-rw-r--r--app/views/shared/projects/_project.html.haml10
-rw-r--r--app/views/shared/snippets/_header.html.haml2
171 files changed, 1328 insertions, 705 deletions
diff --git a/app/views/admin/application_settings/_ci_cd.html.haml b/app/views/admin/application_settings/_ci_cd.html.haml
index d1de4286ee7..1f5bce19bc6 100644
--- a/app/views/admin/application_settings/_ci_cd.html.haml
+++ b/app/views/admin/application_settings/_ci_cd.html.haml
@@ -34,7 +34,7 @@
= f.number_field :max_artifacts_size, class: 'form-control'
.form-text.text-muted
= _("Set the maximum file size for each job's artifacts")
- = link_to icon('question-circle'), help_page_path('user/admin_area/settings/continuous_integration', anchor: 'maximum-artifacts-size')
+ = link_to icon('question-circle'), help_page_path('user/admin_area/settings/continuous_integration', anchor: 'maximum-artifacts-size-core-only')
.form-group
= f.label :default_artifacts_expire_in, _('Default artifacts expiration'), class: 'label-bold'
= f.text_field :default_artifacts_expire_in, class: 'form-control'
diff --git a/app/views/admin/application_settings/_influx.html.haml b/app/views/admin/application_settings/_influx.html.haml
index 98c7a9659c3..300b01c6777 100644
--- a/app/views/admin/application_settings/_influx.html.haml
+++ b/app/views/admin/application_settings/_influx.html.haml
@@ -7,7 +7,7 @@
in running SQL queries. These settings require a
= link_to 'restart', help_page_path('administration/restart_gitlab')
to take effect.
- = link_to icon('question-circle'), help_page_path('administration/monitoring/performance/introduction')
+ = link_to icon('question-circle'), help_page_path('administration/monitoring/performance/index')
.form-group
.form-check
= f.check_box :metrics_enabled, class: 'form-check-input'
diff --git a/app/views/admin/application_settings/_pages.html.haml b/app/views/admin/application_settings/_pages.html.haml
index 1282a032f52..b15afb3b806 100644
--- a/app/views/admin/application_settings/_pages.html.haml
+++ b/app/views/admin/application_settings/_pages.html.haml
@@ -30,6 +30,6 @@
= f.check_box :lets_encrypt_terms_of_service_accepted, class: 'form-check-input'
= f.label :lets_encrypt_terms_of_service_accepted, class: 'form-check-label' do
- terms_of_service_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: lets_encrypt_terms_of_service_admin_application_settings_path }
- = _("I have read and agree to the Let's Encrypt %{link_start}Terms of Service%{link_end}").html_safe % { link_start: terms_of_service_link_start, link_end: '</a>'.html_safe }
+ = _("I have read and agree to the Let's Encrypt %{link_start}Terms of Service%{link_end} (PDF)").html_safe % { link_start: terms_of_service_link_start, link_end: '</a>'.html_safe }
= f.submit _('Save changes'), class: "btn btn-success"
diff --git a/app/views/admin/application_settings/_performance.html.haml b/app/views/admin/application_settings/_performance.html.haml
index b52171afc69..6b02521a0f0 100644
--- a/app/views/admin/application_settings/_performance.html.haml
+++ b/app/views/admin/application_settings/_performance.html.haml
@@ -20,5 +20,15 @@
= f.number_field :raw_blob_request_limit, class: 'form-control'
.form-text.text-muted
= _('Highest number of requests per minute for each raw path, default to 300. To disable throttling set to 0.')
+ .form-group
+ = f.label :push_event_hooks_limit, class: 'label-bold'
+ = f.number_field :push_event_hooks_limit, class: 'form-control'
+ .form-text.text-muted
+ = _("Number of changes (branches or tags) in a single push to determine whether webhooks and services will be fired or not. Webhooks and services won't be submitted if it surpasses that value.")
+ .form-group
+ = f.label :push_event_activities_limit, class: 'label-bold'
+ = f.number_field :push_event_activities_limit, class: 'form-control'
+ .form-text.text-muted
+ = _('Number of changes (branches or tags) in a single push to determine whether individual push events or bulk push event will be created. Bulk push event will be created if it surpasses that value.')
= f.submit 'Save changes', class: "btn btn-success"
diff --git a/app/views/admin/application_settings/_protected_paths.html.haml b/app/views/admin/application_settings/_protected_paths.html.haml
new file mode 100644
index 00000000000..f4d40e10f36
--- /dev/null
+++ b/app/views/admin/application_settings/_protected_paths.html.haml
@@ -0,0 +1,31 @@
+= form_for @application_setting, url: network_admin_application_settings_path(anchor: 'js-protected-paths-settings'), html: { class: 'fieldset-form' } do |f|
+ = form_errors(@application_setting)
+
+ %fieldset
+ - if omnibus_protected_paths_throttle?
+ .bs-callout.bs-callout-danger
+ - relative_url_link = 'https://docs.gitlab.com/ee/user/admin_area/settings/protected_paths.html#migrate-settings-from-gitlab-123-and-earlier'
+ - relative_url_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: relative_url_link }
+ = _("Omnibus Protected Paths throttle is active. From 12.4, Omnibus throttle is deprecated and will be removed in a future release. Please read the %{relative_url_link_start}Migrating Protected Paths documentation%{relative_url_link_end}.").html_safe % { relative_url_link_start: relative_url_link_start, relative_url_link_end: '</a>'.html_safe }
+
+ .form-group
+ .form-check
+ = f.check_box :throttle_protected_paths_enabled, class: 'form-check-input'
+ = f.label :throttle_protected_paths_enabled, class: 'form-check-label' do
+ = _('Enable protected paths rate limit')
+ %span.form-text.text-muted
+ = _('Helps reduce request volume for protected paths')
+ .form-group
+ = f.label :throttle_protected_paths_requests_per_period, 'Max requests per period per user', class: 'label-bold'
+ = f.number_field :throttle_protected_paths_requests_per_period, class: 'form-control'
+ .form-group
+ = f.label :throttle_protected_paths_period_in_seconds, 'Rate limit period in seconds', class: 'label-bold'
+ = f.number_field :throttle_protected_paths_period_in_seconds, class: 'form-control'
+ .form-group
+ = f.label :protected_paths, class: 'label-bold' do
+ - relative_url_link = 'https://docs.gitlab.com/omnibus/settings/configuration.html#configuring-a-relative-url-for-gitlab'
+ - relative_url_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: relative_url_link }
+ = _('All paths are relative to the GitLab URL. Do not include %{relative_url_link_start}relative URL%{relative_url_link_end}.').html_safe % { relative_url_link_start: relative_url_link_start, relative_url_link_end: '</a>'.html_safe }
+ = f.text_area :protected_paths_raw, placeholder: '/users/sign_in,/users/password', class: 'form-control', rows: 10
+
+ = f.submit 'Save changes', class: 'btn btn-success'
diff --git a/app/views/admin/application_settings/_repository_storage.html.haml b/app/views/admin/application_settings/_repository_storage.html.haml
index e5bcb180445..b97e9a194f3 100644
--- a/app/views/admin/application_settings/_repository_storage.html.haml
+++ b/app/views/admin/application_settings/_repository_storage.html.haml
@@ -3,21 +3,24 @@
%fieldset
.sub-section
+ %h4= _("Hashed repository storage paths")
.form-group
.form-check
= f.check_box :hashed_storage_enabled, class: 'form-check-input qa-hashed-storage-checkbox'
- = f.label :hashed_storage_enabled, class: 'form-check-label' do
- Use hashed storage paths for newly created and renamed projects
+ = f.label :hashed_storage_enabled, _("Use hashed storage"), class: 'label-bold form-check-label'
.form-text.text-muted
- Enable immutable, hash-based paths and repository names to store repositories on disk. This prevents
- repositories from having to be moved or renamed when the Project URL changes and may improve disk I/O performance.
+ = _("Use hashed storage paths for newly created and renamed projects. Enable immutable, hash-based paths and repository names to store repositories on disk. This prevents repositories from having to be moved or renamed when the Project URL changes and may improve disk I/O performance.")
+ .sub-section
+ %h4= _("Storage nodes for new projects")
.form-group
- = f.label :repository_storages, 'Storage paths for new projects', class: 'label-bold'
- = f.select :repository_storages, repository_storages_options_for_select(@application_setting.repository_storages),
- {include_hidden: false}, multiple: true, class: 'form-control'
- .form-text.text-muted
- Manage repository storage paths. Learn more in the
- = succeed "." do
- = link_to "repository storages documentation", help_page_path("administration/repository_storage_paths")
+ .form-text
+ %p.text-secondary
+ = _('Select the configured storaged available for new projects to be placed on.')
+ = link_to icon('question-circle'), help_page_path('administration/repository_storage_paths')
+ .form-check
+ = f.collection_check_boxes :repository_storages, Gitlab.config.repositories.storages, :first, :first, include_hidden: false do |b|
+ = b.check_box class: 'form-check-input'
+ = b.label class: 'label-bold form-check-label'
+ %br
- = f.submit 'Save changes', class: "btn btn-success qa-save-changes-button"
+ = f.submit _('Save changes'), class: "btn btn-success qa-save-changes-button"
diff --git a/app/views/admin/application_settings/_snowplow.html.haml b/app/views/admin/application_settings/_snowplow.html.haml
index b60b5d55a1b..31fd12d191e 100644
--- a/app/views/admin/application_settings/_snowplow.html.haml
+++ b/app/views/admin/application_settings/_snowplow.html.haml
@@ -9,7 +9,7 @@
= _('Configure the %{link} integration.').html_safe % { link: link_to('Snowplow', 'https://snowplowanalytics.com/', target: '_blank') }
.settings-content
- = form_for @application_setting, url: integrations_admin_application_settings_path, html: { class: 'fieldset-form' } do |f|
+ = form_for @application_setting, url: integrations_admin_application_settings_path(anchor: 'js-snowplow-settings'), html: { class: 'fieldset-form' } do |f|
= form_errors(@application_setting)
%fieldset
diff --git a/app/views/admin/application_settings/_visibility_and_access.html.haml b/app/views/admin/application_settings/_visibility_and_access.html.haml
index e57ef1ea18f..be5f1f4f9a8 100644
--- a/app/views/admin/application_settings/_visibility_and_access.html.haml
+++ b/app/views/admin/application_settings/_visibility_and_access.html.haml
@@ -53,6 +53,11 @@
= select(:application_setting, :enabled_git_access_protocol, [['Both SSH and HTTP(S)', nil], ['Only SSH', 'ssh'], ['Only HTTP(S)', 'http']], {}, class: 'form-control')
%span.form-text.text-muted#clone-protocol-help
= _('Allow only the selected protocols to be used for Git access.')
+ .form-group
+ = f.label :custom_http_clone_url_root, _('Custom Git clone URL for HTTP(S)'), class: 'label-bold'
+ = f.text_field :custom_http_clone_url_root, class: 'form-control', placeholder: 'https://git.example.com', :'aria-describedby' => 'custom_http_clone_url_root_help_block'
+ %span.form-text.text-muted#custom_http_clone_url_root_help_block
+ = _('Replaces the clone URL root.')
- ApplicationSetting::SUPPORTED_KEY_TYPES.each do |type|
- field_name = :"#{type}_key_restriction"
diff --git a/app/views/admin/application_settings/network.html.haml b/app/views/admin/application_settings/network.html.haml
index 3a4d901ca1d..092834b993c 100644
--- a/app/views/admin/application_settings/network.html.haml
+++ b/app/views/admin/application_settings/network.html.haml
@@ -34,3 +34,16 @@
= _('Allow requests to the local network from hooks and services.')
.settings-content
= render 'outbound'
+
+%section.settings.as-protected-paths.no-animate#js-protected-paths-settings{ class: ('expanded' if expanded_by_default?) }
+ .settings-header
+ %h4
+ = _('Protected Paths')
+ %button.btn.btn-default.js-settings-toggle{ type: 'button' }
+ = expanded_by_default? ? _('Collapse') : _('Expand')
+ %p
+ = _('Configure paths to be protected by Rack Attack. A web server restart is required after changing these settings.')
+ .settings-content
+ = render 'protected_paths'
+
+= render_if_exists 'admin/application_settings/ee_network_settings'
diff --git a/app/views/admin/applications/show.html.haml b/app/views/admin/applications/show.html.haml
index 180066723f1..aca9302aff7 100644
--- a/app/views/admin/applications/show.html.haml
+++ b/app/views/admin/applications/show.html.haml
@@ -13,7 +13,7 @@
.input-group
%input.label.label-monospace.monospace{ id: "application_id", type: "text", autocomplete: 'off', value: @application.uid, readonly: true }
.input-group-append
- = clipboard_button(target: '#application_id', title: _("Copy ID to clipboard"), class: "btn btn btn-default")
+ = clipboard_button(target: '#application_id', title: _("Copy ID"), class: "btn btn btn-default")
%tr
%td
= _('Secret')
@@ -22,7 +22,7 @@
.input-group
%input.label.label-monospace.monospace{ id: "secret", type: "text", autocomplete: 'off', value: @application.secret, readonly: true }
.input-group-append
- = clipboard_button(target: '#secret', title: _("Copy secret to clipboard"), class: "btn btn btn-default")
+ = clipboard_button(target: '#secret', title: _("Copy secret"), class: "btn btn btn-default")
%tr
%td
= _('Callback URL')
diff --git a/app/views/admin/dashboard/index.html.haml b/app/views/admin/dashboard/index.html.haml
index 8fad42436ca..41147950c40 100644
--- a/app/views/admin/dashboard/index.html.haml
+++ b/app/views/admin/dashboard/index.html.haml
@@ -1,6 +1,7 @@
- breadcrumb_title "Dashboard"
-= render_if_exists 'admin/licenses/breakdown', license: @license
+- if show_license_breakdown?
+ = render_if_exists 'admin/licenses/breakdown', license: @license
.admin-dashboard.prepend-top-default
.row
@@ -40,7 +41,7 @@
.info-well
.well-segment.admin-well.admin-well-features
%h4 Features
- = feature_entry(_('Sign up'), href: admin_application_settings_path(anchor: 'js-signup-settings'))
+ = 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?)
diff --git a/app/views/admin/impersonation_tokens/index.html.haml b/app/views/admin/impersonation_tokens/index.html.haml
index 8e869fb4b71..a7da14d16ff 100644
--- a/app/views/admin/impersonation_tokens/index.html.haml
+++ b/app/views/admin/impersonation_tokens/index.html.haml
@@ -8,7 +8,7 @@
- if @new_impersonation_token
= render "shared/personal_access_tokens_created_container", new_token_value: @new_impersonation_token,
container_title: 'Your New Impersonation Token',
- clipboard_button_title: 'Copy impersonation token to clipboard'
+ clipboard_button_title: _('Copy impersonation token')
= render "shared/personal_access_tokens_form", path: admin_user_impersonation_tokens_path, impersonation: true, token: @impersonation_token, scopes: @scopes
diff --git a/app/views/admin/labels/destroy.js.haml b/app/views/admin/labels/destroy.js.haml
index 7a0dcbdd1c6..394d3c11f31 100644
--- a/app/views/admin/labels/destroy.js.haml
+++ b/app/views/admin/labels/destroy.js.haml
@@ -1,2 +1,2 @@
-- if @labels.size == 0
- $('.labels').load(document.URL + ' .card.bg-light').hide().fadeIn(1000)
+- if @labels.size.zero?
+ $('.labels').load(document.URL + ' .nothing-here-block').hide().fadeIn(1000)
diff --git a/app/views/admin/labels/index.html.haml b/app/views/admin/labels/index.html.haml
index 5a5b3d18c5f..38137f360fd 100644
--- a/app/views/admin/labels/index.html.haml
+++ b/app/views/admin/labels/index.html.haml
@@ -14,6 +14,4 @@
= paginate @labels, theme: 'gitlab'
- else
- .card.bg-light
- .nothing-here-block= _('There are no labels yet')
-
+ .nothing-here-block= _('There are no labels yet')
diff --git a/app/views/admin/projects/index.html.haml b/app/views/admin/projects/index.html.haml
index bb0d62a70c0..08e668e8623 100644
--- a/app/views/admin/projects/index.html.haml
+++ b/app/views/admin/projects/index.html.haml
@@ -1,8 +1,20 @@
-- page_title "Projects"
+- page_title _('Projects')
- params[:visibility_level] ||= []
.top-area.scrolling-tabs-container.inner-page-scroll-tabs
- .prepend-top-default
+ %ul.nav-links.nav.nav-tabs
+ - opts = params[:visibility_level].present? ? {} : { page: admin_projects_path }
+ = nav_link(opts) do
+ = link_to _('All'), admin_projects_path
+
+ = nav_link(html_options: { class: active_when(params[:visibility_level] == Gitlab::VisibilityLevel::PRIVATE.to_s) }) do
+ = link_to _('Private'), admin_projects_path(visibility_level: Gitlab::VisibilityLevel::PRIVATE)
+ = nav_link(html_options: { class: active_when(params[:visibility_level] == Gitlab::VisibilityLevel::INTERNAL.to_s) }) do
+ = link_to _('Internal'), admin_projects_path(visibility_level: Gitlab::VisibilityLevel::INTERNAL)
+ = nav_link(html_options: { class: active_when(params[:visibility_level] == Gitlab::VisibilityLevel::PUBLIC.to_s) }) do
+ = link_to _('Public'), admin_projects_path(visibility_level: Gitlab::VisibilityLevel::PUBLIC)
+
+ .nav-controls
.search-holder
= render 'shared/projects/search_form', autofocus: true, admin_view: true
.dropdown
@@ -22,20 +34,4 @@
New Project
= button_tag "Search", class: "btn btn-primary btn-search hide"
- %ul.nav-links.nav.nav-tabs
- - opts = params[:visibility_level].present? ? {} : { page: admin_projects_path }
- = nav_link(opts) do
- = link_to admin_projects_path do
- All
-
- = nav_link(html_options: { class: active_when(params[:visibility_level] == Gitlab::VisibilityLevel::PRIVATE.to_s) }) do
- = link_to admin_projects_path(visibility_level: Gitlab::VisibilityLevel::PRIVATE) do
- Private
- = nav_link(html_options: { class: active_when(params[:visibility_level] == Gitlab::VisibilityLevel::INTERNAL.to_s) }) do
- = link_to admin_projects_path(visibility_level: Gitlab::VisibilityLevel::INTERNAL) do
- Internal
- = nav_link(html_options: { class: active_when(params[:visibility_level] == Gitlab::VisibilityLevel::PUBLIC.to_s) }) do
- = link_to admin_projects_path(visibility_level: Gitlab::VisibilityLevel::PUBLIC) do
- Public
-
= render 'projects'
diff --git a/app/views/admin/runners/index.html.haml b/app/views/admin/runners/index.html.haml
index 76af4189b5b..2bf2b5fce8d 100644
--- a/app/views/admin/runners/index.html.haml
+++ b/app/views/admin/runners/index.html.haml
@@ -43,14 +43,13 @@
.row
.col-sm-9
= form_tag admin_runners_path, id: 'runners-search', method: :get, class: 'filter-form js-filter-form' do
- .filtered-search-wrapper
+ .filtered-search-wrapper.d-flex
.filtered-search-box
- = dropdown_tag(custom_icon('icon_history'),
+ = 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',
- title: _('Recent searches') }) do
+ content_class: 'filtered-search-history-dropdown-content' }) do
.js-filtered-search-history-dropdown{ data: { full_path: admin_runners_path } }
.filtered-search-box-input-container.droplab-dropdown
.scroll-container
diff --git a/app/views/admin/sessions/_new_base.html.haml b/app/views/admin/sessions/_new_base.html.haml
new file mode 100644
index 00000000000..55aea0296e7
--- /dev/null
+++ b/app/views/admin/sessions/_new_base.html.haml
@@ -0,0 +1,7 @@
+= form_tag(admin_session_path, method: :post, html: { class: 'new_user gl-show-field-errors', 'aria-live': 'assertive'}) do
+ .form-group
+ = label_tag :password, _('Password'), class: 'label-bold'
+ = 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' }
diff --git a/app/views/admin/sessions/_signin_box.html.haml b/app/views/admin/sessions/_signin_box.html.haml
new file mode 100644
index 00000000000..69baa76060e
--- /dev/null
+++ b/app/views/admin/sessions/_signin_box.html.haml
@@ -0,0 +1,11 @@
+- if form_based_providers.any?
+
+ - if password_authentication_enabled_for_web?
+ .login-box.tab-pane{ id: 'login-pane', role: 'tabpanel' }
+ .login-body
+ = render 'admin/sessions/new_base'
+
+- elsif password_authentication_enabled_for_web?
+ .login-box.tab-pane.active{ id: 'login-pane', role: 'tabpanel' }
+ .login-body
+ = render 'admin/sessions/new_base'
diff --git a/app/views/admin/sessions/_tabs_normal.html.haml b/app/views/admin/sessions/_tabs_normal.html.haml
new file mode 100644
index 00000000000..f5dedb5ad76
--- /dev/null
+++ b/app/views/admin/sessions/_tabs_normal.html.haml
@@ -0,0 +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')
diff --git a/app/views/admin/sessions/new.html.haml b/app/views/admin/sessions/new.html.haml
new file mode 100644
index 00000000000..ee06b4a1741
--- /dev/null
+++ b/app/views/admin/sessions/new.html.haml
@@ -0,0 +1,15 @@
+- @hide_breadcrumbs = true
+- page_title _('Enter admin mode')
+
+.row.justify-content-center
+ .col-6.new-session-forms-container
+ .login-page
+ #signin-container
+ = render 'admin/sessions/tabs_normal'
+ .tab-content
+ - if password_authentication_enabled_for_web?
+ = render 'admin/sessions/signin_box'
+ - else
+ -# Show a message if none of the mechanisms above are enabled
+ .prepend-top-default.center
+ = _('No authentication methods configured.')
diff --git a/app/views/admin/system_info/show.html.haml b/app/views/admin/system_info/show.html.haml
index 948a11646f7..b7648979edd 100644
--- a/app/views/admin/system_info/show.html.haml
+++ b/app/views/admin/system_info/show.html.haml
@@ -1,35 +1,35 @@
-- page_title "System Info"
+- page_title _('System Info')
.prepend-top-default
.row
- .col-sm-4
- .card.bg-light.light-well
- %h4 CPU
+ .col-sm
+ .bg-light.light-well
+ %h4= _('CPU')
.data
- if @cpus
- %h1 #{@cpus.length} cores
+ %h2= _('%{cores} cores') % { cores: @cpus.length }
- else
= icon('warning', class: 'text-warning')
- Unable to collect CPU info
- .col-sm-4
- .card.bg-light.light-well
- %h4 Memory Usage
+ = _('Unable to collect CPU info')
+ .bg-light.light-well.prepend-top-default
+ %h4= _('Memory Usage')
.data
- if @memory
- %h1 #{number_to_human_size(@memory.active_bytes)} / #{number_to_human_size(@memory.total_bytes)}
+ %h2 #{number_to_human_size(@memory.active_bytes)} / #{number_to_human_size(@memory.total_bytes)}
- else
= icon('warning', class: 'text-warning')
- Unable to collect memory info
- .col-sm-4
- .card.bg-light.light-well
- %h4 Disk Usage
+ = _('Unable to collect memory info')
+ .bg-light.light-well.prepend-top-default
+ %h4= _('Uptime')
.data
- - @disks.each do |disk|
- %h1 #{number_to_human_size(disk[:bytes_used])} / #{number_to_human_size(disk[:bytes_total])}
- %p= disk[:disk_name]
- %p= disk[:mount_path]
- .col-sm-4
- .card.bg-light.light-well
- %h4 Uptime
+ %h2= distance_of_time_in_words_to_now(Rails.application.config.booted_at)
+ .col-sm
+ .bg-light.light-well
+ %h4= _('Disk Usage')
.data
- %h1= distance_of_time_in_words_to_now(Rails.application.config.booted_at)
+ %ul
+ - @disks.each do |disk|
+ %li
+ %h2 #{number_to_human_size(disk[:bytes_used])} / #{number_to_human_size(disk[:bytes_total])}
+ %p= disk[:disk_name]
+ %p= disk[:mount_path]
diff --git a/app/views/admin/users/_head.html.haml b/app/views/admin/users/_head.html.haml
index e7dde7985fd..a218885a00e 100644
--- a/app/views/admin/users/_head.html.haml
+++ b/app/views/admin/users/_head.html.haml
@@ -6,11 +6,13 @@
%span.cred (Internal)
- if @user.admin
%span.cred (Admin)
+ - if @user.deactivated?
+ %span.cred (Deactivated)
= render_if_exists 'admin/users/audtior_user_badge'
.float-right
- if impersonation_enabled? && @user != current_user && @user.can?(:log_in)
- = link_to 'Impersonate', impersonate_admin_user_path(@user), method: :post, class: "btn btn-nr btn-grouped btn-info"
+ = link_to 'Impersonate', impersonate_admin_user_path(@user), method: :post, class: "btn btn-nr btn-grouped btn-info", data: { qa_selector: 'impersonate_user_link' }
= link_to edit_admin_user_path(@user), class: "btn btn-nr btn-grouped" do
%i.fa.fa-pencil-square-o
Edit
diff --git a/app/views/admin/users/_modals.html.haml b/app/views/admin/users/_modals.html.haml
new file mode 100644
index 00000000000..eaec6d69f5a
--- /dev/null
+++ b/app/views/admin/users/_modals.html.haml
@@ -0,0 +1,30 @@
+#user-modal
+#modal-texts.hidden{ "hidden": true, "aria-hidden": true }
+ %div{ data: { modal: "deactivate",
+ title: s_("AdminUsers|Deactivate User %{username}?"),
+ action: s_("AdminUsers|Deactivate") } }
+ = render partial: 'admin/users/user_deactivation_effects'
+
+ %div{ data: { modal: "block",
+ title: s_("AdminUsers|Block user %{username}?"),
+ action: s_("AdminUsers|Block") } }
+ = render partial: 'admin/users/user_block_effects'
+
+ %div{ data: { modal: "delete",
+ title: s_("AdminUsers|Delete User %{username}?"),
+ action: s_('AdminUsers|Delete user'),
+ 'secondary-action': s_('AdminUsers|Block user') } }
+ = s_('AdminUsers|You are about to permanently delete the user %{username}. Issues, merge requests,
+ and groups linked to them will be transferred to a system-wide "Ghost-user". To avoid data loss,
+ consider using the %{strong_start}block user%{strong_end} feature instead. Once you %{strong_start}Delete user%{strong_end},
+ it cannot be undone or recovered.')
+
+ %div{ data: { modal: "delete-with-contributions",
+ title: s_("AdminUsers|Delete User %{username} and contributions?"),
+ action: s_('AdminUsers|Delete user and contributions') ,
+ 'secondary-action': s_('AdminUsers|Block user') } }
+ = s_('AdminUsers|You are about to permanently delete the user %{username}. This will delete all of the issues,
+ merge requests, and groups linked to them. To avoid data loss,
+ consider using the %{strong_start}block user%{strong_end} feature instead. Once you %{strong_start}Delete user%{strong_end},
+ it cannot be undone or recovered.')
+
diff --git a/app/views/admin/users/_user.html.haml b/app/views/admin/users/_user.html.haml
index be7bfa958b2..ca5109614fc 100644
--- a/app/views/admin/users/_user.html.haml
+++ b/app/views/admin/users/_user.html.haml
@@ -1,4 +1,4 @@
-.gl-responsive-table-row{ role: 'row' }
+.gl-responsive-table-row{ role: 'row', data: { qa_selector: 'user_row_content' } }
.table-section.section-40
.table-mobile-header{ role: 'rowheader' }
= _('Name')
@@ -31,7 +31,19 @@
- elsif user.blocked?
= link_to _('Unblock'), unblock_admin_user_path(user), method: :put
- else
- = link_to _('Block'), block_admin_user_path(user), data: { confirm: "#{s_('AdminUsers|User will be blocked').upcase}! #{_('Are you sure')}?" }, method: :put
+ %button.btn{ data: { 'gl-modal-action': 'block',
+ url: block_admin_user_path(user),
+ username: sanitize_name(user.name) } }
+ = s_('AdminUsers|Block')
+ - if user.can_be_deactivated?
+ %li
+ %button.btn{ data: { 'gl-modal-action': 'deactivate',
+ url: deactivate_admin_user_path(user),
+ username: sanitize_name(user.name) } }
+ = s_('AdminUsers|Deactivate')
+ - elsif user.deactivated?
+ %li
+ = link_to _('Activate'), activate_admin_user_path(user), method: :put
- if user.access_locked?
%li
= link_to _('Unlock'), unlock_admin_user_path(user), method: :put, data: { confirm: _('Are you sure?') }
@@ -39,19 +51,14 @@
%li.divider
- if user.can_be_removed?
%li
- %button.delete-user-button.btn.text-danger{ data: { toggle: 'modal',
- target: '#delete-user-modal',
+ %button.delete-user-button.btn.text-danger{ data: { 'gl-modal-action': 'delete',
delete_user_url: admin_user_path(user),
block_user_url: block_admin_user_path(user),
- username: sanitize_name(user.name),
- delete_contributions: false }, type: 'button' }
+ username: sanitize_name(user.name) } }
= s_('AdminUsers|Delete user')
-
- %li
- %button.delete-user-button.btn.text-danger{ data: { toggle: 'modal',
- target: '#delete-user-modal',
- delete_user_url: admin_user_path(user, hard_delete: true),
- block_user_url: block_admin_user_path(user),
- username: sanitize_name(user.name),
- delete_contributions: true }, type: 'button' }
- = s_('AdminUsers|Delete user and contributions')
+ %li
+ %button.delete-user-button.btn.text-danger{ data: { 'gl-modal-action': 'delete-with-contributions',
+ delete_user_url: admin_user_path(user, hard_delete: true),
+ block_user_url: block_admin_user_path(user),
+ username: sanitize_name(user.name) } }
+ = s_('AdminUsers|Delete user and contributions')
diff --git a/app/views/admin/users/_user_activation_effects.html.haml b/app/views/admin/users/_user_activation_effects.html.haml
new file mode 100644
index 00000000000..244836dac11
--- /dev/null
+++ b/app/views/admin/users/_user_activation_effects.html.haml
@@ -0,0 +1,6 @@
+%p
+ = s_('AdminUsers|Reactivating a user will:')
+%ul
+ %li
+ = s_('AdminUsers|Restore user access to the account, including web, Git and API.')
+ = render_if_exists 'admin/users/user_activation_effects_on_seats'
diff --git a/app/views/admin/users/_user_block_effects.html.haml b/app/views/admin/users/_user_block_effects.html.haml
new file mode 100644
index 00000000000..8ffbe145169
--- /dev/null
+++ b/app/views/admin/users/_user_block_effects.html.haml
@@ -0,0 +1,11 @@
+%p
+ = s_('AdminUsers|Blocking user has the following effects:')
+%ul
+ %li
+ = s_('AdminUsers|User will not be able to login')
+ %li
+ = s_('AdminUsers|User will not be able to access git repositories')
+ %li
+ = s_('AdminUsers|Personal projects will be left')
+ %li
+ = s_('AdminUsers|Owned groups will be left')
diff --git a/app/views/admin/users/_user_deactivation_effects.html.haml b/app/views/admin/users/_user_deactivation_effects.html.haml
new file mode 100644
index 00000000000..dc3896e18c0
--- /dev/null
+++ b/app/views/admin/users/_user_deactivation_effects.html.haml
@@ -0,0 +1,18 @@
+%p
+ = s_('AdminUsers|Deactivating a user has the following effects:')
+%ul
+ %li
+ = s_('AdminUsers|The user will be logged out')
+ %li
+ = s_('AdminUsers|The user will not be able to access git repositories')
+ %li
+ = s_('AdminUsers|The user will not be able to access the API')
+ %li
+ = s_('AdminUsers|The user will not receive any notifications')
+ %li
+ = s_('AdminUsers|The user will not be able to use slash commands')
+ %li
+ = s_('AdminUsers|When the user logs back in, their account will reactivate as a fully active account')
+ %li
+ = s_('AdminUsers|Personal projects, group and user history will be left intact')
+ = render_if_exists 'admin/users/user_deactivation_effects_on_seats'
diff --git a/app/views/admin/users/_user_detail.html.haml b/app/views/admin/users/_user_detail.html.haml
index 13d10dcd625..3cc3fc6fa92 100644
--- a/app/views/admin/users/_user_detail.html.haml
+++ b/app/views/admin/users/_user_detail.html.haml
@@ -4,7 +4,7 @@
.row-main-content
.row-title.str-truncated-100
= image_tag avatar_icon_for_user(user), class: 'avatar s16 d-xs-flex d-md-none mr-1 prepend-top-2', alt: _('Avatar for %{name}') % { name: sanitize_name(user.name) }
- = link_to user.name, admin_user_path(user), class: 'text-plain js-user-link', data: { user_id: user.id }
+ = link_to user.name, admin_user_path(user), class: 'text-plain js-user-link', data: { user_id: user.id, qa_selector: 'username_link' }
= render_if_exists 'admin/users/user_listing_note', user: user
diff --git a/app/views/admin/users/index.html.haml b/app/views/admin/users/index.html.haml
index 36b62557fa6..3c6ad899d1e 100644
--- a/app/views/admin/users/index.html.haml
+++ b/app/views/admin/users/index.html.haml
@@ -30,6 +30,10 @@
= link_to admin_users_path(filter: "blocked") do
= s_('AdminUsers|Blocked')
%small.badge.badge-pill= limited_counter_with_delimiter(User.blocked)
+ = nav_link(html_options: { class: active_when(params[:filter] == 'deactivated') }) do
+ = link_to admin_users_path(filter: "deactivated") do
+ = s_('AdminUsers|Deactivated')
+ %small.badge.badge-pill= limited_counter_with_delimiter(User.deactivated)
= nav_link(html_options: { class: active_when(params[:filter] == 'wop') }) do
= link_to admin_users_path(filter: "wop") do
= s_('AdminUsers|Without projects')
@@ -44,12 +48,13 @@
= hidden_field_tag "filter", h(params[:filter])
.search-holder
.search-field-holder
- = search_field_tag :search_query, params[:search_query], placeholder: s_('AdminUsers|Search by name, email or username'), class: 'form-control search-text-input js-search-input', spellcheck: false
+ = search_field_tag :search_query, params[:search_query], placeholder: s_('AdminUsers|Search by name, email or username'), class: 'form-control search-text-input js-search-input', spellcheck: false, data: { qa_selector: 'user_search_field' }
- if @sort.present?
= hidden_field_tag :sort, @sort
= icon("search", class: "search-icon")
= button_tag s_('AdminUsers|Search users') if Rails.env.test?
.dropdown.user-sort-dropdown
+ = label_tag 'Sort by', nil, class: 'label-bold'
- toggle_text = @sort.present? ? users_sort_options_hash[@sort] : sort_title_name
= dropdown_toggle(toggle_text, { toggle: 'dropdown' })
%ul.dropdown-menu.dropdown-menu-right
@@ -74,4 +79,4 @@
= paginate @users, theme: "gitlab"
-#delete-user-modal
+= render partial: 'admin/users/modals'
diff --git a/app/views/admin/users/show.html.haml b/app/views/admin/users/show.html.haml
index a988f746ced..706fa033c51 100644
--- a/app/views/admin/users/show.html.haml
+++ b/app/views/admin/users/show.html.haml
@@ -156,6 +156,27 @@
= render_if_exists 'admin/users/user_detail_note'
+ - if @user.deactivated?
+ .card.border-info
+ .card-header.bg-info.text-white
+ Reactivate this user
+ .card-body
+ = render partial: 'admin/users/user_activation_effects'
+ %br
+ = link_to 'Activate user', activate_admin_user_path(@user), method: :put, class: "btn btn-info", data: { confirm: 'Are you sure?' }
+ - elsif @user.can_be_deactivated?
+ .card.border-warning
+ .card-header.bg-warning.text-white
+ Deactivate this user
+ .card-body
+ = render partial: 'admin/users/user_deactivation_effects'
+ %br
+ %button.btn.btn-warning{ data: { 'gl-modal-action': 'deactivate',
+ content: 'You can always re-activate their account, their data will remain intact.',
+ url: deactivate_admin_user_path(@user),
+ username: sanitize_name(@user.name) } }
+ = s_('AdminUsers|Deactivate user')
+
- if @user.blocked?
.card.border-info
.card-header.bg-info.text-white
@@ -172,14 +193,13 @@
.card-header.bg-warning.text-white
Block this user
.card-body
- %p Blocking user has the following effects:
- %ul
- %li User will not be able to login
- %li User will not be able to access git repositories
- %li Personal projects will be left
- %li Owned groups will be left
+ = render partial: 'admin/users/user_block_effects'
%br
- = link_to 'Block user', block_admin_user_path(@user), data: { confirm: 'USER WILL BE BLOCKED! Are you sure?' }, method: :put, class: "btn btn-warning"
+ %button.btn.btn-warning{ data: { 'gl-modal-action': 'block',
+ content: 'You can always unblock their account, their data will remain intact.',
+ url: block_admin_user_path(@user),
+ username: sanitize_name(@user.name) } }
+ = s_('AdminUsers|Block user')
- if @user.access_locked?
.card.border-info
.card-header.bg-info.text-white
@@ -197,12 +217,10 @@
%p Deleting a user has the following effects:
= render 'users/deletion_guidance', user: @user
%br
- %button.delete-user-button.btn.btn-danger{ data: { toggle: 'modal',
- target: '#delete-user-modal',
+ %button.delete-user-button.btn.btn-danger{ data: { 'gl-modal-action': 'delete',
delete_user_url: admin_user_path(@user),
block_user_url: block_admin_user_path(@user),
- username: @user.name,
- delete_contributions: false }, type: 'button' }
+ username: sanitize_name(@user.name) } }
= s_('AdminUsers|Delete user')
- else
- if @user.solo_owned_groups.present?
@@ -229,15 +247,13 @@
the user, and projects in them, will also be removed. Commits
to other projects are unaffected.
%br
- %button.delete-user-button.btn.btn-danger{ data: { toggle: 'modal',
- target: '#delete-user-modal',
+ %button.delete-user-button.btn.btn-danger{ data: { 'gl-modal-action': 'delete-with-contributions',
delete_user_url: admin_user_path(@user, hard_delete: true),
block_user_url: block_admin_user_path(@user),
- username: @user.name,
- delete_contributions: true }, type: 'button' }
+ username: @user.name } }
= s_('AdminUsers|Delete user and contributions')
- else
%p
You don't have access to delete this user.
- #delete-user-modal
+= render partial: 'admin/users/modals'
diff --git a/app/views/ci/runner/_how_to_setup_runner.html.haml b/app/views/ci/runner/_how_to_setup_runner.html.haml
index 4307060d748..aca8aa5d341 100644
--- a/app/views/ci/runner/_how_to_setup_runner.html.haml
+++ b/app/views/ci/runner/_how_to_setup_runner.html.haml
@@ -8,11 +8,11 @@
%li
= _("Specify the following URL during the Runner setup:")
%code#coordinator_address= root_url(only_path: false)
- = clipboard_button(target: '#coordinator_address', title: _("Copy URL to clipboard"), class: "btn-transparent btn-clipboard")
+ = clipboard_button(target: '#coordinator_address', title: _("Copy URL"), class: "btn-transparent btn-clipboard")
%li
= _("Use the following registration token during setup:")
%code#registration_token= registration_token
- = clipboard_button(target: '#registration_token', title: _("Copy token to clipboard"), class: "btn-transparent btn-clipboard")
+ = clipboard_button(target: '#registration_token', title: _("Copy token"), class: "btn-transparent btn-clipboard")
.prepend-top-10.append-bottom-10
= button_to _("Reset runners registration token"), reset_token_url,
method: :put, class: 'btn btn-default',
diff --git a/app/views/ci/runner/_how_to_setup_runner_automatically.html.haml b/app/views/ci/runner/_how_to_setup_runner_automatically.html.haml
new file mode 100644
index 00000000000..58d2ef5d5e6
--- /dev/null
+++ b/app/views/ci/runner/_how_to_setup_runner_automatically.html.haml
@@ -0,0 +1,22 @@
+.append-bottom-10
+ %h4= _('Set up a %{type} Runner automatically') % { type: type }
+
+%p
+ - link_to_help_page = link_to(_('Learn more about Kubernetes'),
+ help_page_path('user/project/clusters/index'),
+ target: '_blank',
+ rel: 'noopener noreferrer')
+
+ = _('You can easily install a Runner on a Kubernetes cluster. %{link_to_help_page}').html_safe % { link_to_help_page: link_to_help_page }
+
+%ol
+ %li
+ = _('Click the button below to begin the install process by navigating to the Kubernetes page')
+ %li
+ = _('Select an existing Kubernetes cluster or create a new one')
+ %li
+ = _('From the Kubernetes cluster details view, install Runner from the applications list')
+
+= link_to _('Install Runner on Kubernetes'),
+ clusters_path,
+ class: 'btn btn-info'
diff --git a/app/views/ci/variables/_variable_row.html.haml b/app/views/ci/variables/_variable_row.html.haml
index ed4bd5ae19e..ed9b3ab1940 100644
--- a/app/views/ci/variables/_variable_row.html.haml
+++ b/app/views/ci/variables/_variable_row.html.haml
@@ -30,7 +30,7 @@
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
- .form-control.js-secret-value-placeholder.qa-ci-variable-input-value{ class: ('hide' unless id) }
+ .form-control.js-secret-value-placeholder.qa-ci-variable-input-value.overflow-hidden{ class: ('hide' unless id) }
= '*' * 17
%textarea.js-ci-variable-input-value.js-secret-value.qa-ci-variable-input-value.form-control{ class: ('hide' if id),
rows: 1,
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 f707c6585ec..d4999798c19 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
@@ -3,6 +3,6 @@
- label = local_assigns.fetch(:label)
= 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
- = image_tag logo_path, alt: label, class: 'gl-w-13 gl-h-13'
+ .svg-content= image_tag logo_path, alt: label, class: 'gl-w-13 gl-h-13'
%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 24506205243..7a93a7604f5 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
@@ -6,6 +6,6 @@
= create_cluster_label
.d-flex
= render partial: 'clusters/clusters/cloud_providers/cloud_provider_button',
- locals: { provider: 'gke', label: gke_label, logo_path: '' }
+ locals: { provider: 'eks', label: eks_label, logo_path: 'illustrations/logos/amazon_eks.svg' }
= render partial: 'clusters/clusters/cloud_providers/cloud_provider_button',
- locals: { provider: 'eks', label: eks_label, logo_path: '' }
+ locals: { provider: 'gke', label: gke_label, logo_path: 'illustrations/logos/google_gke.svg' }
diff --git a/app/views/clusters/clusters/eks/_index.html.haml b/app/views/clusters/clusters/eks/_index.html.haml
index ca8e9ba527a..db64698a7f2 100644
--- a/app/views/clusters/clusters/eks/_index.html.haml
+++ b/app/views/clusters/clusters/eks/_index.html.haml
@@ -1 +1,2 @@
-.js-create-eks-cluster-form-container
+.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 4d3e3359ea0..cca16ce7eda 100644
--- a/app/views/clusters/clusters/gcp/_form.html.haml
+++ b/app/views/clusters/clusters/gcp/_form.html.haml
@@ -3,13 +3,12 @@
- zones_link_url = 'https://cloud.google.com/compute/docs/regions-zones/regions-zones'
- machine_type_link_url = 'https://cloud.google.com/compute/docs/machine-types'
- pricing_link_url = 'https://cloud.google.com/compute/pricing#machinetype'
+- kubernetes_integration_url = help_page_path('user/project/clusters/index')
- help_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe
- help_link_end = ' %{external_link_icon}</a>'.html_safe % { external_link_icon: external_link_icon }
%p
- - link_to_help_page = link_to(s_('ClusterIntegration|help page'),
- help_page_path('user/project/clusters/index'), target: '_blank', rel: 'noopener noreferrer')
- = s_('ClusterIntegration|Read our %{link_to_help_page} on Kubernetes cluster integration.').html_safe % { link_to_help_page: link_to_help_page }
+ = s_('ClusterIntegration|Read our %{link_start}help page%{link_end} on Kubernetes cluster integration.').html_safe % { link_start: help_link_start % { url: kubernetes_integration_url }, link_end: '</a>'.html_safe }
%p= link_to('Select a different Google account', @authorize_url)
@@ -65,6 +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'
+
.form-group
= field.check_box :managed, { label: s_('ClusterIntegration|GitLab-managed cluster'),
label_class: 'label-bold' }
diff --git a/app/views/clusters/clusters/gcp/_gcp_not_configured.html.haml b/app/views/clusters/clusters/gcp/_gcp_not_configured.html.haml
new file mode 100644
index 00000000000..b57e45e9812
--- /dev/null
+++ b/app/views/clusters/clusters/gcp/_gcp_not_configured.html.haml
@@ -0,0 +1,3 @@
+- documentation_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: help_page_path("integration/google") }
+- link_end = '<a/>'.html_safe
+= s_('Google authentication is not %{link_start}property configured%{link_end}. Ask your GitLab administrator if you want to use this service.').html_safe % { link_start: documentation_link_start, link_end: link_end }
diff --git a/app/views/clusters/clusters/gcp/_signin_with_google_button.html.haml b/app/views/clusters/clusters/gcp/_signin_with_google_button.html.haml
new file mode 100644
index 00000000000..65cfa6552b1
--- /dev/null
+++ b/app/views/clusters/clusters/gcp/_signin_with_google_button.html.haml
@@ -0,0 +1,4 @@
+.signin-with-google
+ - create_account_link = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: 'https://accounts.google.com/SignUpWithoutGmail?service=cloudconsole&continue=https%3A%2F%2Fconsole.cloud.google.com%2Ffreetrial%3Futm_campaign%3D2018_cpanel%26utm_source%3Dgitlab%26utm_medium%3Dreferral' }
+ = link_to(image_tag('auth_buttons/signin_with_google.png', width: '191px', alt: _('Sign in with Google')), @authorize_url)
+ = s_('or %{link_start}create a new Google account%{link_end}').html_safe % { link_start: create_account_link, link_end: '</a>'.html_safe }
diff --git a/app/views/clusters/clusters/new.html.haml b/app/views/clusters/clusters/new.html.haml
index fb182d99ff0..2c23426aaf9 100644
--- a/app/views/clusters/clusters/new.html.haml
+++ b/app/views/clusters/clusters/new.html.haml
@@ -2,7 +2,9 @@
- page_title _('Kubernetes Cluster')
- create_eks_enabled = Feature.enabled?(:create_eks_clusters)
- active_tab = local_assigns.fetch(:active_tab, 'create')
-- link_end = '<a/>'.html_safe
+- 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
@@ -14,7 +16,16 @@
%ul.nav-links.nav-tabs.gitlab-tabs.nav{ role: 'tablist' }
%li.nav-item{ role: 'presentation' }
%a.nav-link{ href: '#create-cluster-pane', id: 'create-cluster-tab', class: active_when(active_tab == 'create'), data: { toggle: 'tab' }, role: 'tab' }
- %span Create new Cluster on GKE
+ %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
+ - else
+ = create_on_gke_tab_label
%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
@@ -22,9 +33,14 @@
.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 && @valid_gcp_token
+ - if @gke_selected
= render 'clusters/clusters/gcp/header'
- = render 'clusters/clusters/gcp/form'
+ - 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
@@ -35,13 +51,9 @@
- if @valid_gcp_token
= render 'clusters/clusters/gcp/form'
- elsif @authorize_url
- .signin-with-google
- - create_account_link = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: 'https://accounts.google.com/SignUpWithoutGmail?service=cloudconsole&continue=https%3A%2F%2Fconsole.cloud.google.com%2Ffreetrial%3Futm_campaign%3D2018_cpanel%26utm_source%3Dgitlab%26utm_medium%3Dreferral' }
- = link_to(image_tag('auth_buttons/signin_with_google.png', width: '191px', alt: _('Sign in with Google')), @authorize_url)
- = s_('or %{link_start}create a new Google account%{link_end}').html_safe % { link_start: create_account_link, link_end: link_end }
+ = render 'clusters/clusters/gcp/signin_with_google_button'
- else
- - documentation_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: help_page_path("integration/google") }
- = s_('Google authentication is not %{link_start}property configured%{link_end}. Ask your GitLab administrator if you want to use this service.').html_safe % { link_start: documentation_link_start, link_end: link_end }
+ = render 'clusters/clusters/gcp/gcp_not_configured'
.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 cccba48624b..31d5f592d75 100644
--- a/app/views/clusters/clusters/show.html.haml
+++ b/app/views/clusters/clusters/show.html.haml
@@ -23,12 +23,15 @@
cluster_type: @cluster.cluster_type,
cluster_status: @cluster.status_name,
cluster_status_reason: @cluster.status_reason,
+ provider_type: @cluster.provider_type,
+ pre_installed_knative: @cluster.knative_pre_installed? ? 'true': 'false',
help_path: help_page_path('user/project/clusters/index.md', anchor: 'installing-applications'),
ingress_help_path: help_page_path('user/project/clusters/index.md', anchor: 'getting-the-external-endpoint'),
ingress_dns_help_path: help_page_path('user/project/clusters/index.md', anchor: 'manually-determining-the-external-endpoint'),
environments_help_path: help_page_path('ci/environments', anchor: 'defining-environments'),
clusters_help_path: help_page_path('user/project/clusters/index.md', anchor: 'deploying-to-a-kubernetes-cluster'),
deploy_boards_help_path: help_page_path('user/project/deploy_boards.html', anchor: 'enabling-deploy-boards'),
+ cloud_run_help_path: help_page_path('user/project/clusters/index.md', anchor: 'cloud-run-on-gke'),
manage_prometheus_path: manage_prometheus_path,
cluster_id: @cluster.id } }
@@ -39,6 +42,6 @@
= render 'banner'
- if cluster_environments_path.present?
- = render_if_exists 'clusters/clusters/group_cluster_environments', expanded: expanded
+ = render_if_exists 'clusters/clusters/cluster_environments', expanded: expanded
- else
= render 'configure', expanded: expanded
diff --git a/app/views/dashboard/projects/_blank_state_admin_welcome.html.haml b/app/views/dashboard/projects/_blank_state_admin_welcome.html.haml
index c50b20a83dc..6e7ec1264ea 100644
--- a/app/views/dashboard/projects/_blank_state_admin_welcome.html.haml
+++ b/app/views/dashboard/projects/_blank_state_admin_welcome.html.haml
@@ -1,41 +1,40 @@
.blank-state-row
- = link_to new_project_path, class: "blank-state-link" do
- .blank-state
+ - if has_start_trial?
+ = render_if_exists "dashboard/projects/blank_state_ee_trial"
+
+ = link_to new_project_path, class: "blank-state blank-state-link" do
+ .blank-state-icon
+ = image_tag("illustrations/welcome/add_new_project")
+ .blank-state-body
+ %h3.blank-state-title
+ Create a project
+ %p.blank-state-text
+ Projects are where you store your code, access issues, wiki and other features of GitLab.
+
+ - if current_user.can_create_group?
+ = link_to new_group_path, class: "blank-state blank-state-link" do
.blank-state-icon
- = custom_icon("add_new_project", size: 50)
+ = image_tag("illustrations/welcome/add_new_group")
.blank-state-body
%h3.blank-state-title
- Create a project
+ Create a group
%p.blank-state-text
- Projects are where you store your code, access issues, wiki and other features of GitLab.
+ Groups are a great way to organize projects and people.
- - if current_user.can_create_group?
- = link_to new_group_path, class: "blank-state-link" do
- .blank-state
- .blank-state-icon
- = custom_icon("add_new_group", size: 50)
- .blank-state-body
- %h3.blank-state-title
- Create a group
- %p.blank-state-text
- Groups are a great way to organize projects and people.
-
- = link_to new_admin_user_path, class: "blank-state-link" do
- .blank-state
- .blank-state-icon
- = custom_icon("add_new_user", size: 50)
- .blank-state-body
- %h3.blank-state-title
- Add people
- %p.blank-state-text
- Add your team members and others to GitLab.
-
- = link_to admin_root_path, class: "blank-state-link" do
- .blank-state
+ = link_to new_admin_user_path, class: "blank-state blank-state-link" do
.blank-state-icon
- = custom_icon("configure_server", size: 50)
+ = image_tag("illustrations/welcome/add_new_user")
.blank-state-body
%h3.blank-state-title
- Configure GitLab
+ Add people
%p.blank-state-text
- Make adjustments to how your GitLab instance is set up.
+ Add your team members and others to GitLab.
+
+ = link_to admin_root_path, class: "blank-state blank-state-link" do
+ .blank-state-icon
+ = image_tag("illustrations/welcome/configure_server")
+ .blank-state-body
+ %h3.blank-state-title
+ Configure GitLab
+ %p.blank-state-text
+ Make adjustments to how your GitLab instance is set up.
diff --git a/app/views/dashboard/projects/_blank_state_welcome.html.haml b/app/views/dashboard/projects/_blank_state_welcome.html.haml
index 8d5bddbb288..e3af3405b76 100644
--- a/app/views/dashboard/projects/_blank_state_welcome.html.haml
+++ b/app/views/dashboard/projects/_blank_state_welcome.html.haml
@@ -2,19 +2,18 @@
.blank-state-row
- if current_user.can_create_project?
- = link_to new_project_path, class: "blank-state-link" do
- .blank-state
- .blank-state-icon
- = custom_icon("add_new_project", size: 50)
- .blank-state-body
- %h3.blank-state-title
- Create a project
- %p.blank-state-text
- Projects are where you store your code, access issues, wiki and other features of GitLab.
+ = link_to new_project_path, class: "blank-state blank-state-link" do
+ .blank-state-icon
+ = image_tag("illustrations/welcome/add_new_project")
+ .blank-state-body
+ %h3.blank-state-title
+ Create a project
+ %p.blank-state-text
+ Projects are where you store your code, access issues, wiki and other features of GitLab.
- else
.blank-state
.blank-state-icon
- = custom_icon("add_new_project", size: 50)
+ = image_tag("illustrations/welcome/add_new_project")
.blank-state-body
%h3.blank-state-title
Create a project
@@ -22,37 +21,34 @@
If you are added to a project, it will be displayed here.
- if current_user.can_create_group?
- = link_to new_group_path, class: "blank-state-link" do
- .blank-state
- .blank-state-icon
- = custom_icon("add_new_group", size: 50)
- .blank-state-body
- %h3.blank-state-title
- Create a group
- %p.blank-state-text
- Groups are the best way to manage projects and members.
+ = link_to new_group_path, class: "blank-state blank-state-link" do
+ .blank-state-icon
+ = image_tag("illustrations/welcome/add_new_group")
+ .blank-state-body
+ %h3.blank-state-title
+ Create a group
+ %p.blank-state-text
+ Groups are the best way to manage projects and members.
- if public_project_count > 0
- = link_to trending_explore_projects_path, class: "blank-state-link" do
- .blank-state
- .blank-state-icon
- = custom_icon("globe", size: 50)
- .blank-state-body
- %h3.blank-state-title
- Explore public projects
- %p.blank-state-text
- There are
- = number_with_delimiter(public_project_count)
- public projects on this server.
- Public projects are an easy way to allow
- everyone to have read-only access.
-
- = link_to "https://docs.gitlab.com/", class: "blank-state-link" do
- .blank-state
+ = link_to trending_explore_projects_path, class: "blank-state blank-state-link" do
.blank-state-icon
- = custom_icon("lightbulb", size: 50)
+ = image_tag("illustrations/welcome/globe")
.blank-state-body
%h3.blank-state-title
- Learn more about GitLab
+ Explore public projects
%p.blank-state-text
- Take a look at the documentation to discover all of GitLab's capabilities.
+ There are
+ = number_with_delimiter(public_project_count)
+ public projects on this server.
+ Public projects are an easy way to allow
+ everyone to have read-only access.
+
+ = link_to "https://docs.gitlab.com/", class: "blank-state blank-state-link" do
+ .blank-state-icon
+ = image_tag("illustrations/welcome/lightbulb")
+ .blank-state-body
+ %h3.blank-state-title
+ Learn more about GitLab
+ %p.blank-state-text
+ Take a look at the documentation to discover all of GitLab's capabilities.
diff --git a/app/views/dashboard/projects/_zero_authorized_projects.html.haml b/app/views/dashboard/projects/_zero_authorized_projects.html.haml
index 8933c5d7227..a2b1f0d9298 100644
--- a/app/views/dashboard/projects/_zero_authorized_projects.html.haml
+++ b/app/views/dashboard/projects/_zero_authorized_projects.html.haml
@@ -1,18 +1,13 @@
-.blank-state-parent-container{ class: ('has-start-trial-container' if has_start_trial?) }
+.blank-state-parent-container
.section-container.section-welcome{ class: "#{ 'section-admin-welcome' if current_user.admin? }" }
.container.section-body
.row
- .blank-state-welcome
+ .blank-state-welcome.w-100
%h2.blank-state-welcome-title
- Welcome to GitLab
+ = _('Welcome to GitLab')
%p.blank-state-text
- Code, test, and deploy together
- .blank-state-row
- %div{ class: ('column-large' if has_start_trial?) }
- - if current_user.admin?
- = render "blank_state_admin_welcome"
- - else
- = render "blank_state_welcome"
- - if has_start_trial?
- .column-small
- = render_if_exists "blank_state_ee_trial"
+ = _('Faster releases. Better code. Less pain.')
+ - if current_user.admin?
+ = render "blank_state_admin_welcome"
+ - else
+ = render "blank_state_welcome"
diff --git a/app/views/dashboard/snippets/index.html.haml b/app/views/dashboard/snippets/index.html.haml
index b649fe91c24..2caa8e0cac4 100644
--- a/app/views/dashboard/snippets/index.html.haml
+++ b/app/views/dashboard/snippets/index.html.haml
@@ -6,10 +6,6 @@
- if current_user.snippets.exists?
= render partial: 'snippets/snippets_scope_menu', locals: { include_private: true }
-.d-block.d-sm-none
- &nbsp;
- = link_to _("New snippet"), new_snippet_path, class: "btn btn-success btn-block", title: _("New snippet")
-
- if current_user.snippets.exists?
= render partial: 'shared/snippets/list', locals: { link_project: true }
- else
diff --git a/app/views/devise/registrations/new.html.haml b/app/views/devise/registrations/new.html.haml
index 42cfbbf84f2..5f85235e8fa 100644
--- a/app/views/devise/registrations/new.html.haml
+++ b/app/views/devise/registrations/new.html.haml
@@ -1,4 +1,7 @@
- page_title "Sign up"
-= render 'devise/shared/signup_box'
+- if experiment_enabled?(:signup_flow)
+ = render 'devise/shared/experimental_separate_sign_up_flow_box'
+- else
+ = render 'devise/shared/signup_box'
= render 'devise/shared/sign_in_link'
diff --git a/app/views/devise/sessions/new.html.haml b/app/views/devise/sessions/new.html.haml
index 30ed7ed6b29..8f6c3ecbe58 100644
--- a/app/views/devise/sessions/new.html.haml
+++ b/app/views/devise/sessions/new.html.haml
@@ -4,7 +4,8 @@
- if form_based_providers.any?
= render 'devise/shared/tabs_ldap'
- else
- = render 'devise/shared/tabs_normal'
+ - unless experiment_enabled?(:signup_flow)
+ = render 'devise/shared/tabs_normal'
.tab-content
- if password_authentication_enabled_for_web? || ldap_enabled? || crowd_enabled?
= render 'devise/shared/signin_box'
diff --git a/app/views/devise/shared/_experimental_separate_sign_up_flow_box.html.haml b/app/views/devise/shared/_experimental_separate_sign_up_flow_box.html.haml
new file mode 100644
index 00000000000..5d163d03c73
--- /dev/null
+++ b/app/views/devise/shared/_experimental_separate_sign_up_flow_box.html.haml
@@ -0,0 +1,31 @@
+- content_for(:page_title, _('Register for GitLab'))
+- max_username_length = 255
+.signup-box.p-3.mb-2
+ .signup-body
+ = form_for(resource, as: "new_#{resource_name}", url: registration_path(resource_name), html: { class: "new_new_user gl-show-field-errors", "aria-live" => "assertive" }) do |f|
+ .devise-errors.mt-0
+ = render "devise/shared/error_messages", resource: resource
+ = invisible_captcha
+ .username.form-group
+ = f.label :username, class: 'label-bold'
+ = f.text_field :username, class: "form-control middle js-block-emoji js-validate-length js-validate-username", :data => { :max_length => max_username_length, :max_length_message => s_("SignUp|Username is too long (maximum is %{max_length} characters).") % { max_length: max_username_length }, :qa_selector => 'new_user_username_field' }, pattern: Gitlab::PathRegex::NAMESPACE_FORMAT_REGEX_JS, required: true, title: _("Please create a username with only alphanumeric characters.")
+ %p.validation-error.gl-field-error-ignore.field-validation.mt-1.hide.cred= _('Username is already taken.')
+ %p.validation-success.gl-field-error-ignore.field-validation.mt-1.hide.cgreen= _('Username is available.')
+ %p.validation-pending.gl-field-error-ignore.field-validation.mt-1.hide= _('Checking username availability...')
+ .form-group
+ = f.label :email, class: 'label-bold'
+ = f.email_field :email, class: "form-control middle", data: { qa_selector: 'new_user_email_field' }, required: true, title: _("Please provide a valid email address.")
+ .form-group.append-bottom-20#password-strength
+ = f.label :password, class: 'label-bold'
+ = f.password_field :password, class: "form-control bottom", data: { qa_selector: 'new_user_password_field' }, required: true, pattern: ".{#{@minimum_password_length},}", title: _("Minimum length is %{minimum_password_length} characters.") % { minimum_password_length: @minimum_password_length }
+ %p.gl-field-hint.text-secondary= _('Minimum length is %{minimum_password_length} characters') % { minimum_password_length: @minimum_password_length }
+ - if Gitlab::CurrentSettings.current_application_settings.enforce_terms?
+ .form-group
+ = check_box_tag :terms_opt_in, '1', false, required: true, data: { qa_selector: 'new_user_accept_terms_checkbox' }
+ = label_tag :terms_opt_in do
+ - terms_link = link_to s_("I accept the|Terms of Service and Privacy Policy"), terms_path, target: "_blank"
+ - accept_terms_label = _("I accept the %{terms_link}") % { terms_link: terms_link }
+ = accept_terms_label.html_safe
+ = render_if_exists 'devise/shared/email_opted_in', f: f
+ .submit-container.mt-3
+ = f.submit _("Register"), class: "btn-register btn btn-block btn-success mb-0 p-2", data: { qa_selector: 'new_user_register_button' }
diff --git a/app/views/devise/shared/_sign_in_link.html.haml b/app/views/devise/shared/_sign_in_link.html.haml
index 77ef103cc47..9a7d8a0a160 100644
--- a/app/views/devise/shared/_sign_in_link.html.haml
+++ b/app/views/devise/shared/_sign_in_link.html.haml
@@ -1,4 +1,4 @@
-%p
+%p.text-center
%span.light
Already have login and password?
= link_to "Sign in", new_session_path(:user, redirect_to_referer: 'yes')
diff --git a/app/views/devise/shared/_signin_box.html.haml b/app/views/devise/shared/_signin_box.html.haml
index f8f36a8bfff..746d43edbad 100644
--- a/app/views/devise/shared/_signin_box.html.haml
+++ b/app/views/devise/shared/_signin_box.html.haml
@@ -22,3 +22,8 @@
.login-box.tab-pane.active{ id: 'login-pane', role: 'tabpanel' }
.login-body
= render 'devise/sessions/new_base'
+
+- if experiment_enabled?(:signup_flow)
+ %p.light.mt-2
+ = _("Don't have an account yet?")
+ = link_to _("Register now"), new_registration_path(:user)
diff --git a/app/views/doorkeeper/applications/show.html.haml b/app/views/doorkeeper/applications/show.html.haml
index 6750732ab67..8a1b7500abf 100644
--- a/app/views/doorkeeper/applications/show.html.haml
+++ b/app/views/doorkeeper/applications/show.html.haml
@@ -16,7 +16,7 @@
.input-group
%input.label.label-monospace.monospace{ id: "application_id", type: "text", autocomplete: 'off', value: @application.uid, readonly: true }
.input-group-append
- = clipboard_button(target: '#application_id', title: _("Copy ID to clipboard"), class: "btn btn btn-default")
+ = clipboard_button(target: '#application_id', title: _("Copy ID"), class: "btn btn btn-default")
%tr
%td
= _('Secret')
@@ -25,7 +25,7 @@
.input-group
%input.label.label-monospace.monospace{ id: "secret", type: "text", autocomplete: 'off', value: @application.secret, readonly: true }
.input-group-append
- = clipboard_button(target: '#secret', title: _("Copy secret to clipboard"), class: "btn btn btn-default")
+ = clipboard_button(target: '#secret', title: _("Copy secret"), class: "btn btn btn-default")
%tr
%td
= _('Callback URL')
diff --git a/app/views/events/event/_push.html.haml b/app/views/events/event/_push.html.haml
index 21c418cb0e4..b9e88f3fc47 100644
--- a/app/views/events/event/_push.html.haml
+++ b/app/views/events/event/_push.html.haml
@@ -6,11 +6,13 @@
.event-title.d-flex.flex-wrap
= inline_event_icon(event)
- %span.event-type.d-inline-block.append-right-4.pushed #{event.action_name} #{event.ref_type}
- %span.append-right-4
- - commits_link = project_commits_path(project, event.ref_name)
- - should_link = event.tag? ? project.repository.tag_exists?(event.ref_name) : project.repository.branch_exists?(event.ref_name)
- = link_to_if should_link, event.ref_name, commits_link, class: 'ref-name'
+ - many_refs = event.ref_count.to_i > 1
+ %span.event-type.d-inline-block.append-right-4.pushed= many_refs ? "#{event.action_name} #{event.ref_count} #{event.ref_type.pluralize}" : "#{event.action_name} #{event.ref_type}"
+ - unless many_refs
+ %span.append-right-4
+ - commits_link = project_commits_path(project, event.ref_name)
+ - should_link = event.tag? ? project.repository.tag_exists?(event.ref_name) : project.repository.branch_exists?(event.ref_name)
+ = link_to_if should_link, event.ref_name, commits_link, class: 'ref-name'
= render "events/event_scope", event: event
diff --git a/app/views/groups/_activities.html.haml b/app/views/groups/_activities.html.haml
index 13df1e57125..44554cab1e9 100644
--- a/app/views/groups/_activities.html.haml
+++ b/app/views/groups/_activities.html.haml
@@ -1,5 +1,5 @@
.nav-block.activities
- = render 'shared/event_filter'
+ = render 'shared/event_filter', show_group_events: @group.supports_events?
.controls
= link_to group_path(@group, rss_url_options), class: 'btn d-none d-sm-inline-block has-tooltip' , title: 'Subscribe' do
%i.fa.fa-rss
diff --git a/app/views/groups/_create_chat_team.html.haml b/app/views/groups/_create_chat_team.html.haml
index 561e68a9155..2531993a095 100644
--- a/app/views/groups/_create_chat_team.html.haml
+++ b/app/views/groups/_create_chat_team.html.haml
@@ -8,7 +8,7 @@
.form-check.js-toggle-container
.js-toggle-button.form-check-input= f.check_box(:create_chat_team, { checked: true }, true, false)
= f.label :create_chat_team, class: 'form-check-label' do
- Create a Mattermost team for this group
+ = _('Create a Mattermost team for this group')
%br
%small.light.js-toggle-content
Mattermost URL:
diff --git a/app/views/groups/edit.html.haml b/app/views/groups/edit.html.haml
index 6d06bb246cb..0e78ce9f656 100644
--- a/app/views/groups/edit.html.haml
+++ b/app/views/groups/edit.html.haml
@@ -1,4 +1,4 @@
-- breadcrumb_title "General Settings"
+- breadcrumb_title _("General Settings")
- @content_class = "limit-container-width" unless fluid_layout
- expanded = expanded_by_default?
@@ -32,7 +32,7 @@
%h4.settings-title.js-settings-toggle.js-settings-toggle-trigger-only{ role: 'button' }
= s_('GroupSettings|Badges')
%button.btn.js-settings-toggle{ type: 'button' }
- = expanded ? 'Collapse' : 'Expand'
+ = expanded ? _('Collapse') : _('Expand')
%p
= s_('GroupSettings|Customize your group badges.')
= link_to s_('GroupSettings|Learn more about badges.'), help_page_path('user/project/badges')
diff --git a/app/views/groups/new.html.haml b/app/views/groups/new.html.haml
index 06e05d898d6..376624f4786 100644
--- a/app/views/groups/new.html.haml
+++ b/app/views/groups/new.html.haml
@@ -40,5 +40,5 @@
= render 'create_chat_team', f: f if Gitlab.config.mattermost.enabled
.form-actions
- = f.submit 'Create group', class: "btn btn-success"
- = link_to 'Cancel', dashboard_groups_path, class: 'btn btn-cancel'
+ = f.submit _('Create group'), class: "btn btn-success"
+ = link_to _('Cancel'), dashboard_groups_path, class: 'btn btn-cancel'
diff --git a/app/views/groups/projects.html.haml b/app/views/groups/projects.html.haml
index ba186875a86..8b01e54474a 100644
--- a/app/views/groups/projects.html.haml
+++ b/app/views/groups/projects.html.haml
@@ -8,21 +8,38 @@
.controls
= link_to new_project_path(namespace_id: @group.id), class: "btn btn-sm btn-success" do
New project
- %ul.content-list
+ %ul.projects-list.content-list.group-settings-projects
- @projects.each do |project|
- %li
- .list-item-name
- %span{ class: visibility_level_color(project.visibility_level) }
- = visibility_level_icon(project.visibility_level)
- %strong= link_to project.full_name, project
- .float-right
+ %li.project-row{ class: ('no-description' if project.description.blank?) }
+ .controls
+ = link_to _('Members'), project_project_members_path(project), id: "edit_#{dom_id(project)}", class: "btn"
+ = link_to _('Edit'), edit_project_path(project), id: "edit_#{dom_id(project)}", class: "btn"
+ = link_to _('Remove'), project, data: { confirm: remove_project_message(project)}, method: :delete, class: "btn btn-remove"
+
+ .stats
+ %span.badge.badge-pill
+ = storage_counter(project.statistics&.storage_size)
- if project.archived
%span.badge.badge-warning archived
- %span.badge.badge-pill
- = storage_counter(project.statistics.storage_size)
- = link_to 'Members', project_project_members_path(project), id: "edit_#{dom_id(project)}", class: "btn btn-sm"
- = link_to 'Edit', edit_project_path(project), id: "edit_#{dom_id(project)}", class: "btn btn-sm"
- = link_to 'Remove', project, data: { confirm: remove_project_message(project)}, method: :delete, class: "btn btn-sm btn-remove"
+
+ .title
+ = link_to(project_path(project)) do
+ .dash-project-avatar
+ .avatar-container.rect-avatar.s40
+ = project_icon(project, alt: '', class: 'avatar project-avatar s40', width: 40, height: 40)
+ %span.project-full-name
+ %span.namespace-name
+ - if project.namespace
+ = project.namespace.human_name
+ \/
+ %span.project-name
+ = project.name
+ %span{ class: visibility_level_color(project.visibility_level) }
+ = visibility_level_icon(project.visibility_level)
+
+ - if project.description.present?
+ .description
+ = markdown_field(project, :description)
- if @projects.blank?
.nothing-here-block This group has no projects yet
diff --git a/app/views/groups/registry/repositories/index.html.haml b/app/views/groups/registry/repositories/index.html.haml
new file mode 100644
index 00000000000..e85b0713230
--- /dev/null
+++ b/app/views/groups/registry/repositories/index.html.haml
@@ -0,0 +1,12 @@
+- page_title _("Container Registry")
+
+%section
+ .row.registry-placeholder.prepend-bottom-10
+ .col-12
+ #js-vue-registry-images{ data: { endpoint: group_container_registries_path(@group, format: :json),
+ "help_page_path" => help_page_path('user/packages/container_registry/index'),
+ "no_containers_image" => image_path('illustrations/docker-empty-state.svg'),
+ "containers_error_image" => image_path('illustrations/docker-error-state.svg'),
+ "repository_url" => "",
+ is_group_page: true,
+ character_error: @character_error.to_s } }
diff --git a/app/views/groups/runners/_group_runners.html.haml b/app/views/groups/runners/_group_runners.html.haml
index fd40ec5a984..f752bc0a702 100644
--- a/app/views/groups/runners/_group_runners.html.haml
+++ b/app/views/groups/runners/_group_runners.html.haml
@@ -10,6 +10,10 @@
-# Proper policies should be implemented per
-# https://gitlab.com/gitlab-org/gitlab-foss/issues/45894
- if can?(current_user, :admin_pipeline, @group)
+ = render partial: 'ci/runner/how_to_setup_runner_automatically',
+ locals: { type: 'group',
+ clusters_path: group_clusters_path(@group) }
+ %hr
= render partial: 'ci/runner/how_to_setup_runner',
locals: { registration_token: @group.runners_token,
type: 'group',
diff --git a/app/views/groups/settings/_advanced.html.haml b/app/views/groups/settings/_advanced.html.haml
index 64fec260f3b..307309c6ca3 100644
--- a/app/views/groups/settings/_advanced.html.haml
+++ b/app/views/groups/settings/_advanced.html.haml
@@ -1,12 +1,12 @@
.sub-section
- %h4.warning-title Change group path
+ %h4.warning-title= s_('GroupSettings|Change group path')
= form_for @group, html: { multipart: true, class: 'gl-show-field-errors' }, authenticity_token: true do |f|
= form_errors(@group)
.form-group
%p
- Changing group path can have unintended side effects.
+ = s_('GroupSettings|Changing group path can have unintended side effects.')
= succeed '.' do
- = link_to 'Learn more', help_page_path('user/group/index', anchor: 'changing-a-groups-path'), target: '_blank'
+ = link_to _('Learn more'), help_page_path('user/group/index', anchor: 'changing-a-groups-path'), target: '_blank'
.input-group.gl-field-error-anchor
.group-root-path.input-group-prepend.has-tooltip{ title: group_path(@group), :'data-placement' => 'bottom' }
@@ -18,24 +18,26 @@
= f.text_field :path, placeholder: 'open-source', class: 'form-control',
autofocus: local_assigns[:autofocus] || false, required: true,
pattern: Gitlab::PathRegex::NAMESPACE_FORMAT_REGEX_JS,
- title: 'Please choose a group path with no special characters.',
+ title: s_('GroupSettings|Please choose a group path with no special characters.'),
"data-bind-in" => "#{'create_chat_team' if Gitlab.config.mattermost.enabled}"
- = f.submit 'Change group path', class: 'btn btn-warning'
+ = f.submit s_('GroupSettings|Change group path'), class: 'btn btn-warning'
.sub-section
- %h4.warning-title Transfer group
+ %h4.warning-title= s_('GroupSettings|Transfer group')
= form_for @group, url: transfer_group_path(@group), method: :put, html: { class: 'js-group-transfer-form' } do |f|
.form-group
= dropdown_tag('Select parent group', options: { toggle_class: 'js-groups-dropdown', title: 'Parent Group', filter: true, dropdown_class: 'dropdown-open-top dropdown-group-transfer', placeholder: 'Search groups', data: { data: parent_group_options(@group) } })
= hidden_field_tag 'new_parent_group_id'
%ul
- %li Be careful. Changing a group's parent can have unintended #{link_to 'side effects', 'https://docs.gitlab.com/ce/user/project/index.html#redirects-when-changing-repository-paths', target: 'blank'}.
- %li You can only transfer the group to a group you manage.
- %li You will need to update your local repositories to point to the new location.
- %li If the parent group's visibility is lower than the group current visibility, visibility levels for subgroups and projects will be changed to match the new parent group's visibility.
- = f.submit 'Transfer group', class: 'btn btn-warning'
+ - side_effects_link_start = '<a href="https://docs.gitlab.com/ce/user/project/index.html#redirects-when-changing-repository-paths" target="_blank">'
+ - warning_text = s_("GroupSettings|Be careful. Changing a group's parent can have unintended %{side_effects_link_start}side effects%{side_effects_link_end}.") % { side_effects_link_start: side_effects_link_start, side_effects_link_end:'</a>' }
+ %li= warning_text.html_safe
+ %li= s_('GroupSettings|You can only transfer the group to a group you manage.')
+ %li= s_('GroupSettings|You will need to update your local repositories to point to the new location.')
+ %li= s_("GroupSettings|If the parent group's visibility is lower than the group current visibility, visibility levels for subgroups and projects will be changed to match the new parent group's visibility.")
+ = f.submit s_('GroupSettings|Transfer group'), class: 'btn btn-warning'
.sub-section
%h4.danger-title= _('Remove group')
diff --git a/app/views/groups/settings/ci_cd/_form.html.haml b/app/views/groups/settings/ci_cd/_form.html.haml
new file mode 100644
index 00000000000..54e88d11827
--- /dev/null
+++ b/app/views/groups/settings/ci_cd/_form.html.haml
@@ -0,0 +1,13 @@
+.row.prepend-top-default
+ .col-lg-12
+ = form_for group, url: group_settings_ci_cd_path(group, anchor: 'js-general-pipeline-settings') do |f|
+ = form_errors(group)
+ %fieldset.builds-feature
+ .form-group
+ = f.label :max_artifacts_size, _('Maximum artifacts size (MB)'), class: 'label-bold'
+ = f.number_field :max_artifacts_size, class: 'form-control'
+ %p.form-text.text-muted
+ = _("Set the maximum file size for each job's artifacts")
+ = link_to icon('question-circle'), help_page_path('user/admin_area/settings/continuous_integration', anchor: 'maximum-artifacts-size-core-only'), target: '_blank'
+
+ = f.submit _('Save changes'), class: "btn btn-success"
diff --git a/app/views/groups/settings/ci_cd/show.html.haml b/app/views/groups/settings/ci_cd/show.html.haml
index d21496ee0aa..a3f35b72cc6 100644
--- a/app/views/groups/settings/ci_cd/show.html.haml
+++ b/app/views/groups/settings/ci_cd/show.html.haml
@@ -2,6 +2,21 @@
- page_title "CI / CD"
- expanded = expanded_by_default?
+- general_expanded = @group.errors.empty? ? expanded : true
+
+-# Given we only have one field in this form which is also admin-only,
+-# we don't want to show an empty section to non-admin users,
+- if can?(current_user, :update_max_artifacts_size, @group)
+ %section.settings#js-general-pipeline-settings.no-animate{ class: ('expanded' if general_expanded) }
+ .settings-header
+ %h4
+ = _("General pipelines")
+ %button.btn.js-settings-toggle{ type: 'button' }
+ = expanded ? _('Collapse') : _('Expand')
+ %p
+ = _("Customize your pipeline configuration.")
+ .settings-content
+ = render 'groups/settings/ci_cd/form', group: @group
%section.settings#ci-variables.no-animate{ class: ('expanded' if expanded) }
.settings-header
diff --git a/app/views/groups/show.html.haml b/app/views/groups/show.html.haml
index 0e6c16f0f06..457d05b4a97 100644
--- a/app/views/groups/show.html.haml
+++ b/app/views/groups/show.html.haml
@@ -5,6 +5,8 @@
= auto_discovery_link_tag(:atom, group_url(@group, rss_url_options), title: "#{@group.name} activity")
%div{ class: [("limit-container-width" unless fluid_layout)] }
+ = render_if_exists 'trials/banner', namespace: @group
+
= render 'groups/home_panel'
.groups-listing{ data: { endpoints: { default: group_children_path(@group, format: :json), shared: group_shared_projects_path(@group, format: :json) } } }
diff --git a/app/views/groups/sidebar/_packages.html.haml b/app/views/groups/sidebar/_packages.html.haml
new file mode 100644
index 00000000000..16b902a18b9
--- /dev/null
+++ b/app/views/groups/sidebar/_packages.html.haml
@@ -0,0 +1,16 @@
+- if group_container_registry_nav?
+ = nav_link(path: group_packages_nav_link_paths) do
+ = link_to group_container_registries_path(@group), title: _('Container Registry') do
+ .nav-icon-container
+ = sprite_icon('package')
+ %span.nav-item-name
+ = _('Packages')
+ %ul.sidebar-sub-level-items
+ = nav_link(controller: [:packages, :repositories], html_options: { class: "fly-out-top-item" } ) do
+ = link_to group_container_registries_path(@group), title: _('Container Registry') do
+ %strong.fly-out-top-item-name
+ = _('Packages')
+ %li.divider.fly-out-top-item
+ = nav_link(controller: 'groups/container_registries') do
+ = link_to group_container_registries_path(@group), title: _('Container Registry') do
+ %span= _('Container Registry')
diff --git a/app/views/help/instance_configuration/_ssh_info.html.haml b/app/views/help/instance_configuration/_ssh_info.html.haml
index 987cc61b3f6..a7ee37b2784 100644
--- a/app/views/help/instance_configuration/_ssh_info.html.haml
+++ b/app/views/help/instance_configuration/_ssh_info.html.haml
@@ -1,22 +1,29 @@
- ssh_info = @instance_configuration.settings[:ssh_algorithms_hashes]
-- if ssh_info.any?
- - content_for :table_content do
- %li= link_to 'SSH host keys fingerprints', '#ssh-host-keys-fingerprints'
+- content_for :table_content do
+ %li
+ = link_to _('SSH host key fingerprints'), '#ssh-host-keys-fingerprints'
- - content_for :settings_content do
- %h2#ssh-host-keys-fingerprints
- SSH host keys fingerprints
+- content_for :settings_content do
+ %h2#ssh-host-keys-fingerprints
+ = _('SSH host key fingerprints')
+ - if ssh_info.blank?
%p
- Below are the fingerprints for the current instance SSH host keys.
+ = _('SSH host keys are not available on this system. Please use <code>ssh-keyscan</code> command or contact your GitLab administrator for more information.').html_safe
+ - else
+ %p
+ = _('Below are the fingerprints for the current instance SSH host keys.')
.table-responsive
%table
%thead
%tr
- %th Algorithm
- %th MD5
- %th SHA256
+ %th
+ = _('Algorithm')
+ %th
+ = _('MD5')
+ %th
+ = _('SHA256')
%tbody
- ssh_info.each do |algorithm|
%tr
diff --git a/app/views/help/show.html.haml b/app/views/help/show.html.haml
index dce27dee9be..dace8a77736 100644
--- a/app/views/help/show.html.haml
+++ b/app/views/help/show.html.haml
@@ -1,3 +1,5 @@
- page_title @path.split("/").reverse.map(&:humanize)
+- @content_class = "limit-container-width" unless fluid_layout
+
.documentation.md.prepend-top-default
= markdown @markdown
diff --git a/app/views/help/ui.html.haml b/app/views/help/ui.html.haml
index cdc894ee5a0..b8a421ac9d3 100644
--- a/app/views/help/ui.html.haml
+++ b/app/views/help/ui.html.haml
@@ -508,8 +508,7 @@
.btn-group
%a.btn Edit
%a.btn.btn-danger Remove
- .file-contenta.code
- = render 'shared/file_highlight', blob: blob
+ = render 'shared/file_highlight', blob: blob
%h2#markdown Markdown
%h4
diff --git a/app/views/import/bitbucket/status.html.haml b/app/views/import/bitbucket/status.html.haml
index 2336e1e83f9..7399ff937ce 100644
--- a/app/views/import/bitbucket/status.html.haml
+++ b/app/views/import/bitbucket/status.html.haml
@@ -8,7 +8,6 @@
- if @repos.any?
%p.light
= _('Select projects you want to import.')
- %hr
%p
- if @incompatible_repos.any?
= button_tag class: 'btn btn-import btn-success js-import-all' do
@@ -19,6 +18,14 @@
= _('Import all projects')
= icon('spinner spin', class: 'loading-icon')
+.position-relative.ms-no-clear.d-flex.flex-fill.float-right.append-bottom-10
+ = form_tag status_import_bitbucket_path, method: 'get' do
+ = text_field_tag :filter, @filter, class: 'form-control pr-5', placeholder: _('Filter projects'), size: 40, autofocus: true, 'aria-label': _('Search')
+ .position-absolute.position-top-0.d-flex.align-items-center.text-muted.position-right-0.h-100
+ .border-left
+ %button{ class: 'btn btn-transparent btn-secondary', 'aria-label': _('Search Button'), type: 'submit' }
+ %i{ class: 'fa fa-search', 'aria-hidden': true }
+
.table-responsive
%table.table.import-jobs
%colgroup.import-jobs-from-col
@@ -59,7 +66,7 @@
- if current_user.can_select_namespace?
- selected = params[:namespace_id] || :current_user
- opts = current_user.can_create_group? ? { extra_group: Group.new(name: repo.owner, path: repo.owner) } : {}
- = select_tag :namespace_id, namespaces_options(selected, opts.merge({ display_path: true })), { class: 'input-group-text select2 js-select-namespace', tabindex: 1 }
+ = select_tag :namespace_id, namespaces_options(selected, opts.merge({ display_path: true })), { class: 'select2 js-select-namespace', tabindex: 1 }
- else
= text_field_tag :path, current_user.namespace_path, class: "input-group-text input-large form-control", tabindex: 1, disabled: true
%span.input-group-prepend
diff --git a/app/views/import/bitbucket_server/status.html.haml b/app/views/import/bitbucket_server/status.html.haml
index aac09801d91..1aaf5883bf4 100644
--- a/app/views/import/bitbucket_server/status.html.haml
+++ b/app/views/import/bitbucket_server/status.html.haml
@@ -62,7 +62,7 @@
- if current_user.can_select_namespace?
- selected = params[:namespace_id] || :extra_group
- opts = current_user.can_create_group? ? { extra_group: Group.new(name: sanitize_project_name(repo.project_key), path: sanitize_project_name(repo.project_key)) } : {}
- = select_tag :namespace_id, namespaces_options(selected, opts.merge({ display_path: true })), { class: 'input-group-text select2 js-select-namespace', tabindex: 1 }
+ = select_tag :namespace_id, namespaces_options(selected, opts.merge({ display_path: true })), { class: 'select2 js-select-namespace', tabindex: 1 }
- else
= text_field_tag :path, current_user.namespace_path, class: "input-group-text input-large form-control", tabindex: 1, disabled: true
%span.input-group-prepend
diff --git a/app/views/layouts/_flash.html.haml b/app/views/layouts/_flash.html.haml
index d673d7164b3..92572f0308c 100644
--- a/app/views/layouts/_flash.html.haml
+++ b/app/views/layouts/_flash.html.haml
@@ -5,4 +5,5 @@
- if value
%div{ class: "flash-content flash-#{key} rounded" }
%span= value
- = sprite_icon('close', size: 16, css_class: 'close-icon')
+ %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 68abfd3f61f..b8c9f0ae1e8 100644
--- a/app/views/layouts/_head.html.haml
+++ b/app/views/layouts/_head.html.haml
@@ -1,5 +1,17 @@
- page_description brand_title unless page_description
+-# Needs a redirect on the client side since it's using an anchor to distuingish
+-# between sign in and registration. We need to inline the JS to not render
+-# anything from this page beforehand.
+-# Part of an experiment to build a new sign up flow. Will be removed again with
+-# https://gitlab.com/gitlab-org/growth/engineering/issues/64
+- if experiment_enabled?(:signup_flow) && current_path?("sessions#new")
+ = javascript_tag nonce: true do
+ :plain
+ if (window.location.hash === '#register-pane') {
+ window.location.replace("/users/sign_up")
+ }
+
- site_name = "GitLab"
%head{ prefix: "og: http://ogp.me/ns#" }
%meta{ charset: "utf-8" }
diff --git a/app/views/layouts/_page.html.haml b/app/views/layouts/_page.html.haml
index 443a73f5cce..6cdb85456c3 100644
--- a/app/views/layouts/_page.html.haml
+++ b/app/views/layouts/_page.html.haml
@@ -17,4 +17,6 @@
%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/devise_experimental_separate_sign_up_flow.html.haml b/app/views/layouts/devise_experimental_separate_sign_up_flow.html.haml
new file mode 100644
index 00000000000..2f05717fc0e
--- /dev/null
+++ b/app/views/layouts/devise_experimental_separate_sign_up_flow.html.haml
@@ -0,0 +1,26 @@
+!!! 5
+%html.devise-layout-html.navless{ class: system_message_class }
+ = render "layouts/head"
+ %body.ui-indigo.signup-page.application.navless{ class: "#{client_class_list}", data: { page: body_data_page, qa_selector: 'signup_page' } }
+ = header_message
+ = render "layouts/init_client_detection_flags"
+ .page-wrap
+ .container.signup-box-container.navless-container.mt-0
+ = render "layouts/broadcast"
+ .content
+ = render "layouts/flash"
+ .row.mb-3
+ .col-sm-8.offset-sm-2.col-md-6.offset-md-3.new-session-forms-container
+ = render_if_exists 'layouts/devise_help_text'
+ .text-center.signup-heading.mt-3.mb-3
+ = image_tag(image_url('logo.svg'), class: 'gitlab-logo', alt: 'GitLab Logo')
+ - if content_for?(:page_title)
+ %h2= yield :page_title
+ = yield
+ %hr.footer-fixed
+ .footer-container
+ .container
+ .footer-links
+ = link_to _("Help"), help_path
+ = link_to _("About GitLab"), "https://about.gitlab.com/"
+ = footer_message
diff --git a/app/views/layouts/header/_current_user_dropdown.html.haml b/app/views/layouts/header/_current_user_dropdown.html.haml
index 808290afcad..efe74ddd902 100644
--- a/app/views/layouts/header/_current_user_dropdown.html.haml
+++ b/app/views/layouts/header/_current_user_dropdown.html.haml
@@ -21,6 +21,24 @@
- if current_user_menu?(:settings)
%li
= link_to s_("CurrentUser|Settings"), profile_path, data: { qa_selector: 'settings_link' }
+
+ - if current_user_menu?(:help)
+ %li.divider.d-md-none
+ %li.d-md-none
+ = link_to _("Help"), help_path
+ %li.d-md-none
+ = link_to _("Support"), support_url
+ = render_if_exists "shared/learn_gitlab_menu_item"
+ %li.d-md-none
+ = link_to _("Submit feedback"), "https://about.gitlab.com/submit-feedback"
+ - if current_user_menu?(:help) || current_user_menu?(:settings) || current_user_menu?(:profile)
+ %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
+ = link_to _("Switch to GitLab Next"), "https://next.gitlab.com/"
+
- if current_user_menu?(:sign_out)
%li.divider
%li
diff --git a/app/views/layouts/header/_default.html.haml b/app/views/layouts/header/_default.html.haml
index 14c7b2428b2..d8697be7f7a 100644
--- a/app/views/layouts/header/_default.html.haml
+++ b/app/views/layouts/header/_default.html.haml
@@ -33,9 +33,9 @@
- if current_user
= render 'layouts/header/new_dropdown'
- if header_link?(:search)
- %li.nav-item.d-none.d-sm-none.d-md-block.m-auto
+ %li.nav-item.d-none.d-lg-block.m-auto
= render 'layouts/search' unless current_controller?(:search)
- %li.nav-item.d-inline-block.d-sm-none.d-md-none
+ %li.nav-item.d-inline-block.d-lg-none
= link_to search_path_url, title: _('Search'), aria: { label: _('Search') }, data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do
= sprite_icon('search', size: 16)
- if header_link?(:issues)
@@ -58,7 +58,7 @@
= sprite_icon('todo-done', size: 16)
%span.badge.badge-pill.todos-count{ class: ('hidden' if todos_pending_count.zero?) }
= todos_count_format(todos_pending_count)
- %li.nav-item.header-help.dropdown
+ %li.nav-item.header-help.dropdown.d-none.d-md-block
= link_to help_path, class: 'header-help-dropdown-toggle', data: { toggle: "dropdown" } do
= sprite_icon('question', size: 16)
= sprite_icon('angle-down', css_class: 'caret-down')
@@ -73,7 +73,7 @@
= render 'layouts/header/current_user_dropdown'
- if has_impersonation_link
%li.nav-item.impersonation.ml-0
- = link_to admin_impersonation_path, class: 'nav-link impersonation-btn', method: :delete, title: _('Stop impersonation'), aria: { label: _('Stop impersonation') }, data: { toggle: 'tooltip', placement: 'bottom', container: 'body' } do
+ = link_to admin_impersonation_path, class: 'nav-link impersonation-btn', method: :delete, title: _('Stop impersonation'), aria: { label: _('Stop impersonation') }, data: { toggle: 'tooltip', placement: 'bottom', container: 'body', qa_selector: 'stop_impersonation_link' } do
= icon('user-secret')
- if header_link?(:sign_in)
%li.nav-item
diff --git a/app/views/layouts/header/_help_dropdown.html.haml b/app/views/layouts/header/_help_dropdown.html.haml
index 41d7aa3741a..71977b23481 100644
--- a/app/views/layouts/header/_help_dropdown.html.haml
+++ b/app/views/layouts/header/_help_dropdown.html.haml
@@ -9,7 +9,8 @@
%li
= link_to _("Submit feedback"), "https://about.gitlab.com/submit-feedback"
- if current_user_menu?(:help) || current_user_menu?(:settings) || current_user_menu?(:profile)
- = render 'shared/user_dropdown_contributing_link'
+ %li
+ = render 'shared/user_dropdown_contributing_link'
= render_if_exists 'shared/user_dropdown_instance_review'
- if Gitlab.com?
%li.js-canary-link
diff --git a/app/views/layouts/nav/_dashboard.html.haml b/app/views/layouts/nav/_dashboard.html.haml
index 7b0824ae2af..5122c2517aa 100644
--- a/app/views/layouts/nav/_dashboard.html.haml
+++ b/app/views/layouts/nav/_dashboard.html.haml
@@ -10,37 +10,24 @@
= render "layouts/nav/projects_dropdown/show"
- if dashboard_nav_link?(:groups)
- = nav_link(controller: ['dashboard/groups', 'explore/groups'], html_options: { id: 'nav-groups-dropdown', class: "home dropdown header-groups qa-groups-dropdown", data: { track_label: "groups_dropdown", track_event: "click_dropdown", track_value: "" } }) do
+ = nav_link(controller: ['dashboard/groups', 'explore/groups'], html_options: { id: 'nav-groups-dropdown', class: "d-none d-md-block home dropdown header-groups qa-groups-dropdown", data: { track_label: "groups_dropdown", track_event: "click_dropdown", track_value: "" } }) do
%button.btn{ type: 'button', data: { toggle: "dropdown" } }
= _('Groups')
= sprite_icon('angle-down', css_class: 'caret-down')
.dropdown-menu.frequent-items-dropdown-menu
= render "layouts/nav/groups_dropdown/show"
- - if dashboard_nav_link?(:activity)
- = nav_link(path: 'dashboard#activity', html_options: { class: ["d-none d-xl-block", ("d-lg-block" unless has_extra_nav_icons?)] }) do
- = link_to activity_dashboard_path, class: 'dashboard-shortcuts-activity' do
- = _('Activity')
-
- - if dashboard_nav_link?(:milestones)
- = nav_link(controller: 'dashboard/milestones', html_options: { class: ["d-none d-xl-block", ("d-lg-block" unless has_extra_nav_icons?)] }) do
- = link_to dashboard_milestones_path, class: 'dashboard-shortcuts-milestones' do
- = _('Milestones')
-
- - if dashboard_nav_link?(:snippets)
- = nav_link(controller: 'dashboard/snippets', html_options: { class: ["d-none d-xl-block", ("d-lg-block" unless has_extra_nav_icons?)] }) do
- = link_to dashboard_snippets_path, class: 'dashboard-shortcuts-snippets qa-snippets-link' do
- = _('Snippets')
-
- = render_if_exists 'layouts/nav/sidebar/analytics_link'
-
- if any_dashboard_nav_link?([:groups, :milestones, :activity, :snippets])
- %li.header-more.dropdown.d-xl-none{ class: ('d-lg-none' unless has_extra_nav_icons?) }
- %a{ href: "#", data: { toggle: "dropdown" } }
+ %li.header-more.dropdown
+ %a{ href: "#", data: { toggle: "dropdown", qa_selector: 'more_dropdown' } }
= _('More')
= sprite_icon('angle-down', css_class: 'caret-down')
.dropdown-menu
%ul
+ - if dashboard_nav_link?(:groups)
+ %li.d-md-none
+ = link_to dashboard_groups_path do
+ = _('Groups')
- if dashboard_nav_link?(:activity)
= nav_link(path: 'dashboard#activity') do
= link_to activity_dashboard_path do
@@ -53,51 +40,45 @@
- if dashboard_nav_link?(:snippets)
= nav_link(controller: 'dashboard/snippets') do
- = link_to dashboard_snippets_path, class: 'dashboard-shortcuts-snippets' do
+ = link_to dashboard_snippets_path, class: 'dashboard-shortcuts-snippets', data: { qa_selector: 'snippets_link' } do
= _('Snippets')
- = render_if_exists 'layouts/nav/sidebar/analytics_more_link'
+ = render_if_exists 'layouts/nav/sidebar/analytics_link'
- %li.dropdown.d-lg-none
- = render_if_exists 'dashboard/operations/nav_link_list'
+ %li.dropdown
+ = render_if_exists 'dashboard/nav_link_list'
- if can?(current_user, :read_instance_statistics)
- = nav_link(controller: [:conversational_development_index, :cohorts], html_options: { class: 'd-lg-none' }) do
+ = nav_link(controller: [:conversational_development_index, :cohorts]) do
= link_to instance_statistics_root_path do
= _('Instance Statistics')
- if current_user.admin?
= nav_link(controller: 'admin/dashboard') do
- = link_to admin_root_path, class: 'd-lg-none admin-icon qa-admin-area-link' 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 Gitlab::Sherlock.enabled?
%li
- = link_to sherlock_transactions_path, class: 'd-lg-none admin-icon' do
+ = link_to sherlock_transactions_path, class: 'admin-icon' do
= _('Sherlock Transactions')
+ - if current_user.admin?
+ = nav_link(controller: 'admin/dashboard', html_options: { class: "d-none d-xl-block"}) do
+ = 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)
+
+
-# Shortcut to Dashboard > Projects
- if dashboard_nav_link?(:projects)
%li.hidden
= link_to dashboard_projects_path, class: 'dashboard-shortcuts-projects' do
= _('Projects')
- - if current_controller?('ide')
- %li.line-separator.d-none.d-sm-block
- = nav_link(controller: 'ide') do
- = link_to '#', class: 'dashboard-shortcuts-web-ide' do
- = _('Web IDE')
-
- %li.dropdown{ class: 'd-none d-lg-block' }
- = render_if_exists 'dashboard/operations/nav_link'
- - if can?(current_user, :read_instance_statistics)
- = nav_link(controller: [:conversational_development_index, :cohorts], html_options: { class: "d-none d-lg-block d-xl-block"}) do
- = link_to instance_statistics_root_path, title: _('Instance Statistics'), aria: { label: _('Instance Statistics') }, data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do
- = sprite_icon('chart', size: 18)
- - if current_user.admin?
- = nav_link(controller: 'admin/dashboard', html_options: { class: "d-none d-lg-block d-xl-block"}) do
- = 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 Gitlab::Sherlock.enabled?
- %li
- = link_to sherlock_transactions_path, class: 'admin-icon d-none d-lg-block d-xl-block', title: _('Sherlock Transactions'),
- data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do
- = icon('tachometer fw')
= render_if_exists 'layouts/nav/geo_primary_node_url'
diff --git a/app/views/layouts/nav/sidebar/_admin.html.haml b/app/views/layouts/nav/sidebar/_admin.html.haml
index 784fe556123..b33ef26f87d 100644
--- a/app/views/layouts/nav/sidebar/_admin.html.haml
+++ b/app/views/layouts/nav/sidebar/_admin.html.haml
@@ -6,7 +6,7 @@
= sprite_icon('admin', size: 24)
.sidebar-context-title
= _('Admin Area')
- %ul.sidebar-top-level-items
+ %ul.sidebar-top-level-items{ data: { qa_selector: 'admin_sidebar_overview_submenu_content' } }
= nav_link(controller: %w(dashboard admin admin/projects users groups jobs runners gitaly_servers), html_options: {class: 'home'}) do
= link_to admin_root_path, class: 'shortcuts-tree' do
.nav-icon-container
@@ -28,7 +28,7 @@
%span
= _('Projects')
= nav_link(controller: :users) do
- = link_to admin_users_path, title: _('Users') do
+ = link_to admin_users_path, title: _('Users') , data: { qa_selector: 'users_overview_link' } do
%span
= _('Users')
= nav_link(controller: :groups) do
@@ -49,13 +49,13 @@
= _('Gitaly Servers')
= nav_link(controller: admin_monitoring_nav_links) do
- = link_to admin_system_info_path do
+ = link_to admin_system_info_path, data: { qa_selector: 'admin_monitoring_link' } do
.nav-icon-container
= sprite_icon('monitor')
%span.nav-item-name
= _('Monitoring')
- %ul.sidebar-sub-level-items
+ %ul.sidebar-sub-level-items{ data: { qa_selector: 'admin_sidebar_monitoring_submenu_content' } }
= nav_link(controller: %w(system_info background_jobs logs health_check requests_profiles), html_options: { class: "fly-out-top-item" } ) do
= link_to admin_system_info_path do
%strong.fly-out-top-item-name
@@ -225,7 +225,7 @@
%span.nav-item-name.qa-admin-settings-item
= _('Settings')
- %ul.sidebar-sub-level-items.qa-admin-sidebar-submenu
+ %ul.sidebar-sub-level-items.qa-admin-sidebar-settings-submenu
= nav_link(controller: :application_settings, html_options: { class: "fly-out-top-item" } ) do
= link_to admin_application_settings_path do
%strong.fly-out-top-item-name
diff --git a/app/views/layouts/nav/sidebar/_group.html.haml b/app/views/layouts/nav/sidebar/_group.html.haml
index 7cc7d1783c4..4930c6cf5f7 100644
--- a/app/views/layouts/nav/sidebar/_group.html.haml
+++ b/app/views/layouts/nav/sidebar/_group.html.haml
@@ -118,7 +118,7 @@
%strong.fly-out-top-item-name
= _('Kubernetes')
- = render_if_exists 'groups/sidebar/packages' # EE-specific
+ = render_if_exists 'groups/sidebar/packages'
- if group_sidebar_link?(:group_members)
= nav_link(path: 'group_members#index') do
diff --git a/app/views/layouts/nav/sidebar/_profile.html.haml b/app/views/layouts/nav/sidebar/_profile.html.haml
index 22ac9ee234d..9be39d14169 100644
--- a/app/views/layouts/nav/sidebar/_profile.html.haml
+++ b/app/views/layouts/nav/sidebar/_profile.html.haml
@@ -64,7 +64,7 @@
%strong.fly-out-top-item-name
= _('Access Tokens')
= nav_link(controller: :emails) do
- = link_to profile_emails_path do
+ = link_to profile_emails_path, data: { qa_selector: 'profile_emails_link' } do
.nav-icon-container
= sprite_icon('mail')
%span.nav-item-name
@@ -76,7 +76,7 @@
= _('Emails')
- if current_user.allow_password_authentication?
= nav_link(controller: :passwords) do
- = link_to edit_profile_password_path do
+ = link_to edit_profile_password_path , data: { qa_selector: 'profile_password_link' } do
.nav-icon-container
= sprite_icon('lock')
%span.nav-item-name
diff --git a/app/views/layouts/nav/sidebar/_project.html.haml b/app/views/layouts/nav/sidebar/_project.html.haml
index 48fea2bbecf..c84bc0b5cd4 100644
--- a/app/views/layouts/nav/sidebar/_project.html.haml
+++ b/app/views/layouts/nav/sidebar/_project.html.haml
@@ -182,11 +182,17 @@
= _('Pipelines')
- if project_nav_tab? :builds
- = nav_link(controller: [:jobs, :artifacts]) do
+ = nav_link(controller: :jobs) do
= link_to project_jobs_path(@project), title: _('Jobs'), class: 'shortcuts-builds' do
%span
= _('Jobs')
+ - if Feature.enabled?(:artifacts_management_page, @project)
+ = nav_link(controller: :artifacts, action: :index) do
+ = link_to project_artifacts_path(@project), title: _('Artifacts'), class: 'shortcuts-builds' do
+ %span
+ = _('Artifacts')
+
- if project_nav_tab? :pipelines
= nav_link(controller: :pipeline_schedules) do
= link_to pipeline_schedules_path(@project), title: _('Schedules'), class: 'shortcuts-builds' do
diff --git a/app/views/notify/new_release_email.html.haml b/app/views/notify/new_release_email.html.haml
new file mode 100644
index 00000000000..45e99f3c07a
--- /dev/null
+++ b/app/views/notify/new_release_email.html.haml
@@ -0,0 +1,18 @@
+- release_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: @target_url }
+- description_details = { tag: @release.tag, name: @project.name, release_link_start: release_link_start, release_link_end: '</a>'.html_safe }
+
+%div{ style: "font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif;" }
+ %p
+ = _("A new Release %{tag} for %{name} was published. Visit the %{release_link_start}Releases page%{release_link_end} to read more about it.").html_safe % description_details
+
+ %p
+ %h4= _("Assets:")
+ %ul
+ - @release.links.each do |link|
+ %li= link_to(link.name, link.url)
+ - @release.sources.each do |source|
+ %li= link_to(_("Download %{format}") % { format: source.format }, source.url)
+
+ %p
+ %h4= _("Release notes:")
+ = markdown_field(@release, :description)
diff --git a/app/views/notify/new_release_email.text.erb b/app/views/notify/new_release_email.text.erb
new file mode 100644
index 00000000000..e03cf2d5fd1
--- /dev/null
+++ b/app/views/notify/new_release_email.text.erb
@@ -0,0 +1,12 @@
+<%= _("A new Release %{tag} for %{name} was published. Visit the Releases page to read more about it:").html_safe % { tag: @release.tag, name: @project.name } %> <%= @target_url %>
+
+<%= _("Assets:") %>
+<% @release.links.each do |link| -%>
+ - <%= link.name %>: <%= link.url %>
+<% end -%>
+<% @release.sources.each do |source| -%>
+ - <%= _("Download %{format}:") % { format: source.format } %> <%= source.url %>
+<% end -%>
+
+<%= _("Release notes:") %>
+<%= @release.description %>
diff --git a/app/views/notify/pipeline_failed_email.html.haml b/app/views/notify/pipeline_failed_email.html.haml
index 86dcca4a447..f01181857ce 100644
--- a/app/views/notify/pipeline_failed_email.html.haml
+++ b/app/views/notify/pipeline_failed_email.html.haml
@@ -34,7 +34,7 @@
%img{ height: "13", src: image_url('mailers/ci_pipeline_notif_v1/icon-branch-gray.gif'), style: "display:block;", width: "13", alt: "" }/
%td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;font-size:15px;line-height:1.4;vertical-align:middle;" }
%a.muted{ href: commits_url(@pipeline), style: "color:#333333;text-decoration:none;" }
- = @pipeline.ref
+ = @pipeline.source_ref
%tr
%td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;font-size:15px;line-height:1.4;color:#8c8c8c;font-weight:300;padding:14px 0;margin:0;border-top:1px solid #ededed;" } Commit
%td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;font-size:15px;line-height:1.4;color:#8c8c8c;font-weight:400;padding:14px 0;margin:0;color:#333333;width:75%;padding-left:5px;border-top:1px solid #ededed;" }
diff --git a/app/views/notify/pipeline_failed_email.text.erb b/app/views/notify/pipeline_failed_email.text.erb
index 722eedf90be..9cd479ef1e6 100644
--- a/app/views/notify/pipeline_failed_email.text.erb
+++ b/app/views/notify/pipeline_failed_email.text.erb
@@ -1,7 +1,7 @@
Your pipeline has failed.
Project: <%= @project.name %> ( <%= project_url(@project) %> )
-Branch: <%= @pipeline.ref %> ( <%= commits_url(@pipeline) %> )
+Branch: <%= @pipeline.source_ref %> ( <%= commits_url(@pipeline) %> )
<% if @merge_request -%>
Merge Request: <%= @merge_request.to_reference %> ( <%= merge_request_url(@merge_request) %> )
<% end -%>
diff --git a/app/views/notify/pipeline_success_email.html.haml b/app/views/notify/pipeline_success_email.html.haml
index 4fe3c4c8269..e575a5569fa 100644
--- a/app/views/notify/pipeline_success_email.html.haml
+++ b/app/views/notify/pipeline_success_email.html.haml
@@ -34,7 +34,7 @@
%img{ height: "13", src: image_url('mailers/ci_pipeline_notif_v1/icon-branch-gray.gif'), style: "display:block;", width: "13", alt: "" }/
%td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;font-size:15px;line-height:1.4;vertical-align:middle;" }
%a.muted{ href: commits_url(@pipeline), style: "color:#333333;text-decoration:none;" }
- = @pipeline.ref
+ = @pipeline.source_ref
%tr
%td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;font-size:15px;line-height:1.4;color:#8c8c8c;font-weight:300;padding:14px 0;margin:0;border-top:1px solid #ededed;" } Commit
%td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;font-size:15px;line-height:1.4;color:#8c8c8c;font-weight:400;padding:14px 0;margin:0;color:#333333;width:75%;padding-left:5px;border-top:1px solid #ededed;" }
diff --git a/app/views/notify/pipeline_success_email.text.erb b/app/views/notify/pipeline_success_email.text.erb
index 9aadf380f79..4005158dc9e 100644
--- a/app/views/notify/pipeline_success_email.text.erb
+++ b/app/views/notify/pipeline_success_email.text.erb
@@ -1,7 +1,7 @@
Your pipeline has passed.
Project: <%= @project.name %> ( <%= project_url(@project) %> )
-Branch: <%= @pipeline.ref %> ( <%= commits_url(@pipeline) %> )
+Branch: <%= @pipeline.source_ref %> ( <%= commits_url(@pipeline) %> )
<% if @merge_request -%>
Merge Request: <%= @merge_request.to_reference %> ( <%= merge_request_url(@merge_request) %> )
<% end -%>
diff --git a/app/views/profiles/emails/index.html.haml b/app/views/profiles/emails/index.html.haml
index 3c20518c038..6ea4eeb66c5 100644
--- a/app/views/profiles/emails/index.html.haml
+++ b/app/views/profiles/emails/index.html.haml
@@ -13,9 +13,9 @@
= form_for 'email', url: profile_emails_path do |f|
.form-group
= f.label :email, _('Email'), class: 'label-bold'
- = f.text_field :email, class: 'form-control'
+ = f.text_field :email, class: 'form-control', data: { qa_selector: 'email_address_field' }
.prepend-top-default
- = f.submit _('Add email address'), class: 'btn btn-success'
+ = f.submit _('Add email address'), class: 'btn btn-success', data: { qa_selector: 'add_email_address_button' }
%hr
%h4.prepend-top-0
= _('Linked emails (%{email_count})') % { email_count: @emails.count + 1 }
@@ -45,7 +45,7 @@
- if @primary_email === current_user.notification_email
%span.badge.badge-info= s_('Profiles|Default notification email')
- @emails.each do |email|
- %li
+ %li{ data: { qa_selector: 'email_row_content' } }
= render partial: 'shared/email_with_badge', locals: { email: email.email, verified: email.confirmed? }
%span.float-right
- if email.email === current_user.commit_email
@@ -58,6 +58,6 @@
- confirm_title = "#{email.confirmation_sent_at ? _('Resend confirmation email') : _('Send confirmation email')}"
= link_to confirm_title, resend_confirmation_instructions_profile_email_path(email), method: :put, class: 'btn btn-sm btn-warning prepend-left-10'
- = link_to profile_email_path(email), data: { confirm: _('Are you sure?')}, method: :delete, class: 'btn btn-sm btn-danger prepend-left-10' do
+ = link_to profile_email_path(email), data: { confirm: _('Are you sure?'), qa_selector: 'delete_email_link'}, method: :delete, class: 'btn btn-sm btn-danger prepend-left-10' do
%span.sr-only= _('Remove')
= icon('trash')
diff --git a/app/views/profiles/notifications/_group_settings.html.haml b/app/views/profiles/notifications/_group_settings.html.haml
index 1776d260e19..33b0aa93d84 100644
--- a/app/views/profiles/notifications/_group_settings.html.haml
+++ b/app/views/profiles/notifications/_group_settings.html.haml
@@ -12,5 +12,5 @@
= render 'shared/notifications/button', notification_setting: setting, emails_disabled: emails_disabled
.table-section.section-30
- = form_for @user.notification_settings.find { |ns| ns.source == group }, url: profile_notifications_group_path(group), method: :put, html: { class: 'update-notifications' } do |f|
+ = form_for setting, url: profile_notifications_group_path(group), method: :put, html: { class: 'update-notifications' } do |f|
= f.select :notification_email, @user.all_emails, { include_blank: 'Global notification email' }, class: 'select2 js-group-notification-email'
diff --git a/app/views/profiles/passwords/edit.html.haml b/app/views/profiles/passwords/edit.html.haml
index ac8c31189d0..0e2b0430fec 100644
--- a/app/views/profiles/passwords/edit.html.haml
+++ b/app/views/profiles/passwords/edit.html.haml
@@ -20,16 +20,16 @@
- unless @user.password_automatically_set?
.form-group
= f.label :current_password, _('Current password'), class: 'label-bold'
- = f.password_field :current_password, required: true, class: 'form-control'
+ = f.password_field :current_password, required: true, class: 'form-control', data: { qa_selector: 'current_password_field' }
%p.form-text.text-muted
= _('You must provide your current password in order to change it.')
.form-group
= f.label :password, _('New password'), class: 'label-bold'
- = f.password_field :password, required: true, class: 'form-control'
+ = f.password_field :password, required: true, class: 'form-control', data: { qa_selector: 'new_password_field' }
.form-group
= f.label :password_confirmation, _('Password confirmation'), class: 'label-bold'
- = f.password_field :password_confirmation, required: true, class: 'form-control'
+ = f.password_field :password_confirmation, required: true, class: 'form-control', data: { qa_selector: 'confirm_password_field' }
.prepend-top-default.append-bottom-default
- = f.submit _('Save password'), class: "btn btn-success append-right-10"
+ = f.submit _('Save password'), class: "btn btn-success append-right-10", data: { qa_selector: 'save_password_button' }
- unless @user.password_automatically_set?
= link_to _('I forgot my password'), reset_profile_password_path, method: :put, class: "account-btn-link"
diff --git a/app/views/profiles/show.html.haml b/app/views/profiles/show.html.haml
index 0576f51fa83..68b7efc6fb4 100644
--- a/app/views/profiles/show.html.haml
+++ b/app/views/profiles/show.html.haml
@@ -94,6 +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'
= 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 f564ed41760..e4129a91daf 100644
--- a/app/views/projects/_export.html.haml
+++ b/app/views/projects/_export.html.haml
@@ -10,12 +10,8 @@
%p.append-bottom-0
%p= _('The following items will be exported:')
%ul
- %li= _('Project and wiki repositories')
- %li= _('Project uploads')
- %li= _('Project configuration, including services')
- %li= _('Issues with comments, merge requests with diffs and comments, labels, milestones, snippets, and other project entities')
- %li= _('LFS objects')
- %li= _('Issue Boards')
+ - project_export_descriptions.each do |desc|
+ %li= desc
%p= _('The following items will NOT be exported:')
%ul
%li= _('Job traces and artifacts')
diff --git a/app/views/projects/_new_project_push_tip.html.haml b/app/views/projects/_new_project_push_tip.html.haml
index 22e9522c0e7..e008130436c 100644
--- a/app/views/projects/_new_project_push_tip.html.haml
+++ b/app/views/projects/_new_project_push_tip.html.haml
@@ -6,6 +6,6 @@
%span
= text_field_tag :push_to_create_tip, push_to_create_project_command, class: "js-select-on-focus form-control monospace", readonly: true, aria: { label: _("Push project from command line") }
%span.input-group-append
- = clipboard_button(text: push_to_create_project_command, title: _("Copy command to clipboard"), class: 'input-group-text', placement: "right")
+ = clipboard_button(text: push_to_create_project_command, title: _("Copy command"), class: 'input-group-text', placement: "right")
%p
= link_to("What does this command do?", help_page_path("gitlab-basics/create-project", anchor: "push-to-create-a-new-project"), target: "_blank")
diff --git a/app/views/projects/artifacts/_artifact.html.haml b/app/views/projects/artifacts/_artifact.html.haml
new file mode 100644
index 00000000000..36e149556e0
--- /dev/null
+++ b/app/views/projects/artifacts/_artifact.html.haml
@@ -0,0 +1,61 @@
+.gl-responsive-table-row.px-md-3
+ .table-section.section-25.section-wrap.commit
+ .table-mobile-header{ role: 'rowheader' }= _('Job')
+ .table-mobile-content
+ .branch-commit.cgray
+ - if can?(current_user, :read_build, @project)
+ = link_to project_job_path(@project, artifact.job) do
+ %span.build-link ##{artifact.job_id}
+ - else
+ %span.build-link ##{artifact.job_id}
+
+ - if artifact.job.ref
+ .icon-container{ "aria-label" => artifact.job.tag? ? _('Tag') : _('Branch') }
+ = artifact.job.tag? ? sprite_icon('tag', css_class: 'sprite') : sprite_icon('branch', css_class: 'sprite')
+ = link_to artifact.job.ref, project_ref_path(@project, artifact.job.ref), class: 'ref-name'
+ - else
+ .light= _('none')
+ .icon-container.commit-icon{ "aria-label" => _('Commit') }
+ = sprite_icon('commit')
+
+ - if artifact.job.sha
+ = link_to artifact.job.short_sha, project_commit_path(@project, artifact.job.sha), class: 'commit-sha mr-0'
+
+ .table-section.section-15.section-wrap
+ .table-mobile-header{ role: 'rowheader' }= _('Name')
+ .table-mobile-content
+ = artifact.job.name
+
+ .table-section.section-20
+ .table-mobile-header{ role: 'rowheader' }= _('Creation date')
+ .table-mobile-content
+ %p.finished-at
+ = icon("calendar")
+ %span= time_ago_with_tooltip(artifact.created_at)
+
+ .table-section.section-20
+ .table-mobile-header{ role: 'rowheader' }= _('Expiration date')
+ .table-mobile-content
+ - if artifact.expire_at
+ %p.finished-at
+ = icon("calendar")
+ %span= time_ago_with_tooltip(artifact.expire_at)
+
+ .table-section.section-10
+ .table-mobile-header{ role: 'rowheader' }= _('Size')
+ .table-mobile-content
+ = number_to_human_size(artifact.size, precision: 2)
+
+ .table-section.table-button-footer.section-10
+ .table-action-buttons
+ .btn-group
+ - if can?(current_user, :read_build, @project)
+ = link_to download_project_job_artifacts_path(@project, artifact.job), rel: 'nofollow', download: '', title: _('Download artifacts'), data: { placement: 'top', container: 'body' }, ref: 'tooltip', aria: { label: _('Download artifacts') }, class: 'btn btn-build has-tooltip ml-0' do
+ = sprite_icon('download')
+
+ = link_to browse_project_job_artifacts_path(@project, artifact.job), rel: 'nofollow', title: _('Browse artifacts'), data: { placement: 'top', container: 'body' }, ref: 'tooltip', aria: { label: _('Browse artifacts') }, class: 'btn btn-build has-tooltip' do
+ = sprite_icon('folder-open')
+
+ - if can?(current_user, :destroy_artifacts, @project)
+ = link_to project_artifact_path(@project, artifact), data: { placement: 'top', container: 'body', confirm: _('Are you sure you want to delete these artifacts?') }, method: :delete, title: _('Delete artifacts'), ref: 'tooltip', aria: { label: _('Delete artifacts') }, class: 'btn btn-remove has-tooltip' do
+ = sprite_icon('remove')
diff --git a/app/views/projects/artifacts/_table.html.haml b/app/views/projects/artifacts/_table.html.haml
new file mode 100644
index 00000000000..1963449d704
--- /dev/null
+++ b/app/views/projects/artifacts/_table.html.haml
@@ -0,0 +1,16 @@
+- if artifacts.blank?
+ .nothing-here-block= _('No jobs to show')
+- else
+ .table-holder
+ .ci-table
+ .gl-responsive-table-row.table-row-header.px-md-3{ role: 'row' }
+ .table-section.section-25{ role: 'rowheader' }= _('Job')
+ .table-section.section-15{ role: 'rowheader' }= _('Name')
+ .table-section.section-20{ role: 'rowheader' }= _('Creation date')
+ .table-section.section-20{ role: 'rowheader' }= _('Expiration date')
+ .table-section.section-10{ role: 'rowheader' }= _('Size')
+ .table-section.section-10{ role: 'rowheader' }
+
+ = render partial: 'artifact', collection: artifacts, as: :artifact
+
+ = paginate artifacts, theme: "gitlab", total_pages: @total_pages
diff --git a/app/views/projects/artifacts/index.html.haml b/app/views/projects/artifacts/index.html.haml
new file mode 100644
index 00000000000..1ab3e8e67d8
--- /dev/null
+++ b/app/views/projects/artifacts/index.html.haml
@@ -0,0 +1,10 @@
+- @no_container = true
+- page_title _('Artifacts')
+
+%div{ class: container_class }
+ .top-area.py-3
+ .align-self-center
+ = _('Total artifacts size: %{total_size}') % { total_size: number_to_human_size(@total_size, precicion: 2) }
+
+ .content-list.builds-content-list
+ = render "table", artifacts: @artifacts, project: @project
diff --git a/app/views/projects/blob/_editor.html.haml b/app/views/projects/blob/_editor.html.haml
index 283b845e40d..961b873b571 100644
--- a/app/views/projects/blob/_editor.html.haml
+++ b/app/views/projects/blob/_editor.html.haml
@@ -3,20 +3,22 @@
- is_markdown = Gitlab::MarkupHelper.gitlab_markdown?(file_name)
.file-holder-bottom-radius.file-holder.file.append-bottom-default
- .js-file-title.file-title.clearfix{ data: { current_action: action } }
+ .js-file-title.file-title.align-items-center.clearfix{ data: { current_action: action } }
.editor-ref.block-truncated
= sprite_icon('fork', size: 12)
= ref
- if current_action?(:edit) || current_action?(:update)
%span.pull-left.append-right-10
- = text_field_tag 'file_path', (params[:file_path] || @path),
- class: 'form-control new-file-path js-file-path-name-input'
+ = text_field_tag 'file_path', (params[:file_path] || @path),
+ class: 'form-control new-file-path js-file-path-name-input'
+ = render 'template_selectors'
- if current_action?(:new) || current_action?(:create)
%span.pull-left.append-right-10
\/
= text_field_tag 'file_name', params[:file_name], placeholder: "File name",
required: true, class: 'form-control new-file-name js-file-path-name-input'
+ = render 'template_selectors'
.file-buttons
- if is_markdown
diff --git a/app/views/projects/blob/_template_selectors.html.haml b/app/views/projects/blob/_template_selectors.html.haml
index bd46f5a4349..5ecfa135446 100644
--- a/app/views/projects/blob/_template_selectors.html.haml
+++ b/app/views/projects/blob/_template_selectors.html.haml
@@ -1,17 +1,12 @@
-.template-selectors-menu
- .templates-selectors-label
- Template
+.template-selectors-menu.gl-pl-2
.template-selector-dropdowns-wrap
.template-type-selector.js-template-type-selector-wrap.hidden
- = dropdown_tag("Choose type", options: { toggle_class: 'js-template-type-selector qa-template-type-dropdown', title: "Choose a template type" } )
+ = dropdown_tag(_("Select a template type"), options: { toggle_class: 'js-template-type-selector qa-template-type-dropdown', dropdown_class: 'dropdown-menu-selectable'} )
.license-selector.js-license-selector-wrap.js-template-selector-wrap.hidden
- = dropdown_tag("Apply a license template", options: { toggle_class: 'js-license-selector qa-license-dropdown', title: "Apply a license", filter: true, placeholder: "Filter", data: { data: licenses_for_select(@project), project: @project.name, fullname: @project.namespace.human_name } } )
+ = dropdown_tag(_("Apply a template"), options: { toggle_class: 'js-license-selector qa-license-dropdown', dropdown_class: 'dropdown-menu-selectable', filter: true, placeholder: "Filter", data: { data: licenses_for_select(@project), project: @project.name, fullname: @project.namespace.human_name } } )
.gitignore-selector.js-gitignore-selector-wrap.js-template-selector-wrap.hidden
- = dropdown_tag("Apply a .gitignore template", options: { toggle_class: 'js-gitignore-selector qa-gitignore-dropdown', title: "Apply a template", filter: true, placeholder: "Filter", data: { data: gitignore_names(@project) } } )
+ = dropdown_tag(_("Apply a template"), options: { toggle_class: 'js-gitignore-selector qa-gitignore-dropdown', dropdown_class: 'dropdown-menu-selectable', filter: true, placeholder: "Filter", data: { data: gitignore_names(@project) } } )
.gitlab-ci-yml-selector.js-gitlab-ci-yml-selector-wrap.js-template-selector-wrap.hidden
- = dropdown_tag("Apply a GitLab CI Yaml template", options: { toggle_class: 'js-gitlab-ci-yml-selector qa-gitlab-ci-yml-dropdown', title: "Apply a template", filter: true, placeholder: "Filter", data: { data: gitlab_ci_ymls(@project) } } )
+ = dropdown_tag(_("Apply a template"), options: { toggle_class: 'js-gitlab-ci-yml-selector qa-gitlab-ci-yml-dropdown', dropdown_class: 'dropdown-menu-selectable', filter: true, placeholder: "Filter", data: { data: gitlab_ci_ymls(@project) } } )
.dockerfile-selector.js-dockerfile-selector-wrap.js-template-selector-wrap.hidden
- = dropdown_tag("Apply a Dockerfile template", options: { toggle_class: 'js-dockerfile-selector qa-dockerfile-dropdown', title: "Apply a template", filter: true, placeholder: "Filter", data: { data: dockerfile_names(@project) } } )
- .template-selectors-undo-menu.hidden
- %span.text-info Template applied
- %button.btn.btn-sm.btn-info Undo
+ = dropdown_tag(_("Apply a template"), options: { toggle_class: 'js-dockerfile-selector qa-dockerfile-dropdown', dropdown_class: 'dropdown-menu-selectable', filter: true, placeholder: "Filter", data: { data: dockerfile_names(@project) } } )
diff --git a/app/views/projects/blob/edit.html.haml b/app/views/projects/blob/edit.html.haml
index 51e42091ab8..870e37488cf 100644
--- a/app/views/projects/blob/edit.html.haml
+++ b/app/views/projects/blob/edit.html.haml
@@ -11,7 +11,6 @@
.editor-title-row
%h3.page-title.blob-edit-page-title
Edit file
- = render 'template_selectors'
.file-editor
%ul.nav-links.no-bottom.js-edit-mode.nav.nav-tabs
%li.active
diff --git a/app/views/projects/blob/new.html.haml b/app/views/projects/blob/new.html.haml
index 4be87b9e074..c5e3923f1e8 100644
--- a/app/views/projects/blob/new.html.haml
+++ b/app/views/projects/blob/new.html.haml
@@ -5,7 +5,6 @@
.editor-title-row
%h3.page-title.blob-new-page-title
New file
- = render 'template_selectors'
.file-editor
= form_tag(project_create_blob_path(@project, @id), method: :post, class: 'js-edit-blob-form js-new-blob-form js-quick-submit js-requires-input', data: blob_editor_paths(@project)) do
= render 'projects/blob/editor', ref: @ref
diff --git a/app/views/projects/blob/show.html.haml b/app/views/projects/blob/show.html.haml
index 688b8f001c3..7c73bbc7479 100644
--- a/app/views/projects/blob/show.html.haml
+++ b/app/views/projects/blob/show.html.haml
@@ -1,6 +1,6 @@
- breadcrumb_title "Repository"
- page_title @blob.path, @ref
-- signatures_path = namespace_project_signatures_path(namespace_id: @project.namespace.full_path, project_id: @project.path, id: @last_commit)
+- signatures_path = namespace_project_signatures_path(namespace_id: @project.namespace.full_path, project_id: @project.path, id: @last_commit, limit: 1)
.js-signature-container{ data: { 'signatures-path': signatures_path } }
diff --git a/app/views/projects/blob/viewers/_audio.html.haml b/app/views/projects/blob/viewers/_audio.html.haml
new file mode 100644
index 00000000000..dbdf243c36b
--- /dev/null
+++ b/app/views/projects/blob/viewers/_audio.html.haml
@@ -0,0 +1,2 @@
+.file-content.audio
+ %audio{ src: blob_raw_path, controls: true, data: { setup: '{}' } }
diff --git a/app/views/projects/branches/_branch.html.haml b/app/views/projects/branches/_branch.html.haml
index dbff2115f50..3e53cb510b0 100644
--- a/app/views/projects/branches/_branch.html.haml
+++ b/app/views/projects/branches/_branch.html.haml
@@ -34,8 +34,9 @@
= _('Merge request')
- if branch.name != @repository.root_ref
- = link_to project_compare_path(@project, @repository.root_ref, branch.name),
+ = link_to project_compare_index_path(@project, from: @repository.root_ref, to: branch.name),
class: "btn btn-default js-onboarding-compare-branches #{'prepend-left-10' unless merge_project}",
+ method: :post,
title: s_('Branches|Compare') do
= s_('Branches|Compare')
diff --git a/app/views/projects/buttons/_clone.html.haml b/app/views/projects/buttons/_clone.html.haml
index 09f05b30433..abef33ca01c 100644
--- a/app/views/projects/buttons/_clone.html.haml
+++ b/app/views/projects/buttons/_clone.html.haml
@@ -13,7 +13,7 @@
.input-group
= text_field_tag :ssh_project_clone, project.ssh_url_to_repo, class: "js-select-on-focus form-control qa-ssh-clone-url", readonly: true, aria: { label: 'Project clone URL' }
.input-group-append
- = clipboard_button(target: '#ssh_project_clone', title: _("Copy URL to clipboard"), class: "input-group-text btn-default btn-clipboard")
+ = clipboard_button(target: '#ssh_project_clone', title: _("Copy URL"), class: "input-group-text btn-default btn-clipboard")
= render_if_exists 'projects/buttons/geo'
- if http_enabled?
%li.pt-2
@@ -22,7 +22,7 @@
.input-group
= text_field_tag :http_project_clone, project.http_url_to_repo, class: "js-select-on-focus form-control qa-http-clone-url", readonly: true, aria: { label: 'Project clone URL' }
.input-group-append
- = clipboard_button(target: '#http_project_clone', title: _("Copy URL to clipboard"), class: "input-group-text btn-default btn-clipboard")
+ = 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'
diff --git a/app/views/projects/commit/_commit_box.html.haml b/app/views/projects/commit/_commit_box.html.haml
index 6c77036a85b..d07407a6d13 100644
--- a/app/views/projects/commit/_commit_box.html.haml
+++ b/app/views/projects/commit/_commit_box.html.haml
@@ -6,7 +6,7 @@
%strong
#{ s_('CommitBoxTitle|Commit') }
%span.commit-sha{ data: { qa_selector: 'commit_sha_content' } }= @commit.short_id
- = clipboard_button(text: @commit.id, title: _('Copy commit SHA to clipboard'))
+ = clipboard_button(text: @commit.id, title: _('Copy commit SHA'))
%span.d-none.d-sm-inline= _('authored')
#{time_ago_with_tooltip(@commit.authored_date)}
%span= s_('ByAuthor|by')
diff --git a/app/views/projects/commits/_commit.html.haml b/app/views/projects/commits/_commit.html.haml
index 2c78e74be2f..3a9c7a8bec5 100644
--- a/app/views/projects/commits/_commit.html.haml
+++ b/app/views/projects/commits/_commit.html.haml
@@ -6,7 +6,8 @@
- merge_request = local_assigns.fetch(:merge_request, nil)
- project = local_assigns.fetch(:project) { merge_request&.project }
- ref = local_assigns.fetch(:ref) { merge_request&.source_branch }
-- commit_status = commit.present(current_user: current_user).status_for(ref)
+- commit = commit.present(current_user: current_user)
+- commit_status = commit.status_for(ref)
- link = commit_path(project, commit, merge_request: merge_request)
@@ -48,12 +49,12 @@
= render partial: 'projects/commit/ajax_signature', locals: { commit: commit }
- if commit_status
- = render_commit_status(commit, ref: ref)
+ = render_commit_status(commit, commit_status, ref: ref)
.js-commit-pipeline-status{ data: { endpoint: pipelines_project_commit_path(project, commit.id, ref: ref) } }
.commit-sha-group.d-none.d-sm-flex
.label.label-monospace.monospace
= commit.short_id
- = clipboard_button(text: commit.id, title: _("Copy commit SHA to clipboard"), class: "btn btn-default", container: "body")
+ = clipboard_button(text: commit.id, title: _("Copy commit SHA"), class: "btn btn-default", container: "body")
= link_to_browse_code(project, commit)
diff --git a/app/views/projects/cycle_analytics/_overview.html.haml b/app/views/projects/cycle_analytics/_overview.html.haml
index 5b0d73b8c68..ea94b637f89 100644
--- a/app/views/projects/cycle_analytics/_overview.html.haml
+++ b/app/views/projects/cycle_analytics/_overview.html.haml
@@ -9,7 +9,7 @@
Cycle Analytics gives an overview of how much time it takes to go from idea to production in your project.
To set up CA, you must first define a production environment by setting up your CI and then deploy to production.
%p
- %a.btn{ href: help_page_path('user/project/cycle_analytics'), target: '_blank' } Read more
+ %a.btn{ href: help_page_path('user/analytics/cycle_analytics.md'), target: '_blank' } Read more
.col-md-6.overview-image
%span.overview-icon
= custom_icon ('icon_cycle_analytics_overview')
diff --git a/app/views/projects/cycle_analytics/show.html.haml b/app/views/projects/cycle_analytics/show.html.haml
index 6b56a4ee7ab..7fedd1ab785 100644
--- a/app/views/projects/cycle_analytics/show.html.haml
+++ b/app/views/projects/cycle_analytics/show.html.haml
@@ -3,7 +3,7 @@
#cycle-analytics{ "v-cloak" => "true", data: { request_path: project_cycle_analytics_path(@project) } }
- if @cycle_analytics_no_data
%banner{ "v-if" => "!isOverviewDialogDismissed",
- "documentation-link": help_page_path('user/project/cycle_analytics'),
+ "documentation-link": help_page_path('user/analytics/cycle_analytics.md'),
"v-on:dismiss-overview-dialog" => "dismissOverviewDialog()" }
= icon("spinner spin", "v-show" => "isLoading")
.wrapper{ "v-show" => "!isLoading && !hasError" }
diff --git a/app/views/projects/deploy_tokens/_new_deploy_token.html.haml b/app/views/projects/deploy_tokens/_new_deploy_token.html.haml
index c805ee73acc..f295fa82192 100644
--- a/app/views/projects/deploy_tokens/_new_deploy_token.html.haml
+++ b/app/views/projects/deploy_tokens/_new_deploy_token.html.haml
@@ -7,12 +7,12 @@
.input-group
= text_field_tag 'deploy-token-user', deploy_token.username, readonly: true, class: 'deploy-token-field form-control js-select-on-focus qa-deploy-token-user'
.input-group-append
- = clipboard_button(text: deploy_token.username, title: s_('DeployTokens|Copy username to clipboard'), placement: 'left')
+ = clipboard_button(text: deploy_token.username, title: s_('DeployTokens|Copy username'), placement: 'left')
%span.deploy-token-help-block.prepend-top-5.text-success= s_("DeployTokens|Use this username as a login.")
.form-group
.input-group
= text_field_tag 'deploy-token', deploy_token.token, readonly: true, class: 'deploy-token-field form-control js-select-on-focus qa-deploy-token'
.input-group-append
- = clipboard_button(text: deploy_token.token, title: s_('DeployTokens|Copy deploy token to clipboard'), placement: 'left')
+ = clipboard_button(text: deploy_token.token, title: s_('DeployTokens|Copy deploy token'), placement: 'left')
%span.deploy-token-help-block.prepend-top-5.text-danger= s_("DeployTokens|Use this token as a password. Make sure you save it - you won't be able to access it again.")
diff --git a/app/views/projects/deployments/_deployment.html.haml b/app/views/projects/deployments/_deployment.html.haml
index ef2ab4c698e..8270477ed3f 100644
--- a/app/views/projects/deployments/_deployment.html.haml
+++ b/app/views/projects/deployments/_deployment.html.haml
@@ -1,31 +1,49 @@
.gl-responsive-table-row.deployment{ role: 'row' }
+ .table-section.section-15{ role: 'gridcell' }
+ .table-mobile-header{ role: 'rowheader' }= _("Status")
+ .table-mobile-content
+ = render_deployment_status(deployment)
+
.table-section.section-10{ role: 'gridcell' }
.table-mobile-header{ role: 'rowheader' }= _("ID")
%strong.table-mobile-content ##{deployment.iid}
- .table-section.section-30{ role: 'gridcell' }
+ .table-section.section-10{ role: 'gridcell' }
+ .table-mobile-header{ role: 'rowheader' }= _("Triggerer")
+ .table-mobile-content
+ - if deployment.deployed_by
+ = user_avatar(user: deployment.deployed_by, size: 26, css_class: "mr-0 float-none")
+
+ .table-section.section-25{ role: 'gridcell' }
.table-mobile-header{ role: 'rowheader' }= _("Commit")
= render 'projects/deployments/commit', deployment: deployment
- .table-section.section-25.build-column{ role: 'gridcell' }
+ .table-section.section-10.build-column{ role: 'gridcell' }
.table-mobile-header{ role: 'rowheader' }= _("Job")
- if deployment.deployable
.table-mobile-content
.flex-truncate-parent
.flex-truncate-child
- = link_to [@project.namespace.becomes(Namespace), @project, deployment.deployable], class: 'build-link' do
+ = link_to deployment_path(deployment), class: 'build-link' do
#{deployment.deployable.name} (##{deployment.deployable.id})
- - if deployment.deployed_by
- %div
- by
- = user_avatar(user: deployment.deployed_by, size: 20, css_class: "mr-0 float-none")
+ - else
+ .badge.badge-info.suggestion-help-hover{ title: s_('Deployment|This deployment was created using the API') }
+ = s_('Deployment|API')
- .table-section.section-15{ role: 'gridcell' }
+ .table-section.section-10{ role: 'gridcell' }
.table-mobile-header{ role: 'rowheader' }= _("Created")
+ %span.table-mobile-content.flex-truncate-parent
+ %span.flex-truncate-child
+ = time_ago_with_tooltip(deployment.created_at)
+
+ .table-section.section-10{ role: 'gridcell' }
+ .table-mobile-header{ role: 'rowheader' }= _("Deployed")
- if deployment.deployed_at
- %span.table-mobile-content= time_ago_with_tooltip(deployment.deployed_at)
+ %span.table-mobile-content.flex-truncate-parent
+ %span.flex-truncate-child
+ = time_ago_with_tooltip(deployment.deployed_at)
- .table-section.section-20.table-button-footer{ role: 'gridcell' }
+ .table-section.section-10.table-button-footer{ role: 'gridcell' }
.btn-group.table-action-buttons
= render 'projects/deployments/actions', deployment: deployment
= render 'projects/deployments/rollback', deployment: deployment
diff --git a/app/views/projects/deployments/_rollback.haml b/app/views/projects/deployments/_rollback.haml
index d6bf8d564de..dffa5e4ba40 100644
--- a/app/views/projects/deployments/_rollback.haml
+++ b/app/views/projects/deployments/_rollback.haml
@@ -1,4 +1,4 @@
-- if can?(current_user, :create_deployment, deployment)
+- if deployment.deployable && can?(current_user, :create_deployment, deployment)
- tooltip = deployment.last? ? s_('Environments|Re-deploy to environment') : s_('Environments|Rollback environment')
= button_tag class: 'btn btn-default btn-build has-tooltip', type: 'button', data: { toggle: 'modal', target: "#confirm-rollback-modal-#{deployment.id}" }, title: tooltip do
- if deployment.last?
diff --git a/app/views/projects/diffs/_diffs.html.haml b/app/views/projects/diffs/_diffs.html.haml
index 2dba3fcd664..cf7fe36af9d 100644
--- a/app/views/projects/diffs/_diffs.html.haml
+++ b/app/views/projects/diffs/_diffs.html.haml
@@ -21,7 +21,7 @@
= parallel_diff_btn
= render 'projects/diffs/stats', diff_files: diff_files
-- if render_overflow_warning?(diff_files)
+- if render_overflow_warning?(diffs)
= render 'projects/diffs/warning', diff_files: diffs
.files{ data: { can_create_note: can_create_note } }
diff --git a/app/views/projects/diffs/_stats.html.haml b/app/views/projects/diffs/_stats.html.haml
index c9057f385da..86e6e732610 100644
--- a/app/views/projects/diffs/_stats.html.haml
+++ b/app/views/projects/diffs/_stats.html.haml
@@ -24,9 +24,9 @@
%a.diff-changed-file{ href: "##{hexdigest(diff_file.file_path)}", title: diff_file.new_path }
= sprite_icon(diff_file_changed_icon(diff_file), size: 16, css_class: "#{diff_file_changed_icon_color(diff_file)} diff-file-changed-icon append-right-8")
%span.diff-changed-file-content.append-right-8
- - if diff_file.blob&.name
+ - if diff_file.file_path
%strong.diff-changed-file-name
- = diff_file.blob.name
+ = diff_file.file_path
- else
%strong.diff-changed-blank-file-name
= s_('Diffs|No file name available')
diff --git a/app/views/projects/environments/show.html.haml b/app/views/projects/environments/show.html.haml
index 75da151f329..c4c39c227c6 100644
--- a/app/views/projects/environments/show.html.haml
+++ b/app/views/projects/environments/show.html.haml
@@ -60,10 +60,13 @@
.table-holder
.ci-table.environments{ role: 'grid' }
.gl-responsive-table-row.table-row-header{ role: 'row' }
+ .table-section.section-15{ role: 'columnheader' }= _('Status')
.table-section.section-10{ role: 'columnheader' }= _('ID')
- .table-section.section-30{ role: 'columnheader' }= _('Commit')
- .table-section.section-25{ role: 'columnheader' }= _('Job')
- .table-section.section-15{ role: 'columnheader' }= _('Created')
+ .table-section.section-10{ role: 'columnheader' }= _('Triggerer')
+ .table-section.section-25{ role: 'columnheader' }= _('Commit')
+ .table-section.section-10{ role: 'columnheader' }= _('Job')
+ .table-section.section-10{ role: 'columnheader' }= _('Created')
+ .table-section.section-10{ role: 'columnheader' }= _('Deployed')
= render @deployments
diff --git a/app/views/projects/find_file/show.html.haml b/app/views/projects/find_file/show.html.haml
index 82f035f24da..caaf164a763 100644
--- a/app/views/projects/find_file/show.html.haml
+++ b/app/views/projects/find_file/show.html.haml
@@ -15,4 +15,12 @@
.table-holder
%table.table.files-slider{ class: "table_#{@hex_path} tree-table" }
%tbody
+ .col-12.empty-state.hidden
+ .svg-250.svg-content
+ = image_tag('illustrations/profile-page/personal-projects.svg', alt: 'No files svg', lazy: true)
+ .text-center
+ %h4
+ = _('There are no matching files')
+ %p.text-secondary
+ = _('Try using a different search term to find the file you are looking for.')
= spinner nil, true
diff --git a/app/views/projects/issues/_issue.html.haml b/app/views/projects/issues/_issue.html.haml
index de0c21e7cf6..367b8c1138e 100644
--- a/app/views/projects/issues/_issue.html.haml
+++ b/app/views/projects/issues/_issue.html.haml
@@ -43,7 +43,10 @@
.issuable-meta
%ul.controls
- - if issue.closed?
+ - if issue.moved?
+ %li.issuable-status
+ = _('CLOSED (MOVED)')
+ - elsif issue.closed?
%li.issuable-status
= _('CLOSED')
- if issue.assignees.any?
diff --git a/app/views/projects/issues/import_csv/_button.html.haml b/app/views/projects/issues/import_csv/_button.html.haml
index acc2c50294f..fe89d2fb748 100644
--- a/app/views/projects/issues/import_csv/_button.html.haml
+++ b/app/views/projects/issues/import_csv/_button.html.haml
@@ -3,7 +3,7 @@
%button.csv-import-button.btn{ title: _('Import CSV'), class: ('has-tooltip' if type == :icon),
data: { toggle: 'modal', target: '.issues-import-modal' } }
- if type == :icon
- = sprite_icon('upload')
+ = sprite_icon('import')
- else
= _('Import CSV')
diff --git a/app/views/projects/issues/index.html.haml b/app/views/projects/issues/index.html.haml
index 49e482ff1df..2633a3899f7 100644
--- a/app/views/projects/issues/index.html.haml
+++ b/app/views/projects/issues/index.html.haml
@@ -20,4 +20,5 @@
- if new_issue_email
= render 'projects/issuable_by_email', email: new_issue_email, issuable_type: 'issue'
- else
- = render 'shared/empty_states/issues', button_path: new_project_issue_path(@project), show_import_button: true
+ - new_project_issue_button_path = @project.archived? ? false : new_project_issue_path(@project)
+ = render 'shared/empty_states/issues', new_project_issue_button_path: new_project_issue_button_path, show_import_button: true
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 928b54ea28f..57205682bda 100644
--- a/app/views/projects/merge_requests/_how_to_merge.html.haml
+++ b/app/views/projects/merge_requests/_how_to_merge.html.haml
@@ -9,7 +9,7 @@
%p
%strong Step 1.
Fetch and check out the branch for this merge request
- = clipboard_button(target: "pre#merge-info-1", title: "Copy commands to clipboard")
+ = clipboard_button(target: "pre#merge-info-1", title: _("Copy commands"))
%pre.dark#merge-info-1
- if @merge_request.for_fork?
:preserve
@@ -27,7 +27,7 @@
%p
%strong Step 3.
Merge the branch and fix any conflicts that come up
- = clipboard_button(target: "pre#merge-info-3", title: "Copy commands to clipboard")
+ = clipboard_button(target: "pre#merge-info-3", title: _("Copy commands"))
%pre.dark#merge-info-3
- if @merge_request.for_fork?
:preserve
@@ -42,7 +42,7 @@
%p
%strong Step 4.
Push the result of the merge to GitLab
- = clipboard_button(target: "pre#merge-info-4", title: "Copy commands to clipboard")
+ = clipboard_button(target: "pre#merge-info-4", title: _("Copy commands"))
%pre.dark#merge-info-4
:preserve
git push origin "#{h @merge_request.target_branch}"
diff --git a/app/views/projects/merge_requests/show.html.haml b/app/views/projects/merge_requests/show.html.haml
index da90c41e2f5..dee6bc8bae4 100644
--- a/app/views/projects/merge_requests/show.html.haml
+++ b/app/views/projects/merge_requests/show.html.haml
@@ -24,6 +24,7 @@
window.gl.mrWidgetData.squash_before_merge_help_path = '#{help_page_path("user/project/merge_requests/squash_and_merge")}';
window.gl.mrWidgetData.troubleshooting_docs_path = '#{help_page_path('user/project/merge_requests/index.md', anchor: 'troubleshooting')}';
+ window.gl.mrWidgetData.security_approvals_help_page_path = '#{help_page_path('user/application_security/index.html', anchor: 'security-approvals-in-merge-requests-ultimate')}';
#js-vue-mr-widget.mr-widget
diff --git a/app/views/projects/mirrors/_mirror_repos.html.haml b/app/views/projects/mirrors/_mirror_repos.html.haml
index 104c68919f0..80d2d2afada 100644
--- a/app/views/projects/mirrors/_mirror_repos.html.haml
+++ b/app/views/projects/mirrors/_mirror_repos.html.haml
@@ -1,7 +1,7 @@
- expanded = expanded_by_default?
- protocols = Gitlab::UrlSanitizer::ALLOWED_SCHEMES.join('|')
-%section.settings.project-mirror-settings.js-mirror-settings.no-animate.qa-mirroring-repositories-settings#js-push-remote-settings{ class: ('expanded' if expanded) }
+%section.settings.project-mirror-settings.js-mirror-settings.no-animate#js-push-remote-settings{ class: ('expanded' if expanded), data: { qa_selector: 'mirroring_repositories_settings_section' } }
.settings-header
%h4= _('Mirroring repositories')
%button.btn.js-settings-toggle
@@ -59,10 +59,10 @@
- if mirror.disabled?
= render 'projects/mirrors/disabled_mirror_badge'
- if mirror.last_error.present?
- .badge.mirror-error-badge{ data: { toggle: 'tooltip', html: 'true' }, title: html_escape(mirror.last_error.try(:strip)) }= _('Error')
+ .badge.mirror-error-badge{ data: { toggle: 'tooltip', html: 'true', qa_selector: 'mirror_error_badge' }, title: html_escape(mirror.last_error.try(:strip)) }= _('Error')
%td
.btn-group.mirror-actions-group.pull-right{ role: 'group' }
- if mirror.ssh_key_auth?
- = clipboard_button(text: mirror.ssh_public_key, class: 'btn btn-default', title: _('Copy SSH public key'))
+ = clipboard_button(text: mirror.ssh_public_key, class: 'btn btn-default', title: _('Copy SSH public key'), qa_selector: 'copy_public_key_button')
= render 'shared/remote_mirror_update_button', remote_mirror: mirror
%button.js-delete-mirror.qa-delete-mirror.rspec-delete-mirror.btn.btn-danger{ type: 'button', data: { mirror_id: mirror.id, toggle: 'tooltip', container: 'body' }, title: _('Remove') }= icon('trash-o')
diff --git a/app/views/projects/mirrors/_ssh_host_keys.html.haml b/app/views/projects/mirrors/_ssh_host_keys.html.haml
index 7762fb4b844..3279d3eb251 100644
--- a/app/views/projects/mirrors/_ssh_host_keys.html.haml
+++ b/app/views/projects/mirrors/_ssh_host_keys.html.haml
@@ -3,13 +3,13 @@
- verified_at = mirror.ssh_known_hosts_verified_at
.form-group.js-ssh-host-keys-section{ class: ('collapse' unless mirror.ssh_mirror_url?) }
- %button.btn.btn-inverted.btn-secondary.inline.js-detect-host-keys.append-right-10{ type: 'button' }
+ %button.btn.btn-inverted.btn-secondary.inline.js-detect-host-keys.append-right-10{ type: 'button', data: { qa_selector: 'detect_host_keys' } }
= icon('spinner spin', class: 'js-spinner d-none')
= _('Detect host keys')
.fingerprint-ssh-info.js-fingerprint-ssh-info.prepend-top-10.append-bottom-10{ class: ('collapse' unless mirror.ssh_mirror_url?) }
%label.label-bold
= _('Fingerprints')
- .fingerprints-list.js-fingerprints-list
+ .fingerprints-list.js-fingerprints-list{ data: { qa_selector: 'fingerprints_list' } }
- mirror.ssh_known_hosts_fingerprints.each do |fp|
%code= fp.fingerprint
- if verified_at
diff --git a/app/views/projects/notes/_more_actions_dropdown.html.haml b/app/views/projects/notes/_more_actions_dropdown.html.haml
index 8a6e5fde99b..2f0394538bb 100644
--- a/app/views/projects/notes/_more_actions_dropdown.html.haml
+++ b/app/views/projects/notes/_more_actions_dropdown.html.haml
@@ -7,7 +7,7 @@
= custom_icon('ellipsis_v')
%ul.dropdown-menu.more-actions-dropdown.dropdown-open-left
%li
- = clipboard_button(text: noteable_note_url(note), title: 'Copy reference to clipboard', button_text: 'Copy link', class: 'btn-clipboard', hide_tooltip: true, hide_button_icon: true)
+ = clipboard_button(text: noteable_note_url(note), title: _('Copy reference'), button_text: _('Copy link'), class: 'btn-clipboard', hide_tooltip: true, hide_button_icon: true)
- unless is_current_user
%li
= link_to new_abuse_report_path(user_id: note.author.id, ref_url: noteable_note_url(note)) do
diff --git a/app/views/projects/pages/_access.html.haml b/app/views/projects/pages/_access.html.haml
index 7b6d46964a2..178f0acc5b9 100644
--- a/app/views/projects/pages/_access.html.haml
+++ b/app/views/projects/pages/_access.html.haml
@@ -1,11 +1,11 @@
- if @project.pages_deployed?
.card
.card-header
- Access pages
+ = s_('GitLabPages|Access pages')
.card-body
%p
%strong
- = _("Your pages are served under:")
+ = s_('GitLabPages|Your pages are served under:')
%p
= external_link(@project.pages_url, @project.pages_url)
@@ -14,4 +14,4 @@
%p
= external_link(domain.url, domain.url)
.card-footer.alert-primary
- = _("It may take up to 30 minutes before the site is available after the first deployment.")
+ = 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/_destroy.haml b/app/views/projects/pages/_destroy.haml
index 138e2864bad..58dbbb5bcfc 100644
--- a/app/views/projects/pages/_destroy.haml
+++ b/app/views/projects/pages/_destroy.haml
@@ -1,12 +1,14 @@
- if @project.pages_deployed?
- if can?(current_user, :remove_pages, @project)
.card.border-danger
- .card-header.bg-danger.text-white Remove pages
+ .card-header.bg-danger.text-white
+ = s_('GitLabPages|Remove pages')
.errors-holder
.card-body
%p
- Removing pages will prevent them from being exposed to the outside world.
+ = s_('GitLabPages|Removing pages will prevent them from being exposed to the outside world.')
.form-actions
- = link_to 'Remove pages', project_pages_path(@project), data: { confirm: 'Are you sure?'}, method: :delete, class: "btn btn-remove"
+ = link_to s_('GitLabPages|Remove pages'), project_pages_path(@project), data: { confirm: s_('GitLabPages|Are you sure?')}, method: :delete, class: "btn btn-remove"
- else
- .nothing-here-block Only project maintainers can remove pages
+ .nothing-here-block
+ = s_('GitLabPages|Only project maintainers can remove pages')
diff --git a/app/views/projects/pages/_https_only.html.haml b/app/views/projects/pages/_https_only.html.haml
index 74478ee011c..d8c4a5f0a5d 100644
--- a/app/views/projects/pages/_https_only.html.haml
+++ b/app/views/projects/pages/_https_only.html.haml
@@ -3,8 +3,9 @@
.form-check
= f.check_box :pages_https_only, class: 'form-check-input', disabled: pages_https_only_disabled?
= f.label :pages_https_only, class: pages_https_only_label_class do
- %strong Force HTTPS (requires valid certificates)
+ %strong
+ = s_('GitLabPages|Force HTTPS (requires valid certificates)')
- unless pages_https_only_disabled?
.prepend-top-10
- = f.submit 'Save', class: 'btn btn-success'
+ = f.submit s_('GitLabPages|Save'), class: 'btn btn-success'
diff --git a/app/views/projects/pages/_list.html.haml b/app/views/projects/pages/_list.html.haml
index c4285e7f3d2..b05491f2c6e 100644
--- a/app/views/projects/pages/_list.html.haml
+++ b/app/views/projects/pages/_list.html.haml
@@ -8,20 +8,25 @@
- @domains.each do |domain|
%li.pages-domain-list-item.list-group-item.d-flex.justify-content-between
- if verification_enabled
- - tooltip, status = domain.unverified? ? [_('Unverified'), 'failed'] : [_('Verified'), 'success']
+ - tooltip, status = domain.unverified? ? [s_('GitLabPages|Unverified'), 'failed'] : [s_('GitLabPages|Verified'), 'success']
.domain-status.ci-status-icon.has-tooltip{ class: "ci-status-icon-#{status}", title: tooltip }
= sprite_icon("status_#{status}", size: 16 )
.domain-name
= external_link(domain.url, domain.url)
- if domain.subject
%div
- %span.badge.badge-gray Certificate: #{domain.subject}
+ %span.badge.badge-gray
+ = s_('GitLabPages|Certificate: %{subject}') % { subject: domain.subject }
- if domain.expired?
- %span.badge.badge-danger Expired
+ %span.badge.badge-danger
+ = s_('GitLabPages|Expired')
%div
- = link_to 'Details', project_pages_domain_path(@project, domain), class: "btn btn-sm btn-grouped"
- = link_to 'Remove', project_pages_domain_path(@project, domain), data: { confirm: 'Are you sure?'}, method: :delete, class: "btn btn-remove btn-sm btn-grouped"
+ = link_to s_('GitLabPages|Details'), project_pages_domain_path(@project, domain), class: "btn btn-sm btn-grouped"
+ = 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
- #{domain.domain} is not verified. To learn how to verify ownership, visit your
- #{link_to 'domain details', project_pages_domain_path(@project, domain)}.
+ - details_link_start = "<a href='#{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,
+ link_end: details_link_end }
diff --git a/app/views/projects/pages/_no_domains.html.haml b/app/views/projects/pages/_no_domains.html.haml
index 8c93cf7a8ad..8d6e403b93a 100644
--- a/app/views/projects/pages/_no_domains.html.haml
+++ b/app/views/projects/pages/_no_domains.html.haml
@@ -1,7 +1,6 @@
- if can?(current_user, :update_pages, @project)
.card
.card-header
- Domains
+ = s_('GitLabPages|Domains')
.nothing-here-block
- Support for domains and certificates is disabled.
- Ask your system's administrator to enable it.
+ = s_("GitLabPages|Support for domains and certificates is disabled. Ask your system's administrator to enable it.")
diff --git a/app/views/projects/pages/_use.html.haml b/app/views/projects/pages/_use.html.haml
index 988dabef3a0..ab44fd77e1e 100644
--- a/app/views/projects/pages/_use.html.haml
+++ b/app/views/projects/pages/_use.html.haml
@@ -1,10 +1,10 @@
- unless @project.pages_deployed?
.card.border-info
.card-header.bg-info.text-white
- Configure pages
+ = s_('GitLabPages|Configure pages')
.card-body
%p
- Learn how to upload your static site and have it served by
- GitLab by following the
- = succeed '.' do
- = link_to 'documentation on GitLab Pages', help_page_path('user/project/pages/index.md'), target: '_blank'
+ - link_start = "<a href='#{help_page_path('user/project/pages/index.md')}' target='_blank' rel='noopener noreferrer'>".html_safe
+ - link_end = '</a>'.html_safe
+ = s_('GitLabPages|Learn how to upload your static site and have it served by GitLab by following the %{link_start}documentation on GitLab Pages%{link_end}.').html_safe % { link_start: link_start,
+ link_end: link_end }
diff --git a/app/views/projects/pages/show.html.haml b/app/views/projects/pages/show.html.haml
index 88ab486a248..0e1f281410a 100644
--- a/app/views/projects/pages/show.html.haml
+++ b/app/views/projects/pages/show.html.haml
@@ -1,17 +1,14 @@
- page_title 'Pages'
%h3.page-title.with-button
- Pages
+ = 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: 'New Domain' do
- New Domain
+ = 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
- 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.
-
+ = 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'
diff --git a/app/views/projects/pipelines/_info.html.haml b/app/views/projects/pipelines/_info.html.haml
index 53bb3c7487d..4eec81c9125 100644
--- a/app/views/projects/pipelines/_info.html.haml
+++ b/app/views/projects/pipelines/_info.html.haml
@@ -43,7 +43,7 @@
} }
Auto DevOps
- if @pipeline.detached_merge_request_pipeline?
- %span.js-pipeline-url-mergerequest.badge.badge-info.has-tooltip{ title: _('Pipelines for merge requests are configured. A detached pipeline runs in the context of the merge request, and not against the merged result. Learn more on the documentation for Pipelines for Merged Results.') }
+ %span.js-pipeline-url-mergerequest.badge.badge-info.has-tooltip{ title: _('Pipelines for merge requests are configured. A detached pipeline runs in the context of the merge request, and not against the merged result. Learn more in the documentation for Pipelines for Merged Results.') }
detached
- if @pipeline.stuck?
%span.js-pipeline-url-stuck.badge.badge-warning
@@ -58,4 +58,10 @@
= sprite_icon('ellipsis_h', size: 12)
%span.js-details-content.hide
= link_to @pipeline.sha, project_commit_path(@project, @pipeline.sha), class: "commit-sha commit-hash-full"
- = clipboard_button(text: @pipeline.sha, title: "Copy commit SHA to clipboard")
+ = clipboard_button(text: @pipeline.sha, title: _("Copy commit SHA"))
+
+ .well-segment.related-merge-request-info
+ .icon-container
+ = sprite_icon("git-merge")
+ %span.related-merge-requests
+ = @pipeline.all_related_merge_request_text
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 1913d06a6f8..9dff251101b 100644
--- a/app/views/projects/protected_branches/shared/_branches_list.html.haml
+++ b/app/views/projects/protected_branches/shared/_branches_list.html.haml
@@ -1,9 +1,9 @@
.protected-branches-list.js-protected-branches-list.qa-protected-branches-list
- if @protected_branches.empty?
.card-header.bg-white
- Protected branch (#{@protected_branches_count})
+ = s_("ProtectedBranch|Protected branch (%{protected_branches_count})") % { protected_branches_count: @protected_branches_count }
%p.settings-message.text-center
- There are currently no protected branches, protect a branch with the form above.
+ = s_("ProtectedBranch|There are currently no protected branches, protect a branch with the form above.")
- else
%table.table.table-bordered
%colgroup
@@ -15,10 +15,15 @@
%col
%thead
%tr
- %th Protected branch (#{@protected_branches_count})
- %th Last commit
- %th Allowed to merge
- %th Allowed to push
+ %th
+ = s_("ProtectedBranch|Branch")
+ %th
+ = s_("ProtectedBranch|Allowed to merge")
+ %th
+ = s_("ProtectedBranch|Allowed to push")
+
+ = render_if_exists 'projects/protected_branches/ee/code_owner_approval_table_head'
+
- if can_admin_project
%th
%tbody
diff --git a/app/views/projects/protected_branches/shared/_create_protected_branch.html.haml b/app/views/projects/protected_branches/shared/_create_protected_branch.html.haml
index bba4949277d..f84c7b39733 100644
--- a/app/views/projects/protected_branches/shared/_create_protected_branch.html.haml
+++ b/app/views/projects/protected_branches/shared/_create_protected_branch.html.haml
@@ -2,7 +2,7 @@
%input{ type: 'hidden', name: 'update_section', value: 'js-protected-branches-settings' }
.card
.card-header
- Protect a branch
+ = s_("ProtectedBranch|Protect a branch")
.card-body
= form_errors(@protected_branch)
.form-group.row
@@ -11,22 +11,19 @@
.col-md-10
= render partial: "projects/protected_branches/shared/dropdown", locals: { f: f }
.form-text.text-muted
- = link_to 'Wildcards', help_page_path('user/project/protected_branches', anchor: 'wildcard-protected-branches')
- such as
- %code *-stable
- or
- %code production/*
- are supported
+ - wildcards_url = help_page_url('user/project/protected_branches', anchor: 'wildcard-protected-branches')
+ - wildcards_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: wildcards_url }
+ = (s_("ProtectedBranch|%{wildcards_link_start}Wildcards%{wildcards_link_end} such as %{code_tag_start}*-stable%{code_tag_end} or %{code_tag_start}production/*%{code_tag_end} are supported") % { wildcards_link_start: wildcards_link_start, wildcards_link_end: '</a>', code_tag_start: '<code>', code_tag_end: '</code>' }).html_safe
.form-group.row
%label.col-md-2.text-right{ for: 'merge_access_levels_attributes' }
- Allowed to merge:
+ = s_("ProtectedBranch|Allowed to merge:")
.col-md-10
= yield :merge_access_levels
.form-group.row
%label.col-md-2.text-right{ for: 'push_access_levels_attributes' }
- Allowed to push:
+ = s_("ProtectedBranch|Allowed to push:")
.col-md-10
= yield :push_access_levels
-
+ = render_if_exists 'projects/protected_branches/ee/code_owner_approval_form'
.card-footer
- = f.submit 'Protect', class: 'btn-success btn', disabled: true, data: { qa_selector: 'protect_button' }
+ = f.submit s_('ProtectedBranch|Protect'), class: 'btn-success btn', disabled: true, data: { qa_selector: 'protect_button' }
diff --git a/app/views/projects/protected_branches/shared/_protected_branch.html.haml b/app/views/projects/protected_branches/shared/_protected_branch.html.haml
index 81dcab1d1ab..4ca6ebe9c78 100644
--- a/app/views/projects/protected_branches/shared/_protected_branch.html.haml
+++ b/app/views/projects/protected_branches/shared/_protected_branch.html.haml
@@ -5,20 +5,19 @@
%span.ref-name= protected_branch.name
- if @project.root_ref?(protected_branch.name)
- %span.badge.badge-info.prepend-left-5 default
- %td
- - if protected_branch.wildcard?
- - matching_branches = protected_branch.matching(repository.branches)
- = link_to pluralize(matching_branches.count, "matching branch"), namespace_project_protected_branch_path(@project.namespace, @project, protected_branch)
- - else
- - if commit = protected_branch.commit
- = link_to(commit.short_id, namespace_project_commit_path(@project.namespace, @project, commit.id), class: 'commit-sha')
- = time_ago_with_tooltip(commit.committed_date)
- - else
- (branch was deleted from repository)
+ %span.badge.badge-info.d-inline default
+
+ %div
+ - if protected_branch.wildcard?
+ - matching_branches = protected_branch.matching(repository.branches)
+ = link_to pluralize(matching_branches.count, "matching branch"), namespace_project_protected_branch_path(@project.namespace, @project, protected_branch)
+ - elsif !protected_branch.commit
+ %span.text-muted Branch was deleted.
= yield
+ = render_if_exists 'projects/protected_branches/ee/code_owner_approval_table', protected_branch: protected_branch
+
- if can_admin_project
%td
= link_to 'Unprotect', [@project.namespace.becomes(Namespace), @project, protected_branch, { update_section: 'js-protected-branches-settings' }], disabled: local_assigns[:disabled], data: { confirm: 'Branch will be writable for developers. Are you sure?' }, method: :delete, class: "btn btn-warning"
diff --git a/app/views/projects/registry/repositories/index.html.haml b/app/views/projects/registry/repositories/index.html.haml
index d0d06a0df7e..b2e160e37bc 100644
--- a/app/views/projects/registry/repositories/index.html.haml
+++ b/app/views/projects/registry/repositories/index.html.haml
@@ -1,9 +1,14 @@
+- page_title _("Container Registry")
+
%section
.row.registry-placeholder.prepend-bottom-10
.col-12
#js-vue-registry-images{ data: { endpoint: project_container_registry_index_path(@project, format: :json),
"help_page_path" => help_page_path('user/packages/container_registry/index'),
+ "two_factor_auth_help_link" => help_page_path('user/profile/account/two_factor_authentication'),
+ "personal_access_tokens_help_link" => help_page_path('user/profile/personal_access_tokens'),
"no_containers_image" => image_path('illustrations/docker-empty-state.svg'),
"containers_error_image" => image_path('illustrations/docker-error-state.svg'),
"repository_url" => escape_once(@project.container_registry_url),
+ "registry_host_url_with_port" => escape_once(registry_config.host_port),
character_error: @character_error.to_s } }
diff --git a/app/views/projects/releases/edit.html.haml b/app/views/projects/releases/edit.html.haml
new file mode 100644
index 00000000000..88ca64f2af0
--- /dev/null
+++ b/app/views/projects/releases/edit.html.haml
@@ -0,0 +1,3 @@
+- page_title _('Edit Release')
+
+#js-edit-release-page{ data: data_for_edit_release_page }
diff --git a/app/views/projects/runners/_specific_runners.html.haml b/app/views/projects/runners/_specific_runners.html.haml
index dc56a515d4c..4cc67a8f5d8 100644
--- a/app/views/projects/runners/_specific_runners.html.haml
+++ b/app/views/projects/runners/_specific_runners.html.haml
@@ -2,28 +2,9 @@
= _('Specific Runners')
.bs-callout.help-callout
- .append-bottom-10
- %h4= _('Set up a specific Runner automatically')
-
- %p
- - link_to_help_page = link_to(_('Learn more about Kubernetes'),
- help_page_path('user/project/clusters/index'),
- target: '_blank',
- rel: 'noopener noreferrer')
-
- = _('You can easily install a Runner on a Kubernetes cluster. %{link_to_help_page}').html_safe % { link_to_help_page: link_to_help_page }
-
- %ol
- %li
- = _('Click the button below to begin the install process by navigating to the Kubernetes page')
- %li
- = _('Select an existing Kubernetes cluster or create a new one')
- %li
- = _('From the Kubernetes cluster details view, install Runner from the applications list')
-
- = link_to _('Install Runner on Kubernetes'),
- project_clusters_path(@project),
- class: 'btn btn-info'
+ = render partial: 'ci/runner/how_to_setup_runner_automatically',
+ locals: { type: 'specific',
+ clusters_path: project_clusters_path(@project) }
%hr
= render partial: 'ci/runner/how_to_setup_runner',
locals: { registration_token: @project.runners_token,
diff --git a/app/views/projects/settings/ci_cd/_autodevops_form.html.haml b/app/views/projects/settings/ci_cd/_autodevops_form.html.haml
index 1d5d90593ae..6702786fdb3 100644
--- a/app/views/projects/settings/ci_cd/_autodevops_form.html.haml
+++ b/app/views/projects/settings/ci_cd/_autodevops_form.html.haml
@@ -46,12 +46,12 @@
= form.radio_button :deploy_strategy, 'timed_incremental', class: 'form-check-input'
= form.label :deploy_strategy_timed_incremental, class: 'form-check-label' do
= s_('CICD|Continuous deployment to production using timed incremental rollout')
- = link_to icon('question-circle'), help_page_path('topics/autodevops/index.md', anchor: 'timed-incremental-rollout-to-production'), target: '_blank'
+ = link_to icon('question-circle'), help_page_path('topics/autodevops/index.md', anchor: 'timed-incremental-rollout-to-production-premium'), target: '_blank'
.form-check
= form.radio_button :deploy_strategy, 'manual', class: 'form-check-input'
= form.label :deploy_strategy_manual, class: 'form-check-label' do
= s_('CICD|Automatic deployment to staging, manual deployment to production')
- = link_to icon('question-circle'), help_page_path('topics/autodevops/index.md', anchor: 'incremental-rollout-to-production'), target: '_blank'
+ = link_to icon('question-circle'), help_page_path('topics/autodevops/index.md', anchor: 'incremental-rollout-to-production-premium'), target: '_blank'
= f.submit _('Save changes'), class: "btn btn-success prepend-top-15", data: { qa_selector: 'save_changes_button' }
diff --git a/app/views/projects/settings/ci_cd/_form.html.haml b/app/views/projects/settings/ci_cd/_form.html.haml
index 430d6071468..66ed1cadf6a 100644
--- a/app/views/projects/settings/ci_cd/_form.html.haml
+++ b/app/views/projects/settings/ci_cd/_form.html.haml
@@ -40,12 +40,21 @@
= _('If any job surpasses this timeout threshold, it will be marked as failed. Human readable time input language is accepted like "1 hour". Values without specification represent seconds.')
= link_to icon('question-circle'), help_page_path('user/project/pipelines/settings', anchor: 'timeout'), target: '_blank'
+ - if can?(current_user, :update_max_artifacts_size, @project)
+ %hr
+ .form-group
+ = f.label :max_artifacts_size, _('Maximum artifacts size (MB)'), class: 'label-bold'
+ = f.number_field :max_artifacts_size, class: 'form-control'
+ %p.form-text.text-muted
+ = _("Set the maximum file size for each job's artifacts")
+ = link_to icon('question-circle'), help_page_path('user/admin_area/settings/continuous_integration', anchor: 'maximum-artifacts-size-core-only'), target: '_blank'
+
%hr
.form-group
- = f.label :ci_config_path, _('Custom CI config path'), class: 'label-bold'
+ = f.label :ci_config_path, _('Custom CI configuration path'), class: 'label-bold'
= f.text_field :ci_config_path, class: 'form-control', placeholder: '.gitlab-ci.yml'
%p.form-text.text-muted
- = _("The path to CI config file. Defaults to <code>.gitlab-ci.yml</code>").html_safe
+ = _("The path to the CI configuration file. Defaults to <code>.gitlab-ci.yml</code>").html_safe
= link_to icon('question-circle'), help_page_path('user/project/pipelines/settings', anchor: 'custom-ci-config-path'), target: '_blank'
%hr
diff --git a/app/views/projects/tags/_tag.html.haml b/app/views/projects/tags/_tag.html.haml
index b1432917f1d..c7bd0262c54 100644
--- a/app/views/projects/tags/_tag.html.haml
+++ b/app/views/projects/tags/_tag.html.haml
@@ -19,9 +19,15 @@
- else
%p
= s_("TagsPage|Can't find HEAD commit for this tag")
- - if release && release.description.present?
- .description.md.prepend-top-default
- = markdown_field(release, :description)
+
+ - if release
+ .text-secondary
+ = icon('rocket')
+ = _("Release")
+ = link_to release.name, project_releases_path(@project, anchor: release.tag), class: 'tag-release-link'
+ - if release.description.present?
+ .description.md.prepend-top-default
+ = markdown_field(release, :description)
.row-fixed-content.controls.flex-row
= render 'projects/buttons/download', project: @project, ref: tag.name, pipeline: @tags_pipelines[tag.name]
diff --git a/app/views/projects/tags/new.html.haml b/app/views/projects/tags/new.html.haml
index 5e6d06d980e..a7f739ab13d 100644
--- a/app/views/projects/tags/new.html.haml
+++ b/app/views/projects/tags/new.html.haml
@@ -31,7 +31,7 @@
.col-sm-10
= text_area_tag :message, @message, required: false, class: 'form-control', rows: 5
.form-text.text-muted
- = s_('TagsPage|Optionally, add a message to the tag.')
+ = tag_description_help_text
%hr
.form-group.row
= label_tag :release_description, s_('TagsPage|Release notes'), class: 'col-form-label col-sm-2'
diff --git a/app/views/projects/tree/_tree_header.html.haml b/app/views/projects/tree/_tree_header.html.haml
index 41cd044a5b0..38422d4533d 100644
--- a/app/views/projects/tree/_tree_header.html.haml
+++ b/app/views/projects/tree/_tree_header.html.haml
@@ -41,7 +41,7 @@
%li
= link_to '#modal-create-new-dir', { 'data-target' => '#modal-create-new-dir', 'data-toggle' => 'modal' } do
#{ _('New directory') }
- - elsif can?(current_user, :fork_project, @project) && can?(current_user, :create_merge_request_in, @project)
+ - elsif can_create_mr_from_fork
%li
- continue_params = { to: project_new_blob_path(@project, @id),
notice: edit_in_new_fork_notice,
@@ -81,10 +81,15 @@
= render 'projects/find_file_link'
- - if can_collaborate
+ - if can_create_mr_from_fork
= succeed " " do
- = link_to ide_edit_path(@project, @ref, @path), class: 'btn btn-default qa-web-ide-button' do
- = _('Web IDE')
+ - 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')
+ - else
+ = link_to '#modal-confirm-fork', class: 'btn btn-default qa-web-ide-button', data: { target: '#modal-confirm-fork', toggle: 'modal'} do
+ = _('Web IDE')
+ = render 'shared/confirm_fork_modal', fork_path: ide_fork_and_edit_path(@project, @ref, @path)
- if show_xcode_link?(@project)
.project-action-button.project-xcode.inline
diff --git a/app/views/projects/triggers/_trigger.html.haml b/app/views/projects/triggers/_trigger.html.haml
index 9899cf9c6de..60de3630bb5 100644
--- a/app/views/projects/triggers/_trigger.html.haml
+++ b/app/views/projects/triggers/_trigger.html.haml
@@ -2,7 +2,7 @@
%td
- if trigger.has_token_exposed?
%span= trigger.token
- = clipboard_button(text: trigger.token, title: "Copy trigger token to clipboard")
+ = clipboard_button(text: trigger.token, title: _("Copy trigger token"))
- else
%span= trigger.short_token
diff --git a/app/views/registrations/welcome.html.haml b/app/views/registrations/welcome.html.haml
new file mode 100644
index 00000000000..02ab974ecc0
--- /dev/null
+++ b/app/views/registrations/welcome.html.haml
@@ -0,0 +1,17 @@
+- content_for(:page_title, _('Welcome to GitLab<br>%{username}!' % { username: html_escape(current_user.username) }).html_safe)
+- 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
+.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|
+ .devise-errors.mt-0
+ = render 'devise/shared/error_messages', resource: current_user
+ .name.form-group
+ = f.label :name, _('Full name'), class: 'label-bold'
+ = f.text_field :name, class: 'form-control top js-block-emoji js-validate-length', :data => { :max_length => max_name_length, :max_length_message => s_('Name is too long (maximum is %{max_length} characters).') % { max_length: max_name_length }, :qa_selector => 'new_user_name_field' }, required: true, title: _('This field is required.')
+ .form-group
+ = f.label :role, _('Role'), class: 'label-bold'
+ = f.select :role, ::User.roles.keys.map { |role| [role.titleize, role] }, {}, class: 'form-control'
+ .submit-container.mt-3
+ = f.submit _('Get started!'), class: 'btn-register btn btn-block mb-0 p-2'
diff --git a/app/views/search/_form.html.haml b/app/views/search/_form.html.haml
index 464db94b7f4..dc75918eb93 100644
--- a/app/views/search/_form.html.haml
+++ b/app/views/search/_form.html.haml
@@ -18,4 +18,3 @@
= render 'filter'
.d-flex-center.flex-column.flex-lg-row
= button_tag _("Search"), class: "btn btn-success btn-search form-control mt-lg-0 ml-lg-1 align-self-end"
- = render_if_exists 'search/form_elasticsearch'
diff --git a/app/views/search/results/_empty.html.haml b/app/views/search/results/_empty.html.haml
index 9d15995bb51..6c7c6de1178 100644
--- a/app/views/search/results/_empty.html.haml
+++ b/app/views/search/results/_empty.html.haml
@@ -2,5 +2,4 @@
.search_glyph
%h4
= icon('search')
- = _("We couldn't find any results matching")
- %code= @search_term
+ = search_entries_empty_message(@scope, @search_term)
diff --git a/app/views/search/show.html.haml b/app/views/search/show.html.haml
index 9235678bc1d..f300e1d4841 100644
--- a/app/views/search/show.html.haml
+++ b/app/views/search/show.html.haml
@@ -2,9 +2,10 @@
- page_title @search_term
- @hide_breadcrumbs = true
-.page-title-holder.d-flex.align-items-center
+.page-title-holder.d-sm-flex.align-items-sm-center
%h1.page-title<
= _('Search')
+ = render_if_exists 'search/form_elasticsearch', attrs: { class: 'ml-sm-auto' }
.prepend-top-default
= render 'search/form'
diff --git a/app/views/shared/_allow_request_access.html.haml b/app/views/shared/_allow_request_access.html.haml
index 2b24bde9e59..ca82f2f3377 100644
--- a/app/views/shared/_allow_request_access.html.haml
+++ b/app/views/shared/_allow_request_access.html.haml
@@ -3,6 +3,4 @@
.form-check
= form.check_box :request_access_enabled, class: 'form-check-input', data: { qa_selector: 'request_access_checkbox' }
= form.label :request_access_enabled, class: 'form-check-label' do
- %span{ class: label_class }= _('Allow users to request access')
- %br
- %span.text-muted= _('Allow users to request access if visibility is public or internal.')
+ %span{ class: label_class }= _('Allow users to request access (if visibility is public or internal)')
diff --git a/app/views/shared/_auto_devops_implicitly_enabled_banner.html.haml b/app/views/shared/_auto_devops_implicitly_enabled_banner.html.haml
index 755fd3a17d3..fb03e6e12e3 100644
--- a/app/views/shared/_auto_devops_implicitly_enabled_banner.html.haml
+++ b/app/views/shared/_auto_devops_implicitly_enabled_banner.html.haml
@@ -1,5 +1,5 @@
- if show_auto_devops_implicitly_enabled_banner?(project, current_user)
- .qa-auto-devops-banner.auto-devops-implicitly-enabled-banner.alert.alert-warning
+ .qa-auto-devops-banner.auto-devops-implicitly-enabled-banner.alert.alert-info
- more_information_link = link_to _('More information'), help_page_path('topics/autodevops/index.md'), target: '_blank', class: 'alert-link'
- auto_devops_message = s_("AutoDevOps|The Auto DevOps pipeline has been enabled and will be used if no alternative CI configuration file is found. %{more_information_link}") % { more_information_link: more_information_link }
= auto_devops_message.html_safe
diff --git a/app/views/shared/_clone_panel.html.haml b/app/views/shared/_clone_panel.html.haml
index 1e509ea0d1f..cb834878276 100644
--- a/app/views/shared/_clone_panel.html.haml
+++ b/app/views/shared/_clone_panel.html.haml
@@ -20,7 +20,7 @@
= text_field_tag :project_clone, default_url_to_repo(project), class: "js-select-on-focus form-control", readonly: true, aria: { label: 'Project clone URL' }
.input-group-append
- = clipboard_button(target: '#project_clone', title: _("Copy URL to clipboard"), class: "input-group-text btn-default btn-clipboard")
+ = clipboard_button(target: '#project_clone', title: _("Copy URL"), class: "input-group-text btn-default btn-clipboard")
= render_if_exists 'shared/geo_modal_button'
diff --git a/app/views/shared/_confirm_fork_modal.html.haml b/app/views/shared/_confirm_fork_modal.html.haml
new file mode 100644
index 00000000000..db50ea41387
--- /dev/null
+++ b/app/views/shared/_confirm_fork_modal.html.haml
@@ -0,0 +1,12 @@
+#modal-confirm-fork.modal.qa-confirm-fork-modal
+ .modal-dialog
+ .modal-content
+ .modal-header
+ %h3.page-title= _('Fork project?')
+ %button.close{ type: "button", "data-dismiss": "modal", "aria-label" => _('Close') }
+ %span{ "aria-hidden": true } &times;
+ .modal-body.p-3
+ %p= _("You're not allowed to %{tag_start}edit%{tag_end} files in this project directly. Please fork this project, make your changes there, and submit a merge request.") % { tag_start: '', tag_end: ''}
+ .modal-footer
+ = link_to _('Cancel'), '#', class: "btn btn-cancel", "data-dismiss" => "modal"
+ = link_to _('Fork project'), fork_path, class: 'btn btn-success', method: :post
diff --git a/app/views/shared/_confirm_modal.html.haml b/app/views/shared/_confirm_modal.html.haml
index 8e3b482e27d..ecb462205b0 100644
--- a/app/views/shared/_confirm_modal.html.haml
+++ b/app/views/shared/_confirm_modal.html.haml
@@ -12,9 +12,8 @@
%p
%span.js-warning-text= _('This action can lead to data loss. To prevent accidental actions we ask you to confirm your intention.')
%br
- Please type
- %code.js-confirm-danger-match= phrase
- to proceed or close this modal to cancel.
+ - phrase_code = '<code class="js-confirm-danger-match">%{phrase_name}</code>'.html_safe % { phrase_name: phrase }
+ = _('Please type %{phrase_code} to proceed or close this modal to cancel.').html_safe % { phrase_code: phrase_code }
.form-group
= text_field_tag 'confirm_name_input', '', class: 'form-control js-confirm-danger-input qa-confirm-input'
diff --git a/app/views/shared/_event_filter.html.haml b/app/views/shared/_event_filter.html.haml
index 6612497e7e2..ad9eb325ff0 100644
--- a/app/views/shared/_event_filter.html.haml
+++ b/app/views/shared/_event_filter.html.haml
@@ -1,3 +1,5 @@
+- show_group_events = local_assigns.fetch(:show_group_events, false)
+
.scrolling-tabs-container.inner-page-scroll-tabs.is-smaller.flex-fill
.fade-left= icon('angle-left')
.fade-right= icon('angle-right')
@@ -9,6 +11,8 @@
= event_filter_link EventFilter::MERGED, _('Merge events'), s_('EventFilterBy|Filter by merge events')
- if event_filter_visible(:issues)
= event_filter_link EventFilter::ISSUE, _('Issue events'), s_('EventFilterBy|Filter by issue events')
+ - if show_group_events
+ = render_if_exists 'events/epics_filter'
- if comments_visible?
= event_filter_link EventFilter::COMMENTS, _('Comments'), s_('EventFilterBy|Filter by comments')
= event_filter_link EventFilter::TEAM, _('Team'), s_('EventFilterBy|Filter by team')
diff --git a/app/views/shared/_group_form.html.haml b/app/views/shared/_group_form.html.haml
index 973c756f496..959792718ca 100644
--- a/app/views/shared/_group_form.html.haml
+++ b/app/views/shared/_group_form.html.haml
@@ -30,9 +30,9 @@
- if @group.persisted?
.alert.alert-warning.prepend-top-10
- Changing group path can have unintended side effects.
+ = _('Changing group path can have unintended side effects.')
= succeed '.' do
- = link_to 'Learn more', help_page_path('user/group/index', anchor: 'changing-a-groups-path'), target: '_blank'
+ = link_to _('Learn more'), help_page_path('user/group/index', anchor: 'changing-a-groups-path'), target: '_blank'
- if @group.persisted?
.row
diff --git a/app/views/shared/_personal_access_tokens_created_container.html.haml b/app/views/shared/_personal_access_tokens_created_container.html.haml
index 42989b145a2..df4577e2862 100644
--- a/app/views/shared/_personal_access_tokens_created_container.html.haml
+++ b/app/views/shared/_personal_access_tokens_created_container.html.haml
@@ -1,5 +1,5 @@
- container_title = local_assigns.fetch(:container_title, _('Your New Personal Access Token'))
-- clipboard_button_title = local_assigns.fetch(:clipboard_button_title, _('Copy personal access token to clipboard'))
+- clipboard_button_title = local_assigns.fetch(:clipboard_button_title, _('Copy personal access token'))
.created-personal-access-token-container
%h5.prepend-top-0
diff --git a/app/views/shared/_remote_mirror_update_button.html.haml b/app/views/shared/_remote_mirror_update_button.html.haml
index 4b39c8b06e9..54bd4ba04a0 100644
--- a/app/views/shared/_remote_mirror_update_button.html.haml
+++ b/app/views/shared/_remote_mirror_update_button.html.haml
@@ -1,5 +1,5 @@
- if remote_mirror.update_in_progress?
- %button.btn.disabled{ type: 'button', data: { toggle: 'tooltip', container: 'body' }, title: _('Updating') }
+ %button.btn.disabled{ type: 'button', data: { toggle: 'tooltip', container: 'body', qa_selector: 'updating_button' }, title: _('Updating') }
= icon("refresh spin")
- elsif remote_mirror.enabled?
= link_to update_now_project_mirror_path(@project, sync_remote: true), method: :post, class: "btn qa-update-now-button rspec-update-now-button", data: { toggle: 'tooltip', container: 'body' }, title: _('Update now') do
diff --git a/app/views/shared/_user_dropdown_contributing_link.html.haml b/app/views/shared/_user_dropdown_contributing_link.html.haml
index 564d21a39be..d4c3e11d051 100644
--- a/app/views/shared/_user_dropdown_contributing_link.html.haml
+++ b/app/views/shared/_user_dropdown_contributing_link.html.haml
@@ -1,3 +1,2 @@
-%li
- = link_to "https://about.gitlab.com/contributing", target: '_blank', class: 'text-nowrap' do
- = _("Contribute to GitLab")
+= link_to "https://about.gitlab.com/contributing", target: '_blank', class: 'text-nowrap' do
+ = _("Contribute to GitLab")
diff --git a/app/views/shared/boards/_switcher.html.haml b/app/views/shared/boards/_switcher.html.haml
index 79118630762..09a365a290a 100644
--- a/app/views/shared/boards/_switcher.html.haml
+++ b/app/views/shared/boards/_switcher.html.haml
@@ -1,4 +1,4 @@
-- parent = board.parent
+- parent = board.resource_parent
- milestone_filter_opts = { format: :json }
- milestone_filter_opts = milestone_filter_opts.merge(only_group_milestones: true) if board.group_board?
- weights = Gitlab.ee? ? ([Issue::WEIGHT_ANY] + Issue.weight_options) : []
diff --git a/app/views/shared/deploy_keys/_form.html.haml b/app/views/shared/deploy_keys/_form.html.haml
index bc0dc7f9631..1944c293be1 100644
--- a/app/views/shared/deploy_keys/_form.html.haml
+++ b/app/views/shared/deploy_keys/_form.html.haml
@@ -6,7 +6,7 @@
.form-group
= form.label :title, class: 'col-form-label col-sm-2'
- .col-sm-10= form.text_field :title, class: 'form-control'
+ .col-sm-10= form.text_field :title, class: 'form-control', readonly: ('readonly' unless can?(current_user, :update_deploy_key, deploy_key))
.form-group
- if deploy_key.new_record?
diff --git a/app/views/shared/empty_states/_issues.html.haml b/app/views/shared/empty_states/_issues.html.haml
index 9173b802dd4..325e01bb5c8 100644
--- a/app/views/shared/empty_states/_issues.html.haml
+++ b/app/views/shared/empty_states/_issues.html.haml
@@ -1,4 +1,4 @@
-- button_path = local_assigns.fetch(:button_path, false)
+- button_path = local_assigns.fetch(:new_project_issue_button_path, false)
- project_select_button = local_assigns.fetch(:project_select_button, false)
- show_import_button = local_assigns.fetch(:show_import_button, false) && can?(current_user, :import_issues, @project)
- has_button = button_path || project_select_button
@@ -56,4 +56,3 @@
- if show_import_button
= render 'projects/issues/import_csv/modal'
-
diff --git a/app/views/shared/form_elements/_apply_template_warning.html.haml b/app/views/shared/form_elements/_apply_template_warning.html.haml
new file mode 100644
index 00000000000..09ca59a520c
--- /dev/null
+++ b/app/views/shared/form_elements/_apply_template_warning.html.haml
@@ -0,0 +1,14 @@
+.form-group.row.js-template-warning.mb-0.hidden.js-issuable-template-warning
+ .offset-sm-2.col-sm-10
+
+ .warning_message.mb-0{ role: 'alert' }
+ %btn.js-close-btn.js-dismiss-btn.close{ type: "button", "aria-hidden": true, "aria-label": _("Close") }
+ = sprite_icon("close")
+
+ %p
+ = _("Applying a template will replace the existing issue description. Any changes you have made will be lost.")
+
+ %button.js-override-template.btn.btn-warning.mr-2{ type: 'button' }
+ = _("Apply template")
+ %button.js-close-btn.js-cancel-btn.btn.btn-inverted{ type: 'button' }
+ = _("Cancel")
diff --git a/app/views/shared/issuable/_assignees.html.haml b/app/views/shared/issuable/_assignees.html.haml
index 24734ed66cf..cec865ec8de 100644
--- a/app/views/shared/issuable/_assignees.html.haml
+++ b/app/views/shared/issuable/_assignees.html.haml
@@ -7,4 +7,4 @@
= link_to_member(@project, assignee, name: false, title: "Assigned to :name")
- if more_assignees_count.positive?
- %span{ class: 'avatar-counter has-tooltip', data: { container: 'body', placement: 'bottom', 'line-type' => 'old', 'original-title' => "+#{more_assignees_count} more assignees" } } +#{more_assignees_count}
+ %span{ class: 'avatar-counter has-tooltip', data: { container: 'body', placement: 'bottom', 'line-type' => 'old', 'original-title' => "+#{more_assignees_count} more assignees", qa_selector: 'avatar_counter' } } +#{more_assignees_count}
diff --git a/app/views/shared/issuable/_board_create_list_dropdown.html.haml b/app/views/shared/issuable/_board_create_list_dropdown.html.haml
index 416b4a34651..ae0e5e45afe 100644
--- a/app/views/shared/issuable/_board_create_list_dropdown.html.haml
+++ b/app/views/shared/issuable/_board_create_list_dropdown.html.haml
@@ -3,6 +3,6 @@
Add list
.dropdown-menu.dropdown-extended-height.dropdown-menu-paging.dropdown-menu-right.dropdown-menu-issues-board-new.dropdown-menu-selectable.js-tab-container-labels
= render partial: "shared/issuable/label_page_default", locals: { show_footer: true, show_create: true, show_boards_content: true, title: "Add list" }
- - if can?(current_user, :admin_label, board.parent)
+ - if can?(current_user, :admin_label, board.resource_parent)
= render partial: "shared/issuable/label_page_create", locals: { show_add_list: true, add_list: true, add_list_class: 'd-none' }
= dropdown_loading
diff --git a/app/views/shared/issuable/_feed_buttons.html.haml b/app/views/shared/issuable/_feed_buttons.html.haml
index 83f60fa6fe2..4fed95e2607 100644
--- a/app/views/shared/issuable/_feed_buttons.html.haml
+++ b/app/views/shared/issuable/_feed_buttons.html.haml
@@ -1,4 +1,4 @@
-= link_to safe_params.merge(rss_url_options), class: 'btn has-tooltip', data: { container: 'body' }, title: _('Subscribe to RSS feed') do
- = icon('rss')
+= link_to safe_params.merge(rss_url_options), class: 'btn has-tooltip js-rss-button', data: { container: 'body' }, title: _('Subscribe to RSS feed') do
+ = sprite_icon('rss')
= link_to safe_params.merge(calendar_url_options), class: 'btn has-tooltip', data: { container: 'body' }, title: _('Subscribe to calendar') do
- = custom_icon('icon_calendar')
+ = sprite_icon('calendar')
diff --git a/app/views/shared/issuable/_form.html.haml b/app/views/shared/issuable/_form.html.haml
index 04a70e406ca..5e2b5f95ee3 100644
--- a/app/views/shared/issuable/_form.html.haml
+++ b/app/views/shared/issuable/_form.html.haml
@@ -19,6 +19,7 @@
= render 'shared/issuable/form/title', issuable: issuable, form: form, has_wip_commits: commits && commits.detect(&:work_in_progress?)
#js-suggestions{ data: { project_path: @project.full_path } }
+= render 'shared/form_elements/apply_template_warning'
= render 'shared/form_elements/description', model: issuable, form: form, project: project
- if issuable.respond_to?(:confidential)
diff --git a/app/views/shared/issuable/_search_bar.html.haml b/app/views/shared/issuable/_search_bar.html.haml
index c9458475aa5..9d580930fb8 100644
--- a/app/views/shared/issuable/_search_bar.html.haml
+++ b/app/views/shared/issuable/_search_bar.html.haml
@@ -2,7 +2,7 @@
- board = local_assigns.fetch(:board, nil)
- is_not_boards_modal_or_productivity_analytics = type != :boards_modal && type != :productivity_analytics
- block_css_class = is_not_boards_modal_or_productivity_analytics ? 'row-content-block second-block' : ''
-- user_can_admin_list = board && can?(current_user, :admin_list, board.parent)
+- 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 }
@@ -17,12 +17,11 @@
.issues-other-filters.filtered-search-wrapper.d-flex.flex-column.flex-md-row
.filtered-search-box
- if type != :boards_modal && type != :boards
- = dropdown_tag(custom_icon('icon_history'),
+ = 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",
- title: "Recent searches" }) do
+ 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
diff --git a/app/views/shared/issuable/_sidebar.html.haml b/app/views/shared/issuable/_sidebar.html.haml
index 3b26b8df8a1..c8b2adcf084 100644
--- a/app/views/shared/issuable/_sidebar.html.haml
+++ b/app/views/shared/issuable/_sidebar.html.haml
@@ -5,174 +5,178 @@
- signed_in = !!issuable_sidebar.dig(:current_user, :id)
- can_edit_issuable = issuable_sidebar.dig(:current_user, :can_edit)
-%aside.right-sidebar.js-right-sidebar.js-issuable-sidebar{ data: { signed: { in: signed_in } }, class: sidebar_gutter_collapsed_class, 'aria-live' => 'polite' }
- .issuable-sidebar
- .block.issuable-sidebar-header
- - if signed_in
- %span.issuable-header-text.hide-collapsed.float-left
- = _('To Do')
- %a.gutter-toggle.float-right.js-sidebar-toggle.has-tooltip{ role: "button", href: "#", "aria-label" => "Toggle sidebar", title: sidebar_gutter_tooltip_text, data: { container: 'body', placement: 'left', boundary: 'viewport' } }
- = sidebar_gutter_toggle_icon
- - if signed_in
- = render "shared/issuable/sidebar_todo", issuable_sidebar: issuable_sidebar
-
- = form_for issuable_type, url: issuable_sidebar[:issuable_json_path], remote: true, html: { class: 'issuable-context-form inline-update js-issuable-update' } do |f|
- - if signed_in
- .block.todo.hide-expanded
- = render "shared/issuable/sidebar_todo", issuable_sidebar: issuable_sidebar, is_collapsed: true
- .block.assignee.qa-assignee-block
- = render "shared/issuable/sidebar_assignees", issuable_sidebar: issuable_sidebar, assignees: assignees
-
- = render_if_exists 'shared/issuable/sidebar_item_epic', issuable_sidebar: issuable_sidebar
-
- - milestone = issuable_sidebar[:milestone] || {}
- .block.milestone
- .sidebar-collapsed-icon.has-tooltip{ title: sidebar_milestone_tooltip_label(milestone), data: { container: 'body', html: 'true', placement: 'left', boundary: 'viewport' } }
- = icon('clock-o', 'aria-hidden': 'true')
- %span.milestone-title.collapse-truncated-title
- - if milestone.present?
- = milestone[:title]
- - else
- = _('None')
- .title.hide-collapsed
- = _('Milestone')
- = icon('spinner spin', class: 'hidden block-loading', 'aria-hidden': 'true')
- - if can_edit_issuable
- = link_to _('Edit'), '#', class: 'js-sidebar-dropdown-toggle edit-link float-right', data: { track_label: "right_sidebar", track_property: "milestone", track_event: "click_edit_button", track_value: "" }
- .value.hide-collapsed
- - if milestone.present?
- = link_to milestone[:title], milestone[:web_url], class: "bold has-tooltip", title: sidebar_milestone_remaining_days(milestone), data: { container: "body", html: 'true', boundary: 'viewport', qa_selector: 'milestone_link' }
- - else
- %span.no-value
- = _('None')
-
- .selectbox.hide-collapsed
- = f.hidden_field 'milestone_id', value: milestone[:id], id: nil
- = dropdown_tag('Milestone', options: { title: _('Assign milestone'), toggle_class: 'js-milestone-select js-extra-options', filter: true, dropdown_class: 'dropdown-menu-selectable', placeholder: _('Search milestones'), data: { show_no: true, field_name: "#{issuable_type}[milestone_id]", project_id: issuable_sidebar[:project_id], issuable_id: issuable_sidebar[:id], milestones: issuable_sidebar[:project_milestones_path], ability_name: issuable_type, issue_update: issuable_sidebar[:issuable_json_path], use_id: true, default_no: true, selected: milestone[:title], null_default: true, display: 'static' }})
-
- #issuable-time-tracker.block
- // Fallback while content is loading
- .title.hide-collapsed
- = _('Time tracking')
- = icon('spinner spin', 'aria-hidden': 'true')
-
- - if issuable_sidebar.has_key?(:due_date)
- .block.due_date
- .sidebar-collapsed-icon.has-tooltip{ data: { placement: 'left', container: 'body', html: 'true', boundary: 'viewport' }, title: sidebar_due_date_tooltip_label(issuable_sidebar[:due_date]) }
- = icon('calendar', 'aria-hidden': 'true')
- %span.js-due-date-sidebar-value
- = issuable_sidebar[:due_date].try(:to_s, :medium) || 'None'
+- if Feature.enabled?(:vue_issuable_sidebar, @project.group)
+ %aside#js-vue-issuable-sidebar{ data: { signed_in: signed_in,
+ sidebar_status_class: sidebar_gutter_collapsed_class } }
+- else
+ %aside.right-sidebar.js-right-sidebar.js-issuable-sidebar{ data: { signed: { in: signed_in } }, class: sidebar_gutter_collapsed_class, 'aria-live' => 'polite' }
+ .issuable-sidebar
+ .block.issuable-sidebar-header
+ - if signed_in
+ %span.issuable-header-text.hide-collapsed.float-left
+ = _('To Do')
+ %a.gutter-toggle.float-right.js-sidebar-toggle.has-tooltip{ role: "button", href: "#", "aria-label" => "Toggle sidebar", title: sidebar_gutter_tooltip_text, data: { container: 'body', placement: 'left', boundary: 'viewport' } }
+ = sidebar_gutter_toggle_icon
+ - if signed_in
+ = render "shared/issuable/sidebar_todo", issuable_sidebar: issuable_sidebar
+
+ = form_for issuable_type, url: issuable_sidebar[:issuable_json_path], remote: true, html: { class: 'issuable-context-form inline-update js-issuable-update' } do |f|
+ - if signed_in
+ .block.todo.hide-expanded
+ = render "shared/issuable/sidebar_todo", issuable_sidebar: issuable_sidebar, is_collapsed: true
+ .block.assignee.qa-assignee-block
+ = render "shared/issuable/sidebar_assignees", issuable_sidebar: issuable_sidebar, assignees: assignees
+
+ = render_if_exists 'shared/issuable/sidebar_item_epic', issuable_sidebar: issuable_sidebar
+
+ - milestone = issuable_sidebar[:milestone] || {}
+ .block.milestone
+ .sidebar-collapsed-icon.has-tooltip{ title: sidebar_milestone_tooltip_label(milestone), data: { container: 'body', html: 'true', placement: 'left', boundary: 'viewport' } }
+ = icon('clock-o', 'aria-hidden': 'true')
+ %span.milestone-title.collapse-truncated-title
+ - if milestone.present?
+ = milestone[:title]
+ - else
+ = _('None')
.title.hide-collapsed
- = _('Due date')
+ = _('Milestone')
= icon('spinner spin', class: 'hidden block-loading', 'aria-hidden': 'true')
- if can_edit_issuable
- = link_to _('Edit'), '#', class: 'js-sidebar-dropdown-toggle edit-link float-right', data: { track_label: "right_sidebar", track_property: "due_date", track_event: "click_edit_button", track_value: "" }
+ = link_to _('Edit'), '#', class: 'js-sidebar-dropdown-toggle edit-link float-right', data: { track_label: "right_sidebar", track_property: "milestone", track_event: "click_edit_button", track_value: "" }
.value.hide-collapsed
- %span.value-content
- - if issuable_sidebar[:due_date]
- %span.bold= issuable_sidebar[:due_date].to_s(:medium)
- - else
- %span.no-value
- = _('None')
+ - if milestone.present?
+ = link_to milestone[:title], milestone[:web_url], class: "bold has-tooltip", title: sidebar_milestone_remaining_days(milestone), data: { container: "body", html: 'true', boundary: 'viewport', qa_selector: 'milestone_link' }
+ - else
+ %span.no-value
+ = _('None')
+
+ .selectbox.hide-collapsed
+ = f.hidden_field 'milestone_id', value: milestone[:id], id: nil
+ = dropdown_tag('Milestone', options: { title: _('Assign milestone'), toggle_class: 'js-milestone-select js-extra-options', filter: true, dropdown_class: 'dropdown-menu-selectable', placeholder: _('Search milestones'), data: { show_no: true, field_name: "#{issuable_type}[milestone_id]", project_id: issuable_sidebar[:project_id], issuable_id: issuable_sidebar[:id], milestones: issuable_sidebar[:project_milestones_path], ability_name: issuable_type, issue_update: issuable_sidebar[:issuable_json_path], use_id: true, default_no: true, selected: milestone[:title], null_default: true, display: 'static' }})
+
+ #issuable-time-tracker.block
+ // Fallback while content is loading
+ .title.hide-collapsed
+ = _('Time tracking')
+ = icon('spinner spin', 'aria-hidden': 'true')
+
+ - if issuable_sidebar.has_key?(:due_date)
+ .block.due_date
+ .sidebar-collapsed-icon.has-tooltip{ data: { placement: 'left', container: 'body', html: 'true', boundary: 'viewport' }, title: sidebar_due_date_tooltip_label(issuable_sidebar[:due_date]) }
+ = icon('calendar', 'aria-hidden': 'true')
+ %span.js-due-date-sidebar-value
+ = issuable_sidebar[:due_date].try(:to_s, :medium) || 'None'
+ .title.hide-collapsed
+ = _('Due date')
+ = icon('spinner spin', class: 'hidden block-loading', 'aria-hidden': 'true')
+ - if can_edit_issuable
+ = link_to _('Edit'), '#', class: 'js-sidebar-dropdown-toggle edit-link float-right', data: { track_label: "right_sidebar", track_property: "due_date", track_event: "click_edit_button", track_value: "" }
+ .value.hide-collapsed
+ %span.value-content
+ - if issuable_sidebar[:due_date]
+ %span.bold= issuable_sidebar[:due_date].to_s(:medium)
+ - else
+ %span.no-value
+ = _('None')
+ - if can_edit_issuable
+ %span.no-value.js-remove-due-date-holder{ class: ("hidden" if issuable_sidebar[:due_date].nil?) }
+ \-
+ %a.js-remove-due-date{ href: "#", role: "button" }
+ = _('remove due date')
- if can_edit_issuable
- %span.no-value.js-remove-due-date-holder{ class: ("hidden" if issuable_sidebar[:due_date].nil?) }
- \-
- %a.js-remove-due-date{ href: "#", role: "button" }
- = _('remove due date')
- - if can_edit_issuable
- .selectbox.hide-collapsed
- = f.hidden_field :due_date, value: issuable_sidebar[:due_date].try(:strftime, 'yy-mm-dd')
- .dropdown
- %button.dropdown-menu-toggle.js-due-date-select{ type: 'button', data: { toggle: 'dropdown', field_name: "#{issuable_type}[due_date]", ability_name: issuable_type, issue_update: issuable_sidebar[:issuable_json_path], display: 'static' } }
- %span.dropdown-toggle-text
- = _('Due date')
- = icon('chevron-down', 'aria-hidden': 'true')
- .dropdown-menu.dropdown-menu-due-date
- = dropdown_title(_('Due date'))
- = dropdown_content do
- .js-due-date-calendar
-
- - selected_labels = issuable_sidebar[:labels]
- .block.labels
- .sidebar-collapsed-icon.js-sidebar-labels-tooltip{ title: issuable_labels_tooltip(selected_labels), data: { placement: "left", container: "body", boundary: 'viewport' } }
- = icon('tags', 'aria-hidden': 'true')
- %span
- = selected_labels.size
- .title.hide-collapsed
- = _('Labels')
- = icon('spinner spin', class: 'hidden block-loading', 'aria-hidden': 'true')
- - if can_edit_issuable
- = link_to _('Edit'), '#', class: 'js-sidebar-dropdown-toggle edit-link qa-edit-link-labels float-right', data: { track_label: "right_sidebar", track_property: "labels", track_event: "click_edit_button", track_value: "" }
- .value.issuable-show-labels.dont-hide.hide-collapsed.qa-labels-block{ class: ("has-labels" if selected_labels.any?) }
- - if selected_labels.any?
- - selected_labels.each do |label_hash|
- = render_label(label_from_hash(label_hash).present(issuable_subject: nil), link: sidebar_label_filter_path(issuable_sidebar[:project_issuables_path], label_hash[:title]))
- - else
- %span.no-value
- = _('None')
- .selectbox.hide-collapsed
- - selected_labels.each do |label|
- = hidden_field_tag "#{issuable_type}[label_names][]", label[:id], id: nil
- .dropdown
- %button.dropdown-menu-toggle.js-label-select.js-multiselect.js-label-sidebar-dropdown{ type: "button", data: sidebar_label_dropdown_data(issuable_type, issuable_sidebar) }
- %span.dropdown-toggle-text{ class: ("is-default" if selected_labels.empty?) }
- = multi_label_name(selected_labels, "Labels")
- = icon('chevron-down', 'aria-hidden': 'true')
- .dropdown-menu.dropdown-select.dropdown-menu-paging.qa-dropdown-menu-labels.dropdown-menu-labels.dropdown-menu-selectable.dropdown-extended-height
- = render partial: "shared/issuable/label_page_default"
- - if issuable_sidebar.dig(:current_user, :can_admin_label)
- = render partial: "shared/issuable/label_page_create"
-
- = render_if_exists 'shared/issuable/sidebar_weight', issuable_sidebar: issuable_sidebar
-
- - if issuable_sidebar.has_key?(:confidential)
+ .selectbox.hide-collapsed
+ = f.hidden_field :due_date, value: issuable_sidebar[:due_date].try(:strftime, 'yy-mm-dd')
+ .dropdown
+ %button.dropdown-menu-toggle.js-due-date-select{ type: 'button', data: { toggle: 'dropdown', field_name: "#{issuable_type}[due_date]", ability_name: issuable_type, issue_update: issuable_sidebar[:issuable_json_path], display: 'static' } }
+ %span.dropdown-toggle-text
+ = _('Due date')
+ = icon('chevron-down', 'aria-hidden': 'true')
+ .dropdown-menu.dropdown-menu-due-date
+ = dropdown_title(_('Due date'))
+ = dropdown_content do
+ .js-due-date-calendar
+
+ - selected_labels = issuable_sidebar[:labels]
+ .block.labels
+ .sidebar-collapsed-icon.js-sidebar-labels-tooltip{ title: issuable_labels_tooltip(selected_labels), data: { placement: "left", container: "body", boundary: 'viewport' } }
+ = icon('tags', 'aria-hidden': 'true')
+ %span
+ = selected_labels.size
+ .title.hide-collapsed
+ = _('Labels')
+ = icon('spinner spin', class: 'hidden block-loading', 'aria-hidden': 'true')
+ - if can_edit_issuable
+ = link_to _('Edit'), '#', class: 'js-sidebar-dropdown-toggle edit-link qa-edit-link-labels float-right', data: { track_label: "right_sidebar", track_property: "labels", track_event: "click_edit_button", track_value: "" }
+ .value.issuable-show-labels.dont-hide.hide-collapsed.qa-labels-block{ class: ("has-labels" if selected_labels.any?) }
+ - if selected_labels.any?
+ - selected_labels.each do |label_hash|
+ = render_label(label_from_hash(label_hash).present(issuable_subject: nil), link: sidebar_label_filter_path(issuable_sidebar[:project_issuables_path], label_hash[:title]))
+ - else
+ %span.no-value
+ = _('None')
+ .selectbox.hide-collapsed
+ - selected_labels.each do |label|
+ = hidden_field_tag "#{issuable_type}[label_names][]", label[:id], id: nil
+ .dropdown
+ %button.dropdown-menu-toggle.js-label-select.js-multiselect.js-label-sidebar-dropdown{ type: "button", data: sidebar_label_dropdown_data(issuable_type, issuable_sidebar) }
+ %span.dropdown-toggle-text{ class: ("is-default" if selected_labels.empty?) }
+ = multi_label_name(selected_labels, "Labels")
+ = icon('chevron-down', 'aria-hidden': 'true')
+ .dropdown-menu.dropdown-select.dropdown-menu-paging.qa-dropdown-menu-labels.dropdown-menu-labels.dropdown-menu-selectable.dropdown-extended-height
+ = render partial: "shared/issuable/label_page_default"
+ - if issuable_sidebar.dig(:current_user, :can_admin_label)
+ = render partial: "shared/issuable/label_page_create"
+
+ = render_if_exists 'shared/issuable/sidebar_weight', issuable_sidebar: issuable_sidebar
+
+ - if issuable_sidebar.has_key?(:confidential)
+ -# haml-lint:disable InlineJavaScript
+ %script#js-confidential-issue-data{ type: "application/json" }= { is_confidential: issuable_sidebar[:confidential], is_editable: can_edit_issuable }.to_json.html_safe
+ #js-confidential-entry-point
+
-# haml-lint:disable InlineJavaScript
- %script#js-confidential-issue-data{ type: "application/json" }= { is_confidential: issuable_sidebar[:confidential], is_editable: can_edit_issuable }.to_json.html_safe
- #js-confidential-entry-point
+ %script#js-lock-issue-data{ type: "application/json" }= { is_locked: !!issuable_sidebar[:discussion_locked], is_editable: can_edit_issuable }.to_json.html_safe
+ #js-lock-entry-point
+
+ .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
+
+ - project_ref = issuable_sidebar[:reference]
+ .block.project-reference
+ .sidebar-collapsed-icon.dont-change-state
+ = clipboard_button(text: project_ref, title: _('Copy reference'), placement: "left", boundary: 'viewport')
+ .cross-project-reference.hide-collapsed
+ %span
+ = _('Reference:')
+ %cite{ title: project_ref }
+ = project_ref
+ = clipboard_button(text: project_ref, title: _('Copy reference'), placement: "left", boundary: 'viewport')
+
+ - if issuable_sidebar.dig(:current_user, :can_move)
+ .block.js-sidebar-move-issue-block
+ .sidebar-collapsed-icon{ data: { toggle: 'tooltip', placement: 'left', container: 'body', boundary: 'viewport' }, title: _('Move issue') }
+ = custom_icon('icon_arrow_right')
+ .dropdown.sidebar-move-issue-dropdown.hide-collapsed
+ %button.btn.btn-default.btn-block.js-sidebar-dropdown-toggle.js-move-issue{ type: 'button',
+ data: { toggle: 'dropdown', display: 'static', track_label: "right_sidebar", track_property: "move_issue", track_event: "click_button", track_value: "" } }
+ = _('Move issue')
+ .dropdown-menu.dropdown-menu-selectable.dropdown-extended-height
+ = dropdown_title(_('Move issue'))
+ = dropdown_filter(_('Search project'), search_id: 'sidebar-move-issue-dropdown-search')
+ = dropdown_content
+ = dropdown_loading
+ = dropdown_footer add_content_class: true do
+ %button.btn.btn-success.sidebar-move-issue-confirmation-button.js-move-issue-confirmation-button{ type: 'button', disabled: true }
+ = _('Move')
+ = icon('spinner spin', class: 'sidebar-move-issue-confirmation-loading-icon')
-# haml-lint:disable InlineJavaScript
- %script#js-lock-issue-data{ type: "application/json" }= { is_locked: !!issuable_sidebar[:discussion_locked], is_editable: can_edit_issuable }.to_json.html_safe
- #js-lock-entry-point
-
- .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
-
- - project_ref = issuable_sidebar[:reference]
- .block.project-reference
- .sidebar-collapsed-icon.dont-change-state
- = clipboard_button(text: project_ref, title: _('Copy reference to clipboard'), placement: "left", boundary: 'viewport')
- .cross-project-reference.hide-collapsed
- %span
- = _('Reference:')
- %cite{ title: project_ref }
- = project_ref
- = clipboard_button(text: project_ref, title: _('Copy reference to clipboard'), placement: "left", boundary: 'viewport')
-
- - if issuable_sidebar.dig(:current_user, :can_move)
- .block.js-sidebar-move-issue-block
- .sidebar-collapsed-icon{ data: { toggle: 'tooltip', placement: 'left', container: 'body', boundary: 'viewport' }, title: _('Move issue') }
- = custom_icon('icon_arrow_right')
- .dropdown.sidebar-move-issue-dropdown.hide-collapsed
- %button.btn.btn-default.btn-block.js-sidebar-dropdown-toggle.js-move-issue{ type: 'button',
- data: { toggle: 'dropdown', display: 'static', track_label: "right_sidebar", track_property: "move_issue", track_event: "click_button", track_value: "" } }
- = _('Move issue')
- .dropdown-menu.dropdown-menu-selectable.dropdown-extended-height
- = dropdown_title(_('Move issue'))
- = dropdown_filter(_('Search project'), search_id: 'sidebar-move-issue-dropdown-search')
- = dropdown_content
- = dropdown_loading
- = dropdown_footer add_content_class: true do
- %button.btn.btn-success.sidebar-move-issue-confirmation-button.js-move-issue-confirmation-button{ type: 'button', disabled: true }
- = _('Move')
- = icon('spinner spin', class: 'sidebar-move-issue-confirmation-loading-icon')
-
- -# haml-lint:disable InlineJavaScript
- %script.js-sidebar-options{ type: "application/json" }= issuable_sidebar_options(issuable_sidebar).to_json.html_safe
+ %script.js-sidebar-options{ type: "application/json" }= issuable_sidebar_options(issuable_sidebar).to_json.html_safe
diff --git a/app/views/shared/issuable/_sidebar_assignees.html.haml b/app/views/shared/issuable/_sidebar_assignees.html.haml
index dfb0e7ed297..e6b8e299e1c 100644
--- a/app/views/shared/issuable/_sidebar_assignees.html.haml
+++ b/app/views/shared/issuable/_sidebar_assignees.html.haml
@@ -11,7 +11,7 @@
= hidden_field_tag "#{issuable_type}[assignee_ids][]", 0, id: nil
- else
- assignees.each do |assignee|
- = hidden_field_tag "#{issuable_type}[assignee_ids][]", assignee.id, id: nil, data: { avatar_url: assignee.avatar_url, name: assignee.name, username: assignee.username }
+ = hidden_field_tag "#{issuable_type}[assignee_ids][]", assignee.id, id: nil, data: assignee_sidebar_data(assignee, merge_request: @merge_request)
- options = { toggle_class: 'js-user-search js-author-search',
title: _('Assign to'),
diff --git a/app/views/shared/milestones/_sidebar.html.haml b/app/views/shared/milestones/_sidebar.html.haml
index ced6af50501..22a6d5e33f0 100644
--- a/app/views/shared/milestones/_sidebar.html.haml
+++ b/app/views/shared/milestones/_sidebar.html.haml
@@ -142,10 +142,10 @@
- if milestone_ref.present?
.block.reference
.sidebar-collapsed-icon.dont-change-state
- = clipboard_button(text: milestone_ref, title: "Copy reference to clipboard", placement: "left", boundary: 'viewport')
+ = clipboard_button(text: milestone_ref, title: _("Copy reference"), placement: "left", boundary: 'viewport')
.cross-project-reference.hide-collapsed
%span
Reference:
%cite{ title: milestone_ref }
= milestone_ref
- = clipboard_button(text: milestone_ref, title: "Copy reference to clipboard", placement: "left", boundary: 'viewport')
+ = clipboard_button(text: milestone_ref, title: _("Copy reference"), placement: "left", boundary: 'viewport')
diff --git a/app/views/shared/projects/_project.html.haml b/app/views/shared/projects/_project.html.haml
index bcce7cb52fb..67dad9b7a75 100644
--- a/app/views/shared/projects/_project.html.haml
+++ b/app/views/shared/projects/_project.html.haml
@@ -12,7 +12,9 @@
- css_class += " no-description" if project.description.blank? && !show_last_commit_as_description
- cache_key = project_list_cache_key(project, pipeline_status: pipeline_status)
- updated_tooltip = time_ago_with_tooltip(project.last_activity_date)
-- css_controls_class = compact_mode ? "" : "flex-lg-row justify-content-lg-between"
+- show_pipeline_status_icon = pipeline_status && can?(current_user, :read_cross_project) && project.pipeline_status.has_status? && can?(current_user, :read_build, project)
+- css_controls_class = compact_mode ? [] : ["flex-lg-row", "justify-content-lg-between"]
+- css_controls_class << "with-pipeline-status" if show_pipeline_status_icon
- avatar_container_class = project.creator && use_creator_avatar ? '' : 'rect-avatar'
%li.project-row.d-flex{ class: css_class }
@@ -58,12 +60,12 @@
.description.d-none.d-sm-block.append-right-default
= markdown_field(project, :description)
- .controls.d-flex.flex-sm-column.align-items-center.align-items-sm-end.flex-wrap.flex-shrink-0.text-secondary{ class: css_controls_class }
+ .controls.d-flex.flex-sm-column.align-items-center.align-items-sm-end.flex-wrap.flex-shrink-0.text-secondary{ class: css_controls_class.join(" ") }
.icon-container.d-flex.align-items-center
- - if pipeline_status && can?(current_user, :read_cross_project) && project.pipeline_status.has_status? && can?(current_user, :read_build, project)
+ - if show_pipeline_status_icon
- pipeline_path = pipelines_project_commit_path(project.pipeline_status.project, project.pipeline_status.sha, ref: project.pipeline_status.ref)
%span.icon-wrapper.pipeline-status
- = render 'ci/status/icon', status: project.commit.last_pipeline.detailed_status(current_user), tooltip_placement: 'top', path: pipeline_path
+ = render 'ci/status/icon', status: project.last_pipeline.detailed_status(current_user), tooltip_placement: 'top', path: pipeline_path
- if project.archived
%span.d-flex.icon-wrapper.badge.badge-warning archived
diff --git a/app/views/shared/snippets/_header.html.haml b/app/views/shared/snippets/_header.html.haml
index 69481293f90..8d94a87a775 100644
--- a/app/views/shared/snippets/_header.html.haml
+++ b/app/views/shared/snippets/_header.html.haml
@@ -46,5 +46,5 @@
%strong.embed-toggle-list-item= _("Share")
%input.js-snippet-url-area.snippet-embed-input.form-control{ type: "text", autocomplete: 'off', value: snippet_embed }
.input-group-append
- = clipboard_button(title: s_('Copy to clipboard'), class: 'js-clipboard-btn snippet-clipboard-btn btn btn-default', target: '.js-snippet-url-area')
+ = clipboard_button(title: _('Copy'), class: 'js-clipboard-btn snippet-clipboard-btn btn btn-default', target: '.js-snippet-url-area')
.clearfix