Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/app/views
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2024-01-16 13:42:19 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2024-01-16 13:42:19 +0300
commit84d1bd786125c1c14a3ba5f63e38a4cc736a9027 (patch)
treef550fa965f507077e20dbb6d61a8269a99ef7107 /app/views
parent3a105e36e689f7b75482236712f1a47fd5a76814 (diff)
Add latest changes from gitlab-org/gitlab@16-8-stable-eev16.8.0-rc42
Diffstat (limited to 'app/views')
-rw-r--r--app/views/admin/application_settings/_members_api_limits.html.haml21
-rw-r--r--app/views/admin/application_settings/_repository_storage.html.haml2
-rw-r--r--app/views/admin/application_settings/_signin.html.haml3
-rw-r--r--app/views/admin/application_settings/_user_restrictions.html.haml1
-rw-r--r--app/views/admin/application_settings/appearances/_form.html.haml105
-rw-r--r--app/views/admin/application_settings/ci_cd.html.haml11
-rw-r--r--app/views/admin/application_settings/general.html.haml5
-rw-r--r--app/views/admin/application_settings/network.html.haml2
-rw-r--r--app/views/admin/dashboard/_stats_users_table.html.haml2
-rw-r--r--app/views/admin/dashboard/stats.html.haml2
-rw-r--r--app/views/admin/sessions/new.html.haml4
-rw-r--r--app/views/admin/sessions/two_factor.html.haml3
-rw-r--r--app/views/admin/users/show.html.haml2
-rw-r--r--app/views/ci/runner/_how_to_setup_runner.html.haml23
-rw-r--r--app/views/ci/variables/_attributes.html.haml13
-rw-r--r--app/views/ci/variables/_index.html.haml11
-rw-r--r--app/views/dashboard/todos/index.html.haml5
-rw-r--r--app/views/devise/confirmations/new.html.haml3
-rw-r--r--app/views/devise/passwords/new.html.haml6
-rw-r--r--app/views/devise/registrations/new.html.haml3
-rw-r--r--app/views/devise/sessions/new.html.haml33
-rw-r--r--app/views/devise/sessions/two_factor.html.haml3
-rw-r--r--app/views/devise/shared/_footer.html.haml3
-rw-r--r--app/views/devise/shared/_omniauth_box.html.haml19
-rw-r--r--app/views/devise/shared/_omniauth_provider_button.haml7
-rw-r--r--app/views/devise/shared/_signup_box.html.haml5
-rw-r--r--app/views/devise/shared/_signup_omniauth_provider_button.haml14
-rw-r--r--app/views/devise/shared/_signup_omniauth_provider_list.haml24
-rw-r--r--app/views/devise/shared/_signup_omniauth_providers.haml3
-rw-r--r--app/views/devise/shared/_tabs_ldap.html.haml2
-rw-r--r--app/views/devise/shared/_terms_of_service_notice.html.haml18
-rw-r--r--app/views/devise/unlocks/new.html.haml7
-rw-r--r--app/views/groups/_import_group_from_file_panel.html.haml4
-rw-r--r--app/views/groups/settings/_export.html.haml2
-rw-r--r--app/views/groups/settings/_permissions.html.haml9
-rw-r--r--app/views/import/github/status.html.haml2
-rw-r--r--app/views/layouts/_head.html.haml1
-rw-r--r--app/views/layouts/_page.html.haml15
-rw-r--r--app/views/layouts/_snowplow.html.haml5
-rw-r--r--app/views/layouts/application.html.haml4
-rw-r--r--app/views/layouts/devise.html.haml78
-rw-r--r--app/views/layouts/devise_empty.html.haml2
-rw-r--r--app/views/layouts/group.html.haml1
-rw-r--r--app/views/layouts/header/_super_sidebar_logged_out.haml2
-rw-r--r--app/views/layouts/nav/breadcrumbs/_collapsed_inline_list.html.haml4
-rw-r--r--app/views/layouts/project.html.haml1
-rw-r--r--app/views/layouts/signup_onboarding.html.haml2
-rw-r--r--app/views/notify/_reassigned_issuable_email.html.haml17
-rw-r--r--app/views/notify/new_review_email.html.haml59
-rw-r--r--app/views/notify/reassigned_issue_email.html.haml2
-rw-r--r--app/views/notify/reassigned_issue_email.text.erb13
-rw-r--r--app/views/notify/reassigned_merge_request_email.html.haml2
-rw-r--r--app/views/notify/reassigned_merge_request_email.text.erb13
-rw-r--r--app/views/profiles/accounts/_providers.html.haml41
-rw-r--r--app/views/profiles/emails/index.html.haml10
-rw-r--r--app/views/profiles/gpg_keys/_key_table.html.haml2
-rw-r--r--app/views/profiles/preferences/show.html.haml4
-rw-r--r--app/views/profiles/show.html.haml2
-rw-r--r--app/views/projects/_home_panel.html.haml4
-rw-r--r--app/views/projects/_import_project_pane.html.haml18
-rw-r--r--app/views/projects/_readme.html.haml2
-rw-r--r--app/views/projects/_sidebar.html.haml69
-rw-r--r--app/views/projects/buttons/_code.html.haml12
-rw-r--r--app/views/projects/buttons/_download_menu_items.html.haml4
-rw-r--r--app/views/projects/commit/_commit_box.html.haml3
-rw-r--r--app/views/projects/edit.html.haml7
-rw-r--r--app/views/projects/empty.html.haml2
-rw-r--r--app/views/projects/environments/folder.html.haml2
-rw-r--r--app/views/projects/forks/index.html.haml2
-rw-r--r--app/views/projects/gcp/artifact_registry/docker_images/_docker_image.html.haml4
-rw-r--r--app/views/projects/merge_requests/_code_dropdown.html.haml6
-rw-r--r--app/views/projects/merge_requests/_mr_title.html.haml5
-rw-r--r--app/views/projects/merge_requests/_page.html.haml1
-rw-r--r--app/views/projects/merge_requests/creations/new.html.haml2
-rw-r--r--app/views/projects/mirrors/_mirror_repos_list.html.haml2
-rw-r--r--app/views/projects/ml/models/index.html.haml2
-rw-r--r--app/views/projects/ml/models/new.html.haml5
-rw-r--r--app/views/projects/pages_domains/_dns.html.haml4
-rw-r--r--app/views/search/results/_blob_data.html.haml6
-rw-r--r--app/views/search/results/_blob_highlight.html.haml2
-rw-r--r--app/views/sent_notifications/unsubscribe.html.haml7
-rw-r--r--app/views/shared/_auto_devops_callout.html.haml5
-rw-r--r--app/views/shared/_auto_devops_implicitly_enabled_banner.html.haml2
-rw-r--r--app/views/shared/_file_highlight.html.haml2
-rw-r--r--app/views/shared/_visibility_radios.html.haml2
-rw-r--r--app/views/shared/deploy_keys/_index.html.haml7
-rw-r--r--app/views/shared/deploy_tokens/_new_deploy_token.html.haml24
-rw-r--r--app/views/shared/groups/_group.html.haml7
-rw-r--r--app/views/shared/groups/_list.html.haml1
-rw-r--r--app/views/shared/issuable/_sort_dropdown.html.haml2
-rw-r--r--app/views/shared/members/_member.html.haml4
-rw-r--r--app/views/shared/notes/_notes_with_form.html.haml2
-rw-r--r--app/views/shared/users/_user.html.haml2
-rw-r--r--app/views/shared/web_hooks/_index.html.haml2
-rw-r--r--app/views/shared/wikis/_sidebar.html.haml2
-rw-r--r--app/views/shared/wikis/git_error.html.haml4
-rw-r--r--app/views/shared/wikis/show.html.haml7
-rw-r--r--app/views/user_settings/passwords/edit.html.haml8
-rw-r--r--app/views/user_settings/passwords/new.html.haml8
-rw-r--r--app/views/users/show.html.haml6
100 files changed, 452 insertions, 478 deletions
diff --git a/app/views/admin/application_settings/_members_api_limits.html.haml b/app/views/admin/application_settings/_members_api_limits.html.haml
new file mode 100644
index 00000000000..3065c62b7e2
--- /dev/null
+++ b/app/views/admin/application_settings/_members_api_limits.html.haml
@@ -0,0 +1,21 @@
+%section.settings.as-members-api-limits.no-animate#js-members-api-limits-settings{ class: ('expanded' if expanded_by_default?) }
+ .settings-header
+ %h4.settings-title.js-settings-toggle.js-settings-toggle-trigger-only
+ = _('Members API rate limit')
+ = render Pajamas::ButtonComponent.new(button_options: { class: 'js-settings-toggle' }) do
+ = expanded_by_default? ? _('Collapse') : _('Expand')
+ %p.gl-text-secondary
+ = _('Limit the number of project or group members a user can delete per minute through API requests.')
+ = link_to _('Learn more.'), help_page_path('administration/settings/rate_limit_on_members_api'), target: '_blank', rel: 'noopener noreferrer'
+ .settings-content
+ = gitlab_ui_form_for @application_setting, url: network_admin_application_settings_path(anchor: 'js-members-api-limits-settings'), html: { class: 'fieldset-form' } do |f|
+ = form_errors(@application_setting)
+
+ %fieldset
+ .form-group
+ = f.label :members_delete_limit, _('Maximum requests per minute per group / project'), class: 'label-bold'
+ = f.number_field :members_delete_limit, min: 0, class: 'form-control gl-form-input'
+ .form-text.gl-text-gray-600
+ = _("Set to 0 to disable the limit.")
+
+ = f.submit _('Save changes'), pajamas_button: true
diff --git a/app/views/admin/application_settings/_repository_storage.html.haml b/app/views/admin/application_settings/_repository_storage.html.haml
index 412098cfae4..5fc9db06bb2 100644
--- a/app/views/admin/application_settings/_repository_storage.html.haml
+++ b/app/views/admin/application_settings/_repository_storage.html.haml
@@ -5,7 +5,7 @@
.sub-section
%h4= _('Hashed repository storage paths')
.form-group
- - repository_storage_help_link_url = help_page_path('administration/repository_storage_types')
+ - repository_storage_help_link_url = help_page_path('administration/repository_storage_paths')
- repository_storage_help_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: repository_storage_help_link_url }
= f.gitlab_ui_checkbox_component :hashed_storage_enabled,
_('Use hashed storage'),
diff --git a/app/views/admin/application_settings/_signin.html.haml b/app/views/admin/application_settings/_signin.html.haml
index 2b972a2d7f1..3d3d4ab29d1 100644
--- a/app/views/admin/application_settings/_signin.html.haml
+++ b/app/views/admin/application_settings/_signin.html.haml
@@ -24,6 +24,9 @@
_('Enforce two-factor authentication'),
help_text: '%{help_text} %{help_link}'.html_safe % { help_text: help_text, help_link: help_link }
.form-group
+ = f.label :require_admin_two_factor_authentication, _('Enforce Two-Factor authentication for administrator users'), class: 'label-bold'
+ = f.gitlab_ui_checkbox_component :require_admin_two_factor_authentication, _('Require administrators to enable 2FA')
+ .form-group
= f.label :two_factor_authentication, _('Two-factor grace period'), class: 'label-bold'
= f.number_field :two_factor_grace_period, min: 0, class: 'form-control gl-form-input', placeholder: '0'
.form-text.text-muted
diff --git a/app/views/admin/application_settings/_user_restrictions.html.haml b/app/views/admin/application_settings/_user_restrictions.html.haml
index 4fb65c20daf..4bdc21a3695 100644
--- a/app/views/admin/application_settings/_user_restrictions.html.haml
+++ b/app/views/admin/application_settings/_user_restrictions.html.haml
@@ -8,3 +8,4 @@
= form.gitlab_ui_checkbox_component :can_create_group, _("Allow new users to create top-level groups")
= form.gitlab_ui_checkbox_component :user_defaults_to_private_profile, _("Make new users' profiles private by default")
= render_if_exists 'admin/application_settings/allow_account_deletion', form: form
+ = form.gitlab_ui_checkbox_component :allow_project_creation_for_guest_and_below, _("Allow users with up to Guest role to create groups and personal projects")
diff --git a/app/views/admin/application_settings/appearances/_form.html.haml b/app/views/admin/application_settings/appearances/_form.html.haml
index 672af002e5e..e8bf25b8da6 100644
--- a/app/views/admin/application_settings/appearances/_form.html.haml
+++ b/app/views/admin/application_settings/appearances/_form.html.haml
@@ -6,6 +6,28 @@
.settings-section
.settings-sticky-header
.settings-sticky-header-inner
+ %h4.gl-my-0 Favicon
+
+ .form-group
+ = f.label :favicon, _('Favicon'), class: 'col-form-label gl-pt-0'
+ %p
+ - if @appearance.favicon?
+ = image_tag @appearance.favicon_path, class: 'appearance-light-logo-preview'
+ - if @appearance.persisted?
+ %br
+ = render Pajamas::ButtonComponent.new(variant: :danger, category: :secondary, size: :small, method: :delete, href: favicon_admin_application_settings_appearances_path, button_options: { data: { confirm: _("Favicon will be removed. Are you sure?"), confirm_btn_variant: "danger" }, aria: { label: _('Remove favicon') } }) do
+ = _('Remove favicon')
+ %hr
+ = f.hidden_field :favicon_cache
+ = f.file_field :favicon, class: '', accept: 'image/*'
+ .form-text.text-muted
+ = _("Maximum file size is 1 MB. Image size must be 32 x 32 pixels. Allowed image formats are %{favicon_extension_allowlist}.") % { favicon_extension_allowlist: favicon_extension_allowlist }
+ %br
+ = _("Images with incorrect dimensions are not resized automatically, and may result in unexpected behavior.")
+
+ .settings-section
+ .settings-sticky-header
+ .settings-sticky-header-inner
%h4.gl-my-0= _('Navigation bar')
.form-group
@@ -26,54 +48,29 @@
.settings-section
.settings-sticky-header
.settings-sticky-header-inner
- %h4.gl-my-0 Favicon
+ %h4.gl-my-0= _('New project pages')
.form-group
- = f.label :favicon, _('Favicon'), class: 'col-form-label gl-pt-0'
+ = f.label :new_project_guidelines, class: 'col-form-label'
%p
- - if @appearance.favicon?
- = image_tag @appearance.favicon_path, class: 'appearance-light-logo-preview'
- - if @appearance.persisted?
- %br
- = render Pajamas::ButtonComponent.new(variant: :danger, category: :secondary, size: :small, method: :delete, href: favicon_admin_application_settings_appearances_path, button_options: { data: { confirm: _("Favicon will be removed. Are you sure?"), confirm_btn_variant: "danger" }, aria: { label: _('Remove favicon') } }) do
- = _('Remove favicon')
- %hr
- = f.hidden_field :favicon_cache
- = f.file_field :favicon, class: '', accept: 'image/*'
+ = f.text_area :new_project_guidelines, class: "form-control gl-form-input", rows: 10
.form-text.text-muted
- = _("Maximum file size is 1 MB. Image size must be 32 x 32 pixels. Allowed image formats are %{favicon_extension_allowlist}.") % { favicon_extension_allowlist: favicon_extension_allowlist }
- %br
- = _("Images with incorrect dimensions are not resized automatically, and may result in unexpected behavior.")
-
- = render partial: 'admin/application_settings/appearances/system_header_footer_form', locals: { form: f }
+ = parsed_with_gfm
.settings-section
.settings-sticky-header
.settings-sticky-header-inner
- %h4.gl-my-0= _('Sign in/Sign up pages')
+ %h4.gl-my-0= _('Profile image guidelines')
+
+ %p.gl-text-secondary
+ = _('These guidelines for public avatars are displayed on the user settings page.')
.form-group
- = f.label :title, class: 'col-form-label'
- = f.text_field :title, class: "form-control gl-form-input"
- .form-group
- = f.label :description, class: 'col-form-label'
- = f.text_area :description, class: "form-control gl-form-input", rows: 10
- .form-text.text-muted
- = parsed_with_gfm
- .form-group
- = f.label :logo, class: 'col-form-label gl-pt-0'
+ = f.label :profile_image_guidelines, class: 'col-form-label'
%p
- - if @appearance.logo?
- = image_tag @appearance.logo_path, class: 'appearance-logo-preview'
- - if @appearance.persisted?
- %br
- = render Pajamas::ButtonComponent.new(variant: :danger, category: :secondary, size: :small, method: :delete, href: logo_admin_application_settings_appearances_path, button_options: { data: { confirm: _("Logo will be removed. Are you sure?"), confirm_btn_variant: "danger" }, aria: { label: _('Remove logo') } }) do
- = _('Remove logo')
- %hr
- = f.hidden_field :logo_cache
- = f.file_field :logo, class: "", accept: 'image/*'
+ = f.text_area :profile_image_guidelines, class: "form-control gl-form-input", rows: 10
.form-text.text-muted
- = _('Maximum file size is 1 MB. Pages are optimized for a 128x128 px logo.')
+ = parsed_with_gfm
.settings-section
.settings-sticky-header
@@ -109,26 +106,32 @@
.settings-section
.settings-sticky-header
.settings-sticky-header-inner
- %h4.gl-my-0= _('New project pages')
+ %h4.gl-my-0= _('Sign in/Sign up pages')
.form-group
- = f.label :new_project_guidelines, class: 'col-form-label'
- %p
- = f.text_area :new_project_guidelines, class: "form-control gl-form-input", rows: 10
- .form-text.text-muted
- = parsed_with_gfm
-
- .settings-section
- .settings-sticky-header
- .settings-sticky-header-inner
- %h4.gl-my-0= _('Profile image guideline')
-
+ = f.label :title, class: 'col-form-label'
+ = f.text_field :title, class: "form-control gl-form-input"
.form-group
- = f.label :profile_image_guidelines, class: 'col-form-label'
+ = f.label :description, class: 'col-form-label'
+ = f.text_area :description, class: "form-control gl-form-input", rows: 10
+ .form-text.text-muted
+ = parsed_with_gfm
+ .form-group
+ = f.label :logo, class: 'col-form-label gl-pt-0'
%p
- = f.text_area :profile_image_guidelines, class: "form-control gl-form-input", rows: 10
+ - if @appearance.logo?
+ = image_tag @appearance.logo_path, class: 'appearance-logo-preview'
+ - if @appearance.persisted?
+ %br
+ = render Pajamas::ButtonComponent.new(variant: :danger, category: :secondary, size: :small, method: :delete, href: logo_admin_application_settings_appearances_path, button_options: { data: { confirm: _("Logo will be removed. Are you sure?"), confirm_btn_variant: "danger" }, aria: { label: _('Remove logo') } }) do
+ = _('Remove logo')
+ %hr
+ = f.hidden_field :logo_cache
+ = f.file_field :logo, class: "", accept: 'image/*'
.form-text.text-muted
- = parsed_with_gfm
+ = _('Maximum file size is 1 MB. Pages are optimized for a 128x128 px logo.')
+
+ = render partial: 'admin/application_settings/appearances/system_header_footer_form', locals: { form: f }
- if @appearance.persisted? || @appearance.updated_at
.settings-section
diff --git a/app/views/admin/application_settings/ci_cd.html.haml b/app/views/admin/application_settings/ci_cd.html.haml
index addd23688b4..b7a43916a30 100644
--- a/app/views/admin/application_settings/ci_cd.html.haml
+++ b/app/views/admin/application_settings/ci_cd.html.haml
@@ -7,16 +7,7 @@
.settings-header
= render 'admin/application_settings/ci/header', expanded: expanded_by_default?
.settings-content
- %p
- = _('Variables can be:')
- %ul
- %li
- = html_escape(_('%{code_open}Protected:%{code_close} Only exposed to protected branches or protected tags.')) % { code_open: '<code>'.html_safe, code_close: '</code>'.html_safe }
- = link_to _('Learn more.'), help_page_path('ci/variables/index', anchor: 'protect-a-cicd-variable'), target: '_blank', rel: 'noopener noreferrer'
- %li
- = html_escape(_('%{code_open}Masked:%{code_close} Hidden in job logs. Must match masking requirements.')) % { code_open: '<code>'.html_safe, code_close: '</code>'.html_safe }
- = link_to _('Learn more.'), help_page_path('ci/variables/index', anchor: 'mask-a-cicd-variable'), target: '_blank', rel: 'noopener noreferrer'
-
+ = render 'ci/variables/attributes'
- if ci_variable_protected_by_default?
%p.settings-message.text-center.gl-mb-0
- help_link = link_to('', help_page_path('ci/variables/index', anchor: 'protect-a-cicd-variable', target: '_blank', rel: 'noopener noreferrer'))
diff --git a/app/views/admin/application_settings/general.html.haml b/app/views/admin/application_settings/general.html.haml
index 39f1ec7056c..2e16161cde4 100644
--- a/app/views/admin/application_settings/general.html.haml
+++ b/app/views/admin/application_settings/general.html.haml
@@ -120,8 +120,5 @@
= render_if_exists 'admin/application_settings/add_license'
= render 'admin/application_settings/jira_connect'
= render 'admin/application_settings/slack'
-- if Feature.enabled?(:updated_ai_powered_features_menu_for_sm)
- = render_if_exists 'admin/application_settings/ai_powered'
-- else
- = render_if_exists 'admin/application_settings/ai_access'
+= render_if_exists 'admin/application_settings/ai_powered'
= render 'admin/application_settings/security_txt', expanded: expanded_by_default?
diff --git a/app/views/admin/application_settings/network.html.haml b/app/views/admin/application_settings/network.html.haml
index ae5f7a5cec3..c2f19c11b4e 100644
--- a/app/views/admin/application_settings/network.html.haml
+++ b/app/views/admin/application_settings/network.html.haml
@@ -151,6 +151,8 @@
= render 'projects_api_limits'
+= render 'members_api_limits'
+
%section.settings.as-import-export-limits.no-animate#js-import-export-limits-settings{ class: ('expanded' if expanded_by_default?) }
.settings-header
%h4.settings-title.js-settings-toggle.js-settings-toggle-trigger-only
diff --git a/app/views/admin/dashboard/_stats_users_table.html.haml b/app/views/admin/dashboard/_stats_users_table.html.haml
index 473384b8961..a23674c79db 100644
--- a/app/views/admin/dashboard/_stats_users_table.html.haml
+++ b/app/views/admin/dashboard/_stats_users_table.html.haml
@@ -1,4 +1,4 @@
-%table.table.gl-text-gray-500
+%table.table.gl-text-gray-500.gl-w-full
%tr
%td.gl-p-5!
= s_('AdminArea|Users without a Group and Project')
diff --git a/app/views/admin/dashboard/stats.html.haml b/app/views/admin/dashboard/stats.html.haml
index 059460ae5b2..8c096e2936f 100644
--- a/app/views/admin/dashboard/stats.html.haml
+++ b/app/views/admin/dashboard/stats.html.haml
@@ -8,7 +8,7 @@
%p.gl-font-weight-bold.gl-mt-8
= s_('AdminArea|Totals')
-%table.gl-table.gl-text-gray-500
+%table.gl-table.gl-text-gray-500.gl-w-full
= render_if_exists 'admin/dashboard/stats_active_users_row', users_statistics: @users_statistics
%tr.bg-gray-light.gl-text-gray-900
diff --git a/app/views/admin/sessions/new.html.haml b/app/views/admin/sessions/new.html.haml
index b3e24d5b3ac..e2f5ef5d786 100644
--- a/app/views/admin/sessions/new.html.haml
+++ b/app/views/admin/sessions/new.html.haml
@@ -4,11 +4,9 @@
.row.gl-mt-5.justify-content-center
.col-md-5
.login-page
- #signin-container{ class: ('borderless' if Feature.enabled?(:restyle_login_page, @project)) }
+ .borderless
- if any_form_based_providers_enabled?
= render 'devise/shared/tabs_ldap', show_password_form: allow_admin_mode_password_authentication_for_web?, render_signup_link: false
- - else
- = render 'devise/shared/tab_single', tab_title: page_title if Feature.disabled?(:restyle_login_page, @project)
.tab-content
- if allow_admin_mode_password_authentication_for_web? || ldap_sign_in_enabled? || crowd_enabled?
= render 'admin/sessions/signin_box'
diff --git a/app/views/admin/sessions/two_factor.html.haml b/app/views/admin/sessions/two_factor.html.haml
index ef004004227..898d47f446a 100644
--- a/app/views/admin/sessions/two_factor.html.haml
+++ b/app/views/admin/sessions/two_factor.html.haml
@@ -4,8 +4,7 @@
.row.justify-content-center
.col-md-5
.login-page
- #signin-container{ class: ('borderless' if Feature.enabled?(:restyle_login_page, @project)) }
- = render 'devise/shared/tab_single', tab_title: _('Enter admin mode') if Feature.disabled?(:restyle_login_page, @project)
+ .borderless
.login-box.gl-p-5
.login-body
- if current_user.two_factor_enabled?
diff --git a/app/views/admin/users/show.html.haml b/app/views/admin/users/show.html.haml
index 46fe6bed05e..649ed00ea22 100644
--- a/app/views/admin/users/show.html.haml
+++ b/app/views/admin/users/show.html.haml
@@ -151,6 +151,8 @@
= render_if_exists 'admin/users/credit_card_info', user: @user, link_to_match_page: true
+ = render_if_exists 'admin/users/phone_info', user: @user, link_to_match_page: true
+
= render 'shared/custom_attributes', custom_attributes: @user.custom_attributes
-# Rendered on desktop only so order of cards can be different on desktop vs mobile
diff --git a/app/views/ci/runner/_how_to_setup_runner.html.haml b/app/views/ci/runner/_how_to_setup_runner.html.haml
deleted file mode 100644
index 29c2e364c37..00000000000
--- a/app/views/ci/runner/_how_to_setup_runner.html.haml
+++ /dev/null
@@ -1,23 +0,0 @@
-- link = link_to _("Install GitLab Runner and ensure it's running."), 'https://docs.gitlab.com/runner/install/', target: '_blank', rel: 'noopener noreferrer'
-.gl-mb-3
- %h5= _("Set up a %{type} runner for a project") % { type: type }
-%ol
- %li
- = link.html_safe
- %li
- = _("Register the runner with this URL:")
- %br
- %code#coordinator_address= root_url(only_path: false)
- = deprecated_clipboard_button(target: '#coordinator_address', title: _("Copy URL"))
- %br
- %br
- = _("And this registration token:")
- %br
- %code#registration_token= registration_token
- = deprecated_clipboard_button(target: '#registration_token', title: _("Copy token"))
-
-.gl-mt-3.gl-mb-3
-= render Pajamas::ButtonComponent.new(variant: :default, method: :put, href: reset_token_url, button_options: { id: 'Reset registration token', data: { confirm: _("Are you sure you want to reset the registration token?") } }) do
- = _('Reset registration token')
-
-#js-install-runner
diff --git a/app/views/ci/variables/_attributes.html.haml b/app/views/ci/variables/_attributes.html.haml
new file mode 100644
index 00000000000..a924d92a4bb
--- /dev/null
+++ b/app/views/ci/variables/_attributes.html.haml
@@ -0,0 +1,13 @@
+%p
+ = s_('CiVariables|Variables can be accidentally exposed in a job log, or maliciously sent to a third party server. The masked variable feature can help reduce the risk of accidentally exposing variable values, but is not a guaranteed method to prevent malicious users from accessing variables.')
+ = link_to _('How can I make my variables more secure?'), help_page_path('ci/variables/index', anchor: 'cicd-variable-security'), target: '_blank', rel: 'noopener noreferrer'
+%p
+ = s_('CiVariables|Variables can have several attributes.')
+ = link_to _('Learn more.'), help_page_path('ci/variables/index', anchor: 'define-a-cicd-variable-in-the-ui'), target: '_blank', rel: 'noopener noreferrer'
+%ul
+ %li
+ = html_escape(s_('CiVariables|%{code_open}Protected:%{code_close} Only exposed to protected branches or protected tags.')) % { code_open: '<code>'.html_safe, code_close: '</code>'.html_safe }
+ %li
+ = html_escape(s_('CiVariables|%{code_open}Masked:%{code_close} Hidden in job logs. Must match masking requirements.')) % { code_open: '<code>'.html_safe, code_close: '</code>'.html_safe }
+ %li
+ = html_escape(s_('CiVariables|%{code_open}Expanded:%{code_close} Variables with %{code_open}$%{code_close} will be treated as the start of a reference to another variable.')) % { code_open: '<code>'.html_safe, code_close: '</code>'.html_safe }
diff --git a/app/views/ci/variables/_index.html.haml b/app/views/ci/variables/_index.html.haml
index 65f9e6c2342..a1567ad34e8 100644
--- a/app/views/ci/variables/_index.html.haml
+++ b/app/views/ci/variables/_index.html.haml
@@ -2,16 +2,7 @@
- is_group = !@group.nil?
- is_project = !@project.nil?
-%p
- = _('Variables can have several attributes.')
- = link_to _('Learn more.'), help_page_path('ci/variables/index', anchor: 'define-a-cicd-variable-in-the-ui'), target: '_blank', rel: 'noopener noreferrer'
-%ul
- %li
- = html_escape(_('%{code_open}Protected:%{code_close} Only exposed to protected branches or protected tags.')) % { code_open: '<code>'.html_safe, code_close: '</code>'.html_safe }
- %li
- = html_escape(_('%{code_open}Masked:%{code_close} Hidden in job logs. Must match masking requirements.')) % { code_open: '<code>'.html_safe, code_close: '</code>'.html_safe }
- %li
- = html_escape(_('%{code_open}Expanded:%{code_close} Variables with %{code_open}$%{code_close} will be treated as the start of a reference to another variable.')) % { code_open: '<code>'.html_safe, code_close: '</code>'.html_safe }
+= render 'ci/variables/attributes'
#js-ci-variables{ data: { endpoint: save_endpoint,
is_project: is_project.to_s,
diff --git a/app/views/dashboard/todos/index.html.haml b/app/views/dashboard/todos/index.html.haml
index 4f3ca9fd71b..1b0bd10db77 100644
--- a/app/views/dashboard/todos/index.html.haml
+++ b/app/views/dashboard/todos/index.html.haml
@@ -104,7 +104,10 @@
- if todos_filter_empty?
%p
- = (s_("Todos|Are you looking for things to do? Take a look at %{strongStart}%{openIssuesLinkStart}open issues%{openIssuesLinkEnd}%{strongEnd}, contribute to %{strongStart}%{mergeRequestLinkStart}a merge request%{mergeRequestLinkEnd}%{mergeRequestLinkEnd}%{strongEnd}, or mention someone in a comment to automatically assign them a new to-do item.") % { strongStart: '<strong>', strongEnd: '</strong>', openIssuesLinkStart: "<a href=\"#{issues_dashboard_path}\">", openIssuesLinkEnd: '</a>', mergeRequestLinkStart: "<a href=\"#{merge_requests_dashboard_path}\">", mergeRequestLinkEnd: '</a>' }).html_safe
+ = (s_("Todos|Not sure where to go next? Take a look at your %{strongStart}%{assignedIssuesLinkStart}assigned issues%{assignedIssuesLinkEnd}%{strongEnd} or %{strongStart}%{mergeRequestLinkStart}merge requests%{mergeRequestLinkEnd}%{mergeRequestLinkEnd}%{strongEnd}.") % { strongStart: '<strong>', strongEnd: '</strong>', assignedIssuesLinkStart: "<a href=\"#{issues_dashboard_path(assignee_username: current_user.username)}\">", assignedIssuesLinkEnd: '</a>', mergeRequestLinkStart: "<a href=\"#{merge_requests_dashboard_path(assignee_username: current_user.username)}\">", mergeRequestLinkEnd: '</a>' }).html_safe
+ %p
+ = link_to s_("Todos| What actions create to-do items?"), help_page_path('user/todos', anchor: 'actions-that-create-to-do-items'), target: '_blank', rel: 'noopener noreferrer'
+
- elsif todos_has_filtered_results?
%p
= link_to s_("Todos|Do you want to remove the filters?"), todos_filter_path(without: [:project_id, :author_id, :type, :action_id])
diff --git a/app/views/devise/confirmations/new.html.haml b/app/views/devise/confirmations/new.html.haml
index 00652e8574a..0ce6d9b1095 100644
--- a/app/views/devise/confirmations/new.html.haml
+++ b/app/views/devise/confirmations/new.html.haml
@@ -8,7 +8,8 @@
= f.label :email
= f.email_field :email, class: "form-control gl-form-input", required: true, autocomplete: 'off', title: _('Please provide a valid email address.'), value: nil
.form-text.gl-text-secondary
- = _('Requires your primary GitLab email address.')
+ - emails_link = link_to('', profile_emails_url, target: '_blank', rel: 'noopener noreferrer')
+ = safe_format(s_('Requires your primary GitLab email address. If you want to confirm a secondary email address, go to %{emails_link_start}Emails%{emails_link_end}'), tag_pair(emails_link, :emails_link_start, :emails_link_end))
%div
- if recaptcha_enabled?
diff --git a/app/views/devise/passwords/new.html.haml b/app/views/devise/passwords/new.html.haml
index 227418e366d..536d4c9fd4b 100644
--- a/app/views/devise/passwords/new.html.haml
+++ b/app/views/devise/passwords/new.html.haml
@@ -16,8 +16,4 @@
= render Pajamas::ButtonComponent.new(type: :submit, variant: :confirm, block: true) do
= _('Reset password')
-- if Feature.enabled?(:restyle_login_page, @project)
- = render 'devise/shared/sign_in_link'
-- else
- .gl-mt-3
- = render 'devise/shared/sign_in_link'
+= render 'devise/shared/sign_in_link'
diff --git a/app/views/devise/registrations/new.html.haml b/app/views/devise/registrations/new.html.haml
index 29f1a1f398b..ec85c680f7f 100644
--- a/app/views/devise/registrations/new.html.haml
+++ b/app/views/devise/registrations/new.html.haml
@@ -11,9 +11,8 @@
= render 'devise/shared/signup_omniauth_providers'
.signup-page
- = render signup_box_template,
+ = render 'devise/shared/signup_box',
url: registration_path(resource_name, registration_path_params),
button_text: _('Register'),
- borderless: Feature.enabled?(:restyle_login_page, @project),
show_omniauth_providers: omniauth_enabled? && button_based_providers_enabled?
= 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 e7ebe6d808c..728728ea653 100644
--- a/app/views/devise/sessions/new.html.haml
+++ b/app/views/devise/sessions/new.html.haml
@@ -9,26 +9,23 @@
= render_if_exists "layouts/google_tag_manager_body"
-#signin-container
+.js-non-oauth-login
- if any_form_based_providers_enabled?
= render 'devise/shared/tabs_ldap', render_signup_link: false
.tab-content
- if password_authentication_enabled_for_web? || ldap_sign_in_enabled? || crowd_enabled?
= render 'devise/shared/signin_box'
-
- -# Show a message if none of the mechanisms above are enabled
- - if !password_authentication_enabled_for_web? && !ldap_sign_in_enabled? && !(omniauth_enabled? && devise_mapping.omniauthable?)
- %div
- = _('No authentication methods configured.')
-
- - if Feature.enabled?(:restyle_login_page, @project) && Gitlab::CurrentSettings.current_application_settings.terms
- %p.gl-px-5
- = html_escape(s_("SignUp|By signing in you accept the %{link_start}Terms of Use and acknowledge the Privacy Statement and Cookie Policy%{link_end}.")) % { link_start: "<a href='#{terms_path}' target='_blank' rel='noreferrer noopener'>".html_safe,
- link_end: '</a>'.html_safe }
-
- - if allow_signup?
- %p{ class: "gl-mt-3 #{'gl-text-center' if Feature.enabled?(:restyle_login_page, @project)}" }
- = _("Don't have an account yet?")
- = link_to _("Register now"), new_registration_path(:user, invite_email: @invite_email), data: { testid: 'register-link' }
- - if omniauth_enabled? && devise_mapping.omniauthable? && button_based_providers_enabled?
- = render 'devise/shared/omniauth_box'
+-# Show a message if none of the mechanisms above are enabled
+- if !password_authentication_enabled_for_web? && !ldap_sign_in_enabled? && !(omniauth_enabled? && devise_mapping.omniauthable?)
+ %div
+ = _('No authentication methods configured.')
+- if Gitlab::CurrentSettings.current_application_settings.terms
+ %p.gl-px-5
+ = html_escape(s_("SignUp|By signing in you accept the %{link_start}Terms of Use and acknowledge the Privacy Statement and Cookie Policy%{link_end}.")) % { link_start: "<a href='#{terms_path}' target='_blank' rel='noreferrer noopener'>".html_safe,
+ link_end: '</a>'.html_safe }
+- if allow_signup?
+ %p.gl-mt-3.gl-text-center
+ = _("Don't have an account yet?")
+ = link_to _("Register now"), new_registration_path(:user, invite_email: @invite_email), data: { testid: 'register-link' }
+- if omniauth_enabled? && devise_mapping.omniauthable? && button_based_providers_enabled?
+ = render 'devise/shared/omniauth_box'
diff --git a/app/views/devise/sessions/two_factor.html.haml b/app/views/devise/sessions/two_factor.html.haml
index 96f6f5cb095..454b89e40f8 100644
--- a/app/views/devise/sessions/two_factor.html.haml
+++ b/app/views/devise/sessions/two_factor.html.haml
@@ -1,8 +1,7 @@
-= render 'devise/shared/tab_single', tab_title: _('Two-factor authentication') if Feature.disabled?(:restyle_login_page, @project)
.login-box.gl-p-5
.login-body
- if @user.two_factor_enabled?
- = gitlab_ui_form_for(resource, as: resource_name, url: session_path(resource_name), method: :post, html: { class: "edit_user gl-show-field-errors js-2fa-form #{'hidden' if @user.two_factor_webauthn_enabled?}" }) do |f|
+ = gitlab_ui_form_for(resource, as: resource_name, url: session_path(resource_name), method: :post, html: { class: "gl-show-field-errors js-2fa-form #{'hidden' if @user.two_factor_webauthn_enabled?}", aria: { live: 'assertive' }}) do |f|
.form-group
= f.label :otp_attempt, _('Enter verification code')
= f.text_field :otp_attempt, class: 'form-control gl-form-input', required: true, autofocus: true, autocomplete: 'off', inputmode: 'numeric', title: _('This field is required.'), data: { testid: 'two-fa-code-field' }
diff --git a/app/views/devise/shared/_footer.html.haml b/app/views/devise/shared/_footer.html.haml
index c35e43b909e..44f34e3f342 100644
--- a/app/views/devise/shared/_footer.html.haml
+++ b/app/views/devise/shared/_footer.html.haml
@@ -7,5 +7,8 @@
= link_to _("Help"), help_path
= link_to _("About GitLab"), "https://#{ApplicationHelper.promo_host}"
= link_to _("Community forum"), ApplicationHelper.community_forum, target: '_blank', class: 'text-nowrap', rel: 'noopener noreferrer'
+ - if one_trust_enabled?
+ = render Pajamas::ButtonComponent.new(category: :tertiary, size: :small, button_options: { class: 'ot-sdk-show-settings' }) do
+ = _("Cookie Preferences")
= render 'devise/shared/language_switcher'
= footer_message
diff --git a/app/views/devise/shared/_omniauth_box.html.haml b/app/views/devise/shared/_omniauth_box.html.haml
index 45062745b77..8197abcc787 100644
--- a/app/views/devise/shared/_omniauth_box.html.haml
+++ b/app/views/devise/shared/_omniauth_box.html.haml
@@ -1,21 +1,16 @@
- render_remember_me = remember_me_enabled? && local_assigns.fetch(:render_remember_me, true)
-- restyle_login_page_enabled = Feature.enabled?(:restyle_login_page, @project)
-- if restyle_login_page_enabled && (any_form_based_providers_enabled? || password_authentication_enabled_for_web?)
+- if any_form_based_providers_enabled? || password_authentication_enabled_for_web?
.omniauth-divider.gl-display-flex.gl-align-items-center
= _("or sign in with")
-.gl-mt-5.gl-px-5{ class: restyle_login_page_enabled ? 'omniauth-container gl-text-center gl-ml-auto gl-mr-auto' : 'omniauth-container gl-py-5' }
- - if !restyle_login_page_enabled
- %label.gl-font-weight-bold
- = _('Sign in with')
+.gl-mt-5.gl-px-5.gl-text-center.gl-display-flex.gl-flex-direction-column.gl-gap-3.js-oauth-login
- enabled_button_based_providers.each do |provider|
- - has_icon = provider_has_icon?(provider)
- = button_to omniauth_authorize_path(:user, provider), id: "oauth-login-#{provider}", data: { testid: "#{test_id_for_provider(provider)}" }, class: "btn gl-button btn-default gl-mb-2 js-oauth-login gl-w-full", form: { class: restyle_login_page_enabled ? 'gl-mb-3' : 'gl-w-full gl-mb-3' } do
- - if has_icon
- = provider_image_tag(provider)
- %span.gl-button-text
- = label_for_provider(provider)
+ = render 'devise/shared/omniauth_provider_button',
+ href: omniauth_authorize_path(:user, provider),
+ provider: provider,
+ data: { testid: test_id_for_provider(provider) },
+ id: "oauth-login-#{provider}"
- if render_remember_me
= render Pajamas::CheckboxTagComponent.new(name: 'remember_me_omniauth', value: nil) do |c|
- c.with_label do
diff --git a/app/views/devise/shared/_omniauth_provider_button.haml b/app/views/devise/shared/_omniauth_provider_button.haml
new file mode 100644
index 00000000000..c33e2253bb1
--- /dev/null
+++ b/app/views/devise/shared/_omniauth_provider_button.haml
@@ -0,0 +1,7 @@
+- button_options = { class: local_assigns.fetch(:classes, nil) || nil, data: data, id: id }
+
+= render Pajamas::ButtonComponent.new(href: href, method: :post, form: true, block: true, button_options: button_options) do
+ - if provider_has_icon?(provider)
+ = provider_image_tag(provider)
+ %span.gl-button-text
+ = label_for_provider(provider)
diff --git a/app/views/devise/shared/_signup_box.html.haml b/app/views/devise/shared/_signup_box.html.haml
index fb60b8c08eb..9eb0b773ebb 100644
--- a/app/views/devise/shared/_signup_box.html.haml
+++ b/app/views/devise/shared/_signup_box.html.haml
@@ -1,10 +1,7 @@
-- borderless ||= false
-
-.gl-mb-3.gl-p-4{ class: (borderless ? '' : 'gl-border-gray-100 gl-border-1 gl-border-solid gl-rounded-base') }
+.gl-mb-3.gl-p-4
= yield :omniauth_providers_top if show_omniauth_providers
= render 'devise/shared/signup_box_form',
button_text: button_text,
url: url,
show_omniauth_providers: omniauth_enabled? && button_based_providers_enabled?
-
diff --git a/app/views/devise/shared/_signup_omniauth_provider_button.haml b/app/views/devise/shared/_signup_omniauth_provider_button.haml
index 74f009a97d3..9870e90cfff 100644
--- a/app/views/devise/shared/_signup_omniauth_provider_button.haml
+++ b/app/views/devise/shared/_signup_omniauth_provider_button.haml
@@ -1,8 +1,6 @@
-- data = { provider: provider, track_action: "#{provider}_sso", track_label: tracking_label }
-- button_options = { class: 'js-oauth-login', data: data, id: "oauth-login-#{provider}" }
-
-= render Pajamas::ButtonComponent.new(href: href, method: :post, form: true, block: true, button_options: button_options) do
- - if provider_has_icon?(provider)
- = provider_image_tag(provider)
- %span.gl-button-text
- = label_for_provider(provider)
+= render 'devise/shared/omniauth_provider_button',
+ href: href,
+ provider: provider,
+ classes: 'js-track-omni-auth',
+ data: { provider: provider, track_action: "#{provider}_sso", track_label: tracking_label },
+ id: "oauth-login-#{provider}"
diff --git a/app/views/devise/shared/_signup_omniauth_provider_list.haml b/app/views/devise/shared/_signup_omniauth_provider_list.haml
index 9916d3fa026..c1026c0f431 100644
--- a/app/views/devise/shared/_signup_omniauth_provider_list.haml
+++ b/app/views/devise/shared/_signup_omniauth_provider_list.haml
@@ -1,21 +1,9 @@
-- if Feature.enabled?(:restyle_login_page, @project)
- .gl-text-center.gl-pt-5
- %label.gl-font-weight-normal
- = _("Register with:")
- .gl-display-flex.gl-flex-direction-column.gl-gap-3
- - providers.each do |provider|
- = render 'devise/shared/signup_omniauth_provider_button',
- href: omniauth_authorize_path(:user, provider, register_omniauth_params(local_assigns)),
- provider: provider,
- tracking_label: tracking_label
-
-
-- else
- %label.gl-font-weight-bold
- = _("Create an account using:")
+.gl-text-center.gl-pt-5
+ %label.gl-font-weight-normal
+ = _("Register with:")
.gl-display-flex.gl-flex-direction-column.gl-gap-3
- providers.each do |provider|
= render 'devise/shared/signup_omniauth_provider_button',
- href: omniauth_authorize_path(:user, provider, register_omniauth_params(local_assigns)),
- provider: provider,
- tracking_label: tracking_label
+ href: omniauth_authorize_path(:user, provider, register_omniauth_params(local_assigns)),
+ provider: provider,
+ tracking_label: tracking_label
diff --git a/app/views/devise/shared/_signup_omniauth_providers.haml b/app/views/devise/shared/_signup_omniauth_providers.haml
index 4e62c10b258..263e11ab341 100644
--- a/app/views/devise/shared/_signup_omniauth_providers.haml
+++ b/app/views/devise/shared/_signup_omniauth_providers.haml
@@ -1,6 +1,3 @@
-- if Feature.disabled?(:restyle_login_page, @project)
- .omniauth-divider.gl-display-flex.gl-align-items-center
- = _("or")
= render 'devise/shared/signup_omniauth_provider_list',
providers: enabled_button_based_providers,
tracking_label: oauth_tracking_label
diff --git a/app/views/devise/shared/_tabs_ldap.html.haml b/app/views/devise/shared/_tabs_ldap.html.haml
index e6bc38ba6dd..3e9d60da228 100644
--- a/app/views/devise/shared/_tabs_ldap.html.haml
+++ b/app/views/devise/shared/_tabs_ldap.html.haml
@@ -1,7 +1,7 @@
- show_password_form = local_assigns.fetch(:show_password_form, password_authentication_enabled_for_web?)
- render_signup_link = local_assigns.fetch(:render_signup_link, true)
-%ul.nav-links.new-session-tabs.nav-tabs.nav{ class: "#{'custom-provider-tabs' if any_form_based_providers_enabled?} #{'nav-links-unboxed' if Feature.enabled?(:restyle_login_page, @project)}" }
+%ul.nav-links.new-session-tabs.nav-tabs.nav.nav-links-unboxed
- if crowd_enabled?
%li.nav-item
= link_to _("Crowd"), "#crowd", class: "nav-link #{active_when(form_based_auth_provider_has_active_class?(:crowd))}", 'data-toggle' => 'tab', role: 'tab'
diff --git a/app/views/devise/shared/_terms_of_service_notice.html.haml b/app/views/devise/shared/_terms_of_service_notice.html.haml
index 3749dc66a04..5d5a5a64c29 100644
--- a/app/views/devise/shared/_terms_of_service_notice.html.haml
+++ b/app/views/devise/shared/_terms_of_service_notice.html.haml
@@ -1,17 +1,9 @@
- return unless Gitlab::CurrentSettings.current_application_settings.enforce_terms?
%p.gl-text-gray-500.gl-mt-5.gl-mb-0
- - if Feature.enabled?(:restyle_login_page, @project)
- - if Gitlab.com?
- = html_escape(s_("SignUp|By clicking %{button_text} or registering through a third party you accept the GitLab%{link_start} Terms of Use and acknowledge the Privacy Statement and Cookie Policy%{link_end}")) % { button_text: button_text,
- link_start: "<a href='#{terms_path}' target='_blank' rel='noreferrer noopener'>".html_safe, link_end: '</a>'.html_safe }
- - else
- = html_escape(s_("SignUp|By clicking %{button_text} or registering through a third party you accept the%{link_start} Terms of Use and acknowledge the Privacy Statement and Cookie Policy%{link_end}")) % { button_text: button_text,
- link_start: "<a href='#{terms_path}' target='_blank' rel='noreferrer noopener'>".html_safe, link_end: '</a>'.html_safe }
+ - if Gitlab.com?
+ = html_escape(s_("SignUp|By clicking %{button_text} or registering through a third party you accept the GitLab%{link_start} Terms of Use and acknowledge the Privacy Statement and Cookie Policy%{link_end}")) % { button_text: button_text,
+ link_start: "<a href='#{terms_path}' target='_blank' rel='noreferrer noopener'>".html_safe, link_end: '</a>'.html_safe }
- else
- - if Gitlab.com?
- = html_escape(s_("SignUp|By clicking %{button_text}, I agree that I have read and accepted the GitLab %{link_start}Terms of Use and Privacy Statement%{link_end}")) % { button_text: button_text,
- link_start: "<a href='#{terms_path}' target='_blank' rel='noreferrer noopener'>".html_safe, link_end: '</a>'.html_safe }
- - else
- = html_escape(s_("SignUp|By clicking %{button_text}, I agree that I have read and accepted the %{link_start}Terms of Use and Privacy Statement%{link_end}")) % { button_text: button_text,
- link_start: "<a href='#{terms_path}' target='_blank' rel='noreferrer noopener'>".html_safe, link_end: '</a>'.html_safe }
+ = html_escape(s_("SignUp|By clicking %{button_text} or registering through a third party you accept the%{link_start} Terms of Use and acknowledge the Privacy Statement and Cookie Policy%{link_end}")) % { button_text: button_text,
+ link_start: "<a href='#{terms_path}' target='_blank' rel='noreferrer noopener'>".html_safe, link_end: '</a>'.html_safe }
diff --git a/app/views/devise/unlocks/new.html.haml b/app/views/devise/unlocks/new.html.haml
index 8bae27020c2..393f42cd197 100644
--- a/app/views/devise/unlocks/new.html.haml
+++ b/app/views/devise/unlocks/new.html.haml
@@ -11,8 +11,5 @@
= render Pajamas::ButtonComponent.new(type: :submit, variant: :confirm, block: true) do
= _('Resend unlock instructions')
-- if Feature.enabled?(:restyle_login_page, @project)
- = render 'devise/shared/sign_in_link'
-- else
- .gl-mt-3
- = render 'devise/shared/sign_in_link'
+= render 'devise/shared/sign_in_link'
+
diff --git a/app/views/groups/_import_group_from_file_panel.html.haml b/app/views/groups/_import_group_from_file_panel.html.haml
index c39f5cf87c7..43a8ccdaae4 100644
--- a/app/views/groups/_import_group_from_file_panel.html.haml
+++ b/app/views/groups/_import_group_from_file_panel.html.haml
@@ -10,14 +10,14 @@
alert_options: { class: 'gl-mb-5' },
dismissible: false) do |c|
- c.with_body do
- - docs_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: help_page_path('user/group/import/index', anchor: 'migrate-groups-by-direct-transfer-recommended') }
+ - docs_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: help_page_path('user/group/import/index') }
- link_end = '</a>'.html_safe
= s_('GroupsNew|This feature is deprecated and replaced by group migration by direct transfer. %{docs_link_start}Learn more%{docs_link_end}.').html_safe % { docs_link_start: docs_link_start, docs_link_end: link_end }
= render 'shared/groups/group_name_and_path_fields', f: f
.form-group
= f.label :file, s_('GroupsNew|Upload file')
.gl-font-weight-normal
- - import_export_link_start = '<a href="%{url}" target="_blank">'.html_safe % { url: help_page_path('user/group/import/index') }
+ - import_export_link_start = '<a href="%{url}" target="_blank">'.html_safe % { url: help_page_path('user/project/settings/import_export', anchor: 'migrate-groups-by-uploading-an-export-file-deprecated') }
= s_('GroupsNew|To import a group, navigate to the group settings for the GitLab source instance, %{link_start}generate an export file%{link_end}, and upload it here.').html_safe % { link_start: import_export_link_start, link_end: '</a>'.html_safe }
.gl-mt-3
= render 'shared/file_picker_button', f: f, field: :file, help_text: nil
diff --git a/app/views/groups/settings/_export.html.haml b/app/views/groups/settings/_export.html.haml
index ff1d76f470c..c7909a7c249 100644
--- a/app/views/groups/settings/_export.html.haml
+++ b/app/views/groups/settings/_export.html.haml
@@ -10,7 +10,7 @@
- c.with_body do
= render Pajamas::AlertComponent.new(variant: :warning, dismissible: false, alert_options: { class: 'gl-mb-4' }) do |c|
- c.with_body do
- - docs_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: help_page_path('user/group/import/index', anchor: 'migrate-groups-by-direct-transfer-recommended') }
+ - docs_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: help_page_path('user/group/import/index') }
- docs_link_end = '</a>'.html_safe
= s_('GroupsNew|This feature is deprecated and replaced by group migration by direct transfer. %{docs_link_start}Learn more%{docs_link_end}.').html_safe % { docs_link_start: docs_link_start, docs_link_end: docs_link_end }
%p
diff --git a/app/views/groups/settings/_permissions.html.haml b/app/views/groups/settings/_permissions.html.haml
index 4334c4996f2..fae0c41b683 100644
--- a/app/views/groups/settings/_permissions.html.haml
+++ b/app/views/groups/settings/_permissions.html.haml
@@ -49,6 +49,7 @@
= render_if_exists 'groups/personal_access_token_expiration_policy', f: f, group: @group
= render 'groups/settings/membership', f: f, group: @group
= render_if_exists 'groups/settings/security_policies_custom_ci', f: f, group: @group
+ = render_if_exists 'groups/settings/security_policies_policy_scope', f: f, group: @group
%h5= _('Customer relations')
.form-group.gl-mb-3
@@ -57,4 +58,12 @@
checkbox_options: { checked: @group.crm_enabled? },
help_text: s_('GroupSettings|Organizations and contacts can be created and associated with issues.')
+ - if Feature.enabled?(:group_hierarchy_optimization, @group, type: :beta)
+ %h5= _('Performance')
+ .form-group.gl-mb-3
+ = f.gitlab_ui_checkbox_component :enable_namespace_descendants_cache,
+ s_('GroupSettings|Enable caching of hierarchical objects (subgroups and projects) to improve the performance of group-level features within a large group.'),
+ checkbox_options: { checked: @group.namespace_descendants.present? },
+ help_text: s_('GroupSettings|Building the cache is asynchronous, happens in a background job. The cache invalidation is synchronous with strong consistency guarantees.')
+
= f.submit _('Save changes'), pajamas_button: true, class: 'gl-mt-3 js-dirty-submit', data: { testid: 'save-permissions-changes-button' }
diff --git a/app/views/import/github/status.html.haml b/app/views/import/github/status.html.haml
index 97acafe24d0..0f56ae92557 100644
--- a/app/views/import/github/status.html.haml
+++ b/app/views/import/github/status.html.haml
@@ -12,4 +12,4 @@
cancel_path: cancel_import_github_path,
details_path: details_import_github_path,
status_import_github_group_path: status_import_github_group_path(format: :json),
- optional_stages: Gitlab::GithubImport::Settings.stages_array
+ optional_stages: Gitlab::GithubImport::Settings.stages_array(current_user)
diff --git a/app/views/layouts/_head.html.haml b/app/views/layouts/_head.html.haml
index 5f038ac467d..79fa5bfeac0 100644
--- a/app/views/layouts/_head.html.haml
+++ b/app/views/layouts/_head.html.haml
@@ -19,7 +19,6 @@
= yield :prefetch_asset_tags
- diffs_colors = user_diffs_colors
- = stylesheet_link_tag "themes/#{user_application_theme_css_filename}" if user_application_theme_css_filename
= render 'layouts/diffs_colors_css', diffs_colors if diffs_colors.present? || request.path == profile_preferences_path
- if user_application_theme == 'gl-dark'
diff --git a/app/views/layouts/_page.html.haml b/app/views/layouts/_page.html.haml
index a7caa797a46..3af04db4cfd 100644
--- a/app/views/layouts/_page.html.haml
+++ b/app/views/layouts/_page.html.haml
@@ -1,16 +1,13 @@
.layout-page{ class: page_with_sidebar_class }
- - if show_super_sidebar?
- -# Render the parent group sidebar while creating a new subgroup/project, see GroupsController#new.
- - group = @parent_group || @group
+ -# Render the parent group sidebar while creating a new subgroup/project, see GroupsController#new.
+ - group = @parent_group || @group
- - sidebar_panel = super_sidebar_nav_panel(nav: nav, user: current_user, group: group, project: @project, current_ref: current_ref, ref_type: @ref_type, viewed_user: @user, organization: @organization)
- - sidebar_data = super_sidebar_context(current_user, group: group, project: @project, panel: sidebar_panel, panel_type: nav).to_json
- %aside.js-super-sidebar.super-sidebar.super-sidebar-loading{ data: { root_path: root_path, sidebar: sidebar_data, force_desktop_expanded_sidebar: @force_desktop_expanded_sidebar.to_s, command_palette: command_palette_data(project: @project).to_json } }
+ - sidebar_panel = super_sidebar_nav_panel(nav: nav, user: current_user, group: group, project: @project, current_ref: current_ref, ref_type: @ref_type, viewed_user: @user, organization: @organization)
+ - sidebar_data = super_sidebar_context(current_user, group: group, project: @project, panel: sidebar_panel, panel_type: nav).to_json
+ %aside.js-super-sidebar.super-sidebar.super-sidebar-loading{ data: { root_path: root_path, sidebar: sidebar_data, force_desktop_expanded_sidebar: @force_desktop_expanded_sidebar.to_s, command_palette: command_palette_data(project: @project).to_json } }
- = render_if_exists "layouts/tanuki_bot_chat"
+ = render_if_exists "layouts/tanuki_bot_chat"
- - elsif defined?(nav) && nav
- = render "layouts/nav/sidebar/#{nav}"
.content-wrapper{ class: "#{@content_wrapper_class}" }
.mobile-overlay
= dispensable_render_if_exists 'layouts/header/verification_reminder'
diff --git a/app/views/layouts/_snowplow.html.haml b/app/views/layouts/_snowplow.html.haml
index 3582deea902..503b38496f7 100644
--- a/app/views/layouts/_snowplow.html.haml
+++ b/app/views/layouts/_snowplow.html.haml
@@ -2,7 +2,7 @@
- namespace = @group || @project&.namespace || @namespace
= webpack_bundle_tag 'tracker'
-- if Gitlab.com? && Feature.enabled?(:browsersdk_tracking) && Feature.enabled?(:gl_analytics_tracking, Feature.current_request)
+- if Gitlab.com? && Feature.enabled?(:gl_analytics_tracking, Feature.current_request)
= webpack_bundle_tag 'analytics'
= javascript_tag do
:plain
@@ -13,7 +13,6 @@
namespace_id: namespace&.id,
plan_name: namespace&.actual_plan_name,
project_id: @project&.id,
- user_id: current_user&.id,
- new_nav: show_super_sidebar?
+ user_id: current_user&.id
).to_context.to_json.to_json}
gl.snowplowPseudonymizedPageUrl = #{masked_page_url(group: namespace, project: @project).to_json};
diff --git a/app/views/layouts/application.html.haml b/app/views/layouts/application.html.haml
index 78fa40167f8..b9257bcedc9 100644
--- a/app/views/layouts/application.html.haml
+++ b/app/views/layouts/application.html.haml
@@ -1,11 +1,13 @@
- page_classes = page_class << @html_class
- page_classes = [user_application_theme, page_classes.flatten.compact]
- body_classes = [user_tab_width, @body_class, client_class_list, *custom_diff_color_classes]
+- ff_simplified_labels_enabled = Feature.enabled?(:simplified_labels) ? 'ff-simplified-labels-enabled' : ''
+- ff_simplified_badges_class = Feature.enabled?(:simplified_badges) ? 'ff-simplified-badges-enabled' : ''
!!! 5
%html{ lang: I18n.locale, class: page_classes }
= render "layouts/head"
- %body{ class: body_classes, data: body_data }
+ %body{ class: [body_classes, ff_simplified_labels_enabled, ff_simplified_badges_class], data: body_data }
= render "layouts/init_auto_complete" if @gfm_form
= render "layouts/init_client_detection_flags"
= render "layouts/visual_review" if review_apps_enabled?
diff --git a/app/views/layouts/devise.html.haml b/app/views/layouts/devise.html.haml
index 920771bf4c2..2905ba924ca 100644
--- a/app/views/layouts/devise.html.haml
+++ b/app/views/layouts/devise.html.haml
@@ -6,63 +6,31 @@
%body.gl-h-full.login-page.navless{ class: "#{system_message_class} #{client_class_list}", data: { page: body_data_page, testid: 'login-page' } }
= header_message
= render "layouts/init_client_detection_flags"
- - if Feature.enabled?(:restyle_login_page, @project)
- = yield :sessions_broadcast
- .gl-h-full.borderless.gl-display-flex.gl-flex-wrap
- .container
- .content
- = render "layouts/flash"
- - if custom_text.present?
- .row
- .col-md.order-12.sm-bg-gray
- .col-sm-12
- %h1.mb-3.gl-font-size-h2
- = brand_title
- = custom_text
- .col-md.order-md-12
- .col-sm-12.bar
- .gl-text-center
- = brand_image
- = yield
- - else
- .mt-3
- .col-sm-12.gl-text-center
- = brand_image
+ = yield :sessions_broadcast
+ .gl-h-full.borderless.gl-display-flex.gl-flex-wrap
+ .container.gl-align-self-center
+ .content
+ = render "layouts/flash"
+ - if custom_text.present?
+ .row
+ .col-md.order-12.sm-bg-gray
+ .col-sm-12
%h1.mb-3.gl-font-size-h2
= brand_title
- .mb-3
- .gl-w-full.gl-sm-w-half.gl-ml-auto.gl-mr-auto.bar
+ = custom_text
+ .col-md.order-md-12
+ .col-sm-12.bar
+ .gl-text-center
+ = brand_image
= yield
-
- = render 'devise/shared/footer'
- - else
- = render "layouts/header/empty"
- = yield :sessions_broadcast
- .gl-h-full.gl-display-flex.gl-flex-wrap
- .container
- .content
- = render "layouts/flash"
- .row.mt-3
- .col-sm-12
- %h1.mb-3.font-weight-normal
- = current_appearance&.title.presence || _('GitLab')
- .row.mb-3
- .col-md-6.order-12.order-sm-1.brand-holder
- - unless recently_confirmed_com?
- = brand_image
- - if custom_text.present?
- = custom_text
- - else
- %h3.gl-sm-mt-0
- = _('A complete DevOps platform')
-
- %p
- = _('GitLab is a single application for the entire software development lifecycle. From project planning and source code management to CI/CD, monitoring, and security.')
-
- %p
- = _('This is a self-managed instance of GitLab.')
-
- .col-md-6.order-1{ class: recently_confirmed_com? ? 'order-sm-first' : 'order-sm-12' }
+ - else
+ .mt-3
+ .col-sm-12.gl-text-center
+ = brand_image
+ %h1.mb-3.gl-font-size-h2
+ = brand_title
+ .mb-3
+ .gl-w-full.gl-sm-w-half.gl-ml-auto.gl-mr-auto.bar
= yield
- = render 'devise/shared/footer'
+ = render 'devise/shared/footer'
diff --git a/app/views/layouts/devise_empty.html.haml b/app/views/layouts/devise_empty.html.haml
index 6816a64ac8f..faf45ae78ef 100644
--- a/app/views/layouts/devise_empty.html.haml
+++ b/app/views/layouts/devise_empty.html.haml
@@ -7,7 +7,7 @@
= render "layouts/init_client_detection_flags"
= render "layouts/header/empty"
.gl-h-full.gl-display-flex.gl-flex-wrap
- .container
+ .container.gl-align-self-center
.content
= render "layouts/flash"
= yield
diff --git a/app/views/layouts/group.html.haml b/app/views/layouts/group.html.haml
index 498e9216894..28305960de9 100644
--- a/app/views/layouts/group.html.haml
+++ b/app/views/layouts/group.html.haml
@@ -23,5 +23,6 @@
= dispensable_render_if_exists "shared/free_user_cap_alert", source: @group
= dispensable_render_if_exists "shared/unlimited_members_during_trial_alert", resource: @group
= dispensable_render_if_exists "shared/code_suggestions_ga_non_owner_alert", resource: @group
+= dispensable_render_if_exists "shared/code_suggestions_ga_owner_alert", resource: @group
= render template: base_layout || "layouts/application"
diff --git a/app/views/layouts/header/_super_sidebar_logged_out.haml b/app/views/layouts/header/_super_sidebar_logged_out.haml
index fc63400e011..9b0424ea478 100644
--- a/app/views/layouts/header/_super_sidebar_logged_out.haml
+++ b/app/views/layouts/header/_super_sidebar_logged_out.haml
@@ -2,7 +2,7 @@
%a.gl-sr-only.gl-accessibility{ href: "#content-body" } Skip to content
.container-fluid
%nav.header-logged-out-nav.gl-display-flex.gl-gap-3.gl-justify-content-space-between{ 'aria-label': s_('LoggedOutMarketingHeader|Explore GitLab') }
- .header-logged-out-logo.gl-display-flex.gl-align-items-center
+ .header-logged-out-logo.gl-display-flex.gl-align-items-center.gl-gap-3
%span.gl-sr-only GitLab
= link_to root_path, title: _('Homepage'), id: 'logo', class: 'has-tooltip', aria: { label: _('Homepage') }, **tracking_attrs('main_navigation', 'click_gitlab_logo_link', 'navigation_top') do
= brand_header_logo
diff --git a/app/views/layouts/nav/breadcrumbs/_collapsed_inline_list.html.haml b/app/views/layouts/nav/breadcrumbs/_collapsed_inline_list.html.haml
index 3894501bbbb..37bf8515a8c 100644
--- a/app/views/layouts/nav/breadcrumbs/_collapsed_inline_list.html.haml
+++ b/app/views/layouts/nav/breadcrumbs/_collapsed_inline_list.html.haml
@@ -1,8 +1,8 @@
- dropdown_location = local_assigns.fetch(:location, nil)
- button_tooltip = local_assigns.fetch(:title, _("Show all breadcrumbs"))
- if defined?(@breadcrumb_collapsed_links) && @breadcrumb_collapsed_links.key?(dropdown_location)
- %li.expander.gl-breadcrumb-item
- %button.text-expander.has-tooltip.js-breadcrumbs-collapsed-expander{ type: "button", data: { container: "body" }, "aria-label": button_tooltip, title: button_tooltip }
+ %li.expander.gl-breadcrumb-item.gl-display-inline-flex
+ %button.text-expander.has-tooltip.js-breadcrumbs-collapsed-expander.gl-ml-0{ type: "button", data: { container: "body" }, "aria-label": button_tooltip, title: button_tooltip }
= sprite_icon("ellipsis_h", size: 12)
- @breadcrumb_collapsed_links[dropdown_location].each_with_index do |link, index|
%li.gl-breadcrumb-item{ :class => "gl-display-none!" }
diff --git a/app/views/layouts/project.html.haml b/app/views/layouts/project.html.haml
index e95d645769e..5a6f45d4dd7 100644
--- a/app/views/layouts/project.html.haml
+++ b/app/views/layouts/project.html.haml
@@ -26,5 +26,6 @@
= dispensable_render_if_exists "projects/free_user_cap_alert", project: @project
= dispensable_render_if_exists 'shared/unlimited_members_during_trial_alert', resource: @project
= dispensable_render_if_exists 'projects/code_suggestions_ga_non_owner_alert', project: @project
+= dispensable_render_if_exists 'projects/code_suggestions_ga_owner_alert', project: @project
= render template: "layouts/application"
diff --git a/app/views/layouts/signup_onboarding.html.haml b/app/views/layouts/signup_onboarding.html.haml
index c8e15896b97..e3e071c2226 100644
--- a/app/views/layouts/signup_onboarding.html.haml
+++ b/app/views/layouts/signup_onboarding.html.haml
@@ -7,7 +7,7 @@
= header_message
= render "layouts/init_client_detection_flags"
= render "layouts/header/logo_with_title"
- .container
+ .container.gl-align-self-center
.content
= yield
diff --git a/app/views/notify/_reassigned_issuable_email.html.haml b/app/views/notify/_reassigned_issuable_email.html.haml
index ead8e5d0a7e..b89d897a81b 100644
--- a/app/views/notify/_reassigned_issuable_email.html.haml
+++ b/app/views/notify/_reassigned_issuable_email.html.haml
@@ -1,7 +1,12 @@
-- to_names = content_tag(:strong, issuable.assignees.any? ? sanitize_name(issuable.assignee_list) : _('Unassigned'))
+- added_names = content_tag(:strong, sanitize_name(added_assignees.to_sentence(locale: I18n.locale)))
+- removed_names = content_tag(:strong, sanitize_name(removed_assignees.to_sentence(locale: I18n.locale)))
-%p
- - if previous_assignees.any?
- = html_escape(s_('Notify|Assignee changed from %{fromNames} to %{toNames}').html_safe % { fromNames: content_tag(:strong, sanitize_name(previous_assignees.map(&:name).to_sentence)), toNames: to_names })
- - else
- = html_escape(s_('Notify|Assignee changed to %{toNames}').html_safe % { toNames: to_names})
+- if added_assignees.any?
+ %p
+ = html_escape(n_(s_('Notify|%{added} was added as an assignee.'), s_('Notify|%{added} were added as assignees.'), added_assignees.length).html_safe % { added: added_names })
+- if removed_assignees.any? && issuable.assignees.any?
+ %p
+ = html_escape(n_(s_('Notify|%{removed} was removed as an assignee.'), s_('Notify|%{removed} were removed as assignees.'), removed_assignees.length).html_safe % { removed: removed_names })
+- if removed_assignees.any? && issuable.assignees.empty?
+ %p
+ = html_escape(s_('Notify|All assignees were removed.'))
diff --git a/app/views/notify/new_review_email.html.haml b/app/views/notify/new_review_email.html.haml
index 8a184aa9696..5b870fe2214 100644
--- a/app/views/notify/new_review_email.html.haml
+++ b/app/views/notify/new_review_email.html.haml
@@ -2,24 +2,41 @@
= content_for :head do
= stylesheet_link_tag 'mailers/highlighted_diff_email'
-%table{ border: "0", cellpadding: "0", cellspacing: "0", style: "width:100%;margin:0 auto;border-collapse:separate;border-spacing:0;" }
- %tbody
- %tr
- %td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;background-color:#ffffff;text-align:left;overflow:hidden;" }
- %table{ border: "0", cellpadding: "0", cellspacing: "0", style: "width:100%;border-collapse:separate;border-spacing:0;" }
- %tbody
- %tr
- %td{ style: "color:#333333;border-bottom:1px solid #ededed;font-weight:bold;line-height:1.4;padding: 20px 0;" }
- - mr_link = link_to(@merge_request.to_reference(@project), project_merge_request_url(@project, @merge_request))
- - mr_author_link = link_to(@author_name, user_url(@author))
- = _('Merge request %{mr_link} was reviewed by %{mr_author}').html_safe % { mr_link: mr_link, mr_author: mr_author_link }
- %tr
- %td{ style: "overflow:hidden;line-height:1.4;display:grid;" }
- - @notes.each do |note|
- -# Get preloaded note discussion
- - discussion = @discussions[note.discussion_id] if note.part_of_discussion?
- -# Preload project for discussions first note
- - discussion.first_note.project = @project if discussion&.first_note
- - target_url = project_merge_request_url(@project, @merge_request, anchor: "note_#{note.id}")
- = render 'note_email', note: note, diff_limit: 3, target_url: target_url, note_style: "border-bottom:1px solid #ededed; padding-bottom: 1em;", include_stylesheet_link: false, discussion: discussion, author: @author
- = render_if_exists 'notify/review_summary'
+- if Feature.enabled?(:enhanced_review_email, @project, type: :gitlab_com_derisk)
+ %div{ style: "color:#333333;border-bottom:8px solid #ededed;font-weight:bold;line-height:1.4;padding: 20px 0;" }
+ - mr_link = link_to(@merge_request.to_reference(@project), project_merge_request_url(@project, @merge_request))
+ - mr_author_link = link_to(@author_name, user_url(@author))
+ = _('Merge request %{mr_link} was reviewed by %{mr_author}').html_safe % { mr_link: mr_link, mr_author: mr_author_link }
+
+ - @notes.each do |note|
+ -# Get preloaded note discussion
+ - discussion = @discussions[note.discussion_id] if note.part_of_discussion?
+ -# Preload project for discussions first note
+ - discussion.first_note.project = @project if discussion&.first_note
+ - target_url = project_merge_request_url(@project, @merge_request, anchor: "note_#{note.id}")
+ = render 'note_email', note: note, diff_limit: 3, target_url: target_url, note_style: "border-bottom:4px solid #ededed; padding-bottom: 1em;", include_stylesheet_link: false, discussion: discussion, author: @author
+ = render_if_exists 'notify/review_summary'
+
+- else
+
+ %table{ border: "0", cellpadding: "0", cellspacing: "0", style: "width:100%;margin:0 auto;border-collapse:separate;border-spacing:0;" }
+ %tbody
+ %tr
+ %td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;background-color:#ffffff;text-align:left;overflow:hidden;" }
+ %table{ border: "0", cellpadding: "0", cellspacing: "0", style: "width:100%;border-collapse:separate;border-spacing:0;" }
+ %tbody
+ %tr
+ %td{ style: "color:#333333;border-bottom:1px solid #ededed;font-weight:bold;line-height:1.4;padding: 20px 0;" }
+ - mr_link = link_to(@merge_request.to_reference(@project), project_merge_request_url(@project, @merge_request))
+ - mr_author_link = link_to(@author_name, user_url(@author))
+ = _('Merge request %{mr_link} was reviewed by %{mr_author}').html_safe % { mr_link: mr_link, mr_author: mr_author_link }
+ %tr
+ %td{ style: "overflow:hidden;line-height:1.4;display:grid;" }
+ - @notes.each do |note|
+ -# Get preloaded note discussion
+ - discussion = @discussions[note.discussion_id] if note.part_of_discussion?
+ -# Preload project for discussions first note
+ - discussion.first_note.project = @project if discussion&.first_note
+ - target_url = project_merge_request_url(@project, @merge_request, anchor: "note_#{note.id}")
+ = render 'note_email', note: note, diff_limit: 3, target_url: target_url, note_style: "border-bottom:1px solid #ededed; padding-bottom: 1em;", include_stylesheet_link: false, discussion: discussion, author: @author
+ = render_if_exists 'notify/review_summary'
diff --git a/app/views/notify/reassigned_issue_email.html.haml b/app/views/notify/reassigned_issue_email.html.haml
index 6b088927623..e5860c1672a 100644
--- a/app/views/notify/reassigned_issue_email.html.haml
+++ b/app/views/notify/reassigned_issue_email.html.haml
@@ -1 +1 @@
-= render 'reassigned_issuable_email', issuable: @issue, previous_assignees: @previous_assignees
+= render 'reassigned_issuable_email', issuable: @issue, added_assignees: @added_assignees, removed_assignees: @removed_assignees
diff --git a/app/views/notify/reassigned_issue_email.text.erb b/app/views/notify/reassigned_issue_email.text.erb
index f37c8ffa515..b5e5abbbccf 100644
--- a/app/views/notify/reassigned_issue_email.text.erb
+++ b/app/views/notify/reassigned_issue_email.text.erb
@@ -1,6 +1,15 @@
+<% added_names = sanitize_name(@added_assignees.to_sentence(locale: I18n.locale)) -%>
+<% removed_names = sanitize_name(@removed_assignees.to_sentence(locale: I18n.locale)) -%>
Reassigned Issue <%= @issue.iid %>
<%= url_for([@issue.project, @issue, { only_path: false }]) %>
-Assignee changed<%= " from #{sanitize_name(@previous_assignees.map(&:name).to_sentence)}" if @previous_assignees.any? -%>
- to <%= "#{@issue.assignees.any? ? @issue.assignee_list : 'Unassigned'}" %>
+<%- if @added_assignees.any? %>
+<%= html_escape(n_(s_('Notify|%{added} was added as an assignee.'), s_('Notify|%{added} were added as assignees.'), @added_assignees.length).html_safe % { added: added_names }) %>
+<% end -%>
+<%- if @removed_assignees.any? && @issue.assignees.any? %>
+<%= html_escape(n_(s_('Notify|%{removed} was removed as an assignee.'), s_('Notify|%{removed} were removed as assignees.'), @removed_assignees.length).html_safe % { removed: removed_names }) %>
+<% end -%>
+<%- if @removed_assignees.any? && @issue.assignees.empty? %>
+<%= html_escape(s_('Notify|All assignees were removed.')) %>
+<% end -%>
diff --git a/app/views/notify/reassigned_merge_request_email.html.haml b/app/views/notify/reassigned_merge_request_email.html.haml
index 0aefca6b14a..74de6767fe2 100644
--- a/app/views/notify/reassigned_merge_request_email.html.haml
+++ b/app/views/notify/reassigned_merge_request_email.html.haml
@@ -1 +1 @@
-= render 'reassigned_issuable_email', issuable: @merge_request, previous_assignees: @previous_assignees
+= render 'reassigned_issuable_email', issuable: @merge_request, added_assignees: @added_assignees, removed_assignees: @removed_assignees
diff --git a/app/views/notify/reassigned_merge_request_email.text.erb b/app/views/notify/reassigned_merge_request_email.text.erb
index 888b995b67c..7929349c439 100644
--- a/app/views/notify/reassigned_merge_request_email.text.erb
+++ b/app/views/notify/reassigned_merge_request_email.text.erb
@@ -1,6 +1,15 @@
+<% added_names = sanitize_name(@added_assignees.to_sentence(locale: I18n.locale)) -%>
+<% removed_names = sanitize_name(@removed_assignees.to_sentence(locale: I18n.locale)) -%>
Reassigned merge request <%= @merge_request.iid %>
<%= url_for([@merge_request.project, @merge_request, { only_path: false }]) %>
-Assignee changed <%= "from #{sanitize_name(@previous_assignees.map(&:name).to_sentence)}" if @previous_assignees.any? -%>
- to <%= "#{@merge_request.assignees.any? ? @merge_request.assignee_list : 'Unassigned'}" %>
+<%- if @added_assignees.any? %>
+<%= html_escape(n_(s_('Notify|%{added} was added as an assignee.'), s_('Notify|%{added} were added as assignees.'), @added_assignees.length).html_safe % { added: added_names }) %>
+<% end -%>
+<%- if @removed_assignees.any? && @merge_request.assignees.any? %>
+<%= html_escape(n_(s_('Notify|%{removed} was removed as an assignee.'), s_('Notify|%{removed} were removed as assignees.'), @removed_assignees.length).html_safe % { removed: removed_names }) %>
+<% end -%>
+<%- if @removed_assignees.any? && @merge_request.assignees.empty? %>
+<%= html_escape(s_('Notify|All assignees were removed.')) %>
+<% end -%>
diff --git a/app/views/profiles/accounts/_providers.html.haml b/app/views/profiles/accounts/_providers.html.haml
index 6f0c091dfdb..3ecdc3f63e5 100644
--- a/app/views/profiles/accounts/_providers.html.haml
+++ b/app/views/profiles/accounts/_providers.html.haml
@@ -3,26 +3,27 @@
%label.label-bold.gl-mb-0
= s_('Profiles|Connected Accounts')
%p= s_('Profiles|Select a service to sign in with.')
- - providers.each do |provider|
- - unlink_allowed = unlink_provider_allowed?(provider)
- - link_allowed = link_provider_allowed?(provider)
- - has_icon = provider_has_icon?(provider)
- - if unlink_allowed || link_allowed
- - if auth_active?(provider)
- - if unlink_allowed
- = link_to unlink_profile_account_path(provider: provider), method: :delete, class: button_class do
+ .gl-display-flex.gl-flex-wrap.gl-gap-3
+ - providers.each do |provider|
+ - unlink_allowed = unlink_provider_allowed?(provider)
+ - link_allowed = link_provider_allowed?(provider)
+ - has_icon = provider_has_icon?(provider)
+ - if unlink_allowed || link_allowed
+ - if auth_active?(provider)
+ - if unlink_allowed
+ = link_to unlink_profile_account_path(provider: provider), method: :delete, class: button_class do
+ - if has_icon
+ .social-provider-btn-image.gl-button-icon= provider_image_tag(provider)
+ .gl-button-text
+ = s_('Profiles|Disconnect %{provider}') % { provider: label_for_provider(provider) }
+ - else
+ %a{ class: button_class }
+ .gl-button-text
+ = s_('Profiles|%{provider} Active') % { provider: label_for_provider(provider) }
+ - elsif link_allowed
+ = link_to omniauth_authorize_path(:user, provider), method: :post, class: button_class do
- if has_icon
.social-provider-btn-image.gl-button-icon= provider_image_tag(provider)
.gl-button-text
- = s_('Profiles|Disconnect %{provider}') % { provider: label_for_provider(provider) }
- - else
- %a{ class: button_class }
- .gl-button-text
- = s_('Profiles|%{provider} Active') % { provider: label_for_provider(provider) }
- - elsif link_allowed
- = link_to omniauth_authorize_path(:user, provider), method: :post, class: button_class do
- - if has_icon
- .social-provider-btn-image.gl-button-icon= provider_image_tag(provider)
- .gl-button-text
- = s_('Profiles|Connect %{provider}') % { provider: label_for_provider(provider) }
- = render_if_exists 'profiles/accounts/group_saml_unlink_buttons', group_saml_identities: group_saml_identities
+ = s_('Profiles|Connect %{provider}') % { provider: label_for_provider(provider) }
+ = render_if_exists 'profiles/accounts/group_saml_unlink_buttons', group_saml_identities: group_saml_identities
diff --git a/app/views/profiles/emails/index.html.haml b/app/views/profiles/emails/index.html.haml
index 6dcd661ecdb..3f18a7bbda6 100644
--- a/app/views/profiles/emails/index.html.haml
+++ b/app/views/profiles/emails/index.html.haml
@@ -24,7 +24,7 @@
= sprite_icon('mail', css_class: 'gl-mr-2')
= @emails.load.size
.gl-new-card-actions
- = render Pajamas::ButtonComponent.new(size: :small, button_options: { class: "js-toggle-button js-toggle-content", data: { testid: 'toggle_email_address_field' } }) do
+ = render Pajamas::ButtonComponent.new(size: :small, button_options: { class: "js-toggle-button js-toggle-content", data: { testid: 'toggle-email-address-field' } }) do
= s_('Profiles|Add new email')
- c.with_body do
.gl-new-card-add-form.gl-m-3.gl-mb-4.gl-display-none.js-toggle-content
@@ -33,9 +33,9 @@
= gitlab_ui_form_for 'email', url: profile_emails_path do |f|
.form-group
= f.label :email, s_('Profiles|Email address'), class: 'label-bold'
- = f.text_field :email, class: 'form-control gl-form-input gl-form-input-xl', data: { qa_selector: 'email_address_field' }
+ = f.text_field :email, class: 'form-control gl-form-input gl-form-input-xl', data: { testid: 'email-address-field' }
.gl-mt-3
- = f.submit s_('Profiles|Add email address'), data: { qa_selector: 'add_email_address_button' }, pajamas_button: true
+ = f.submit s_('Profiles|Add email address'), data: { testid: 'add-email-address-button' }, pajamas_button: true
= render Pajamas::ButtonComponent.new(button_options: { type: 'reset', class: 'gl-ml-2 js-toggle-button' }) do
= _('Cancel')
- if @emails.any?
@@ -59,7 +59,7 @@
= s_('Profiles|Default notification email')
.gl-text-secondary.gl-font-sm= notification_message.html_safe
- @emails.reject(&:user_primary_email?).each do |email|
- %li{ class: 'gl-px-5!', data: { qa_selector: 'email_row_content' } }
+ %li{ class: 'gl-px-5!', data: { testid: 'email-row-content' } }
.gl-display-flex.gl-justify-content-space-between.gl-flex-wrap.gl-gap-3
%div
= render partial: 'shared/email_with_badge', locals: { email: email.email, verified: email.confirmed? }
@@ -81,4 +81,4 @@
- confirm_title = "#{email.confirmation_sent_at ? s_('Profiles|Resend confirmation email') : s_('Profiles|Send confirmation email')}"
= link_button_to confirm_title, resend_confirmation_instructions_profile_email_path(email), method: :put, size: :small
- = link_button_to nil, profile_email_path(email), data: { confirm: _('Are you sure?'), confirm_btn_variant: 'danger', qa_selector: 'delete_email_link'}, method: :delete, size: :small, icon: 'remove', 'aria-label': _('Remove')
+ = link_button_to nil, profile_email_path(email), data: { confirm: _('Are you sure?'), confirm_btn_variant: 'danger', testid: 'delete-email-link'}, method: :delete, size: :small, icon: 'remove', 'aria-label': _('Remove')
diff --git a/app/views/profiles/gpg_keys/_key_table.html.haml b/app/views/profiles/gpg_keys/_key_table.html.haml
index 0a50ce55b50..ea7068e0484 100644
--- a/app/views/profiles/gpg_keys/_key_table.html.haml
+++ b/app/views/profiles/gpg_keys/_key_table.html.haml
@@ -3,7 +3,7 @@
- if @gpg_keys.any?
.table-holder
- %table.table.b-table.gl-table.b-table-stacked-md.gl-mt-n1.gl-mb-n2.ssh-keys-list{ data: { qa_selector: 'ssh_keys_list' } }
+ %table.table.b-table.gl-table.b-table-stacked-md.gl-mt-n1.gl-mb-n2.ssh-keys-list
%thead.d-none.d-md-table-header-group
%tr
%th= s_('Profiles|Key')
diff --git a/app/views/profiles/preferences/show.html.haml b/app/views/profiles/preferences/show.html.haml
index 96375412f94..0d1e911f29d 100644
--- a/app/views/profiles/preferences/show.html.haml
+++ b/app/views/profiles/preferences/show.html.haml
@@ -9,9 +9,6 @@
- data_attributes = { themes: @themes, integration_views: integration_views.to_json, user_fields: user_fields, body_classes: Gitlab::Themes.body_classes, profile_preferences_path: profile_preferences_path }
- @force_desktop_expanded_sidebar = true
-- Gitlab::Themes.each do |theme|
- = stylesheet_link_tag "themes/#{theme.css_filename}" if theme.css_filename
-
= gitlab_ui_form_for @user, url: profile_preferences_path, remote: true, method: :put, html: { id: "profile-preferences-form" } do |f|
= render_if_exists 'profiles/preferences/code_suggestions_settings_self_assignment'
.settings-section.js-preferences-form.js-search-settings-section.application-theme#navigation-theme
@@ -173,7 +170,6 @@
.form-group
= f.gitlab_ui_checkbox_component :enabled_following,
s_('Preferences|Enable follow users')
- = render_if_exists 'profiles/preferences/code_suggestions_settings', form: f
= render_if_exists 'profiles/preferences/zoekt_settings', form: f
#js-profile-preferences-app{ data: data_attributes }
diff --git a/app/views/profiles/show.html.haml b/app/views/profiles/show.html.haml
index 79b2726ed2d..9f33ad0c2d4 100644
--- a/app/views/profiles/show.html.haml
+++ b/app/views/profiles/show.html.haml
@@ -66,7 +66,7 @@
%h4.gl-my-0= s_("Profiles|Time settings")
%p.gl-text-secondary= s_("Profiles|Set your local time zone.")
= f.label :user_timezone, _("Time zone")
- .js-timezone-dropdown{ data: { timezone_data: timezone_data.to_json, initial_value: @user.timezone, name: 'user[timezone]' } }
+ .js-timezone-dropdown{ data: { timezone_data: timezone_data_with_unique_identifiers.to_json, initial_value: @user.timezone, name: 'user[timezone]' } }
.settings-section.js-search-settings-section.gl-border-t.gl-pt-6
.settings-sticky-header
diff --git a/app/views/projects/_home_panel.html.haml b/app/views/projects/_home_panel.html.haml
index 63226838166..0bf05c85f5f 100644
--- a/app/views/projects/_home_panel.html.haml
+++ b/app/views/projects/_home_panel.html.haml
@@ -14,8 +14,6 @@
= render partial: 'shared/ci_catalog_badge', locals: { href: explore_catalog_path(@project.catalog_resource), css_class: 'gl-mx-0' }
- if @project.group
= render_if_exists 'shared/tier_badge', source: @project, namespace_to_track: @project.namespace
- .gl-text-secondary
- = render_if_exists "projects/home_mirror"
.project-repo-buttons.gl-display-flex.gl-justify-content-md-end.gl-align-items-center.gl-flex-wrap.gl-gap-3
- if current_user
@@ -48,7 +46,7 @@
= render Pajamas::ButtonComponent.new(category: :tertiary, variant: :link, button_options: { class: 'js-read-more-trigger gl-lg-display-none' }) do
= _("Read more")
- = render_if_exists "projects/home_mirror"
+ = render_if_exists "projects/home_mirror"
- if ff_reorg_disabled && @project.badges.present?
.project-badges.mb-2{ data: { testid: 'project-badges-content' } }
diff --git a/app/views/projects/_import_project_pane.html.haml b/app/views/projects/_import_project_pane.html.haml
index 3e92ef25552..b9abaa07c2c 100644
--- a/app/views/projects/_import_project_pane.html.haml
+++ b/app/views/projects/_import_project_pane.html.haml
@@ -18,42 +18,42 @@
.import-buttons
- if gitlab_project_import_enabled?
.import_gitlab_project.has-tooltip{ data: { container: 'body', testid: 'gitlab-import-button' } }
- = render Pajamas::ButtonComponent.new(href: '#', icon: 'tanuki', button_options: { class: 'btn_import_gitlab_project js-import-project-btn', data: { href: new_import_gitlab_project_path, platform: 'gitlab_export', **tracking_attrs_data(track_label, 'click_button', 'gitlab_export') } }) do
+ = render Pajamas::ButtonComponent.new(href: '#', icon: 'tanuki', button_options: { class: 'btn_import_gitlab_project js-import-project-btn', data: { href: new_import_gitlab_project_path, platform: 'gitlab_export', track_experiment: local_assigns[:track_experiment], **tracking_attrs_data(track_label, 'click_button', 'gitlab_export') } }) do
= _('GitLab export')
- if github_import_enabled?
%div
- = render Pajamas::ButtonComponent.new(href: new_import_github_path(namespace_id: namespace_id), icon: 'github', button_options: { class: 'js-import-github js-import-project-btn', data: { platform: 'github', **tracking_attrs_data(track_label, 'click_button', 'github') } }) do
+ = render Pajamas::ButtonComponent.new(href: new_import_github_path(namespace_id: namespace_id), icon: 'github', button_options: { class: 'js-import-github js-import-project-btn', data: { platform: 'github', track_experiment: local_assigns[:track_experiment], **tracking_attrs_data(track_label, 'click_button', 'github') } }) do
GitHub
- if bitbucket_import_enabled?
%div
- = render Pajamas::ButtonComponent.new(href: status_import_bitbucket_path(namespace_id: namespace_id), icon: 'bitbucket', button_options: { class: "import_bitbucket js-import-project-btn #{'js-how-to-import-link' unless bitbucket_import_configured?}", data: { modal_title: _("Import projects from Bitbucket"), modal_message: import_from_bitbucket_message, platform: 'bitbucket_cloud', **tracking_attrs_data(track_label, 'click_button', 'bitbucket_cloud') } }) do
+ = render Pajamas::ButtonComponent.new(href: status_import_bitbucket_path(namespace_id: namespace_id), icon: 'bitbucket', button_options: { class: "import_bitbucket js-import-project-btn #{'js-how-to-import-link' unless bitbucket_import_configured?}", data: { modal_title: _("Import projects from Bitbucket"), modal_message: import_from_bitbucket_message, platform: 'bitbucket_cloud', track_experiment: local_assigns[:track_experiment], **tracking_attrs_data(track_label, 'click_button', 'bitbucket_cloud') } }) do
Bitbucket Cloud
- if bitbucket_server_import_enabled?
%div
- = render Pajamas::ButtonComponent.new(href: status_import_bitbucket_server_path(namespace_id: namespace_id), icon: 'bitbucket', button_options: { class: 'import_bitbucket js-import-project-btn', data: { platform: 'bitbucket_server', **tracking_attrs_data(track_label, 'click_button', 'bitbucket_server') } }) do
+ = render Pajamas::ButtonComponent.new(href: status_import_bitbucket_server_path(namespace_id: namespace_id), icon: 'bitbucket', button_options: { class: 'import_bitbucket js-import-project-btn', data: { platform: 'bitbucket_server', track_experiment: local_assigns[:track_experiment], **tracking_attrs_data(track_label, 'click_button', 'bitbucket_server') } }) do
Bitbucket Server
- if fogbugz_import_enabled?
%div
- = render Pajamas::ButtonComponent.new(href: new_import_fogbugz_path(namespace_id: namespace_id), icon: 'bug', button_options: { class: 'import_fogbugz js-import-project-btn', data: { platform: 'fogbugz', **tracking_attrs_data(track_label, 'click_button', 'fogbugz') } }) do
+ = render Pajamas::ButtonComponent.new(href: new_import_fogbugz_path(namespace_id: namespace_id), icon: 'bug', button_options: { class: 'import_fogbugz js-import-project-btn', data: { platform: 'fogbugz', track_experiment: local_assigns[:track_experiment], **tracking_attrs_data(track_label, 'click_button', 'fogbugz') } }) do
FogBugz
- if gitea_import_enabled?
%div
- = render Pajamas::ButtonComponent.new(href: new_import_gitea_path(namespace_id: namespace_id), icon: 'gitea', button_options: { class: 'import_gitea js-import-project-btn', data: { platform: 'gitea', **tracking_attrs_data(track_label, 'click_button', 'gitea') } }) do
+ = render Pajamas::ButtonComponent.new(href: new_import_gitea_path(namespace_id: namespace_id), icon: 'gitea', button_options: { class: 'import_gitea js-import-project-btn', data: { platform: 'gitea', track_experiment: local_assigns[:track_experiment], **tracking_attrs_data(track_label, 'click_button', 'gitea') } }) do
Gitea
- if git_import_enabled?
%div
- = render Pajamas::ButtonComponent.new(icon: 'link', button_options: { class: 'js-toggle-button js-import-git-toggle-button js-import-project-btn', data: { platform: 'repo_url', toggle_open_class: 'active', **tracking_attrs_data(track_label, 'click_button', 'repo_url') } }) do
+ = render Pajamas::ButtonComponent.new(icon: 'link', button_options: { class: 'js-toggle-button js-import-git-toggle-button js-import-project-btn', data: { platform: 'repo_url', toggle_open_class: 'active', track_experiment: local_assigns[:track_experiment], **tracking_attrs_data(track_label, 'click_button', 'repo_url') } }) do
= _('Repository by URL')
- if manifest_import_enabled?
%div
- = render Pajamas::ButtonComponent.new(href: new_import_manifest_path(namespace_id: namespace_id), icon: 'doc-text', button_options: { class: 'import_manifest js-import-project-btn', data: { platform: 'manifest_file', **tracking_attrs_data(track_label, 'click_button', 'manifest_file') } }) do
+ = render Pajamas::ButtonComponent.new(href: new_import_manifest_path(namespace_id: namespace_id), icon: 'doc-text', button_options: { class: 'import_manifest js-import-project-btn', data: { platform: 'manifest_file', track_experiment: local_assigns[:track_experiment], **tracking_attrs_data(track_label, 'click_button', 'manifest_file') } }) do
= _('Manifest file')
= render_if_exists "projects/gitee_import_button", namespace_id: namespace_id, track_label: track_label
@@ -63,4 +63,4 @@
= gitlab_ui_form_for @project, html: { class: 'new_project gl-show-field-errors js-project-import' } do |f|
%hr
= render "shared/import_form", f: f
- = render 'projects/new_project_fields', f: f, project_name_id: "import-url-name", hide_init_with_readme: true, track_label: track_label
+ = render 'projects/new_project_fields', f: f, project_name_id: "import-url-name", hide_init_with_readme: true, track_label: 'import_project'
diff --git a/app/views/projects/_readme.html.haml b/app/views/projects/_readme.html.haml
index c3d66396256..fc9ddb650e9 100644
--- a/app/views/projects/_readme.html.haml
+++ b/app/views/projects/_readme.html.haml
@@ -1,5 +1,5 @@
- if (readme = @repository.readme) && readme.rich_viewer
- .tree-holder
+ .tree-holder.gl-mt-5
.nav-block.mt-0
= render 'projects/tree/tree_header', tree: @tree
%article.file-holder.readme-holder{ id: 'readme', class: ("limited-width-container" unless fluid_layout) }
diff --git a/app/views/projects/_sidebar.html.haml b/app/views/projects/_sidebar.html.haml
index 565f14d01d9..7cb2f622788 100644
--- a/app/views/projects/_sidebar.html.haml
+++ b/app/views/projects/_sidebar.html.haml
@@ -2,43 +2,44 @@
- show_auto_devops_callout = show_auto_devops_callout?(@project)
%aside.project-page-sidebar
- - if @project.description.present? || @project.badges.present?
- .project-page-sidebar-block.home-panel-home-desc.gl-py-4.gl-border-b.gl-border-gray-50
- -# Project description
- - if @project.description.present?
- .gl-display-flex.gl-justify-content-space-between.gl-mt-1.gl-pr-2
- %p.gl-font-weight-bold.gl-text-gray-900.gl-m-0= s_('ProjectPage|Project information')
- = render Pajamas::ButtonComponent.new(href: edit_project_path(@project),
- category: :tertiary,
- icon: 'settings',
- size: :small,
- button_options: { class: 'has-tooltip', title: s_('ProjectPage|Project settings'), 'aria-label' => s_('ProjectPage|Project settings') })
- .home-panel-description.text-break
- .home-panel-description-markdown{ itemprop: 'description' }
- = markdown_field(@project, :description)
+ .project-page-sidebar-block.home-panel-home-desc.gl-py-4.gl-border-b.gl-border-gray-50{ class: 'gl-pt-2!' }
+ .gl-display-flex.gl-justify-content-space-between
+ %p.gl-font-weight-bold.gl-text-gray-900.gl-m-0.gl-mb-1= s_('ProjectPage|Project information')
+ -# Project settings
+ - if can?(current_user, :admin_project, @project)
+ = render Pajamas::ButtonComponent.new(href: edit_project_path(@project),
+ category: :tertiary,
+ icon: 'settings',
+ size: :small,
+ button_options: { class: 'has-tooltip gl-ml-2 gl-sm-mr-3', title: s_('ProjectPage|Project settings'), 'aria-label' => s_('ProjectPage|Project settings'), 'data-testid': 'project-settings-button' })
+ -# Project description
+ - if @project.description.present?
+ .home-panel-description.text-break
+ .home-panel-description-markdown{ itemprop: 'description' }
+ = markdown_field(@project, :description)
- -# Topics
- - if @project.topics.present?
- .gl-mb-5
- = render "shared/projects/topics", project: @project
+ -# Topics
+ - if @project.topics.present?
+ .gl-mb-5
+ = render "shared/projects/topics", project: @project
- -# Programming languages
- - if can?(current_user, :read_code, @project) && @project.repository_languages.present?
- .gl-mb-2{ class: ('gl-mb-4!' if @project.badges.present?) }
- = repository_languages_bar(@project.repository_languages)
+ -# Programming languages
+ - if can?(current_user, :read_code, @project) && @project.repository_languages.present?
+ .gl-mb-2{ class: [('gl-mb-4!' if @project.badges.present?), ('gl-mt-3' if !@project.description.present?)] }
+ = repository_languages_bar(@project.repository_languages)
- -# Badges
- - if @project.badges.present?
- .project-badges.gl-mb-2{ data: { testid: 'project-badges-content' } }
- - @project.badges.each do |badge|
- - badge_link_url = badge.rendered_link_url(@project)
- %a.gl-mr-3{ href: badge_link_url,
- target: '_blank',
- rel: 'noopener noreferrer',
- data: { testid: 'badge-image-link', qa_link_url: badge_link_url } }>
- %img.project-badge{ src: badge.rendered_image_url(@project),
- 'aria-hidden': true,
- alt: 'Project badge' }>
+ -# Badges
+ - if @project.badges.present?
+ .project-badges.gl-mb-2{ data: { testid: 'project-badges-content' } }
+ - @project.badges.each do |badge|
+ - badge_link_url = badge.rendered_link_url(@project)
+ %a.gl-mr-3{ href: badge_link_url,
+ target: '_blank',
+ rel: 'noopener noreferrer',
+ data: { testid: 'badge-image-link', qa_link_url: badge_link_url } }>
+ %img.project-badge{ src: badge.rendered_image_url(@project),
+ 'aria-hidden': true,
+ alt: 'Project badge' }>
-# Invite members
- if @project.empty_repo?
diff --git a/app/views/projects/buttons/_code.html.haml b/app/views/projects/buttons/_code.html.haml
index a78e3861e94..9cdbe1d5f6b 100644
--- a/app/views/projects/buttons/_code.html.haml
+++ b/app/views/projects/buttons/_code.html.haml
@@ -8,9 +8,9 @@
%span.js-clone-dropdown-label
= _('Code')
= sprite_icon("chevron-down", css_class: "icon")
- %ul.dropdown-menu.dropdown-menu-large.clone-options-dropdown{ class: dropdown_class, data: { testid: 'clone-dropdown-content' } }
+ %ul.dropdown-menu.dropdown-menu-large.clone-options-dropdown{ role: 'menu', class: dropdown_class, data: { testid: 'clone-dropdown-content' } }
- if ssh_enabled?
- %li.gl-dropdown-item.js-clone-links{ class: 'gl-px-4!' }
+ %li.gl-dropdown-item.js-clone-links{ role: 'menuitem', class: 'gl-px-4!' }
%label.label-bold
= _('Clone with SSH')
.input-group.btn-group
@@ -19,7 +19,7 @@
= clipboard_button(target: '#ssh_project_clone', title: _("Copy URL"), category: :primary, size: :medium)
= render_if_exists 'projects/buttons/geo'
- if http_enabled?
- %li.pt-2.gl-dropdown-item.js-clone-links{ class: 'gl-px-4!' }
+ %li.pt-2.gl-dropdown-item.js-clone-links{ role: 'menuitem', class: 'gl-px-4!' }
%label.label-bold
= _('Clone with %{http_label}') % { http_label: gitlab_config.protocol.upcase }
.input-group.btn-group
@@ -28,8 +28,8 @@
= clipboard_button(target: '#http_project_clone', title: _("Copy URL"), category: :primary, size: :medium)
= render_if_exists 'projects/buttons/geo'
= render_if_exists 'projects/buttons/kerberos_clone_field'
- %li.divider.mt-2
- %li.pt-2.gl-dropdown-item.js-clone-links
+ %li.divider.mt-2{ role: 'presentation' }
+ %li.pt-2.gl-dropdown-item.js-clone-links{ role: 'menuitem' }
%label.label-bold{ class: 'gl-px-4!' }
= _('Open in your IDE')
- if ssh_enabled?
@@ -55,5 +55,5 @@
.gl-dropdown-item-text-wrapper
= _("Xcode")
- if !project.empty_repo? && can?(current_user, :download_code, project)
- %li.divider.mt-2
+ %li.divider.mt-2{ role: 'presentation' }
= render 'projects/buttons/download_menu_items', project: project, ref: ref
diff --git a/app/views/projects/buttons/_download_menu_items.html.haml b/app/views/projects/buttons/_download_menu_items.html.haml
index f5f8efca073..7d7033da9cd 100644
--- a/app/views/projects/buttons/_download_menu_items.html.haml
+++ b/app/views/projects/buttons/_download_menu_items.html.haml
@@ -2,7 +2,7 @@
- ref = local_assigns.fetch(:ref)
- archive_prefix = "#{project.path}-#{ref.tr('/', '-')}"
-%li.gl-dropdown-item{ role: 'menuitem' }
- %h3.h5.m-0.dropdown-bold-header= _('Download source code')
+%li.gl-dropdown-item{ class: 'gl-pt-3!', role: 'menuitem' }
+ %label.label-bold{ class: 'gl-px-4!' }= _('Download source code')
= render 'projects/buttons/download_links', project: project, ref: ref, archive_prefix: archive_prefix, path: nil
.js-directory-downloads{ data: { links: directory_download_links(project, ref, archive_prefix).to_json } }
diff --git a/app/views/projects/commit/_commit_box.html.haml b/app/views/projects/commit/_commit_box.html.haml
index be0e5a428b4..fc9104f9f27 100644
--- a/app/views/projects/commit/_commit_box.html.haml
+++ b/app/views/projects/commit/_commit_box.html.haml
@@ -18,7 +18,6 @@
= commit_committer_link(@commit, avatar: true, size: 24)
#{time_ago_with_tooltip(@commit.committed_date)}
- #js-commit-comments-button{ data: { comments_count: @notes_count.to_i } }
= link_button_to _('Browse files'), project_tree_path(@project, @commit), class: 'gl-mr-3 gl-w-full gl-sm-w-auto gl-mb-3 gl-sm-mb-0'
#js-commit-options-dropdown{ data: commit_options_dropdown_data(@project, @commit) }
@@ -36,7 +35,7 @@
%span.cgray= n_('parent', 'parents', @commit.parents.count)
- @commit.parents.each do |parent|
= link_to parent.short_id, project_commit_path(@project, parent), class: "commit-sha"
- #js-commit-branches-and-tags{ data: { full_path: @project.full_path, commit_sha: @commit.short_id } }
+ #js-commit-branches-and-tags{ data: { full_path: @project.full_path, commit_sha: @commit.short_id } }
.well-segment.merge-request-info
.icon-container
diff --git a/app/views/projects/edit.html.haml b/app/views/projects/edit.html.haml
index 9269369c83e..90837a1a291 100644
--- a/app/views/projects/edit.html.haml
+++ b/app/views/projects/edit.html.haml
@@ -118,8 +118,11 @@
= render 'remove_fork', project: @project
= render 'remove', project: @project
-- elsif can?(current_user, :archive_project, @project)
- = render_if_exists 'projects/settings/archive'
+- else
+ - if can?(current_user, :archive_project, @project)
+ = render_if_exists 'projects/settings/archive'
+ - if can?(current_user, :remove_project, @project)
+ = render 'remove', project: @project
.save-project-loader.hide
.center
diff --git a/app/views/projects/empty.html.haml b/app/views/projects/empty.html.haml
index 684ea8242f7..ac3b67d6157 100644
--- a/app/views/projects/empty.html.haml
+++ b/app/views/projects/empty.html.haml
@@ -20,7 +20,7 @@
.project-clone-holder.d-block.d-sm-none
= render "shared/mobile_clone_panel"
- .project-clone-holder.gl-display-none.gl-sm-display-flex.gl-justify-content-end.gl-w-full.gl-mt-2
+ .project-clone-holder.gl-display-none.gl-sm-display-flex.gl-justify-content-end.gl-w-full
= render "projects/buttons/code", ref: @ref
= render Pajamas::CardComponent.new(card_options: { class: 'gl-mb-5' }, body_options: { class: 'gl-new-card-body gl-bg-gray-10 gl-p-5' }) do |c|
diff --git a/app/views/projects/environments/folder.html.haml b/app/views/projects/environments/folder.html.haml
index 2b4d19a0e1d..54855999431 100644
--- a/app/views/projects/environments/folder.html.haml
+++ b/app/views/projects/environments/folder.html.haml
@@ -3,4 +3,4 @@
- page_title _("Environments in %{name}") % { name: @folder }
- add_page_specific_style 'page_bundles/environments'
-#environments-folder-list-view{ data: { environments_data: environments_folder_list_view_data, project_path: @project.full_path } }
+#environments-folder-list-view{ data: environments_folder_list_view_data(@project, @folder) }
diff --git a/app/views/projects/forks/index.html.haml b/app/views/projects/forks/index.html.haml
index 98055534a27..10ca730ac11 100644
--- a/app/views/projects/forks/index.html.haml
+++ b/app/views/projects/forks/index.html.haml
@@ -16,7 +16,7 @@
.dropdown.gl-display-inline.gl-md-ml-3.issue-sort-dropdown.gl-mt-3.gl-md-mt-0
.btn-group{ role: 'group' }
- = gl_redirect_listbox_tag [created_at, activity], @sort
+ = gl_redirect_listbox_tag [created_at, activity], @sort, class: 'btn-group'
= forks_sort_direction_button(sort_value)
- if current_user && can?(current_user, :fork_project, @project)
diff --git a/app/views/projects/gcp/artifact_registry/docker_images/_docker_image.html.haml b/app/views/projects/gcp/artifact_registry/docker_images/_docker_image.html.haml
index 0118fe94810..750dea9896f 100644
--- a/app/views/projects/gcp/artifact_registry/docker_images/_docker_image.html.haml
+++ b/app/views/projects/gcp/artifact_registry/docker_images/_docker_image.html.haml
@@ -11,8 +11,8 @@
Full name: #{docker_image.name}
.gl-display-flex.gl-align-items-top.gl-font-monospace.gl-font-sm.gl-word-break-all.gl-p-4.gl-border-b-solid.gl-border-gray-100.gl-border-b-1
= sprite_icon('earth', css_class: 'gl-text-gray-500 gl-mr-3 gl-icon s16')
- URI:
- %a{ href: docker_image.uri, target: 'blank', rel: 'noopener noreferrer' }= docker_image.uri
+ %a{ href: docker_image.details_url, target: 'blank', rel: 'noopener noreferrer' }
+ Artifact Registry details page
.gl-display-flex.gl-align-items-top.gl-font-monospace.gl-font-sm.gl-word-break-all.gl-p-4.gl-border-b-solid.gl-border-gray-100.gl-border-b-1
= sprite_icon('doc-code', css_class: 'gl-text-gray-500 gl-mr-3 gl-icon s16')
Media Type: #{docker_image.media_type}
diff --git a/app/views/projects/merge_requests/_code_dropdown.html.haml b/app/views/projects/merge_requests/_code_dropdown.html.haml
index bfa33f26453..c03b1ac1b28 100644
--- a/app/views/projects/merge_requests/_code_dropdown.html.haml
+++ b/app/views/projects/merge_requests/_code_dropdown.html.haml
@@ -1,8 +1,8 @@
.gl-md-ml-3.dropdown.gl-dropdown{ class: "gl-display-none! gl-md-display-flex!" }
#js-check-out-modal{ data: how_merge_modal_data(@merge_request) }
- = button_tag type: 'button', class: "btn dropdown-toggle btn-confirm gl-button gl-dropdown-toggle", data: { toggle: 'dropdown', testid: 'mr-code-dropdown' } do
- %span.gl-dropdown-button-text= _('Code')
- = sprite_icon "chevron-down", size: 16, css_class: "dropdown-icon gl-icon gl-ml-2 gl-mr-0!"
+ = render Pajamas::ButtonComponent.new(category: :primary, variant: :confirm, button_options: { data: { toggle: 'dropdown', testid: 'mr-code-dropdown' } }) do
+ = _('Code')
+ = sprite_icon "chevron-down", size: 16, css_class: "gl-icon gl-mr-0!"
.dropdown-menu.dropdown-menu-right
.gl-dropdown-inner
.gl-dropdown-contents
diff --git a/app/views/projects/merge_requests/_mr_title.html.haml b/app/views/projects/merge_requests/_mr_title.html.haml
index 1b0aba8d496..03c850b7fbb 100644
--- a/app/views/projects/merge_requests/_mr_title.html.haml
+++ b/app/views/projects/merge_requests/_mr_title.html.haml
@@ -24,7 +24,10 @@
.detail-page-header-actions.gl-align-self-start.is-merge-request.js-issuable-actions.gl-display-flex
- if can_update_merge_request
- = render Pajamas::ButtonComponent.new(href: edit_project_merge_request_path(@project, @merge_request), button_options: {class: "gl-display-none gl-md-display-block js-issuable-edit", data: { testid: "edit-title-button" }}) do
+ - edit_action_description = _('Edit merge request')
+ - edit_action_shortcut = 'e'
+ - edit_button_title = "#{edit_action_description} <kbd class='flat ml-1' aria-hidden=true>#{edit_action_shortcut}</kbd>"
+ = render Pajamas::ButtonComponent.new(href: edit_project_merge_request_path(@project, @merge_request), button_options: { aria: {label: edit_action_description, keyshortcuts: edit_action_shortcut}, class: "gl-display-none gl-md-display-block has-tooltip js-issuable-edit", data: { html: "true", testid: "edit-title-button" }, title: edit_button_title }) do
= _('Edit')
- if @merge_request.source_project
diff --git a/app/views/projects/merge_requests/_page.html.haml b/app/views/projects/merge_requests/_page.html.haml
index 03a1f2f3179..af8ad22fa50 100644
--- a/app/views/projects/merge_requests/_page.html.haml
+++ b/app/views/projects/merge_requests/_page.html.haml
@@ -16,6 +16,7 @@
- add_page_specific_style 'page_bundles/ci_status'
- add_page_startup_api_call @endpoint_metadata_url
+- add_page_startup_api_call @pinned_file_url if @pinned_file_url
- if mr_action == 'diffs' && !@file_by_file_default
- add_page_startup_api_call @endpoint_diff_batch_url
diff --git a/app/views/projects/merge_requests/creations/new.html.haml b/app/views/projects/merge_requests/creations/new.html.haml
index f2c2700b012..4f722ba901d 100644
--- a/app/views/projects/merge_requests/creations/new.html.haml
+++ b/app/views/projects/merge_requests/creations/new.html.haml
@@ -11,7 +11,7 @@
= render 'new_submit'
- else
- if conflicting_mr
- - link_to_mr = link_to(conflicting_mr.to_reference, project_merge_request_path(@project, conflicting_mr))
+ - link_to_mr = link_to(conflicting_mr.to_reference, project_merge_request_path(conflicting_mr.target_project, conflicting_mr))
- flash.now[:alert] = safe_format(s_("These branches already have an open merge request: %{link_to_mr}. Select a different source or target branch."), link_to_mr: link_to_mr)
= render 'new_compare'
diff --git a/app/views/projects/mirrors/_mirror_repos_list.html.haml b/app/views/projects/mirrors/_mirror_repos_list.html.haml
index 5e3c4889d1d..ab0786a6f5b 100644
--- a/app/views/projects/mirrors/_mirror_repos_list.html.haml
+++ b/app/views/projects/mirrors/_mirror_repos_list.html.haml
@@ -29,7 +29,7 @@
- if mirror.disabled?
= render 'projects/mirrors/disabled_mirror_badge'
- if mirror.last_error.present?
- = gl_badge_tag _('Error'), { variant: :danger }, { data: { toggle: 'tooltip', html: 'true', testid: 'mirror-error-badge-content' }, title: html_escape(mirror.last_error.try(:strip)) }
+ = gl_badge_tag _('Error'), { variant: :danger }, { data: { toggle: 'tooltip', html: 'true', testid: 'mirror-error-badge-content' }, title: html_escape(mirror.last_error.try(:strip)), tabindex: 0 }
%td
- if mirror_settings_enabled
.btn-group.mirror-actions-group{ role: 'group' }
diff --git a/app/views/projects/ml/models/index.html.haml b/app/views/projects/ml/models/index.html.haml
index ffe7ee3397e..ba695bce435 100644
--- a/app/views/projects/ml/models/index.html.haml
+++ b/app/views/projects/ml/models/index.html.haml
@@ -1,4 +1,4 @@
- breadcrumb_title s_('ModelRegistry|Model registry')
- page_title s_('ModelRegistry|Model registry')
-= render(Projects::Ml::ModelsIndexComponent.new(paginator: @paginator, model_count: @model_count))
+= render(Projects::Ml::ModelsIndexComponent.new(project: @project, current_user: current_user, paginator: @paginator, model_count: @model_count))
diff --git a/app/views/projects/ml/models/new.html.haml b/app/views/projects/ml/models/new.html.haml
new file mode 100644
index 00000000000..8510ffd42fd
--- /dev/null
+++ b/app/views/projects/ml/models/new.html.haml
@@ -0,0 +1,5 @@
+- breadcrumb_title s_('ModelRegistry|New model')
+- page_title s_('ModelRegistry|New model')
+- view_model = Gitlab::Json.generate({ projectPath: @project.full_path })
+
+#js-mount-new-ml-model{ data: { view_model: view_model } }
diff --git a/app/views/projects/pages_domains/_dns.html.haml b/app/views/projects/pages_domains/_dns.html.haml
index bec35dba147..360ef01620b 100644
--- a/app/views/projects/pages_domains/_dns.html.haml
+++ b/app/views/projects/pages_domains/_dns.html.haml
@@ -9,7 +9,7 @@
.input-group
= text_field_tag :domain_dns, dns_record , class: "monospace js-select-on-focus form-control", readonly: true
.input-group-append
- = deprecated_clipboard_button(target: '#domain_dns', class: 'btn-default input-group-text d-none d-sm-block')
+ = clipboard_button(target: '#domain_dns', category: :primary, size: :medium)
%p.form-text.text-muted
= _("To access this domain create a new DNS record")
- if verification_enabled
@@ -25,7 +25,7 @@
.input-group
= text_field_tag :domain_verification, domain_presenter.verification_record, class: "monospace js-select-on-focus form-control", readonly: true
.input-group-append
- = deprecated_clipboard_button(target: '#domain_verification', class: 'btn-default d-none d-sm-block')
+ = clipboard_button(target: '#domain_verification', category: :primary, size: :medium)
%p.form-text.text-muted
- link_to_help = link_to(_('verify ownership'), help_page_path('user/project/pages/custom_domains_ssl_tls_certification/index', anchor: '4-verify-the-domains-ownership'))
= _("To %{link_to_help} of your domain, add the above key to a TXT record within your DNS configuration within seven days.").html_safe % { link_to_help: link_to_help }
diff --git a/app/views/search/results/_blob_data.html.haml b/app/views/search/results/_blob_data.html.haml
index c42367f45c5..6e11b625490 100644
--- a/app/views/search/results/_blob_data.html.haml
+++ b/app/views/search/results/_blob_data.html.haml
@@ -1,6 +1,6 @@
-.js-blob-result.gl-mt-3.gl-mb-5{ data: { qa_selector: 'result_item_content' } }
+.js-blob-result.gl-mt-3.gl-mb-5{ data: { testid: 'result-item-content' } }
.file-holder.file-holder-top-border
- .js-file-title.file-title{ data: { qa_selector: 'file_title_content' } }
+ .js-file-title.file-title{ data: { testid: 'file-title-content' } }
= link_to blob_link, data: {track_action: 'click_text', track_label: 'blob_path', track_property: 'search_result'} do
= sprite_icon('document')
%strong
@@ -8,7 +8,7 @@
= copy_file_path_button(path)
- if blob.data
- if blob.data.size > 0
- .file-content.code.term{ data: { qa_selector: 'file_text_content' } }
+ .file-content.code.term{ data: { testid: 'file-text-content' } }
= render 'search/results/blob_highlight', blob: blob, first_line_number: blob.startline, blob_link: blob_link, blame_link: blame_link, highlight_line: blob.highlight_line
- else
.file-content.code
diff --git a/app/views/search/results/_blob_highlight.html.haml b/app/views/search/results/_blob_highlight.html.haml
index 37ffabad717..2a10bc1989b 100644
--- a/app/views/search/results/_blob_highlight.html.haml
+++ b/app/views/search/results/_blob_highlight.html.haml
@@ -3,7 +3,7 @@
#search-blob-content.file-content.code.js-syntax-highlight{ class: 'gl-py-3!' }
- if blob.present?
- .blob-content{ data: { blob_id: blob.id, path: blob.path, highlight_line: highlight, qa_selector: 'file_content' } }
+ .blob-content{ data: { blob_id: blob.id, path: blob.path, highlight_line: highlight } }
- blob_highlight = blob.present.highlight_and_trim(trim_length: 1024, ellipsis_svg: sprite_icon('ellipsis_h', size: 12, css_class: "gl-text-gray-700"))
- blob_highlight.lines.each_with_index do |line, index|
- i = index + offset
diff --git a/app/views/sent_notifications/unsubscribe.html.haml b/app/views/sent_notifications/unsubscribe.html.haml
index 16e4ff4d17f..3e2373446ca 100644
--- a/app/views/sent_notifications/unsubscribe.html.haml
+++ b/app/views/sent_notifications/unsubscribe.html.haml
@@ -14,6 +14,7 @@
= _("Are you sure you want to unsubscribe from the %{type}: %{link_to_noteable_text}?").html_safe % { type: noteable_type, link_to_noteable_text: link_to_noteable_text }
%p
- = link_to _('Unsubscribe'), unsubscribe_sent_notification_path(@sent_notification, force: true),
- class: 'gl-button btn btn-confirm gl-mr-3'
- = link_button_to _('Cancel'), new_user_session_path, class: 'gl-mr-3'
+ = render Pajamas::ButtonComponent.new(href: unsubscribe_sent_notification_path(@sent_notification, force: true), variant: 'confirm', button_options: { class: 'gl-mr-3'}) do
+ = _('Unsubscribe')
+ = render Pajamas::ButtonComponent.new(href: new_user_session_path, button_options: { class: 'gl-mr-3'}) do
+ = _('Cancel')
diff --git a/app/views/shared/_auto_devops_callout.html.haml b/app/views/shared/_auto_devops_callout.html.haml
index af09b62c229..546e92e7dcb 100644
--- a/app/views/shared/_auto_devops_callout.html.haml
+++ b/app/views/shared/_auto_devops_callout.html.haml
@@ -1,14 +1,13 @@
%div{ class: [container_class, @content_class, 'gl-pt-5!'] }
= render Pajamas::BannerComponent.new(button_text: s_('AutoDevOps|Enable in settings'),
button_link: project_settings_ci_cd_path(@project, anchor: 'autodevops-settings'),
- svg_path: 'illustrations/autodevops.svg',
+ svg_path: 'illustrations/devops-sm.svg',
banner_options: { class: 'js-autodevops-banner auto-devops-callout', data: { uid: 'auto_devops_settings_dismissed', project_path: project_path(@project) } },
close_options: { 'aria-label' => s_('AutoDevOps|Dismiss Auto DevOps box'), class: 'js-close-callout' }) do |c|
- c.with_title do
= s_('AutoDevOps|Auto DevOps')
- %p= s_('AutoDevOps|It will automatically build, test, and deploy your application based on a predefined CI/CD configuration.')
-
%p
- link = link_to(s_('AutoDevOps|Auto DevOps documentation'), help_page_path('topics/autodevops/index'), target: '_blank', rel: 'noopener noreferrer')
+ = s_('AutoDevOps|It will automatically build, test, and deploy your application based on a predefined CI/CD configuration.')
= s_('AutoDevOps|Learn more in the %{link_to_documentation}').html_safe % { link_to_documentation: link }
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 0ff2ee935cc..05a3fd2abc9 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)
- = render Pajamas::AlertComponent.new(alert_options: { class: 'auto-devops-implicitly-enabled-banner', data: { qa_selector: 'auto_devops_banner_content' } },
+ = render Pajamas::AlertComponent.new(alert_options: { class: 'auto-devops-implicitly-enabled-banner' },
close_button_options: { class: 'hide-auto-devops-implicitly-enabled-banner',
data: { project_id: project.id }}) do |c|
- c.with_body do
diff --git a/app/views/shared/_file_highlight.html.haml b/app/views/shared/_file_highlight.html.haml
index 9dfbad20726..3b53a4b4e89 100644
--- a/app/views/shared/_file_highlight.html.haml
+++ b/app/views/shared/_file_highlight.html.haml
@@ -16,7 +16,7 @@
%a.file-line-num.diff-line-num{ class: line_class, href: "#L#{i}", id: "L#{i}", 'data-line-number' => i }
= i
- .blob-content{ data: { blob_id: blob.id, path: blob.path, highlight_line: highlight, qa_selector: 'file_content' } }
+ .blob-content{ data: { blob_id: blob.id, path: blob.path, highlight_line: highlight } }
%pre.code.highlight
%code
= highlighted_blob
diff --git a/app/views/shared/_visibility_radios.html.haml b/app/views/shared/_visibility_radios.html.haml
index 1bac75e0ff5..b4013cb5b80 100644
--- a/app/views/shared/_visibility_radios.html.haml
+++ b/app/views/shared/_visibility_radios.html.haml
@@ -6,7 +6,7 @@
= form.gitlab_ui_radio_component model_method, level,
"#{visibility_level_icon(level)} #{visibility_level_label(level)}".html_safe,
help_text: '<span class="option-description">%{visibility_level_description}</span><span class="option-disabled-reason"></span>'.html_safe % { visibility_level_description: visibility_level_description(level, form_model)},
- radio_options: { checked: (selected_level == level), data: { track_label: "blank_project", track_action: "activate_form_input", track_property: "#{model_method}_#{level}", track_value: "", qa_selector: "#{visibility_level_label(level).downcase}_radio" } },
+ radio_options: { checked: (selected_level == level), data: { track_label: "blank_project", track_action: "activate_form_input", track_property: "#{model_method}_#{level}", track_value: "" } },
label_options: { class: 'js-visibility-level-radio' }
diff --git a/app/views/shared/deploy_keys/_index.html.haml b/app/views/shared/deploy_keys/_index.html.haml
index 5188c530672..95c99f20380 100644
--- a/app/views/shared/deploy_keys/_index.html.haml
+++ b/app/views/shared/deploy_keys/_index.html.haml
@@ -13,4 +13,9 @@
.gl-new-card-add-form.gl-m-3.gl-display-none.js-toggle-content
= render @deploy_keys.form_partial_path
- #js-deploy-keys{ data: { endpoint: project_deploy_keys_path(@project), project_id: @project.id } }
+ #js-deploy-keys{ data: { project_id: @project.id,
+ project_path: @project.full_path,
+ enabled_endpoint: enabled_keys_project_deploy_keys_path(@project),
+ available_project_endpoint: available_project_keys_project_deploy_keys_path(@project),
+ available_public_endpoint: available_public_keys_project_deploy_keys_path(@project)
+ } }
diff --git a/app/views/shared/deploy_tokens/_new_deploy_token.html.haml b/app/views/shared/deploy_tokens/_new_deploy_token.html.haml
deleted file mode 100644
index 2bc2e6c5b81..00000000000
--- a/app/views/shared/deploy_tokens/_new_deploy_token.html.haml
+++ /dev/null
@@ -1,24 +0,0 @@
-.created-deploy-token-container.info-well{ data: { testid: 'created-deploy-token-container' } }
- .well-segment
- %h5.gl-mt-0
- = s_('DeployTokens|Your new Deploy Token username')
-
- .form-group
- .input-group
- = text_field_tag 'deploy-token-user', deploy_token.username, readonly: true, class: 'deploy-token-field form-control js-select-on-focus', data: { testid: 'deploy-token-user-field' }
- .input-group-append
- = deprecated_clipboard_button(text: deploy_token.username, title: s_('DeployTokens|Copy username'), placement: 'left')
- %span.deploy-token-help-block.gl-mt-2.text-success
- - link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: help_page_path('user/project/deploy_tokens/index') }
- - link_end = "</a>".html_safe
- = s_("DeployTokens|This username supports access. %{link_start}What kind of access?%{link_end}").html_safe % { link_start: link_start, link_end: link_end }
-
- .form-group
- .input-group
- = text_field_tag 'deploy-token', deploy_token.token, readonly: true, class: 'deploy-token-field form-control js-select-on-focus', data: { testid: 'deploy-token-field' }
- .input-group-append
- = deprecated_clipboard_button(text: deploy_token.token, title: s_('DeployTokens|Copy deploy token'), placement: 'left')
- %span.deploy-token-help-block.gl-mt-2.text-danger
- - i_start = "<i>".html_safe
- - i_end = "</i>".html_safe
- = s_("DeployTokens|Use this token as a password. Save it. This password can %{i_start}not%{i_end} be recovered.").html_safe % { i_start: i_start, i_end: i_end }
diff --git a/app/views/shared/groups/_group.html.haml b/app/views/shared/groups/_group.html.haml
index 375e10de065..cdcbee1bb72 100644
--- a/app/views/shared/groups/_group.html.haml
+++ b/app/views/shared/groups/_group.html.haml
@@ -2,9 +2,8 @@
- access = user&.max_member_access_for_group(group.id)
%li.group-row.py-3.gl-align-items-center{ class: "gl-display-flex!" }
- .avatar-container.rect-avatar.s48.gl-flex-shrink-0
- = link_to group do
- = render Pajamas::AvatarComponent.new(group, alt: group.name, size: 48)
+ = link_to group do
+ = render Pajamas::AvatarComponent.new(group, alt: group.name, size: 48, class: 'gl-mr-5')
.gl-min-w-0.gl-flex-grow-1
.title
= link_to group.full_name, group, class: 'group-name'
@@ -23,7 +22,7 @@
%span.gl-ml-5.has-tooltip{ title: _('Users') }
= sprite_icon('users', css_class: 'gl-vertical-align-text-bottom')
- = number_with_delimiter(group.users.count)
+ = number_with_delimiter(group.group_members.non_invite.count)
%span.gl-ml-5.visibility-icon.has-tooltip{ data: { container: 'body', placement: 'left' }, title: visibility_icon_description(group) }
= visibility_level_icon(group.visibility_level)
diff --git a/app/views/shared/groups/_list.html.haml b/app/views/shared/groups/_list.html.haml
index 550f079bf3b..ecd722ec53e 100644
--- a/app/views/shared/groups/_list.html.haml
+++ b/app/views/shared/groups/_list.html.haml
@@ -11,6 +11,7 @@
%ul.content-list
- groups.each_with_index do |group, i|
= render "shared/groups/group", group: group, user: user
+ = paginate_collection(groups)
- else
= render partial: 'shared/empty_states/profile_tabs', locals: { illustration_path: illustration_path,
current_user_empty_message_header: current_user_empty_message_header,
diff --git a/app/views/shared/issuable/_sort_dropdown.html.haml b/app/views/shared/issuable/_sort_dropdown.html.haml
index 0a3fd4f8b9e..261a7517eda 100644
--- a/app/views/shared/issuable/_sort_dropdown.html.haml
+++ b/app/views/shared/issuable/_sort_dropdown.html.haml
@@ -5,5 +5,5 @@
.gl-ml-3
.btn-group{ role: 'group' }
- = gl_redirect_listbox_tag(items, selected, data: { placement: 'right' })
+ = gl_redirect_listbox_tag(items, selected, class: 'btn-group', data: { placement: 'right' })
= issuable_sort_direction_button(@sort)
diff --git a/app/views/shared/members/_member.html.haml b/app/views/shared/members/_member.html.haml
index c86993f5b77..42eb9e5ca19 100644
--- a/app/views/shared/members/_member.html.haml
+++ b/app/views/shared/members/_member.html.haml
@@ -9,7 +9,7 @@
-# Note this is just for individual members. For groups please see shared/members/_group
-%li.member.js-member.py-2.px-3.d-flex.flex-column{ class: [dom_class(member), ("flex-md-row" unless force_mobile_view)], id: dom_id(member), data: { qa_selector: 'member_row' } }
+%li.member.js-member.py-2.px-3.d-flex.flex-column{ class: [dom_class(member), ("flex-md-row" unless force_mobile_view)], id: dom_id(member) }
%span.list-item-name.mb-2.m-md-0
- if user
= render Pajamas::AvatarComponent.new(user, size: 32, class: 'gl-mr-3 flex-shrink-0 flex-grow-0')
@@ -49,7 +49,7 @@
= _("Expires %{preposition} %{expires_at}").html_safe % { expires_at: time_ago_with_tooltip(member.expires_at), preposition: preposition }
- else
- = image_tag avatar_icon_for_email(member.invite_email, 40), class: "avatar s40 flex-shrink-0 flex-grow-0", alt: ''
+ = render Pajamas::AvatarComponent.new(Pajamas::AvatarEmail.new(member.invite_email), size: 32, class: 'gl-mr-3 flex-shrink-0 flex-grow-0')
.user-info
.member= member.invite_email
.cgray
diff --git a/app/views/shared/notes/_notes_with_form.html.haml b/app/views/shared/notes/_notes_with_form.html.haml
index 343a8597444..969ca2084d7 100644
--- a/app/views/shared/notes/_notes_with_form.html.haml
+++ b/app/views/shared/notes/_notes_with_form.html.haml
@@ -10,7 +10,7 @@
.notes.notes-form.timeline
.timeline-entry.note-form
.timeline-entry-inner
- .flash-container.timeline-content
+ .flash-container
.timeline-content.timeline-content-form
= render "shared/notes/form", view: diff_view, supports_autocomplete: autocomplete
diff --git a/app/views/shared/users/_user.html.haml b/app/views/shared/users/_user.html.haml
index e3c1ca4d9cf..4dc276a45c2 100644
--- a/app/views/shared/users/_user.html.haml
+++ b/app/views/shared/users/_user.html.haml
@@ -7,7 +7,7 @@
.user-info
.block-truncated
- = link_to user.name, user_path(user), class: 'user js-user-link', data: { user_id: user.id, qa_selector: 'user_link', qa_username: user.username }
+ = link_to user.name, user_path(user), class: 'user js-user-link', data: { user_id: user.id, testid: 'user-link', qa_username: user.username }
.block-truncated
%span.gl-text-gray-900= user.to_reference
diff --git a/app/views/shared/web_hooks/_index.html.haml b/app/views/shared/web_hooks/_index.html.haml
index ccd86937e4f..c4670a3ac73 100644
--- a/app/views/shared/web_hooks/_index.html.haml
+++ b/app/views/shared/web_hooks/_index.html.haml
@@ -11,7 +11,7 @@
- c.with_body do
= gitlab_ui_form_for @hook, as: :hook, url: url, html: { class: 'js-webhook-form gl-new-card-add-form gl-m-3 gl-display-none js-toggle-content' } do |f|
= render partial: partial, locals: { form: f, hook: @hook }
- = f.submit _('Add webhook'), pajamas_button: true, data: { qa_selector: "create_webhook_button" }
+ = f.submit _('Add webhook'), pajamas_button: true
= render Pajamas::ButtonComponent.new(button_options: { type: 'reset', class: 'js-webhook-edit-close gl-ml-2 js-toggle-button' }) do
= _('Cancel')
- if hooks.any?
diff --git a/app/views/shared/wikis/_sidebar.html.haml b/app/views/shared/wikis/_sidebar.html.haml
index cd752d31643..dd4ea9e72ab 100644
--- a/app/views/shared/wikis/_sidebar.html.haml
+++ b/app/views/shared/wikis/_sidebar.html.haml
@@ -15,7 +15,7 @@
- if can?(current_user, :create_wiki, @wiki)
- edit_sidebar_url = wiki_page_path(@wiki, Wiki::SIDEBAR, action: :edit)
- link_class = (editing && @page&.slug == Wiki::SIDEBAR) ? 'active' : ''
- = link_to edit_sidebar_url, class: link_class, data: { qa_selector: 'edit_sidebar_link' } do
+ = link_to edit_sidebar_url, class: link_class do
= sprite_icon('pencil', css_class: 'gl-mr-2')
%span= _("Edit sidebar")
diff --git a/app/views/shared/wikis/git_error.html.haml b/app/views/shared/wikis/git_error.html.haml
index 12eddb4a61e..aee359b35b3 100644
--- a/app/views/shared/wikis/git_error.html.haml
+++ b/app/views/shared/wikis/git_error.html.haml
@@ -8,7 +8,7 @@
.wiki-page-header.top-area.gl-flex-direction-column.gl-lg-flex-direction-row
.gl-mt-5.gl-mb-3
.gl-display-flex.gl-justify-content-space-between
- %h2.gl-mt-0.gl-mb-5{ data: { qa_selector: 'wiki_page_title', testid: 'wiki_page_title' } }= @page ? @page.human_title : _('Failed to retrieve page')
- .js-wiki-page-content.md.gl-pt-2{ data: { qa_selector: 'wiki_page_content', testid: 'wiki-page-content' } }
+ %h2.gl-mt-0.gl-mb-5{ data: { testid: 'wiki-page-title' } }= @page ? @page.human_title : _('Failed to retrieve page')
+ .js-wiki-page-content.md.gl-pt-2{ data: { testid: 'wiki-page-content' } }
= _('The page could not be displayed because it timed out.')
= html_escape(_('You can view the source or %{linkStart}%{cloneIcon} clone the repository%{linkEnd}')) % { linkStart: "<a href=\"#{git_access_url}\">".html_safe, linkEnd: '</a>'.html_safe, cloneIcon: sprite_icon('download', css_class: 'gl-mr-2').html_safe }
diff --git a/app/views/shared/wikis/show.html.haml b/app/views/shared/wikis/show.html.haml
index a896aa29f52..e33828b95ab 100644
--- a/app/views/shared/wikis/show.html.haml
+++ b/app/views/shared/wikis/show.html.haml
@@ -13,7 +13,10 @@
.nav-controls.pb-md-3.pb-lg-0
- if can?(current_user, :create_wiki, @wiki.container) && @page.latest? && @valid_encoding
- = render Pajamas::ButtonComponent.new(href: wiki_page_path(@wiki, @page, action: :edit), button_options: { class: 'js-wiki-edit', data: { testid: 'wiki-edit-button' }}) do
+ - edit_action_description = _('Edit page')
+ - edit_action_shortcut = 'e'
+ - edit_button_title = "#{edit_action_description} <kbd class='flat ml-1' aria-hidden=true>#{edit_action_shortcut}</kbd>"
+ = render Pajamas::ButtonComponent.new(href: wiki_page_path(@wiki, @page, action: :edit), button_options: { aria: {label: edit_action_description, keyshortcuts: edit_action_shortcut}, class: 'has-tooltip js-wiki-edit', data: { html: 'true', testid: 'wiki-edit-button' }, title: edit_button_title }) do
= _('Edit')
= render 'shared/wikis/main_links'
@@ -35,6 +38,6 @@
.gl-display-flex.gl-justify-content-space-between
%h2.gl-mt-0.gl-mb-5{ data: { testid: 'wiki-page-title' } }= @page.human_title
- .js-async-wiki-page-content.md.gl-pt-2{ data: { qa_selector: 'wiki_page_content', testid: 'wiki-page-content', tracking_context: wiki_page_tracking_context(@page).to_json, get_wiki_content_url: wiki_page_render_api_endpoint(@page) } }
+ .js-async-wiki-page-content.md.gl-pt-2{ data: { testid: 'wiki-page-content', tracking_context: wiki_page_tracking_context(@page).to_json, get_wiki_content_url: wiki_page_render_api_endpoint(@page) } }
= render 'shared/wikis/sidebar'
diff --git a/app/views/user_settings/passwords/edit.html.haml b/app/views/user_settings/passwords/edit.html.haml
index afe6ee2c0b3..179f54ac45e 100644
--- a/app/views/user_settings/passwords/edit.html.haml
+++ b/app/views/user_settings/passwords/edit.html.haml
@@ -18,18 +18,18 @@
- unless @user.password_automatically_set?
.form-group
= f.label :password, _('Current password'), class: 'label-bold'
- = f.password_field :password, required: true, autocomplete: 'current-password', class: 'form-control gl-form-input gl-max-w-80', data: { qa_selector: 'current_password_field' }
+ = f.password_field :password, required: true, autocomplete: 'current-password', class: 'form-control gl-form-input gl-max-w-80', data: { testid: 'current-password-field' }
%p.form-text.text-muted
= _('You must provide your current password in order to change it.')
.form-group
= f.label :new_password, _('New password'), class: 'label-bold'
- = f.password_field :new_password, required: true, autocomplete: 'new-password', class: 'form-control gl-form-input js-password-complexity-validation gl-max-w-80', data: { qa_selector: 'new_password_field' }
+ = f.password_field :new_password, required: true, autocomplete: 'new-password', class: 'form-control gl-form-input js-password-complexity-validation gl-max-w-80', data: { testid: 'new-password-field' }
= render_if_exists 'shared/password_requirements_list'
.form-group
= f.label :password_confirmation, _('Password confirmation'), class: 'label-bold'
- = f.password_field :password_confirmation, required: true, autocomplete: 'new-password', class: 'form-control gl-form-input gl-max-w-80', data: { qa_selector: 'confirm_password_field' }
+ = f.password_field :password_confirmation, required: true, autocomplete: 'new-password', class: 'form-control gl-form-input gl-max-w-80', data: { testid: 'confirm-password-field' }
.gl-mt-3.gl-mb-3
- = f.submit _('Save password'), class: "gl-mr-3", data: { qa_selector: 'save_password_button' }, pajamas_button: true
+ = f.submit _('Save password'), class: "gl-mr-3", data: { testid: 'save-password-button' }, pajamas_button: true
- unless @user.password_automatically_set?
= render Pajamas::ButtonComponent.new(href: reset_user_settings_password_path, variant: :link, method: :put) do
= _('I forgot my password')
diff --git a/app/views/user_settings/passwords/new.html.haml b/app/views/user_settings/passwords/new.html.haml
index 3616c9ec252..4b47dfa3e83 100644
--- a/app/views/user_settings/passwords/new.html.haml
+++ b/app/views/user_settings/passwords/new.html.haml
@@ -16,17 +16,17 @@
.col-sm-2.col-form-label
= f.label :password, _('Current password')
.col-sm-10
- = f.password_field :password, required: true, autocomplete: 'current-password', class: 'form-control gl-form-input', data: { qa_selector: 'current_password_field' }
+ = f.password_field :password, required: true, autocomplete: 'current-password', class: 'form-control gl-form-input', data: { testid: 'current-password-field' }
.form-group.row
.col-sm-2.col-form-label
= f.label :new_password, _('New password')
.col-sm-10
- = f.password_field :new_password, required: true, autocomplete: 'new-password', class: 'form-control gl-form-input js-password-complexity-validation', data: { qa_selector: 'new_password_field' }
+ = f.password_field :new_password, required: true, autocomplete: 'new-password', class: 'form-control gl-form-input js-password-complexity-validation', data: { testid: 'new-password-field' }
= render_if_exists 'shared/password_requirements_list'
.form-group.row
.col-sm-2.col-form-label
= f.label :password_confirmation, _('Password confirmation')
.col-sm-10
- = f.password_field :password_confirmation, required: true, autocomplete: 'new-password', class: 'form-control gl-form-input', data: { qa_selector: 'confirm_password_field' }
+ = f.password_field :password_confirmation, required: true, autocomplete: 'new-password', class: 'form-control gl-form-input', data: { testid: 'confirm-password-field' }
.form-actions
- = f.submit _('Set new password'), data: { qa_selector: 'set_new_password_button' }, pajamas_button: true
+ = f.submit _('Set new password'), data: { testid: 'set-new-password-button' }, pajamas_button: true
diff --git a/app/views/users/show.html.haml b/app/views/users/show.html.haml
index 99097ac397c..3aee73b0b96 100644
--- a/app/views/users/show.html.haml
+++ b/app/views/users/show.html.haml
@@ -26,7 +26,7 @@
= render 'users/view_user_in_admin_area'
.js-user-profile-actions{ data: user_profile_actions_data(@user) }
- .profile-header{ class: [('with-no-profile-tabs' if profile_tabs.empty?), ('gl-mb-4!' if show_super_sidebar?)] }
+ .profile-header.gl-mx-5.gl-mb-4{ class: [('gl-mb-6' if profile_tabs.empty?)] }
.gl-display-inline-block.gl-mx-8.gl-vertical-align-top
.avatar-holder
= link_to avatar_icon_for_user(@user, 400, current_user: current_user), target: '_blank', rel: 'noopener noreferrer' do
@@ -113,9 +113,9 @@
= @user.bio
-# TODO: Remove this with the removal of the old navigation.
- -# See https://gitlab.com/groups/gitlab-org/-/epics/11875.
+ -# See https://gitlab.com/gitlab-org/gitlab/-/issues/435899.
- if !profile_tabs.empty? && !Feature.enabled?(:profile_tabs_vue, current_user)
- .scrolling-tabs-container{ class: [('gl-display-none' if show_super_sidebar?)] }
+ .scrolling-tabs-container.gl-display-none
%button.fade-left{ type: 'button', title: _('Scroll left'), 'aria-label': _('Scroll left') }
= sprite_icon('chevron-lg-left', size: 12)
%button.fade-right{ type: 'button', title: _('Scroll right'), 'aria-label': _('Scroll right') }