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>2021-05-19 18:44:42 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2021-05-19 18:44:42 +0300
commit4555e1b21c365ed8303ffb7a3325d773c9b8bf31 (patch)
tree5423a1c7516cffe36384133ade12572cf709398d /app/views
parente570267f2f6b326480d284e0164a6464ba4081bc (diff)
Add latest changes from gitlab-org/gitlab@13-12-stable-eev13.12.0-rc42
Diffstat (limited to 'app/views')
-rw-r--r--app/views/admin/appearances/_form.html.haml34
-rw-r--r--app/views/admin/appearances/preview_sign_in.html.haml8
-rw-r--r--app/views/admin/application_settings/_abuse.html.haml6
-rw-r--r--app/views/admin/application_settings/_floc.html.haml22
-rw-r--r--app/views/admin/application_settings/_gitaly.html.haml8
-rw-r--r--app/views/admin/application_settings/_initial_branch_name.html.haml4
-rw-r--r--app/views/admin/application_settings/_package_registry.html.haml3
-rw-r--r--app/views/admin/application_settings/_package_registry_limits.html.haml37
-rw-r--r--app/views/admin/application_settings/_plantuml.html.haml2
-rw-r--r--app/views/admin/application_settings/_prometheus.html.haml22
-rw-r--r--app/views/admin/application_settings/_repository_check.html.haml2
-rw-r--r--app/views/admin/application_settings/_signin.html.haml22
-rw-r--r--app/views/admin/application_settings/_spam.html.haml32
-rw-r--r--app/views/admin/application_settings/_terminal.html.haml7
-rw-r--r--app/views/admin/application_settings/_usage.html.haml11
-rw-r--r--app/views/admin/application_settings/_whats_new.html.haml13
-rw-r--r--app/views/admin/application_settings/general.html.haml1
-rw-r--r--app/views/admin/application_settings/network.html.haml11
-rw-r--r--app/views/admin/application_settings/preferences.html.haml11
-rw-r--r--app/views/admin/application_settings/repository.html.haml21
-rw-r--r--app/views/admin/background_jobs/show.html.haml7
-rw-r--r--app/views/admin/broadcast_messages/_form.html.haml10
-rw-r--r--app/views/admin/dashboard/index.html.haml2
-rw-r--r--app/views/admin/deploy_keys/new.html.haml2
-rw-r--r--app/views/admin/dev_ops_report/_card.html.haml25
-rw-r--r--app/views/admin/dev_ops_report/_no_data.html.haml7
-rw-r--r--app/views/admin/dev_ops_report/_report.html.haml26
-rw-r--r--app/views/admin/groups/_group.html.haml2
-rw-r--r--app/views/admin/health_check/show.html.haml6
-rw-r--r--app/views/admin/hook_logs/_index.html.haml2
-rw-r--r--app/views/admin/labels/_label.html.haml2
-rw-r--r--app/views/admin/labels/destroy.js.haml3
-rw-r--r--app/views/admin/projects/_projects.html.haml2
-rw-r--r--app/views/admin/requests_profiles/index.html.haml6
-rw-r--r--app/views/admin/runners/index.html.haml2
-rw-r--r--app/views/admin/runners/show.html.haml15
-rw-r--r--app/views/admin/spam_logs/index.html.haml22
-rw-r--r--app/views/admin/users/_ban_user.html.haml9
-rw-r--r--app/views/admin/users/_cohorts.html.haml5
-rw-r--r--app/views/admin/users/_form.html.haml26
-rw-r--r--app/views/admin/users/_head.html.haml3
-rw-r--r--app/views/admin/users/_profile.html.haml16
-rw-r--r--app/views/admin/users/_projects.html.haml4
-rw-r--r--app/views/admin/users/_tabs.html.haml7
-rw-r--r--app/views/admin/users/_user.html.haml8
-rw-r--r--app/views/admin/users/_users.html.haml27
-rw-r--r--app/views/admin/users/cohorts.html.haml7
-rw-r--r--app/views/admin/users/edit.html.haml2
-rw-r--r--app/views/admin/users/index.html.haml14
-rw-r--r--app/views/admin/users/projects.html.haml10
-rw-r--r--app/views/admin/users/show.html.haml115
-rw-r--r--app/views/clusters/clusters/_banner.html.haml2
-rw-r--r--app/views/clusters/clusters/_integrations.html.haml34
-rw-r--r--app/views/clusters/clusters/show.html.haml6
-rw-r--r--app/views/dashboard/_activities.html.haml2
-rw-r--r--app/views/dashboard/groups/_groups.html.haml2
-rw-r--r--app/views/dashboard/todos/_todo.html.haml120
-rw-r--r--app/views/dashboard/todos/index.html.haml87
-rw-r--r--app/views/devise/confirmations/new.html.haml4
-rw-r--r--app/views/devise/mailer/_confirmation_instructions_secondary.html.haml10
-rw-r--r--app/views/devise/mailer/reset_password_instructions.html.haml11
-rw-r--r--app/views/devise/mailer/reset_password_instructions.text.erb9
-rw-r--r--app/views/devise/mailer/unlock_instructions.text.erb6
-rw-r--r--app/views/devise/shared/_links.erb10
-rw-r--r--app/views/devise/shared/_signup_box.html.haml2
-rw-r--r--app/views/devise/shared/_signup_omniauth_providers_top.haml2
-rw-r--r--app/views/devise/shared/_terms_of_service_notice.html.haml12
-rw-r--r--app/views/doorkeeper/authorizations/new.html.haml4
-rw-r--r--app/views/explore/groups/_groups.html.haml2
-rw-r--r--app/views/groups/_activities.html.haml2
-rw-r--r--app/views/groups/_archived_projects.html.haml2
-rw-r--r--app/views/groups/_import_group_from_another_instance_panel.html.haml8
-rw-r--r--app/views/groups/_invite_members_modal.html.haml2
-rw-r--r--app/views/groups/_shared_projects.html.haml2
-rw-r--r--app/views/groups/_subgroups_and_projects.html.haml2
-rw-r--r--app/views/groups/boards/show.html.haml2
-rw-r--r--app/views/groups/group_members/index.html.haml33
-rw-r--r--app/views/groups/imports/show.html.haml2
-rw-r--r--app/views/groups/issues.html.haml2
-rw-r--r--app/views/groups/merge_requests.html.haml2
-rw-r--r--app/views/groups/milestones/_form.html.haml6
-rw-r--r--app/views/groups/milestones/_header_title.html.haml2
-rw-r--r--app/views/groups/milestones/new.html.haml2
-rw-r--r--app/views/groups/runners/edit.html.haml5
-rw-r--r--app/views/groups/runners/show.html.haml3
-rw-r--r--app/views/groups/settings/_lfs.html.haml12
-rw-r--r--app/views/groups/settings/_two_factor_auth.html.haml14
-rw-r--r--app/views/groups/settings/packages_and_registries/show.html.haml (renamed from app/views/groups/settings/packages_and_registries/index.html.haml)0
-rw-r--r--app/views/groups/settings/repository/_initial_branch_name.html.haml4
-rw-r--r--app/views/groups/show.html.haml1
-rw-r--r--app/views/ide/_show.html.haml5
-rw-r--r--app/views/import/bitbucket_server/new.html.haml6
-rw-r--r--app/views/import/bulk_imports/status.html.haml3
-rw-r--r--app/views/import/fogbugz/new.html.haml6
-rw-r--r--app/views/import/gitea/new.html.haml4
-rw-r--r--app/views/import/phabricator/new.html.haml4
-rw-r--r--app/views/import/shared/_new_project_form.html.haml4
-rw-r--r--app/views/layouts/_head.html.haml2
-rw-r--r--app/views/layouts/_loading_hints.html.haml21
-rw-r--r--app/views/layouts/_page_title.html.haml2
-rw-r--r--app/views/layouts/header/_current_user_dropdown.html.haml2
-rw-r--r--app/views/layouts/header/_default.html.haml4
-rw-r--r--app/views/layouts/header/_new_dropdown.html.haml19
-rw-r--r--app/views/layouts/header/_new_repo_experiment.html.haml11
-rw-r--r--app/views/layouts/header/_whats_new_dropdown_item.html.haml2
-rw-r--r--app/views/layouts/nav/_combined_menu.html.haml3
-rw-r--r--app/views/layouts/nav/_dashboard.html.haml6
-rw-r--r--app/views/layouts/nav/_explore.html.haml4
-rw-r--r--app/views/layouts/nav/_top_nav.html.haml7
-rw-r--r--app/views/layouts/nav/groups_dropdown/_show.html.haml10
-rw-r--r--app/views/layouts/nav/projects_dropdown/_show.html.haml6
-rw-r--r--app/views/layouts/nav/sidebar/_admin.html.haml27
-rw-r--r--app/views/layouts/nav/sidebar/_group.html.haml69
-rw-r--r--app/views/layouts/nav/sidebar/_profile.html.haml4
-rw-r--r--app/views/layouts/nav/sidebar/_project.html.haml2
-rw-r--r--app/views/layouts/nav/sidebar/_project_menus.html.haml380
-rw-r--r--app/views/layouts/nav/sidebar/_project_packages_link.html.haml27
-rw-r--r--app/views/layouts/nav/sidebar/_project_security_link.html.haml21
-rw-r--r--app/views/layouts/nav/sidebar/_tracing_link.html.haml7
-rw-r--r--app/views/layouts/simple_registration.html.haml10
-rw-r--r--app/views/notify/change_in_merge_request_draft_status_email.html.haml4
-rw-r--r--app/views/notify/in_product_marketing_email.html.haml24
-rw-r--r--app/views/notify/in_product_marketing_email.text.erb18
-rw-r--r--app/views/notify/new_issue_email.html.haml3
-rw-r--r--app/views/notify/new_issue_email.text.erb3
-rw-r--r--app/views/notify/new_merge_request_email.html.haml6
-rw-r--r--app/views/notify/new_merge_request_email.text.erb6
-rw-r--r--app/views/profiles/chat_names/_chat_name.html.haml8
-rw-r--r--app/views/profiles/keys/_form.html.haml6
-rw-r--r--app/views/profiles/keys/_key.html.haml2
-rw-r--r--app/views/profiles/passwords/new.html.haml8
-rw-r--r--app/views/profiles/preferences/show.html.haml2
-rw-r--r--app/views/profiles/show.html.haml7
-rw-r--r--app/views/profiles/two_factor_auths/show.html.haml4
-rw-r--r--app/views/projects/_activity.html.haml2
-rw-r--r--app/views/projects/_archived_notice.html.haml2
-rw-r--r--app/views/projects/_commit_button.html.haml4
-rw-r--r--app/views/projects/_files.html.haml2
-rw-r--r--app/views/projects/_fork_suggestion.html.haml13
-rw-r--r--app/views/projects/_home_panel.html.haml79
-rw-r--r--app/views/projects/_import_project_pane.html.haml2
-rw-r--r--app/views/projects/_merge_request_merge_method_settings.html.haml2
-rw-r--r--app/views/projects/_merge_request_merge_suggestions_settings.html.haml2
-rw-r--r--app/views/projects/_new_project_fields.html.haml6
-rw-r--r--app/views/projects/blob/_blob.html.haml2
-rw-r--r--app/views/projects/blob/_editor.html.haml20
-rw-r--r--app/views/projects/blob/_template_selectors.html.haml3
-rw-r--r--app/views/projects/blob/_upload.html.haml2
-rw-r--r--app/views/projects/blob/edit.html.haml2
-rw-r--r--app/views/projects/blob/new.html.haml9
-rw-r--r--app/views/projects/blob/show.html.haml2
-rw-r--r--app/views/projects/blob/viewers/_changelog.html.haml3
-rw-r--r--app/views/projects/blob/viewers/_contributing.html.haml4
-rw-r--r--app/views/projects/blob/viewers/_download.html.haml2
-rw-r--r--app/views/projects/blob/viewers/_license.html.haml6
-rw-r--r--app/views/projects/blob/viewers/_readme.html.haml4
-rw-r--r--app/views/projects/buttons/_download.html.haml4
-rw-r--r--app/views/projects/buttons/_dropdown.html.haml6
-rw-r--r--app/views/projects/buttons/_remove_tag.html.haml4
-rw-r--r--app/views/projects/ci/pipeline_editor/show.html.haml2
-rw-r--r--app/views/projects/commit/_commit_box.html.haml4
-rw-r--r--app/views/projects/commit/_pipelines_list.haml4
-rw-r--r--app/views/projects/commit/show.html.haml7
-rw-r--r--app/views/projects/commits/_commit.html.haml26
-rw-r--r--app/views/projects/commits/_commits.html.haml14
-rw-r--r--app/views/projects/compare/index.html.haml6
-rw-r--r--app/views/projects/compare/show.html.haml11
-rw-r--r--app/views/projects/diffs/_diffs.html.haml5
-rw-r--r--app/views/projects/edit.html.haml2
-rw-r--r--app/views/projects/empty.html.haml2
-rw-r--r--app/views/projects/environments/index.html.haml2
-rw-r--r--app/views/projects/feature_flags/edit.html.haml2
-rw-r--r--app/views/projects/feature_flags/new.html.haml2
-rw-r--r--app/views/projects/hook_logs/_index.html.haml2
-rw-r--r--app/views/projects/issues/_issue.html.haml4
-rw-r--r--app/views/projects/issues/_issues.html.haml3
-rw-r--r--app/views/projects/issues/_new_branch.html.haml4
-rw-r--r--app/views/projects/issues/index.html.haml2
-rw-r--r--app/views/projects/jobs/index.html.haml2
-rw-r--r--app/views/projects/learn_gitlab/index.html.haml2
-rw-r--r--app/views/projects/merge_requests/_description.html.haml2
-rw-r--r--app/views/projects/merge_requests/_merge_request.html.haml4
-rw-r--r--app/views/projects/merge_requests/_mr_box.html.haml2
-rw-r--r--app/views/projects/merge_requests/_mr_title.html.haml82
-rw-r--r--app/views/projects/merge_requests/_widget.html.haml6
-rw-r--r--app/views/projects/merge_requests/creations/_new_compare.html.haml4
-rw-r--r--app/views/projects/merge_requests/creations/_new_submit.html.haml8
-rw-r--r--app/views/projects/merge_requests/index.html.haml2
-rw-r--r--app/views/projects/merge_requests/show.html.haml6
-rw-r--r--app/views/projects/milestones/_form.html.haml8
-rw-r--r--app/views/projects/milestones/show.html.haml2
-rw-r--r--app/views/projects/mirrors/_ssh_host_keys.html.haml2
-rw-r--r--app/views/projects/network/show.html.haml2
-rw-r--r--app/views/projects/new.html.haml92
-rw-r--r--app/views/projects/pipeline_schedules/_tabs.html.haml6
-rw-r--r--app/views/projects/pipelines/_with_tabs.html.haml10
-rw-r--r--app/views/projects/pipelines/index.html.haml8
-rw-r--r--app/views/projects/pipelines/new.html.haml58
-rw-r--r--app/views/projects/pipelines/show.html.haml4
-rw-r--r--app/views/projects/project_members/index.html.haml32
-rw-r--r--app/views/projects/project_templates/_template.html.haml2
-rw-r--r--app/views/projects/registry/repositories/index.html.haml2
-rw-r--r--app/views/projects/runners/_group_runners.html.haml2
-rw-r--r--app/views/projects/runners/_shared_runners.html.haml21
-rw-r--r--app/views/projects/runners/edit.html.haml5
-rw-r--r--app/views/projects/runners/show.html.haml3
-rw-r--r--app/views/projects/settings/_archive.html.haml2
-rw-r--r--app/views/projects/settings/access_tokens/index.html.haml11
-rw-r--r--app/views/projects/settings/operations/_configuration_banner.html.haml2
-rw-r--r--app/views/projects/settings/operations/_error_tracking.html.haml4
-rw-r--r--app/views/projects/settings/operations/show.html.haml5
-rw-r--r--app/views/projects/settings/packages_and_registries/show.html.haml16
-rw-r--r--app/views/projects/sidebar/_issues_service_desk.html.haml3
-rw-r--r--app/views/projects/snippets/show.html.haml2
-rw-r--r--app/views/projects/tags/_tag.html.haml4
-rw-r--r--app/views/projects/tags/index.html.haml22
-rw-r--r--app/views/projects/tags/new.html.haml4
-rw-r--r--app/views/projects/tags/releases/edit.html.haml4
-rw-r--r--app/views/projects/triggers/_trigger.html.haml4
-rw-r--r--app/views/registrations/invites/new.html.haml18
-rw-r--r--app/views/registrations/welcome/show.html.haml1
-rw-r--r--app/views/search/_category.html.haml14
-rw-r--r--app/views/search/results/_user.html.haml6
-rw-r--r--app/views/shared/_allow_request_access.html.haml6
-rw-r--r--app/views/shared/_commit_message_container.html.haml12
-rw-r--r--app/views/shared/_confirm_fork_modal.html.haml2
-rw-r--r--app/views/shared/_group_form.html.haml4
-rw-r--r--app/views/shared/_import_form.html.haml14
-rw-r--r--app/views/shared/_issuable_meta_data.html.haml2
-rw-r--r--app/views/shared/_issues.html.haml4
-rw-r--r--app/views/shared/access_tokens/_table.html.haml2
-rw-r--r--app/views/shared/alerts/_positioning_disabled.html.haml2
-rw-r--r--app/views/shared/blob/_markdown_buttons.html.haml3
-rw-r--r--app/views/shared/boards/_show.html.haml2
-rw-r--r--app/views/shared/boards/components/sidebar/_assignee.html.haml5
-rw-r--r--app/views/shared/builds/_tabs.html.haml8
-rw-r--r--app/views/shared/deploy_keys/_form.html.haml4
-rw-r--r--app/views/shared/deploy_keys/_index.html.haml2
-rw-r--r--app/views/shared/deploy_keys/_project_group_form.html.haml6
-rw-r--r--app/views/shared/deploy_tokens/_form.html.haml12
-rw-r--r--app/views/shared/deploy_tokens/_index.html.haml4
-rw-r--r--app/views/shared/deploy_tokens/_new_deploy_token.html.haml6
-rw-r--r--app/views/shared/icons/_dev_ops_report_no_data.svg39
-rw-r--r--app/views/shared/issuable/_search_bar.html.haml6
-rw-r--r--app/views/shared/issuable/_sidebar_assignees.html.haml23
-rw-r--r--app/views/shared/issuable/_status_box.html.haml6
-rw-r--r--app/views/shared/issuable/form/_title.html.haml7
-rw-r--r--app/views/shared/issue_type/_details_header.html.haml9
-rw-r--r--app/views/shared/members/_invite_member.html.haml2
-rw-r--r--app/views/shared/milestones/_delete_button.html.haml2
-rw-r--r--app/views/shared/milestones/_form_dates.html.haml4
-rw-r--r--app/views/shared/milestones/_search_form.html.haml2
-rw-r--r--app/views/shared/milestones/_sidebar.html.haml4
-rw-r--r--app/views/shared/milestones/_tab_loading.html.haml2
-rw-r--r--app/views/shared/namespaces/cascading_settings/_enforcement_checkbox.html.haml11
-rw-r--r--app/views/shared/namespaces/cascading_settings/_lock_icon.html.haml4
-rw-r--r--app/views/shared/namespaces/cascading_settings/_setting_label.html.haml21
-rw-r--r--app/views/shared/namespaces/cascading_settings/_setting_label_checkbox.html.haml16
-rw-r--r--app/views/shared/namespaces/cascading_settings/_setting_label_container.html.haml2
-rw-r--r--app/views/shared/namespaces/cascading_settings/_setting_label_fieldset.html.haml15
-rw-r--r--app/views/shared/nav/_scope_menu.html.haml4
-rw-r--r--app/views/shared/nav/_sidebar.html.haml1
-rw-r--r--app/views/shared/nav/_sidebar_hidden_menu_item.html.haml3
-rw-r--r--app/views/shared/nav/_sidebar_menu.html.haml8
-rw-r--r--app/views/shared/runners/_runner_details.html.haml (renamed from app/views/shared/runners/show.html.haml)39
-rw-r--r--app/views/shared/runners/_shared_runners_description.html.haml10
-rw-r--r--app/views/shared/snippets/_snippet.html.haml4
-rw-r--r--app/views/shared/ssh_keys/_key_delete.html.haml7
-rw-r--r--app/views/shared/tokens/_scopes_form.html.haml2
-rw-r--r--app/views/shared/users/_user.html.haml2
-rw-r--r--app/views/shared/web_hooks/_form.html.haml4
-rw-r--r--app/views/shared/wikis/history.html.haml4
-rw-r--r--app/views/sherlock/queries/show.html.haml2
-rw-r--r--app/views/snippets/_snippets_scope_menu.html.haml8
-rw-r--r--app/views/snippets/edit.html.haml2
-rw-r--r--app/views/snippets/show.html.haml2
-rw-r--r--app/views/users/_overview.html.haml8
-rw-r--r--app/views/users/show.html.haml8
278 files changed, 1386 insertions, 1682 deletions
diff --git a/app/views/admin/appearances/_form.html.haml b/app/views/admin/appearances/_form.html.haml
index 1aaea1999e5..872a6bef18b 100644
--- a/app/views/admin/appearances/_form.html.haml
+++ b/app/views/admin/appearances/_form.html.haml
@@ -1,4 +1,4 @@
-- parsed_with_gfm = "Content parsed with #{link_to('GitLab Flavored Markdown', help_page_path('user/markdown'), target: '_blank')}.".html_safe
+- parsed_with_gfm = (_("Content parsed with %{link}.") % { link: link_to('GitLab Flavored Markdown', help_page_path('user/markdown'), target: '_blank') }).html_safe
= form_for @appearance, url: admin_appearances_path, html: { class: 'gl-mt-3' } do |f|
= form_errors(@appearance)
@@ -6,22 +6,22 @@
.row
.col-lg-4.profile-settings-sidebar
- %h4.gl-mt-0 Navigation bar
+ %h4.gl-mt-0= _('Navigation bar')
.col-lg-8
.form-group
- = f.label :header_logo, 'Header logo', class: 'col-form-label label-bold pt-0'
+ = f.label :header_logo, _('Header logo'), class: 'col-form-label label-bold pt-0'
%p
- if @appearance.header_logo?
= image_tag @appearance.header_logo_path, class: 'appearance-light-logo-preview'
- if @appearance.persisted?
%br
- = link_to 'Remove header logo', header_logos_admin_appearances_path, data: { confirm: "Header logo will be removed. Are you sure?"}, method: :delete, class: "btn gl-button btn-danger btn-danger-secondary btn-sm"
+ = link_to _('Remove header logo'), header_logos_admin_appearances_path, data: { confirm: _("Header logo will be removed. Are you sure?") }, method: :delete, class: "btn gl-button btn-danger btn-danger-secondary btn-sm"
%hr
= f.hidden_field :header_logo_cache
= f.file_field :header_logo, class: "", accept: 'image/*'
.hint
- Maximum file size is 1MB. Pages are optimized for a 28px tall header logo
+ = _('Maximum file size is 1MB. Pages are optimized for a 28px tall header logo')
%hr
.row
.col-lg-4.profile-settings-sidebar
@@ -29,27 +29,27 @@
.col-lg-8
.form-group
- = f.label :favicon, 'Favicon', class: 'col-form-label label-bold pt-0'
+ = f.label :favicon, _('Favicon'), class: 'col-form-label label-bold pt-0'
%p
- if @appearance.favicon?
= image_tag @appearance.favicon_path, class: 'appearance-light-logo-preview'
- if @appearance.persisted?
%br
- = link_to 'Remove favicon', favicon_admin_appearances_path, data: { confirm: "Favicon will be removed. Are you sure?"}, method: :delete, class: "btn gl-button btn-danger btn-danger-secondary btn-sm"
+ = link_to _('Remove favicon'), favicon_admin_appearances_path, data: { confirm: _("Favicon will be removed. Are you sure?") }, method: :delete, class: "btn gl-button btn-danger btn-danger-secondary btn-sm"
%hr
= f.hidden_field :favicon_cache
= f.file_field :favicon, class: '', accept: 'image/*'
.hint
- Maximum file size is 1MB. Image size must be 32x32px. Allowed image formats are #{favicon_extension_whitelist}.
+ = _("Maximum file size is 1MB. Image size must be 32x32px. Allowed image formats are %{favicon_extension_whitelist}.") % { favicon_extension_whitelist: favicon_extension_whitelist }
%br
- Images with incorrect dimensions are not resized automatically, and may result in unexpected behavior.
+ = _("Images with incorrect dimensions are not resized automatically, and may result in unexpected behavior.")
= render partial: 'admin/appearances/system_header_footer_form', locals: { form: f }
%hr
.row
.col-lg-4.profile-settings-sidebar
- %h4.gl-mt-0 Sign in/Sign up pages
+ %h4.gl-mt-0= _('Sign in/Sign up pages')
.col-lg-8
.form-group
@@ -67,17 +67,17 @@
= image_tag @appearance.logo_path, class: 'appearance-logo-preview'
- if @appearance.persisted?
%br
- = link_to 'Remove logo', logo_admin_appearances_path, data: { confirm: "Logo will be removed. Are you sure?"}, method: :delete, class: "btn gl-button btn-danger btn-danger-secondary btn-sm remove-logo"
+ = link_to _('Remove logo'), logo_admin_appearances_path, data: { confirm: _("Logo will be removed. Are you sure?") }, method: :delete, class: "btn gl-button btn-danger btn-danger-secondary btn-sm remove-logo"
%hr
= f.hidden_field :logo_cache
= f.file_field :logo, class: "", accept: 'image/*'
.hint
- Maximum file size is 1MB. Pages are optimized for a 640x360 px logo.
+ = _('Maximum file size is 1MB. Pages are optimized for a 640x360 px logo.')
%hr
.row
.col-lg-4.profile-settings-sidebar
- %h4.gl-mt-0 New project pages
+ %h4.gl-mt-0= _('New project pages')
.col-lg-8
.form-group
@@ -90,7 +90,7 @@
%hr
.row
.col-lg-4.profile-settings-sidebar
- %h4.gl-mt-0 Profile image guideline
+ %h4.gl-mt-0= _('Profile image guideline')
.col-lg-8
.form-group
@@ -101,13 +101,13 @@
= parsed_with_gfm
.gl-mt-3.gl-mb-3
- = f.submit 'Update appearance settings', class: 'btn gl-button btn-confirm'
+ = f.submit _('Update appearance settings'), class: 'btn gl-button btn-confirm'
- if @appearance.persisted? || @appearance.updated_at
.mt-4
- if @appearance.persisted?
Preview last save:
- = link_to 'Sign-in page', preview_sign_in_admin_appearances_path, class: 'btn', target: '_blank', rel: 'noopener noreferrer'
- = link_to 'New project page', new_project_path, class: 'btn', target: '_blank', rel: 'noopener noreferrer'
+ = link_to _('Sign-in page'), preview_sign_in_admin_appearances_path, class: 'btn', target: '_blank', rel: 'noopener noreferrer'
+ = link_to _('New project page'), new_project_path, class: 'btn', target: '_blank', rel: 'noopener noreferrer'
- if @appearance.updated_at
%span.float-right
diff --git a/app/views/admin/appearances/preview_sign_in.html.haml b/app/views/admin/appearances/preview_sign_in.html.haml
index f972b3b5cbf..a317611862c 100644
--- a/app/views/admin/appearances/preview_sign_in.html.haml
+++ b/app/views/admin/appearances/preview_sign_in.html.haml
@@ -1,12 +1,12 @@
-= render 'devise/shared/tab_single', tab_title: 'Sign in preview'
+= render 'devise/shared/tab_single', tab_title: _('Sign in preview')
.login-box
%form.gl-show-field-errors
.form-group
= label_tag :login
- = text_field_tag :login, nil, class: "form-control gl-form-input top", title: 'Please provide your username or email address.'
+ = text_field_tag :login, nil, class: "form-control gl-form-input top", title: _('Please provide your username or email address.')
.form-group
= label_tag :password
- = password_field_tag :password, nil, class: "form-control gl-form-input bottom", title: 'This field is required.'
+ = password_field_tag :password, nil, class: "form-control gl-form-input bottom", title: _('This field is required.')
.form-group
- = button_tag "Sign in", class: "btn gl-button btn-confirm"
+ = button_tag _("Sign in"), class: "btn gl-button btn-confirm"
diff --git a/app/views/admin/application_settings/_abuse.html.haml b/app/views/admin/application_settings/_abuse.html.haml
index f050c0816b1..fab3ce584f0 100644
--- a/app/views/admin/application_settings/_abuse.html.haml
+++ b/app/views/admin/application_settings/_abuse.html.haml
@@ -3,9 +3,9 @@
%fieldset
.form-group
- = f.label :abuse_notification_email, 'Abuse reports notification email', class: 'label-bold'
+ = f.label :abuse_notification_email, _('Abuse reports notification email'), class: 'label-bold'
= f.text_field :abuse_notification_email, class: 'form-control gl-form-input'
.form-text.text-muted
- Abuse reports will be sent to this address if it is set. Abuse reports are always available in the admin area.
+ = _('Abuse reports will be sent to this address if it is set. Abuse reports are always available in the admin area.')
- = f.submit 'Save changes', class: "gl-button btn btn-confirm"
+ = f.submit _('Save changes'), class: "gl-button btn btn-confirm"
diff --git a/app/views/admin/application_settings/_floc.html.haml b/app/views/admin/application_settings/_floc.html.haml
new file mode 100644
index 00000000000..398064f9730
--- /dev/null
+++ b/app/views/admin/application_settings/_floc.html.haml
@@ -0,0 +1,22 @@
+- expanded = integration_expanded?('floc_')
+
+%section.settings.no-animate#js-floc-settings{ class: ('expanded' if expanded) }
+ .settings-header
+ %h4
+ = s_('FloC|Federated Learning of Cohorts')
+ %button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' }
+ = expanded ? _('Collapse') : _('Expand')
+ %p
+ = s_('FloC|Configure whether you want to participate in FloC.').html_safe
+ = link_to sprite_icon('question-o'), 'https://github.com/WICG/floc', target: '_blank', class: 'has-tooltip', title: _('More information')
+
+ .settings-content
+ = form_for @application_setting, url: general_admin_application_settings_path(anchor: 'js-floc-settings'), html: { class: 'fieldset-form', id: 'floc-settings' } do |f|
+ = form_errors(@application_setting)
+
+ %fieldset
+ .form-group
+ .form-check
+ = f.check_box :floc_enabled, class: 'form-check-input'
+ = f.label :floc_enabled, s_('FloC|Enable FloC (Federated Learning of Cohorts)'), class: 'form-check-label'
+ = f.submit s_('Save changes'), class: 'gl-button btn btn-confirm'
diff --git a/app/views/admin/application_settings/_gitaly.html.haml b/app/views/admin/application_settings/_gitaly.html.haml
index 72e7cb0b437..b28a53d8bf6 100644
--- a/app/views/admin/application_settings/_gitaly.html.haml
+++ b/app/views/admin/application_settings/_gitaly.html.haml
@@ -3,7 +3,7 @@
%fieldset
.form-group
- = f.label :gitaly_timeout_default, 'Default Timeout Period', class: 'label-bold'
+ = f.label :gitaly_timeout_default, _('Default Timeout Period'), class: 'label-bold'
= f.number_field :gitaly_timeout_default, class: 'form-control gl-form-input'
.form-text.text-muted
Timeout for Gitaly calls from the GitLab application (in seconds). This timeout is not enforced
@@ -12,16 +12,16 @@
worker timeout, the remaining time from the worker timeout would be used to avoid having to terminate
the worker.
.form-group
- = f.label :gitaly_timeout_fast, 'Fast Timeout Period', class: 'label-bold'
+ = f.label :gitaly_timeout_fast, _('Fast Timeout Period'), class: 'label-bold'
= f.number_field :gitaly_timeout_fast, class: 'form-control gl-form-input'
.form-text.text-muted
Fast operation timeout (in seconds). Some Gitaly operations are expected to be fast.
If they exceed this threshold, there may be a problem with a storage shard and 'failing fast'
can help maintain the stability of the GitLab instance.
.form-group
- = f.label :gitaly_timeout_medium, 'Medium Timeout Period', class: 'label-bold'
+ = f.label :gitaly_timeout_medium, _('Medium Timeout Period'), class: 'label-bold'
= f.number_field :gitaly_timeout_medium, class: 'form-control gl-form-input'
.form-text.text-muted
Medium operation timeout (in seconds). This should be a value between the Fast and the Default timeout.
- = f.submit 'Save changes', class: "gl-button btn btn-confirm"
+ = f.submit _('Save changes'), class: "gl-button btn btn-confirm"
diff --git a/app/views/admin/application_settings/_initial_branch_name.html.haml b/app/views/admin/application_settings/_initial_branch_name.html.haml
index b5c178641df..f881808e51f 100644
--- a/app/views/admin/application_settings/_initial_branch_name.html.haml
+++ b/app/views/admin/application_settings/_initial_branch_name.html.haml
@@ -1,12 +1,12 @@
= form_for @application_setting, url: general_admin_application_settings_path(anchor: 'js-default-branch-name'), html: { class: 'fieldset-form' } do |f|
= form_errors(@application_setting)
- - fallback_branch_name = '<code>master</code>'
+ - fallback_branch_name = "<code>#{Gitlab::DefaultBranch.value}</code>"
%fieldset
.form-group
= f.label :default_branch_name, _('Default initial branch name'), class: 'label-light'
- = f.text_field :default_branch_name, placeholder: 'master', class: 'form-control gl-form-input'
+ = f.text_field :default_branch_name, placeholder: Gitlab::DefaultBranch.value, class: 'form-control gl-form-input'
%span.form-text.text-muted
= (_("Changes affect new repositories only. If not specified, Git's default name %{branch_name_default} will be used.") % { branch_name_default: fallback_branch_name } ).html_safe
diff --git a/app/views/admin/application_settings/_package_registry.html.haml b/app/views/admin/application_settings/_package_registry.html.haml
index 0ca8493c596..8de65f267d2 100644
--- a/app/views/admin/application_settings/_package_registry.html.haml
+++ b/app/views/admin/application_settings/_package_registry.html.haml
@@ -45,6 +45,9 @@
= f.label :pypi_max_file_size, _('Maximum PyPI package file size in bytes'), class: 'label-bold'
= f.number_field :pypi_max_file_size, class: 'form-control gl-form-input'
.form-group
+ = f.label :terraform_module_max_file_size, _('Maximum Terraform Module package file size in bytes'), class: 'label-bold'
+ = f.number_field :terraform_module_max_file_size, class: 'form-control gl-form-input'
+ .form-group
= f.label :generic_packages_max_file_size, _('Generic package file size in bytes'), class: 'label-bold'
= f.number_field :generic_packages_max_file_size, class: 'form-control gl-form-input'
= f.submit _('Save %{name} size limits').html_safe % { name: plan.name.capitalize }, class: 'btn gl-button btn-confirm'
diff --git a/app/views/admin/application_settings/_package_registry_limits.html.haml b/app/views/admin/application_settings/_package_registry_limits.html.haml
new file mode 100644
index 00000000000..b1dfd04c55e
--- /dev/null
+++ b/app/views/admin/application_settings/_package_registry_limits.html.haml
@@ -0,0 +1,37 @@
+= form_for @application_setting, url: network_admin_application_settings_path(anchor: 'js-packages-limits-settings'), html: { class: 'fieldset-form' } do |f|
+ = form_errors(@application_setting)
+
+ %fieldset
+ %h5
+ = _('Unauthenticated API request rate limit')
+ .form-group
+ .form-check
+ = f.check_box :throttle_unauthenticated_packages_api_enabled, class: 'form-check-input', data: { qa_selector: 'throttle_unauthenticated_packages_api_checkbox' }
+ = f.label :throttle_unauthenticated_packages_api_enabled, class: 'form-check-label label-bold' do
+ = _('Enable unauthenticated API request rate limit')
+ %span.form-text.text-muted
+ = _('Helps reduce request volume (e.g. from crawlers or abusive bots)')
+ .form-group
+ = f.label :throttle_unauthenticated_packages_api_requests_per_period, 'Max unauthenticated API requests per period per IP', class: 'label-bold'
+ = f.number_field :throttle_unauthenticated_packages_api_requests_per_period, class: 'form-control gl-form-input'
+ .form-group
+ = f.label :throttle_unauthenticated_packages_api_period_in_seconds, 'Unauthenticated API rate limit period in seconds', class: 'label-bold'
+ = f.number_field :throttle_unauthenticated_packages_api_period_in_seconds, class: 'form-control gl-form-input'
+ %hr
+ %h5
+ = _('Authenticated API request rate limit')
+ .form-group
+ .form-check
+ = f.check_box :throttle_authenticated_packages_api_enabled, class: 'form-check-input', data: { qa_selector: 'throttle_authenticated_packages_api_checkbox' }
+ = f.label :throttle_authenticated_packages_api_enabled, class: 'form-check-label label-bold' do
+ = _('Enable authenticated API request rate limit')
+ %span.form-text.text-muted
+ = _('Helps reduce request volume (e.g. from crawlers or abusive bots)')
+ .form-group
+ = f.label :throttle_authenticated_packages_api_requests_per_period, 'Max authenticated API requests per period per user', class: 'label-bold'
+ = f.number_field :throttle_authenticated_packages_api_requests_per_period, class: 'form-control gl-form-input'
+ .form-group
+ = f.label :throttle_authenticated_packages_api_period_in_seconds, 'Authenticated API rate limit period in seconds', class: 'label-bold'
+ = f.number_field :throttle_authenticated_packages_api_period_in_seconds, class: 'form-control gl-form-input'
+
+ = f.submit 'Save changes', class: "gl-button btn btn-confirm", data: { qa_selector: 'save_changes_button' }
diff --git a/app/views/admin/application_settings/_plantuml.html.haml b/app/views/admin/application_settings/_plantuml.html.haml
index d57ae94b084..632aeec6ce3 100644
--- a/app/views/admin/application_settings/_plantuml.html.haml
+++ b/app/views/admin/application_settings/_plantuml.html.haml
@@ -17,7 +17,7 @@
= f.check_box :plantuml_enabled, class: 'form-check-input'
= f.label :plantuml_enabled, _('Enable PlantUML'), class: 'form-check-label'
.form-group
- = f.label :plantuml_url, 'PlantUML URL', class: 'label-bold'
+ = f.label :plantuml_url, _('PlantUML URL'), class: 'label-bold'
= f.text_field :plantuml_url, class: 'form-control gl-form-input', placeholder: 'http://your-plantuml-instance:8080'
.form-text.text-muted
Allow rendering of
diff --git a/app/views/admin/application_settings/_prometheus.html.haml b/app/views/admin/application_settings/_prometheus.html.haml
index 468c1786d6f..f102b3d580b 100644
--- a/app/views/admin/application_settings/_prometheus.html.haml
+++ b/app/views/admin/application_settings/_prometheus.html.haml
@@ -3,31 +3,25 @@
%fieldset
%p
- Enable a Prometheus metrics endpoint at
- %code= metrics_path
- to expose a variety of statistics on the health and performance of GitLab. Additional information on authenticating and connecting to the metrics endpoint is available
- = link_to 'here', admin_health_check_path
- \. This setting requires a
- = link_to 'restart', help_page_path('administration/restart_gitlab')
- to take effect.
+ - link_to_restart = link_to(_('restart'), help_page_path('administration/restart_gitlab'))
+ = _('Enable a Prometheus metrics endpoint at %{metrics_path} to expose a variety of statistics on the health and performance of GitLab. Additional information on authenticating and connecting to the metrics endpoint is available %{link}.').html_safe % { metrics_path: "<code>#{metrics_path}</code>".html_safe, link: link_to(_('here'), admin_health_check_path) }
+ = _('This setting requires a %{link_to_restart} to take effect.').html_safe % { link_to_restart: link_to_restart }
= link_to sprite_icon('question-o'), help_page_path('administration/monitoring/prometheus/index')
.form-group
.form-check
= f.check_box :prometheus_metrics_enabled, class: 'form-check-input'
= f.label :prometheus_metrics_enabled, class: 'form-check-label' do
- Enable Prometheus Metrics
+ = _("Enable Prometheus Metrics")
- unless Gitlab::Metrics.metrics_folder_present?
.form-text.text-muted
- %strong.cred WARNING:
- Environment variable
- %code prometheus_multiproc_dir
- does not exist or is not pointing to a valid directory.
+ %strong.cred= _("WARNING:")
+ = _("Environment variable %{code_start}%{environment_variable}%{code_end} does not exist or is not pointing to a valid directory.").html_safe % { environment_variable: prometheus_multiproc_dir, code_start: '<code>'.html_safe, code_end: '</code>'.html_safe }
= link_to sprite_icon('question-o'), help_page_path('administration/monitoring/prometheus/gitlab_metrics', anchor: 'metrics-shared-directory')
.form-group
- = f.label :metrics_method_call_threshold, 'Method Call Threshold (ms)', class: 'label-bold'
+ = f.label :metrics_method_call_threshold, _('Method Call Threshold (ms)'), class: 'label-bold'
= f.number_field :metrics_method_call_threshold, class: 'form-control gl-form-input'
.form-text.text-muted
A method call is only tracked when it takes longer to complete than
the given amount of milliseconds.
- = f.submit 'Save changes', class: "gl-button btn btn-confirm"
+ = f.submit _('Save changes'), class: "gl-button btn btn-confirm"
diff --git a/app/views/admin/application_settings/_repository_check.html.haml b/app/views/admin/application_settings/_repository_check.html.haml
index edf6853a1aa..31576d54a04 100644
--- a/app/views/admin/application_settings/_repository_check.html.haml
+++ b/app/views/admin/application_settings/_repository_check.html.haml
@@ -17,7 +17,7 @@
= _("If you got a lot of false alarms from repository checks you can choose to clear all repository check information from the database.")
- clear_repository_checks_link = _('Clear all repository checks')
- clear_repository_checks_message = _('This will clear repository check states for ALL projects in the database. This cannot be undone. Are you sure?')
- = link_to clear_repository_checks_link, clear_repository_check_states_admin_application_settings_path, data: { confirm: clear_repository_checks_message }, method: :put, class: "gl-button btn btn-sm btn-danger"
+ = link_to clear_repository_checks_link, clear_repository_check_states_admin_application_settings_path, data: { confirm: clear_repository_checks_message }, method: :put, class: "gl-button btn btn-sm btn-danger gl-mt-3"
.sub-section
%h4= _("Housekeeping")
diff --git a/app/views/admin/application_settings/_signin.html.haml b/app/views/admin/application_settings/_signin.html.haml
index 62d6c973efe..12a9f949750 100644
--- a/app/views/admin/application_settings/_signin.html.haml
+++ b/app/views/admin/application_settings/_signin.html.haml
@@ -6,14 +6,14 @@
.form-check
= f.check_box :password_authentication_enabled_for_web, class: 'form-check-input'
= f.label :password_authentication_enabled_for_web, class: 'form-check-label' do
- Password authentication enabled for web interface
+ = _('Password authentication enabled for web interface')
.form-text.text-muted
- When disabled, an external authentication provider must be used.
+ = _('When disabled, an external authentication provider must be used.')
.form-group
.form-check
= f.check_box :password_authentication_enabled_for_git, class: 'form-check-input'
= f.label :password_authentication_enabled_for_git, class: 'form-check-label' do
- Password authentication enabled for Git over HTTP(S)
+ = _('Password authentication enabled for Git over HTTP(S)')
.form-text.text-muted
When disabled, a Personal Access Token
- if Gitlab::Auth::Ldap::Config.enabled?
@@ -26,11 +26,11 @@
- oauth_providers_checkboxes.each do |source|
= source
.form-group
- = f.label :two_factor_authentication, 'Two-factor authentication', class: 'label-bold'
+ = f.label :two_factor_authentication, _('Two-factor authentication'), class: 'label-bold'
.form-check
= f.check_box :require_two_factor_authentication, class: 'form-check-input'
= f.label :require_two_factor_authentication, class: 'form-check-label' do
- Require all users to set up Two-factor authentication
+ = _('Require all users to set up two-factor authentication')
.form-group
= f.label :admin_mode, _('Admin Mode'), class: 'label-bold'
= sprite_icon('lock', css_class: 'gl-icon')
@@ -50,19 +50,19 @@
'https://docs.gitlab.com/ee/user/profile/unknown_sign_in_notification.html',
target: '_blank'
.form-group
- = f.label :two_factor_authentication, 'Two-factor grace period (hours)', class: 'label-bold'
+ = f.label :two_factor_authentication, _('Two-factor grace period (hours)'), class: 'label-bold'
= f.number_field :two_factor_grace_period, min: 0, class: 'form-control gl-form-input', placeholder: '0'
- .form-text.text-muted Amount of time (in hours) that users are allowed to skip forced configuration of two-factor authentication
+ .form-text.text-muted= _('Amount of time (in hours) that users are allowed to skip forced configuration of two-factor authentication')
.form-group
- = f.label :home_page_url, 'Home page URL', class: 'label-bold'
+ = f.label :home_page_url, _('Home page URL'), class: 'label-bold'
= f.text_field :home_page_url, class: 'form-control gl-form-input', placeholder: 'http://company.example.com', :'aria-describedby' => 'home_help_block'
- %span.form-text.text-muted#home_help_block We will redirect non-logged in users to this page
+ %span.form-text.text-muted#home_help_block= _("We will redirect non-logged in users to this page")
.form-group
= f.label :after_sign_out_path, _('After sign-out path'), class: 'label-bold'
= f.text_field :after_sign_out_path, class: 'form-control gl-form-input', placeholder: 'http://company.example.com', :'aria-describedby' => 'after_sign_out_path_help_block'
- %span.form-text.text-muted#after_sign_out_path_help_block We will redirect users to this page after they sign out
+ %span.form-text.text-muted#after_sign_out_path_help_block= _("We will redirect users to this page after they sign out")
.form-group
= f.label :sign_in_text, _('Sign-in text'), class: 'label-bold'
= f.text_area :sign_in_text, class: 'form-control gl-form-input', rows: 4
.form-text.text-muted Markdown enabled
- = f.submit 'Save changes', class: "gl-button btn btn-confirm"
+ = f.submit _('Save changes'), class: "gl-button btn btn-confirm"
diff --git a/app/views/admin/application_settings/_spam.html.haml b/app/views/admin/application_settings/_spam.html.haml
index 2086fbc9d32..011bce3ca99 100644
--- a/app/views/admin/application_settings/_spam.html.haml
+++ b/app/views/admin/application_settings/_spam.html.haml
@@ -6,25 +6,25 @@
.form-check
= f.check_box :recaptcha_enabled, class: 'form-check-input'
= f.label :recaptcha_enabled, class: 'form-check-label' do
- Enable reCAPTCHA
+ = _("Enable reCAPTCHA")
%span.form-text.text-muted#recaptcha_help_block
= _('Helps prevent bots from creating accounts.')
.form-group
.form-check
= f.check_box :login_recaptcha_protection_enabled, class: 'form-check-input'
= f.label :login_recaptcha_protection_enabled, class: 'form-check-label' do
- Enable reCAPTCHA for login
+ = _("Enable reCAPTCHA for login")
%span.form-text.text-muted#recaptcha_help_block
= _('Helps prevent bots from brute-force attacks.')
.form-group
- = f.label :recaptcha_site_key, 'reCAPTCHA Site Key', class: 'label-bold'
+ = f.label :recaptcha_site_key, _('reCAPTCHA Site Key'), class: 'label-bold'
= f.text_field :recaptcha_site_key, class: 'form-control gl-form-input'
.form-text.text-muted
- Generate site and private keys at
+ = _("Generate site and private keys at")
%a{ href: 'http://www.google.com/recaptcha', target: 'blank' } http://www.google.com/recaptcha
.form-group
- = f.label :recaptcha_private_key, 'reCAPTCHA Private Key', class: 'label-bold'
+ = f.label :recaptcha_private_key, _('reCAPTCHA Private Key'), class: 'label-bold'
.form-group
= f.text_field :recaptcha_private_key, class: 'form-control gl-form-input'
@@ -41,10 +41,10 @@
= f.check_box :akismet_enabled, class: 'form-check-input'
= f.label :akismet_enabled, class: 'form-check-label' do
Enable Akismet
- %span.form-text.text-muted#akismet_help_block Helps prevent bots from creating issues
+ %span.form-text.text-muted#akismet_help_block= _("Helps prevent bots from creating issues")
.form-group
- = f.label :akismet_api_key, 'Akismet API Key', class: 'label-bold'
+ = f.label :akismet_api_key, _('Akismet API Key'), class: 'label-bold'
= f.text_field :akismet_api_key, class: 'form-control gl-form-input'
.form-text.text-muted
Generate API key at
@@ -54,21 +54,21 @@
.form-check
= f.check_box :unique_ips_limit_enabled, class: 'form-check-input'
= f.label :unique_ips_limit_enabled, class: 'form-check-label' do
- Limit sign in from multiple ips
+ = _("Limit sign in from multiple ips")
%span.form-text.text-muted#unique_ip_help_block
- Helps prevent malicious users hide their activity
+ = _("Helps prevent malicious users hide their activity")
.form-group
- = f.label :unique_ips_limit_per_user, 'IPs per user', class: 'label-bold'
+ = f.label :unique_ips_limit_per_user, _('IPs per user'), class: 'label-bold'
= f.number_field :unique_ips_limit_per_user, class: 'form-control gl-form-input'
.form-text.text-muted
- Maximum number of unique IPs per user
+ = _("Maximum number of unique IPs per user")
.form-group
- = f.label :unique_ips_limit_time_window, 'IP expiration time', class: 'label-bold'
+ = f.label :unique_ips_limit_time_window, _('IP expiration time'), class: 'label-bold'
= f.number_field :unique_ips_limit_time_window, class: 'form-control gl-form-input'
.form-text.text-muted
- How many seconds an IP will be counted towards the limit
+ = _("How many seconds an IP will be counted towards the limit")
.form-group
.form-check
@@ -78,5 +78,9 @@
.form-group
= f.label :spam_check_endpoint_url, _('URL of the external Spam Check endpoint'), class: 'label-bold'
= f.text_field :spam_check_endpoint_url, class: 'form-control gl-form-input'
+ .form-group
+ = f.label :spam_check_api_key, _('Spam Check API Key'), class: 'gl-font-weight-bold'
+ = f.text_field :spam_check_api_key, class: 'form-control gl-form-input'
+ .form-text.text-muted= _('The API key used by GitLab for accessing the Spam Check service endpoint')
- = f.submit 'Save changes', class: "gl-button btn btn-confirm"
+ = f.submit _('Save changes'), class: "gl-button btn btn-confirm"
diff --git a/app/views/admin/application_settings/_terminal.html.haml b/app/views/admin/application_settings/_terminal.html.haml
index 482466c4b3b..d6e31a24cf6 100644
--- a/app/views/admin/application_settings/_terminal.html.haml
+++ b/app/views/admin/application_settings/_terminal.html.haml
@@ -3,9 +3,8 @@
%fieldset
.form-group
- = f.label :terminal_max_session_time, 'Max session time', class: 'label-bold'
+ = f.label :terminal_max_session_time, _('Max session time'), class: 'label-bold'
= f.number_field :terminal_max_session_time, class: 'form-control gl-form-input'
.form-text.text-muted
- Maximum time for web terminal websocket connection (in seconds).
- 0 for unlimited.
- = f.submit 'Save changes', class: "gl-button btn btn-confirm"
+ = _('Maximum time for web terminal websocket connection (in seconds). 0 for unlimited.')
+ = f.submit _('Save changes'), class: "gl-button btn btn-confirm"
diff --git a/app/views/admin/application_settings/_usage.html.haml b/app/views/admin/application_settings/_usage.html.haml
index a2d61bd010f..64e8751bf31 100644
--- a/app/views/admin/application_settings/_usage.html.haml
+++ b/app/views/admin/application_settings/_usage.html.haml
@@ -8,11 +8,10 @@
.form-check
= f.check_box :version_check_enabled, class: 'form-check-input'
= f.label :version_check_enabled, class: 'form-check-label' do
- Enable version check
+ = _("Enable version check")
.form-text.text-muted
- GitLab will inform you if a new version is available.
- = link_to 'Learn more', help_page_path('user/admin_area/settings/usage_statistics', anchor: 'version-check')
- about what information is shared with GitLab Inc.
+ = _("GitLab will inform you if a new version is available.")
+ = _("%{link_start}Learn more%{link_end} about what information is shared with GitLab Inc.").html_safe % { link_start: "<a href='#{help_page_path("user/admin_area/settings/usage_statistics", anchor: "version-check")}'>".html_safe, link_end: '</a>'.html_safe }
.form-group
- can_be_configured = @application_setting.usage_ping_can_be_configured?
.form-check
@@ -28,7 +27,7 @@
%p.mb-2= s_('%{usage_ping_link_start}Learn more%{usage_ping_link_end} about what information is shared with GitLab Inc.').html_safe % { usage_ping_link_start: usage_ping_link_start, usage_ping_link_end: '</a>'.html_safe }
%button.gl-button.btn.btn-default.js-payload-preview-trigger{ type: 'button', data: { payload_selector: ".#{payload_class}" } }
- .spinner.js-spinner.d-none
+ .gl-spinner.js-spinner.gl-display-none.gl-mr-2
.js-text.d-inline= _('Preview payload')
%pre.usage-data.js-syntax-highlight.code.highlight.mt-2.d-none{ class: payload_class, data: { endpoint: usage_data_admin_application_settings_path(format: :html) } }
- else
@@ -37,4 +36,4 @@
- deactivating_usage_ping_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: deactivating_usage_ping_path }
= s_('For more information, see the documentation on %{deactivating_usage_ping_link_start}deactivating the usage ping%{deactivating_usage_ping_link_end}.').html_safe % { deactivating_usage_ping_link_start: deactivating_usage_ping_link_start, deactivating_usage_ping_link_end: '</a>'.html_safe }
- = f.submit 'Save changes', class: "gl-button btn btn-confirm"
+ = f.submit _('Save changes'), class: "gl-button btn btn-confirm"
diff --git a/app/views/admin/application_settings/_whats_new.html.haml b/app/views/admin/application_settings/_whats_new.html.haml
new file mode 100644
index 00000000000..70ba994d21e
--- /dev/null
+++ b/app/views/admin/application_settings/_whats_new.html.haml
@@ -0,0 +1,13 @@
+= form_for @application_setting, url: preferences_admin_application_settings_path(anchor: 'js-whats-new-settings'), html: { class: 'fieldset-form whats-new-settings' } do |f|
+ = form_errors(@application_setting)
+
+ - whats_new_variants.keys.each do |variant|
+ .form-check.gl-mb-4
+ = f.radio_button :whats_new_variant, variant, class: 'form-check-input'
+ = f.label :whats_new_variant, value: variant, class: 'form-check-label' do
+ .font-weight-bold
+ = whats_new_variants_label(variant)
+ .option-description
+ = whats_new_variants_description(variant)
+
+ = f.submit _('Save changes'), class: "gl-button btn btn-confirm"
diff --git a/app/views/admin/application_settings/general.html.haml b/app/views/admin/application_settings/general.html.haml
index 86226a9de2f..217225e6186 100644
--- a/app/views/admin/application_settings/general.html.haml
+++ b/app/views/admin/application_settings/general.html.haml
@@ -112,3 +112,4 @@
= render 'admin/application_settings/third_party_offers'
= render 'admin/application_settings/snowplow'
= render 'admin/application_settings/eks'
+= render 'admin/application_settings/floc'
diff --git a/app/views/admin/application_settings/network.html.haml b/app/views/admin/application_settings/network.html.haml
index 72716e76013..72a27e4523f 100644
--- a/app/views/admin/application_settings/network.html.haml
+++ b/app/views/admin/application_settings/network.html.haml
@@ -24,6 +24,17 @@
.settings-content
= render 'ip_limits'
+%section.settings.as-packages-limits.no-animate#js-packages-limits-settings{ class: ('expanded' if expanded_by_default?), data: { qa_selector: 'packages_limits_content' } }
+ .settings-header
+ %h4
+ = _('Package Registry Rate Limits')
+ %button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' }
+ = expanded_by_default? ? _('Collapse') : _('Expand')
+ %p
+ = _('Configure specific limits for Packages API requests that supersede the general user and IP rate limits.')
+ .settings-content
+ = render 'package_registry_limits'
+
%section.settings.as-outbound.no-animate#js-outbound-settings{ class: ('expanded' if expanded_by_default?), data: { qa_selector: 'outbound_requests_content' } }
.settings-header
%h4
diff --git a/app/views/admin/application_settings/preferences.html.haml b/app/views/admin/application_settings/preferences.html.haml
index fd5ce890648..17bf9ba84a2 100644
--- a/app/views/admin/application_settings/preferences.html.haml
+++ b/app/views/admin/application_settings/preferences.html.haml
@@ -13,6 +13,17 @@
.settings-content
= render 'email'
+%section.settings.as-whats-new-page.no-animate#js-whats-new-settings{ class: ('expanded' if expanded_by_default?) }
+ .settings-header
+ %h4
+ = _("What's new")
+ %button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' }
+ = expanded_by_default? ? _('Collapse') : _('Expand')
+ %p
+ = _("Configure What's new drawer and content.")
+ .settings-content
+ = render 'whats_new'
+
%section.settings.as-help-page.no-animate#js-help-settings{ class: ('expanded' if expanded_by_default?) }
.settings-header
%h4
diff --git a/app/views/admin/application_settings/repository.html.haml b/app/views/admin/application_settings/repository.html.haml
index 4365d8937bd..111cc9c5d7c 100644
--- a/app/views/admin/application_settings/repository.html.haml
+++ b/app/views/admin/application_settings/repository.html.haml
@@ -2,17 +2,16 @@
- page_title _("Repository")
- @content_class = "limit-container-width" unless fluid_layout
-- if Feature.enabled?(:global_default_branch_name, default_enabled: true)
- %section.settings.as-default-branch-name.no-animate#js-default-branch-name{ class: ('expanded' if expanded_by_default?) }
- .settings-header
- %h4
- = _('Default initial branch name')
- %button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' }
- = expanded_by_default? ? _('Collapse') : _('Expand')
- %p
- = _('Set the default name of the initial branch when creating new repositories through the user interface.')
- .settings-content
- = render 'initial_branch_name'
+%section.settings.as-default-branch-name.no-animate#js-default-branch-name{ class: ('expanded' if expanded_by_default?) }
+ .settings-header
+ %h4
+ = _('Default initial branch name')
+ %button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' }
+ = expanded_by_default? ? _('Collapse') : _('Expand')
+ %p
+ = _('Set the default name of the initial branch when creating new repositories through the user interface.')
+ .settings-content
+ = render 'initial_branch_name'
%section.settings.as-mirror.no-animate#js-mirror-settings{ class: ('expanded' if expanded_by_default?) }
.settings-header
diff --git a/app/views/admin/background_jobs/show.html.haml b/app/views/admin/background_jobs/show.html.haml
index 9ba72caa88e..bab9fa02928 100644
--- a/app/views/admin/background_jobs/show.html.haml
+++ b/app/views/admin/background_jobs/show.html.haml
@@ -1,7 +1,10 @@
- page_title _("Background Jobs")
-%h3.page-title Background Jobs
-%p.light GitLab uses #{link_to "sidekiq", "http://sidekiq.org/"} library for async job processing
+%h3.page-title= _('Background Jobs')
+%p.light
+ - sidekiq_link_url = 'http://sidekiq.org/'
+ - sidekiq_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: sidekiq_link_url }
+ = html_escape(_('GitLab uses %{linkStart}Sidekiq%{linkEnd} to process background jobs')) % { linkStart: sidekiq_link_start, linkEnd: '</a>'.html_safe }
%hr
.card.gl-rounded-0
diff --git a/app/views/admin/broadcast_messages/_form.html.haml b/app/views/admin/broadcast_messages/_form.html.haml
index 9a4bb9b0a48..fe5759ecdbf 100644
--- a/app/views/admin/broadcast_messages/_form.html.haml
+++ b/app/views/admin/broadcast_messages/_form.html.haml
@@ -4,7 +4,7 @@
- if @broadcast_message.message.present?
= render_broadcast_message(@broadcast_message)
- else
- Your message here
+ = _('Your message here')
.d-flex.justify-content-center
.broadcast-message.broadcast-notification-message.preview.js-broadcast-notification-message-preview.mt-2{ class: ('hidden' unless @broadcast_message.notification? ) }
= sprite_icon('bullhorn', css_class: 'vertical-align-text-top')
@@ -12,7 +12,7 @@
- if @broadcast_message.message.present?
= render_broadcast_message(@broadcast_message)
- else
- Your message here
+ = _('Your message here')
= form_for [:admin, @broadcast_message], html: { class: 'broadcast-message-form js-quick-submit js-requires-input'} do |f|
= form_errors(@broadcast_message)
@@ -55,7 +55,7 @@
= _('Allow users to dismiss the broadcast message')
.form-group.row.js-toggle-colors-container.toggle-colors.hide
.col-sm-2.col-form-label
- = f.label :font, "Font Color"
+ = f.label :font, _("Font Color")
.col-sm-10
= f.color_field :font, class: "form-control gl-form-input text-font-color"
.form-group.row
@@ -77,6 +77,6 @@
= f.datetime_select :ends_at, {}, class: 'form-control form-control-inline'
.form-actions
- if @broadcast_message.persisted?
- = f.submit "Update broadcast message", class: "btn gl-button btn-confirm"
+ = f.submit _("Update broadcast message"), class: "btn gl-button btn-confirm"
- else
- = f.submit "Add broadcast message", class: "btn gl-button btn-confirm"
+ = f.submit _("Add broadcast message"), class: "btn gl-button btn-confirm"
diff --git a/app/views/admin/dashboard/index.html.haml b/app/views/admin/dashboard/index.html.haml
index e34808665bb..2dbb804d537 100644
--- a/app/views/admin/dashboard/index.html.haml
+++ b/app/views/admin/dashboard/index.html.haml
@@ -44,7 +44,7 @@
trigger: "focus",
content: s_("AdminArea|All users created in the instance, including users who are not %{billable_users_link_start}billable users%{billable_users_link_end}.").html_safe % { billable_users_link_start: billable_users_link_start, billable_users_link_end: '</a>'.html_safe },
} }
- = sprite_icon('question', size: 16, css_class: 'gl-text-gray-700')
+ = sprite_icon('question-o', size: 16, css_class: 'gl-text-blue-600')
.gl-mt-3.text-uppercase
= s_('AdminArea|Users')
= link_to(s_('AdminArea|Users statistics'), admin_dashboard_stats_path, class: "text-capitalize gl-ml-2")
diff --git a/app/views/admin/deploy_keys/new.html.haml b/app/views/admin/deploy_keys/new.html.haml
index 0eaf7b60b25..b0b12a01aed 100644
--- a/app/views/admin/deploy_keys/new.html.haml
+++ b/app/views/admin/deploy_keys/new.html.haml
@@ -6,5 +6,5 @@
= form_for [:admin, @deploy_key], html: { class: 'deploy-key-form' } do |f|
= render partial: 'shared/deploy_keys/form', locals: { form: f, deploy_key: @deploy_key }
.form-actions
- = f.submit 'Create', class: 'btn gl-button btn-confirm'
+ = f.submit 'Create', class: 'btn gl-button btn-confirm', data: { qa_selector: "add_deploy_key_button" }
= link_to 'Cancel', admin_deploy_keys_path, class: 'btn gl-button btn-default btn-cancel'
diff --git a/app/views/admin/dev_ops_report/_card.html.haml b/app/views/admin/dev_ops_report/_card.html.haml
deleted file mode 100644
index dd6e5c0f108..00000000000
--- a/app/views/admin/dev_ops_report/_card.html.haml
+++ /dev/null
@@ -1,25 +0,0 @@
-.devops-card-wrapper
- .devops-card{ class: "devops-card-#{score_level(card.percentage_score)}" }
- .devops-card-title
- %h3
- = card.title
- .light-text
- = card.description
- .board-card-scores
- .board-card-score
- .board-card-score-value
- = format_score(card.instance_score)
- .board-card-score-name= _('You')
- .board-card-score
- .board-card-score-value
- = format_score(card.leader_score)
- .board-card-score-name= _('Lead')
- .board-card-score-big
- = number_to_percentage(card.percentage_score, precision: 1)
- .board-card-buttons
- - if card.blog
- %a.btn-svg{ href: card.blog }
- = sprite_icon('information-o')
- - if card.docs
- %a.btn-svg{ href: card.docs }
- = sprite_icon('question-o')
diff --git a/app/views/admin/dev_ops_report/_no_data.html.haml b/app/views/admin/dev_ops_report/_no_data.html.haml
deleted file mode 100644
index e540a4e2bce..00000000000
--- a/app/views/admin/dev_ops_report/_no_data.html.haml
+++ /dev/null
@@ -1,7 +0,0 @@
-.container.devops-empty
- .col-sm-12.justify-content-center.text-center
- = custom_icon('dev_ops_report_no_data')
- %h4= _('Data is still calculating...')
- %p
- = _('It may be several days before you see feature usage data.')
- = link_to _('Our documentation includes an example DevOps Score report.'), help_page_path('user/admin_area/analytics/dev_ops_report'), target: '_blank'
diff --git a/app/views/admin/dev_ops_report/_report.html.haml b/app/views/admin/dev_ops_report/_report.html.haml
index 95ef1298d03..dbd0020e382 100644
--- a/app/views/admin/dev_ops_report/_report.html.haml
+++ b/app/views/admin/dev_ops_report/_report.html.haml
@@ -4,29 +4,7 @@
= render 'callout'
- if !usage_ping_enabled
- #js-devops-empty-state{ data: { is_admin: current_user&.admin.to_s, empty_state_svg_path: image_path('illustrations/convdev/convdev_no_index.svg'), enable_usage_ping_link: metrics_and_profiling_admin_application_settings_path(anchor: 'js-usage-settings'), docs_link: help_page_path('development/usage_ping/index.md') } }
-- elsif @metric.blank?
- = render 'no_data'
+ #js-devops-usage-ping-disabled{ data: { is_admin: current_user&.admin.to_s, empty_state_svg_path: image_path('illustrations/convdev/convdev_no_index.svg'), enable_usage_ping_link: metrics_and_profiling_admin_application_settings_path(anchor: 'js-usage-settings'), docs_link: help_page_path('development/usage_ping/index.md') } }
- else
- .devops
- .gl-my-3.gl-text-gray-400{ data: { testid: 'devops-score-note-text' } }
- = s_('DevopsReport|DevOps score metrics are based on usage over the last 30 days. Last updated: %{timestamp}.').html_safe % { timestamp: @metric.created_at.strftime('%Y-%m-%d %H:%M') }
- .devops-header
- %h2.devops-header-title{ class: "devops-#{score_level(@metric.average_percentage_score)}-score" }
- = number_to_percentage(@metric.average_percentage_score, precision: 1)
- .devops-header-subtitle
- = s_('DevopsReport|DevOps')
- %br
- = s_('DevopsReport|Score')
- = link_to sprite_icon('question-o', css_class: 'devops-header-icon'), help_page_path('user/admin_area/analytics/dev_ops_report')
+ #js-devops-score{ data: { devops_score_metrics: devops_score_metrics(@metric).to_json, devops_report_docs_path: help_page_path('user/admin_area/analytics/dev_ops_report'), no_data_image_path: image_path('dev_ops_report_no_data.svg') } }
- .devops-cards.board-card-container
- - @metric.cards.each do |card|
- = render 'card', card: card
-
- .devops-steps.d-none.d-lg-block
- - @metric.idea_to_production_steps.each_with_index do |step, index|
- .devops-step{ class: "devops-#{score_level(step.percentage_score)}-score" }
- = custom_icon("i2p_step_#{index + 1}")
- %h4.devops-step-title
- = step.title
diff --git a/app/views/admin/groups/_group.html.haml b/app/views/admin/groups/_group.html.haml
index df7af86e089..bbc65850794 100644
--- a/app/views/admin/groups/_group.html.haml
+++ b/app/views/admin/groups/_group.html.haml
@@ -15,7 +15,7 @@
= markdown_field(group, :description)
.stats.gl-text-gray-500.gl-flex-shrink-0.gl-display-none.gl-sm-display-flex
- %span.badge.badge-pill
+ %span.badge.badge-muted.badge-pill.gl-badge.sm
= storage_counter(group.storage_size)
= render_if_exists 'admin/namespace_plan_badge', namespace: group, css_class: 'gl-ml-5 gl-mr-0'
diff --git a/app/views/admin/health_check/show.html.haml b/app/views/admin/health_check/show.html.haml
index 78f0fd325fb..a289cea0d5a 100644
--- a/app/views/admin/health_check/show.html.haml
+++ b/app/views/admin/health_check/show.html.haml
@@ -23,8 +23,8 @@
%code= metrics_url(token: Gitlab::CurrentSettings.health_check_access_token)
= render_if_exists 'admin/health_check/health_check_url'
%hr
-.card
- .card-header
+.gl-card
+ .gl-card-header
Current Status:
- if no_errors
= sprite_icon('check', css_class: 'cgreen')
@@ -32,7 +32,7 @@
- else
= sprite_icon('warning-solid', css_class: 'cred')
#{ s_('HealthCheck|Unhealthy') }
- .card-body
+ .gl-card-body
- if no_errors
#{ s_('HealthCheck|No Health Problems Detected') }
- else
diff --git a/app/views/admin/hook_logs/_index.html.haml b/app/views/admin/hook_logs/_index.html.haml
index 61af7535c1e..a7f947f96ea 100644
--- a/app/views/admin/hook_logs/_index.html.haml
+++ b/app/views/admin/hook_logs/_index.html.haml
@@ -4,7 +4,7 @@
= _('Recent Deliveries')
%p= _('When an event in GitLab triggers a webhook, you can use the request details to figure out if something went wrong.')
.col-lg-9
- - if hook_logs.any?
+ - if hook_logs.present?
%table.table
%thead
%tr
diff --git a/app/views/admin/labels/_label.html.haml b/app/views/admin/labels/_label.html.haml
index a357c3d9d34..16661efce04 100644
--- a/app/views/admin/labels/_label.html.haml
+++ b/app/views/admin/labels/_label.html.haml
@@ -3,5 +3,5 @@
.label-actions-list
= link_to edit_admin_label_path(label), class: 'btn btn-default gl-button btn-default-tertiary label-action has-tooltip', title: _('Edit'), data: { placement: 'bottom' }, aria_label: _('Edit') do
= sprite_icon('pencil')
- = link_to admin_label_path(label), class: 'btn btn-default gl-button btn-default-tertiary hover-red js-remove-row label-action has-tooltip', title: _('Delete'), data: { placement: 'bottom', confirm: "Delete this label? Are you sure?" }, aria_label: _('Delete'), method: :delete, remote: true do
+ = link_to admin_label_path(label), class: 'btn btn-default gl-button btn-default-tertiary hover-red js-remove-label label-action has-tooltip', title: _('Delete'), data: { placement: 'bottom', confirm: "Delete this label? Are you sure?" }, aria_label: _('Delete'), method: :delete, remote: true do
= sprite_icon('remove')
diff --git a/app/views/admin/labels/destroy.js.haml b/app/views/admin/labels/destroy.js.haml
deleted file mode 100644
index 5ee53088230..00000000000
--- a/app/views/admin/labels/destroy.js.haml
+++ /dev/null
@@ -1,3 +0,0 @@
-- if @labels.size == 0
- var emptyState = document.querySelector('.labels .nothing-here-block.hidden');
- if (emptyState) emptyState.classList.remove('hidden');
diff --git a/app/views/admin/projects/_projects.html.haml b/app/views/admin/projects/_projects.html.haml
index 7e505729213..6f7cea85ed1 100644
--- a/app/views/admin/projects/_projects.html.haml
+++ b/app/views/admin/projects/_projects.html.haml
@@ -1,7 +1,7 @@
.js-projects-list-holder
- if @projects.any?
%ul.projects-list.content-list.admin-projects
- - @projects.each_with_index do |project|
+ - @projects.each do |project|
%li.project-row{ class: ('no-description' if project.description.blank?) }
.controls
= link_to _('Edit'), edit_project_path(project), id: "edit_#{dom_id(project)}", class: "btn gl-button btn-default"
diff --git a/app/views/admin/requests_profiles/index.html.haml b/app/views/admin/requests_profiles/index.html.haml
index 6c75dfe9733..9d42a2bfa93 100644
--- a/app/views/admin/requests_profiles/index.html.haml
+++ b/app/views/admin/requests_profiles/index.html.haml
@@ -4,9 +4,7 @@
= page_title
.bs-callout.clearfix
- Pass the header
- %code X-Profile-Token: #{@profile_token}
- to profile the request
+ = html_escape(_('Pass the header %{codeOpen} X-Profile-Token: %{profile_token} %{codeClose} to profile the request')) % { profile_token: @profile_token, codeOpen: '<code>'.html_safe, codeClose: '</code>'.html_safe }
- if @profiles.present?
.gl-mt-3
@@ -21,4 +19,4 @@
admin_requests_profile_path(profile)
- else
%p
- No profiles found
+ = _('No profiles found')
diff --git a/app/views/admin/runners/index.html.haml b/app/views/admin/runners/index.html.haml
index a38615d9b1b..359e5b411b1 100644
--- a/app/views/admin/runners/index.html.haml
+++ b/app/views/admin/runners/index.html.haml
@@ -5,7 +5,7 @@
.col-sm-6
.bs-callout
%p
- = (_"Runners are processes that pick up and execute CI/CD jobs for GitLab.")
+ = _("Runners are processes that pick up and execute CI/CD jobs for GitLab.")
%br
= _('You can register runners as separate users, on separate servers, and on your local machine. Register as many runners as you want.')
%br
diff --git a/app/views/admin/runners/show.html.haml b/app/views/admin/runners/show.html.haml
index 705716c09b7..d911f35d946 100644
--- a/app/views/admin/runners/show.html.haml
+++ b/app/views/admin/runners/show.html.haml
@@ -1,11 +1,11 @@
- add_page_specific_style 'page_bundles/ci_status'
-- page_title @runner.short_sha
+- breadcrumb_title @runner.short_sha
+- page_title "##{@runner.id} (#{@runner.short_sha})"
- add_to_breadcrumbs _('Runners'), admin_runners_path
-- breadcrumb_title page_title
- if Feature.enabled?(:runner_detailed_view_vue_ui, current_user, default_enabled: :yaml)
- #js-runner-detail{ data: {runner_id: @runner.id} }
+ #js-runner-details{ data: {runner_id: @runner.id} }
- else
%h2.page-title
= s_('Runners|Runner #%{runner_id}' % { runner_id: @runner.id })
@@ -46,9 +46,10 @@
%tr
%td
= form_tag admin_runner_path(@runner), id: 'runner-projects-search', class: 'form-inline', method: :get do
- .form-group
- = search_field_tag :search, params[:search], class: 'form-control', spellcheck: false
- = submit_tag 'Search', class: 'btn'
+ .input-group
+ = search_field_tag :search, params[:search], class: 'form-control gl-form-input', spellcheck: false
+ .input-group-append
+ = submit_tag _('Search'), class: 'gl-button btn btn-default'
%td
- @projects.each do |project|
@@ -59,7 +60,7 @@
.float-right
= form_for project.runner_projects.new, url: admin_namespace_project_runner_projects_path(project.namespace, project), method: :post do |f|
= f.hidden_field :runner_id, value: @runner.id
- = f.submit 'Enable', class: 'gl-button btn btn-sm'
+ = f.submit _('Enable'), class: 'gl-button btn btn-sm'
= paginate_without_count @projects
.col-md-6
diff --git a/app/views/admin/spam_logs/index.html.haml b/app/views/admin/spam_logs/index.html.haml
index 40fbc559d72..2a36c991ed2 100644
--- a/app/views/admin/spam_logs/index.html.haml
+++ b/app/views/admin/spam_logs/index.html.haml
@@ -1,22 +1,22 @@
- page_title _("Spam Logs")
-%h3.page-title Spam Logs
+%h3.page-title= _('Spam Logs')
%hr
- if @spam_logs.present?
.table-holder
%table.table
%thead
%tr
- %th Date
- %th User
- %th Source IP
- %th API?
- %th Recaptcha verified?
- %th Type
- %th Title
- %th Description
- %th Primary Action
+ %th= _('Date')
+ %th= _('User')
+ %th= _('Source IP')
+ %th= _('API?')
+ %th= _('Recaptcha verified?')
+ %th= _('Type')
+ %th= _('Title')
+ %th= _('Description')
+ %th= _('Primary Action')
%th
= render @spam_logs
= paginate @spam_logs, theme: 'gitlab'
- else
- %h4 There are no Spam Logs
+ %h4= _('There are no Spam Logs')
diff --git a/app/views/admin/users/_ban_user.html.haml b/app/views/admin/users/_ban_user.html.haml
new file mode 100644
index 00000000000..229c88adb7f
--- /dev/null
+++ b/app/views/admin/users/_ban_user.html.haml
@@ -0,0 +1,9 @@
+- if ban_feature_available?
+ .card.border-warning
+ .card-header.bg-warning.gl-text-white
+ = s_('AdminUsers|Ban user')
+ .card-body
+ = user_ban_effects
+ %br
+ %button.btn.gl-button.btn-warning.js-confirm-modal-button{ data: user_ban_data(user) }
+ = s_('AdminUsers|Ban user')
diff --git a/app/views/admin/users/_cohorts.html.haml b/app/views/admin/users/_cohorts.html.haml
index 013c6072165..25b30adc5be 100644
--- a/app/views/admin/users/_cohorts.html.haml
+++ b/app/views/admin/users/_cohorts.html.haml
@@ -1,4 +1 @@
-- if @cohorts
- = render 'cohorts_table'
-- else
- #js-cohorts-empty-state{ data: { empty_state_svg_path: image_path('illustrations/convdev/convdev_no_index.svg'), enable_usage_ping_link: metrics_and_profiling_admin_application_settings_path(anchor: 'js-usage-settings'), docs_link: help_page_path('user/admin_area/analytics/user_cohorts') } }
+= render 'cohorts_table'
diff --git a/app/views/admin/users/_form.html.haml b/app/views/admin/users/_form.html.haml
index b3ed8369263..9d62c19e2fc 100644
--- a/app/views/admin/users/_form.html.haml
+++ b/app/views/admin/users/_form.html.haml
@@ -3,40 +3,38 @@
= form_errors(@user)
%fieldset
- %legend Account
+ %legend= _('Account')
.form-group.row
.col-sm-2.col-form-label
= f.label :name
.col-sm-10
= f.text_field :name, required: true, autocomplete: 'off', class: 'form-control gl-form-input'
- %span.help-inline * required
+ %span.help-inline * #{_('required')}
.form-group.row
.col-sm-2.col-form-label
= f.label :username
.col-sm-10
= f.text_field :username, required: true, autocomplete: 'off', autocorrect: 'off', autocapitalize: 'off', spellcheck: false, class: 'form-control gl-form-input'
- %span.help-inline * required
+ %span.help-inline * #{_('required')}
.form-group.row
.col-sm-2.col-form-label
= f.label :email
.col-sm-10
= f.text_field :email, required: true, autocomplete: 'off', class: 'form-control gl-form-input'
- %span.help-inline * required
+ %span.help-inline * #{_('required')}
- if @user.new_record?
%fieldset
- %legend Password
+ %legend= _('Password')
.form-group.row
.col-sm-2.col-form-label
= f.label :password
.col-sm-10
%strong
- Reset link will be generated and sent to the user.
- %br
- User will be forced to set the password on first sign in.
+ = _('Reset link will be generated and sent to the user. %{break} User will be forced to set the password on first sign in.').html_safe % { break: '<br />'.html_safe }
- else
%fieldset
- %legend Password
+ %legend= _('Password')
.form-group.row
.col-sm-2.col-form-label
= f.label :password
@@ -55,7 +53,7 @@
= render_if_exists 'admin/users/limits', f: f
%fieldset
- %legend Profile
+ %legend= _('Profile')
.form-group.row
.col-sm-2.col-form-label
= f.label :avatar
@@ -87,8 +85,8 @@
.form-actions
- if @user.new_record?
- = f.submit 'Create user', class: "btn gl-button btn-confirm"
- = link_to 'Cancel', admin_users_path, class: "gl-button btn btn-default btn-cancel"
+ = f.submit _('Create user'), class: "btn gl-button btn-confirm"
+ = link_to _('Cancel'), admin_users_path, class: "gl-button btn btn-default btn-cancel"
- else
- = f.submit 'Save changes', class: "btn gl-button btn-confirm"
- = link_to 'Cancel', admin_user_path(@user), class: "gl-button btn btn-default btn-cancel"
+ = f.submit _('Save changes'), class: "btn gl-button btn-confirm"
+ = link_to _('Cancel'), admin_user_path(@user), class: "gl-button btn btn-default btn-cancel"
diff --git a/app/views/admin/users/_head.html.haml b/app/views/admin/users/_head.html.haml
index ade3581e5b9..be04e87f8b9 100644
--- a/app/views/admin/users/_head.html.haml
+++ b/app/views/admin/users/_head.html.haml
@@ -3,6 +3,9 @@
- if @user.blocked_pending_approval?
%span.cred
= s_('AdminUsers|(Pending approval)')
+ - elsif @user.banned?
+ %span.cred
+ = s_('AdminUsers|(Banned)')
- elsif @user.blocked?
%span.cred
= s_('AdminUsers|(Blocked)')
diff --git a/app/views/admin/users/_profile.html.haml b/app/views/admin/users/_profile.html.haml
index 4fcb9aad343..e90dab68b39 100644
--- a/app/views/admin/users/_profile.html.haml
+++ b/app/views/admin/users/_profile.html.haml
@@ -1,31 +1,31 @@
.card
.card-header
- Profile
+ = _('Profile')
%ul.content-list
%li
- %span.light Member since
+ %span.light= _('Member since')
%strong= user.created_at.to_s(:medium)
- unless user.public_email.blank?
%li
- %span.light E-mail:
+ %span.light= _('E-mail:')
%strong= link_to user.public_email, "mailto:#{user.public_email}"
- unless user.skype.blank?
%li
- %span.light Skype:
+ %span.light= _('Skype:')
%strong= link_to user.skype, "skype:#{user.skype}"
- unless user.linkedin.blank?
%li
- %span.light LinkedIn:
+ %span.light= _('LinkedIn:')
%strong= link_to user.linkedin, "https://www.linkedin.com/in/#{user.linkedin}"
- unless user.twitter.blank?
%li
- %span.light Twitter:
+ %span.light= _('Twitter:')
%strong= link_to user.twitter, "https://twitter.com/#{user.twitter}"
- unless user.website_url.blank?
%li
- %span.light Website:
+ %span.light= _('Website:')
%strong= link_to user.short_website_url, user.full_website_url
- unless user.location.blank?
%li
- %span.light Location:
+ %span.light= _('Location:')
%strong= user.location
diff --git a/app/views/admin/users/_projects.html.haml b/app/views/admin/users/_projects.html.haml
index 81cfb71af16..a9f5c560b41 100644
--- a/app/views/admin/users/_projects.html.haml
+++ b/app/views/admin/users/_projects.html.haml
@@ -1,13 +1,13 @@
- if local_assigns.has_key?(:contributed_projects) && contributed_projects.present?
.card.contributed-projects
- .card-header Projects contributed to
+ .card-header= _('Projects contributed to')
= render 'shared/projects/list',
projects: contributed_projects.sort_by(&:star_count).reverse,
projects_limit: 5, stars: true, avatar: false
- if local_assigns.has_key?(:projects) && projects.present?
.card
- .card-header Personal projects
+ .card-header= _('Personal projects')
= render 'shared/projects/list',
projects: projects.sort_by(&:star_count).reverse,
projects_limit: 10, stars: true, avatar: false
diff --git a/app/views/admin/users/_tabs.html.haml b/app/views/admin/users/_tabs.html.haml
new file mode 100644
index 00000000000..1a3239897eb
--- /dev/null
+++ b/app/views/admin/users/_tabs.html.haml
@@ -0,0 +1,7 @@
+%ul.nav-links.nav-tabs.nav.js-users-tabs{ role: 'tablist' }
+ %li.nav-item{ role: 'presentation' }
+ %a.nav-link{ href: admin_users_path, class: active_when(current_page?(admin_users_path)), role: 'tab' }
+ = s_('AdminUsers|Users')
+ %li.nav-item{ role: 'presentation' }
+ %a.nav-link{ href: cohorts_admin_users_path, class: active_when(current_page?(cohorts_admin_users_path)), role: 'tab' }
+ = s_('AdminUsers|Cohorts')
diff --git a/app/views/admin/users/_user.html.haml b/app/views/admin/users/_user.html.haml
index f2920579057..2816a1061b9 100644
--- a/app/views/admin/users/_user.html.haml
+++ b/app/views/admin/users/_user.html.haml
@@ -21,13 +21,13 @@
= user.last_activity_on.nil? ? _('Never') : l(user.last_activity_on, format: :admin)
- unless user.internal?
.table-section.section-20.table-button-footer
- .table-action-buttons
- = link_to _('Edit'), edit_admin_user_path(user), id: "edit_#{dom_id(user)}", class: 'btn gl-button btn-default'
+ .table-action-buttons{ data: { testid: "user-actions-#{user.id}" } }
+ = link_to _('Edit'), edit_admin_user_path(user), class: 'btn gl-button btn-default'
- unless user == current_user
- %button.dropdown-new.btn.gl-button.btn-default{ type: 'button', data: { testid: "user-action-button-#{user.id}", toggle: 'dropdown' } }
+ %button.dropdown-new.btn.gl-button.btn-default{ type: 'button', data: { testid: "dropdown-toggle", toggle: 'dropdown' } }
= sprite_icon('settings')
= sprite_icon('chevron-down')
- %ul.dropdown-menu.dropdown-menu-right{ data: { testid: "user-action-dropdown-#{user.id}" } }
+ %ul.dropdown-menu.dropdown-menu-right
%li.dropdown-header
= _('Settings')
%li
diff --git a/app/views/admin/users/_users.html.haml b/app/views/admin/users/_users.html.haml
index c79b2e978f2..e4438f38a47 100644
--- a/app/views/admin/users/_users.html.haml
+++ b/app/views/admin/users/_users.html.haml
@@ -7,39 +7,44 @@
= nav_link(html_options: { class: active_when(params[:filter].nil?) }) do
= link_to admin_users_path do
= s_('AdminUsers|Active')
- %small.badge.badge-pill= limited_counter_with_delimiter(User.active_without_ghosts)
+ %small.badge.gl-tab-counter-badge.badge-muted.badge-pill.gl-badge.sm= limited_counter_with_delimiter(User.active_without_ghosts)
= nav_link(html_options: { class: active_when(params[:filter] == 'admins') }) do
= link_to admin_users_path(filter: "admins") do
= s_('AdminUsers|Admins')
- %small.badge.badge-pill= limited_counter_with_delimiter(User.admins)
+ %small.badge.gl-tab-counter-badge.badge-muted.badge-pill.gl-badge.sm= limited_counter_with_delimiter(User.admins)
= nav_link(html_options: { class: "#{active_when(params[:filter] == 'two_factor_enabled')} filter-two-factor-enabled" }) do
= link_to admin_users_path(filter: 'two_factor_enabled') do
= s_('AdminUsers|2FA Enabled')
- %small.badge.badge-pill= limited_counter_with_delimiter(User.with_two_factor)
+ %small.badge.gl-tab-counter-badge.badge-muted.badge-pill.gl-badge.sm= limited_counter_with_delimiter(User.with_two_factor)
= nav_link(html_options: { class: "#{active_when(params[:filter] == 'two_factor_disabled')} filter-two-factor-disabled" }) do
= link_to admin_users_path(filter: 'two_factor_disabled') do
= s_('AdminUsers|2FA Disabled')
- %small.badge.badge-pill= limited_counter_with_delimiter(User.without_two_factor)
+ %small.badge.gl-tab-counter-badge.badge-muted.badge-pill.gl-badge.sm= limited_counter_with_delimiter(User.without_two_factor)
= nav_link(html_options: { class: active_when(params[:filter] == 'external') }) do
= link_to admin_users_path(filter: 'external') do
= s_('AdminUsers|External')
- %small.badge.badge-pill= limited_counter_with_delimiter(User.external)
+ %small.badge.gl-tab-counter-badge.badge-muted.badge-pill.gl-badge.sm= limited_counter_with_delimiter(User.external)
= nav_link(html_options: { class: active_when(params[:filter] == 'blocked') }) do
= link_to admin_users_path(filter: "blocked") do
= s_('AdminUsers|Blocked')
- %small.badge.badge-pill= limited_counter_with_delimiter(User.blocked)
+ %small.badge.gl-tab-counter-badge.badge-muted.badge-pill.gl-badge.sm= limited_counter_with_delimiter(User.blocked)
+ - if ban_feature_available?
+ = nav_link(html_options: { class: active_when(params[:filter] == 'banned') }) do
+ = link_to admin_users_path(filter: "banned") do
+ = s_('AdminUsers|Banned')
+ %small.badge.gl-tab-counter-badge.badge-muted.badge-pill.gl-badge.sm= limited_counter_with_delimiter(User.banned)
= nav_link(html_options: { class: "#{active_when(params[:filter] == 'blocked_pending_approval')} filter-blocked-pending-approval" }) do
= link_to admin_users_path(filter: "blocked_pending_approval"), data: { qa_selector: 'pending_approval_tab' } do
= s_('AdminUsers|Pending approval')
- %small.badge.badge-pill= limited_counter_with_delimiter(User.blocked_pending_approval)
+ %small.badge.gl-tab-counter-badge.badge-muted.badge-pill.gl-badge.sm= limited_counter_with_delimiter(User.blocked_pending_approval)
= nav_link(html_options: { class: active_when(params[:filter] == 'deactivated') }) do
= link_to admin_users_path(filter: "deactivated") do
= s_('AdminUsers|Deactivated')
- %small.badge.badge-pill= limited_counter_with_delimiter(User.deactivated)
+ %small.badge.gl-tab-counter-badge.badge-muted.badge-pill.gl-badge.sm= limited_counter_with_delimiter(User.deactivated)
= nav_link(html_options: { class: active_when(params[:filter] == 'wop') }) do
= link_to admin_users_path(filter: "wop") do
= s_('AdminUsers|Without projects')
- %small.badge.badge-pill= limited_counter_with_delimiter(User.without_projects)
+ %small.badge.gl-tab-counter-badge.badge-muted.badge-pill.gl-badge.sm= limited_counter_with_delimiter(User.without_projects)
.nav-controls
= render_if_exists 'admin/users/admin_email_users'
= render_if_exists 'admin/users/admin_export_user_permissions'
@@ -68,7 +73,7 @@
= link_to admin_users_path(sort: value, filter: params[:filter], search_query: params[:search_query]) do
= title
-- if Feature.enabled?(:vue_admin_users)
+- if Feature.enabled?(:vue_admin_users, default_enabled: :yaml)
#js-admin-users-app{ data: admin_users_data_attributes(@users) }
.gl-spinner-container.gl-my-7
%span.gl-vertical-align-bottom.gl-spinner.gl-spinner-dark.gl-spinner-lg{ aria: { label: _('Loading') } }
@@ -83,6 +88,6 @@
= render partial: 'admin/users/user', collection: @users
-= paginate @users, theme: "gitlab"
+= paginate_collection @users
= render partial: 'admin/users/modals'
diff --git a/app/views/admin/users/cohorts.html.haml b/app/views/admin/users/cohorts.html.haml
new file mode 100644
index 00000000000..3f3d22fa410
--- /dev/null
+++ b/app/views/admin/users/cohorts.html.haml
@@ -0,0 +1,7 @@
+- page_title _("Users")
+
+= render 'tabs'
+
+.tab-content
+ .tab-pane.active
+ = render 'cohorts'
diff --git a/app/views/admin/users/edit.html.haml b/app/views/admin/users/edit.html.haml
index 7d10e839cd6..e3ebb691ba9 100644
--- a/app/views/admin/users/edit.html.haml
+++ b/app/views/admin/users/edit.html.haml
@@ -1,5 +1,5 @@
- page_title _("Edit"), @user.name, _("Users")
%h3.page-title
- Edit user: #{@user.name}
+ = _("Edit user: %{user_name}") % { user_name: @user.name }
%hr
= render 'form'
diff --git a/app/views/admin/users/index.html.haml b/app/views/admin/users/index.html.haml
index f9b631ed6cf..86b777d8458 100644
--- a/app/views/admin/users/index.html.haml
+++ b/app/views/admin/users/index.html.haml
@@ -1,17 +1,7 @@
- page_title _("Users")
-%ul.nav-links.nav-tabs.nav.js-users-tabs{ role: 'tablist' }
- %li.nav-item.js-users-tab-item{ role: 'presentation' }
- %a.nav-link{ href: '#users', class: active_when(params[:tab] != 'cohorts'), data: { toggle: 'tab' }, role: 'tab' }
- = s_('AdminUsers|Users')
- %li.nav-item.js-users-tab-item{ role: 'presentation' }
- %a.nav-link{ href: '#cohorts', class: active_when(params[:tab] == 'cohorts'), data: { toggle: 'tab' }, role: 'tab' }
- = s_('AdminUsers|Cohorts')
+= render 'tabs'
.tab-content
- .tab-pane{ id: 'users', class: ('active' if params[:tab] != 'cohorts') }
+ .tab-pane.active
= render 'users'
- .tab-pane{ id: 'cohorts', class: ('active' if params[:tab] == 'cohorts') }
- = render 'cohorts'
-
-
diff --git a/app/views/admin/users/projects.html.haml b/app/views/admin/users/projects.html.haml
index 70a497f14ff..3ff726e1945 100644
--- a/app/views/admin/users/projects.html.haml
+++ b/app/views/admin/users/projects.html.haml
@@ -5,7 +5,7 @@
- if @user.groups.any?
.card
- .card-header Group projects
+ .card-header= _('Group projects')
%ul.hover-list
- @user.group_members.includes(:source).each do |group_member| # rubocop: disable CodeReuse/ActiveRecord
- group = group_member.group
@@ -24,12 +24,12 @@
- if @personal_projects.present?
= render 'admin/users/projects', projects: @personal_projects
- else
- .nothing-here-block This user has no personal projects.
+ .nothing-here-block= _('This user has no personal projects.')
.col-md-6
.card
- .card-header Joined projects (#{@joined_projects.count})
+ .card-header= _('Joined projects (%{projects_count})') % { projects_count: @joined_projects.count }
%ul.hover-list
- @joined_projects.sort_by(&:full_name).each do |project|
- member = project.team.find_member(@user.id)
@@ -41,10 +41,10 @@
- if member
.float-right
- if member.owner?
- %span.light Owner
+ %span.light= _('Owner')
- else
%span.light.vertical-align-middle= member.human_access
- if member.respond_to? :project
- = link_to project_project_member_path(project, member), data: { confirm: remove_member_message(member) }, remote: true, method: :delete, class: "btn btn-sm btn-danger gl-button btn-icon gl-ml-3", title: 'Remove user from project' do
+ = link_to project_project_member_path(project, member), data: { confirm: remove_member_message(member) }, remote: true, method: :delete, class: "btn btn-sm btn-danger gl-button btn-icon gl-ml-3", title: _('Remove user from project') do
= sprite_icon('close', size: 16, css_class: 'gl-icon')
diff --git a/app/views/admin/users/show.html.haml b/app/views/admin/users/show.html.haml
index c7ec3ab66d7..19cc29668f5 100644
--- a/app/views/admin/users/show.html.haml
+++ b/app/views/admin/users/show.html.haml
@@ -12,7 +12,7 @@
%li
= image_tag avatar_icon_for_user(@user, 60), class: "avatar s60"
%li
- %span.light Profile page:
+ %span.light= _('Profile page:')
%strong
= link_to user_path(@user) do
= @user.username
@@ -20,25 +20,25 @@
.card
.card-header
- Account:
+ = _('Account:')
%ul.content-list
%li
- %span.light Name:
+ %span.light= _('Name:')
%strong= @user.name
%li
- %span.light Username:
+ %span.light= _('Username:')
%strong
= @user.username
%li
- %span.light Email:
+ %span.light= _('Email:')
%strong
= render partial: 'shared/email_with_badge', locals: { email: mail_to(@user.email), verified: @user.confirmed? }
- @user.emails.each do |email|
%li
- %span.light Secondary email:
+ %span.light= _('Secondary email:')
%strong
= render partial: 'shared/email_with_badge', locals: { email: email.email, verified: email.confirmed? }
- = link_to remove_email_admin_user_path(@user, email), data: { confirm: "Are you sure you want to remove #{email.email}?" }, method: :delete, class: "btn btn-sm btn-danger gl-button btn-icon float-right", title: 'Remove secondary email', id: "remove_email_#{email.id}" do
+ = link_to remove_email_admin_user_path(@user, email), data: { confirm: _("Are you sure you want to remove %{email}?") % { email: email.email } }, method: :delete, class: "btn btn-sm btn-danger gl-button btn-icon float-right", title: _('Remove secondary email'), id: "remove_email_#{email.id}" do
= sprite_icon('close', size: 16, css_class: 'gl-icon')
%li
%span.light ID:
@@ -50,65 +50,68 @@
= @user.namespace_id
%li.two-factor-status
- %span.light Two-factor Authentication:
+ %span.light= _('Two-factor Authentication:')
%strong{ class: @user.two_factor_enabled? ? 'cgreen' : 'cred' }
- if @user.two_factor_enabled?
- Enabled
- = link_to 'Disable', disable_two_factor_admin_user_path(@user), data: {confirm: 'Are you sure?'}, method: :patch, class: 'btn gl-button btn-sm btn-danger float-right', title: 'Disable Two-factor Authentication'
+ = _('Enabled')
+ = link_to _('Disable'), disable_two_factor_admin_user_path(@user), data: { confirm: _('Are you sure?') }, method: :patch, class: 'btn gl-button btn-sm btn-danger float-right', title: _('Disable Two-factor Authentication')
- else
- Disabled
+ = _('Disabled')
= render_if_exists 'admin/namespace_plan_info', namespace: @user.namespace
%li
- %span.light External User:
+ %span.light= _('External User:')
%strong
- = @user.external? ? "Yes" : "No"
+ = @user.external? ? _('Yes') : _('No')
+
+ = render_if_exists 'admin/users/provisioned_by', user: @user
+
%li
- %span.light Can create groups:
+ %span.light= _('Can create groups:')
%strong
- = @user.can_create_group ? "Yes" : "No"
+ = @user.can_create_group ? _('Yes') : _('No')
%li
- %span.light Personal projects limit:
+ %span.light= _('Personal projects limit:')
%strong
= @user.projects_limit
%li
- %span.light Member since:
+ %span.light= _('Member since:')
%strong
= @user.created_at.to_s(:medium)
- if @user.confirmed_at
%li
- %span.light Confirmed at:
+ %span.light= _('Confirmed at:')
%strong
= @user.confirmed_at.to_s(:medium)
- else
%li
- %span.light Confirmed:
+ %span.ligh= _('Confirmed:')
%strong.cred
- No
+ = _('No')
%li
- %span.light Current sign-in IP:
+ %span.light= _('Current sign-in IP:')
%strong
= @user.current_sign_in_ip || _('never')
%li
- %span.light Current sign-in at:
+ %span.light= _('Current sign-in at:')
%strong
= @user.current_sign_in_at&.to_s(:medium) || _('never')
%li
- %span.light Last sign-in IP:
+ %span.light= _('Last sign-in IP:')
%strong
= @user.last_sign_in_ip || _('never')
%li
- %span.light Last sign-in at:
+ %span.light= _('Last sign-in at:')
%strong
= @user.last_sign_in_at&.to_s(:medium) || _('never')
%li
- %span.light Sign-in count:
+ %span.light= _('Sign-in count:')
%strong
= @user.sign_in_count
@@ -121,13 +124,13 @@
- if @user.ldap_user?
%li
- %span.light LDAP uid:
+ %span.light= _('LDAP uid:')
%strong
= @user.ldap_identity.extern_uid
- if @user.created_by
%li
- %span.light Created by:
+ %span.light= _('Created by:')
%strong
= link_to @user.created_by.name, [:admin, @user.created_by]
@@ -140,13 +143,13 @@
- if can_force_email_confirmation?(@user)
.gl-card.border-info.gl-mb-5
.gl-card-header.bg-info.text-white
- Confirm user
+ = _('Confirm user')
.gl-card-body
- if @user.unconfirmed_email.present?
- email = " (#{@user.unconfirmed_email})"
- %p This user has an unconfirmed email address#{email}. You may force a confirmation.
+ %p= _('This user has an unconfirmed email address %{email}. You may force a confirmation.') % { email: email }
%br
- = link_to 'Confirm user', confirm_admin_user_path(@user), method: :put, class: "btn gl-button btn-info", data: { confirm: 'Are you sure?', qa_selector: 'confirm_user_button' }
+ = link_to _('Confirm user'), confirm_admin_user_path(@user), method: :put, class: "btn gl-button btn-info", data: { confirm: _('Are you sure?'), qa_selector: 'confirm_user_button' }
= render 'admin/users/user_detail_note'
@@ -154,7 +157,7 @@
- if @user.deactivated?
.gl-card.border-info.gl-mb-5
.gl-card-header.bg-info.text-white
- Reactivate this user
+ = _('Reactivate this user')
.gl-card-body
= render partial: 'admin/users/user_activation_effects'
%br
@@ -163,7 +166,7 @@
- elsif @user.can_be_deactivated?
.gl-card.border-warning.gl-mb-5
.gl-card-header.bg-warning.text-white
- Deactivate this user
+ = _('Deactivate this user')
.gl-card-body
= user_deactivation_effects
%br
@@ -173,36 +176,51 @@
- if @user.blocked_pending_approval?
= render 'admin/users/approve_user', user: @user
= render 'admin/users/reject_pending_user', user: @user
+ - elsif @user.banned?
+ .gl-card.border-info.gl-mb-5
+ .gl-card-header.gl-bg-blue-500.gl-text-white
+ = _('This user is banned')
+ .gl-card-body
+ %p= _('A banned user cannot:')
+ %ul
+ %li= _('Log in')
+ %li= _('Access Git repositories')
+ - link_start = '<a href="%{url}" target="_blank">'.html_safe % { url: help_page_path("user/admin_area/moderate_users", anchor: "ban-a-user") }
+ = s_('AdminUsers|Learn more about %{link_start}banned users.%{link_end}').html_safe % { link_start: link_start, link_end: '</a>'.html_safe }
+ %p
+ %button.btn.gl-button.btn-info.js-confirm-modal-button{ data: user_unban_data(@user) }
+ = s_('AdminUsers|Unban user')
- else
.gl-card.border-info.gl-mb-5
.gl-card-header.gl-bg-blue-500.gl-text-white
- This user is blocked
+ = _('This user is blocked')
.gl-card-body
- %p A blocked user cannot:
+ %p= _('A blocked user cannot:')
%ul
- %li Log in
- %li Access Git repositories
+ %li= _('Log in')
+ %li= _('Access Git repositories')
%br
%button.btn.gl-button.btn-info.js-confirm-modal-button{ data: user_unblock_data(@user) }
= s_('AdminUsers|Unblock user')
- elsif !@user.internal?
= render 'admin/users/block_user', user: @user
+ = render 'admin/users/ban_user', user: @user
- if @user.access_locked?
.card.border-info.gl-mb-5
.card-header.bg-info.text-white
- This account has been locked
+ = _('This account has been locked')
.card-body
- %p This user has been temporarily locked due to excessive number of failed logins. You may manually unlock the account.
+ %p= _('This user has been temporarily locked due to excessive number of failed logins. You may manually unlock the account.')
%br
- = link_to 'Unlock user', unlock_admin_user_path(@user), method: :put, class: "btn gl-button btn-info", data: { confirm: 'Are you sure?' }
+ = link_to _('Unlock user'), unlock_admin_user_path(@user), method: :put, class: "btn gl-button btn-info", data: { confirm: _('Are you sure?') }
- if !@user.blocked_pending_approval?
.gl-card.border-danger.gl-mb-5
.gl-card-header.bg-danger.text-white
= s_('AdminUsers|Delete user')
.gl-card-body
- if @user.can_be_removed? && can?(current_user, :destroy_user, @user)
- %p Deleting a user has the following effects:
+ %p= _('Deleting a user has the following effects:')
= render 'users/deletion_guidance', user: @user
%br
%button.js-delete-user-modal-button.btn.gl-button.btn-danger{ data: { 'gl-modal-action': 'delete',
@@ -213,13 +231,13 @@
- else
- if @user.solo_owned_groups.present?
%p
- This user is currently an owner in these groups:
+ = _('This user is currently an owner in these groups:')
%strong= @user.solo_owned_groups.map(&:name).join(', ')
%p
- You must transfer ownership or delete these groups before you can delete this user.
+ = _('You must transfer ownership or delete these groups before you can delete this user.')
- else
%p
- You don't have access to delete this user.
+ = _("You don't have access to delete this user.")
.gl-card.border-danger
.gl-card-header.bg-danger.text-white
@@ -227,13 +245,8 @@
.gl-card-body
- if can?(current_user, :destroy_user, @user)
%p
- This option deletes the user and any contributions that
- would usually be moved to the
- = succeed "." do
- = link_to "system ghost user", help_page_path("user/profile/account/delete_account")
- As well as the user's personal projects, groups owned solely by
- the user, and projects in them, will also be removed. Commits
- to other projects are unaffected.
+ - link_to_ghost_user = link_to(_("system ghost user"), help_page_path("user/profile/account/delete_account"))
+ = _("This option deletes the user and any contributions that would usually be moved to the %{link_to_ghost_user}. As well as the user's personal projects, groups owned solely by the user, and projects in them, will also be removed. Commits to other projects are unaffected.").html_safe % { link_to_ghost_user: link_to_ghost_user }
%br
%button.js-delete-user-modal-button.btn.gl-button.btn-danger{ data: { 'gl-modal-action': 'delete-with-contributions',
delete_user_url: admin_user_path(@user, hard_delete: true),
@@ -242,6 +255,6 @@
= s_('AdminUsers|Delete user and contributions')
- else
%p
- You don't have access to delete this user.
+ = _("You don't have access to delete this user.")
= render partial: 'admin/users/modals'
diff --git a/app/views/clusters/clusters/_banner.html.haml b/app/views/clusters/clusters/_banner.html.haml
index 4a84745cf98..6d902132c73 100644
--- a/app/views/clusters/clusters/_banner.html.haml
+++ b/app/views/clusters/clusters/_banner.html.haml
@@ -3,7 +3,7 @@
%p.js-error-reason
.hidden.js-cluster-creating.bs-callout.bs-callout-info{ role: 'alert' }
- %span.spinner.spinner-dark.spinner-sm{ 'aria-label': 'Loading' }
+ %span.gl-spinner.gl-spinner-dark{ 'aria-label': 'Loading' }
%span.gl-ml-2= s_('ClusterIntegration|Kubernetes cluster is being created...')
.hidden.row.js-cluster-api-unreachable.gl-alert.gl-alert-warning{ role: 'alert' }
diff --git a/app/views/clusters/clusters/_integrations.html.haml b/app/views/clusters/clusters/_integrations.html.haml
index d718e3ecb26..96219fa9de5 100644
--- a/app/views/clusters/clusters/_integrations.html.haml
+++ b/app/views/clusters/clusters/_integrations.html.haml
@@ -1,19 +1,29 @@
.settings.expanded.border-0.m-0
%p
- = s_('ClusterIntegration|Integrations enable you to integrate your cluster as part of your GitLab workflow.')
+ = s_('ClusterIntegration|Integrations allow you to use applications installed in your cluster as part of your GitLab workflow.')
= link_to _('Learn more'), help_page_path('user/clusters/integrations.md'), target: '_blank'
- .settings-content#advanced-settings-section
+ .settings-content#integrations-settings-section
- if can?(current_user, :admin_cluster, @cluster)
.sub-section.form-group
- = form_for @prometheus_integration, url: @cluster.integrations_path, as: :integration, method: :post, html: { class: 'js-cluster-integrations-form' } do |form|
- = form.hidden_field :application_type
- .form-group
+ = form_for @prometheus_integration, as: :integration, namespace: :prometheus, url: @cluster.integrations_path, method: :post, html: { class: 'js-cluster-integrations-form' } do |prometheus_form|
+ = prometheus_form.hidden_field :application_type
+ .form-group.gl-form-group
.gl-form-checkbox.custom-control.custom-checkbox
- = form.check_box :enabled, { class: 'custom-control-input'}
- = form.label :enabled, s_('ClusterIntegration|Enable Prometheus integration'), class: 'custom-control-label'
- .gl-form-group
+ = prometheus_form.check_box :enabled, class: 'custom-control-input'
+ = prometheus_form.label :enabled, s_('ClusterIntegration|Enable Prometheus integration'), class: 'custom-control-label'
.form-text.text-gl-muted
- - link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: help_page_path("user/clusters/integrations", anchor: "prometheus-cluster-integration") }
- - link_end = '</a>'.html_safe
- = html_escape(s_('ClusterIntegration|Before you enable this integration, follow the %{link_start}documented process%{link_end}.')) % { link_start: link_start, link_end: link_end }
- = form.submit _('Save changes'), class: 'btn gl-button btn-success'
+ = s_('ClusterIntegration|Allows GitLab to query a specifically configured in-cluster Prometheus for metrics.')
+ = link_to _('More information.'), help_page_path("user/clusters/integrations", anchor: "prometheus-cluster-integration"), target: '_blank'
+ = prometheus_form.submit _('Save changes'), class: 'btn gl-button btn-success'
+
+ .sub-section.form-group
+ = form_for @elastic_stack_integration, as: :integration, namespace: :elastic_stack, url: @cluster.integrations_path, method: :post, html: { class: 'js-cluster-integrations-form' } do |elastic_stack_form|
+ = elastic_stack_form.hidden_field :application_type
+ .form-group.gl-form-group
+ .gl-form-checkbox.custom-control.custom-checkbox
+ = elastic_stack_form.check_box :enabled, class: 'custom-control-input'
+ = elastic_stack_form.label :enabled, s_('ClusterIntegration|Enable Elastic Stack integration'), class: 'custom-control-label'
+ .form-text.text-gl-muted
+ = s_('ClusterIntegration|Allows GitLab to query a specifically configured in-cluster Elasticsearch for pod logs.')
+ = link_to _('More information.'), help_page_path("user/clusters/integrations", anchor: "elastic-stack-cluster-integration"), target: '_blank'
+ = elastic_stack_form.submit _('Save changes'), class: 'btn gl-button btn-success'
diff --git a/app/views/clusters/clusters/show.html.haml b/app/views/clusters/clusters/show.html.haml
index 01ba7c06154..001ca80dbd6 100644
--- a/app/views/clusters/clusters/show.html.haml
+++ b/app/views/clusters/clusters/show.html.haml
@@ -28,13 +28,13 @@
pre_installed_knative: @cluster.knative_pre_installed? ? 'true': 'false',
help_path: help_page_path('user/project/clusters/index.md', anchor: 'installing-applications'),
helm_help_path: help_page_path('user/clusters/applications.md', anchor: 'helm'),
- ingress_help_path: help_page_path('user/project/clusters/index.md', anchor: 'getting-the-external-endpoint'),
+ ingress_help_path: help_page_path('user/clusters/applications.md', anchor: 'determining-the-external-endpoint-automatically'),
ingress_dns_help_path: help_page_path('user/clusters/applications.md', anchor: 'pointing-your-dns-at-the-external-endpoint'),
ingress_mod_security_help_path: help_page_path('user/clusters/applications.md', anchor: 'web-application-firewall-modsecurity'),
- environments_help_path: help_page_path('ci/environments/index.md', anchor: 'defining-environments'),
+ environments_help_path: help_page_path('ci/environments/index.md', anchor: 'create-a-static-environment'),
clusters_help_path: help_page_path('user/project/clusters/index.md', anchor: 'deploying-to-a-kubernetes-cluster'),
deploy_boards_help_path: help_page_path('user/project/deploy_boards.md', anchor: 'enabling-deploy-boards'),
- cloud_run_help_path: help_page_path('user/project/clusters/add_remove_clusters.md', anchor: 'cloud-run-for-anthos'),
+ cloud_run_help_path: help_page_path('user/project/clusters/add_gke_clusters.md', anchor: 'cloud-run-for-anthos'),
manage_prometheus_path: manage_prometheus_path,
cluster_id: @cluster.id,
cilium_help_path: help_page_path('user/clusters/applications.md', anchor: 'install-cilium-using-gitlab-cicd')} }
diff --git a/app/views/dashboard/_activities.html.haml b/app/views/dashboard/_activities.html.haml
index d617ee0e4cc..ec07c636b79 100644
--- a/app/views/dashboard/_activities.html.haml
+++ b/app/views/dashboard/_activities.html.haml
@@ -6,4 +6,4 @@
.content_list
.loading
- .spinner.spinner-md
+ .gl-spinner.gl-spinner-md
diff --git a/app/views/dashboard/groups/_groups.html.haml b/app/views/dashboard/groups/_groups.html.haml
index 2f9dbf87d95..d5cd4b66e2b 100644
--- a/app/views/dashboard/groups/_groups.html.haml
+++ b/app/views/dashboard/groups/_groups.html.haml
@@ -1,4 +1,4 @@
.js-groups-list-holder
#js-groups-tree{ data: { hide_projects: 'true', endpoint: dashboard_groups_path(format: :json), path: dashboard_groups_path, form_sel: 'form#group-filter-form', filter_sel: '.js-groups-list-filter', holder_sel: '.js-groups-list-holder', dropdown_sel: '.js-group-filter-dropdown-wrap' } }
.loading-container.text-center.prepend-top-20
- .spinner.spinner-md
+ .gl-spinner.gl-spinner-md
diff --git a/app/views/dashboard/todos/_todo.html.haml b/app/views/dashboard/todos/_todo.html.haml
index f2f8afb636d..e7d8171d276 100644
--- a/app/views/dashboard/todos/_todo.html.haml
+++ b/app/views/dashboard/todos/_todo.html.haml
@@ -1,61 +1,61 @@
-%li{ class: "todo todo-#{todo.done? ? 'done' : 'pending'}", id: dom_id(todo), data: { url: todo_target_path(todo) } }
- .todo-avatar
- = author_avatar(todo, size: 40)
-
- .todo-item.todo-block.align-self-center{ data: { qa_selector: "todo_item_container" } }
- .todo-title
- - if todo_author_display?(todo)
- = todo_target_state_pill(todo)
-
- %span.title-item.author-name.bold
- - if todo.author
- = link_to_author(todo, self_added: todo.self_added?)
+%li.todo{ class: "todo-#{todo.done? ? 'done' : 'pending'}", id: dom_id(todo), data: { url: todo_target_path(todo) } }
+ .gl-display-flex.gl-flex-direction-row
+ .todo-avatar.gl-display-none.gl-sm-display-inline-block
+ = author_avatar(todo, size: 40)
+
+ .todo-item.gl-w-full.gl-align-self-center{ data: { qa_selector: "todo_item_container" } }
+ .todo-title.gl-mb-3.gl-md-mb-0
+ - if todo_author_display?(todo)
+ = todo_target_state_pill(todo)
+
+ %span.title-item.author-name.bold
+ - if todo.author
+ = link_to_author(todo, self_added: todo.self_added?)
+ - else
+ (removed)
+
+ %span.title-item.action-name{ data: { qa_selector: "todo_action_name_content" } }
+ = todo_action_name(todo)
+
+ %span.title-item.todo-label.todo-target-link
+ - if todo.target
+ = todo_target_link(todo)
- else
- (removed)
-
- %span.title-item.action-name{ data: { qa_selector: "todo_action_name_content" } }
- = todo_action_name(todo)
-
- %span.title-item.todo-label.todo-target-link
- - if todo.target
- = todo_target_link(todo)
- - else
- = _("(removed)")
-
- %span.title-item.todo-target-title{ data: { qa_selector: "todo_target_title_content" } }
- = todo_target_title(todo)
-
- %span.title-item.todo-project.todo-label
- at
- = todo_parent_path(todo)
-
- - if todo.self_assigned?
- %span.title-item.action-name
- = todo_self_addressing(todo)
-
- %span.title-item
- &middot;
-
- %span.title-item.todo-timestamp
- #{time_ago_with_tooltip(todo.created_at)}
- = todo_due_date(todo)
-
- - if todo.note.present?
- .todo-body
- .todo-note.break-word
- .md
- = first_line_in_markdown(todo, :body, 150, project: todo.project)
-
- - if todo.pending?
- .todo-actions
- = link_to dashboard_todo_path(todo), method: :delete, class: 'gl-button btn btn-default btn-loading d-flex align-items-center js-done-todo', data: { href: dashboard_todo_path(todo) } do
- Done
- %span.spinner.ml-1
- = link_to restore_dashboard_todo_path(todo), method: :patch, class: 'gl-button btn btn-default btn-loading d-flex align-items-center js-undo-todo hidden', data: { href: restore_dashboard_todo_path(todo) } do
- Undo
- %span.spinner.ml-1
- - else
- .todo-actions
- = link_to restore_dashboard_todo_path(todo), method: :patch, class: 'gl-button btn btn-default btn-loading d-flex align-items-center js-add-todo', data: { href: restore_dashboard_todo_path(todo) } do
- Add a to do
- %span.spinner.ml-1
+ = _("(removed)")
+
+ %span.title-item.todo-target-title{ data: { qa_selector: "todo_target_title_content" } }
+ = todo_target_title(todo)
+
+ %span.title-item.todo-project.todo-label
+ at
+ = todo_parent_path(todo)
+
+ - if todo.self_assigned?
+ %span.title-item.action-name
+ = todo_self_addressing(todo)
+
+ %span.title-item
+ &middot;
+
+ %span.title-item.todo-timestamp
+ #{time_ago_with_tooltip(todo.created_at)}
+ = todo_due_date(todo)
+
+ - if todo.note.present?
+ .todo-body
+ .todo-note.break-word
+ .md
+ = first_line_in_markdown(todo, :body, 150, project: todo.project)
+
+ .todo-actions.gl-ml-3
+ - if todo.pending?
+ = link_to dashboard_todo_path(todo), method: :delete, class: 'gl-button btn btn-default btn-loading d-flex align-items-center js-done-todo', data: { href: dashboard_todo_path(todo) } do
+ Done
+ %span.gl-spinner.ml-1
+ = link_to restore_dashboard_todo_path(todo), method: :patch, class: 'gl-button btn btn-default btn-loading d-flex align-items-center js-undo-todo hidden', data: { href: restore_dashboard_todo_path(todo) } do
+ Undo
+ %span.gl-spinner.ml-1
+ - else
+ = link_to restore_dashboard_todo_path(todo), method: :patch, class: 'gl-button btn btn-default btn-loading d-flex align-items-center js-add-todo', data: { href: restore_dashboard_todo_path(todo) } do
+ Add a to do
+ %span.gl-spinner.ml-1
diff --git a/app/views/dashboard/todos/index.html.haml b/app/views/dashboard/todos/index.html.haml
index a0016417f0c..52e41946ed1 100644
--- a/app/views/dashboard/todos/index.html.haml
+++ b/app/views/dashboard/todos/index.html.haml
@@ -15,13 +15,13 @@
= link_to todos_filter_path(state: 'pending') do
%span
To Do
- %span.badge.badge-pill
+ %span.badge.gl-tab-counter-badge.badge-muted.badge-pill.gl-badge.sm
= number_with_delimiter(todos_pending_count)
%li.todos-done{ class: active_when(params[:state] == 'done') }>
= link_to todos_filter_path(state: 'done') do
%span
Done
- %span.badge.badge-pill
+ %span.badge.gl-tab-counter-badge.badge-muted.badge-pill.gl-badge.sm
= number_with_delimiter(todos_done_count)
.nav-controls
@@ -29,41 +29,41 @@
.gl-mr-3
= link_to destroy_all_dashboard_todos_path(todos_filter_params), class: 'gl-button btn btn-default btn-loading align-items-center js-todos-mark-all', method: :delete, data: { href: destroy_all_dashboard_todos_path(todos_filter_params) } do
Mark all as done
- %span.spinner.ml-1
+ %span.gl-spinner.ml-1
= link_to bulk_restore_dashboard_todos_path, class: 'gl-button btn btn-default btn-loading align-items-center js-todos-undo-all hidden', method: :patch , data: { href: bulk_restore_dashboard_todos_path(todos_filter_params) } do
Undo mark all as done
- %span.spinner.ml-1
+ %span.gl-spinner.ml-1
.todos-filters
.issues-details-filters.row-content-block.second-block
- = form_tag todos_filter_path(without: [:project_id, :author_id, :type, :action_id]), method: :get, class: 'filter-form d-sm-flex' do
- .filter-categories.flex-fill
- .filter-item.inline
+ = form_tag todos_filter_path(without: [:project_id, :author_id, :type, :action_id]), method: :get, class: 'filter-form gl-display-flex gl-flex-direction-column gl-sm-flex-direction-row' do
+ .filter-categories.gl-display-flex.gl-flex-direction-column.gl-md-flex-direction-row.gl-flex-fill-1.gl-flex-wrap.gl-mx-n2
+ .filter-item.gl-m-2
- if params[:group_id].present?
= hidden_field_tag(:group_id, params[:group_id])
- = dropdown_tag(group_dropdown_label(params[:group_id], 'Group'), options: { toggle_class: 'js-group-search js-filter-submit', title: 'Filter by group', filter: true, filterInput: 'input#group-search', dropdown_class: 'dropdown-menu-selectable dropdown-menu-group js-filter-submit',
+ = dropdown_tag(group_dropdown_label(params[:group_id], 'Group'), options: { toggle_class: 'js-group-search js-filter-submit gl-xs-w-full!', title: 'Filter by group', filter: true, filterInput: 'input#group-search', dropdown_class: 'dropdown-menu-selectable dropdown-menu-group js-filter-submit',
placeholder: 'Search groups', data: { default_label: 'Group', display: 'static' } })
- .filter-item.inline
+ .filter-item.gl-m-2
- if params[:project_id].present?
= hidden_field_tag(:project_id, params[:project_id])
- = dropdown_tag(project_dropdown_label(params[:project_id], 'Project'), options: { toggle_class: 'js-project-search js-filter-submit', title: 'Filter by project', filter: true, filterInput: 'input#project-search', dropdown_class: 'dropdown-menu-selectable dropdown-menu-project js-filter-submit',
+ = dropdown_tag(project_dropdown_label(params[:project_id], 'Project'), options: { toggle_class: 'js-project-search js-filter-submit gl-xs-w-full!', title: 'Filter by project', filter: true, filterInput: 'input#project-search', dropdown_class: 'dropdown-menu-selectable dropdown-menu-project js-filter-submit',
placeholder: 'Search projects', data: { default_label: 'Project', display: 'static' } })
- .filter-item.inline
+ .filter-item.gl-m-2
- if params[:author_id].present?
= hidden_field_tag(:author_id, params[:author_id])
- = dropdown_tag(user_dropdown_label(params[:author_id], 'Author'), options: { toggle_class: 'js-user-search js-filter-submit js-author-search', title: 'Filter by author', filter: true, filterInput: 'input#author-search', dropdown_class: 'dropdown-menu-user dropdown-menu-selectable dropdown-menu-author js-filter-submit',
+ = dropdown_tag(user_dropdown_label(params[:author_id], 'Author'), options: { toggle_class: 'js-user-search js-filter-submit js-author-search gl-xs-w-full!', title: 'Filter by author', filter: true, filterInput: 'input#author-search', dropdown_class: 'dropdown-menu-user dropdown-menu-selectable dropdown-menu-author js-filter-submit',
placeholder: 'Search authors', data: { any_user: 'Any Author', first_user: (current_user.username if current_user), project_id: (@project.id if @project), selected: params[:author_id], field_name: 'author_id', default_label: 'Author', todo_filter: true, todo_state_filter: params[:state] || 'pending' } })
- .filter-item.inline
+ .filter-item.gl-m-2
- if params[:type].present?
= hidden_field_tag(:type, params[:type])
- = dropdown_tag(todo_types_dropdown_label(params[:type], 'Type'), options: { toggle_class: 'js-type-search js-filter-submit', dropdown_class: 'dropdown-menu-selectable dropdown-menu-type js-filter-submit',
+ = dropdown_tag(todo_types_dropdown_label(params[:type], 'Type'), options: { toggle_class: 'js-type-search js-filter-submit gl-xs-w-full!', dropdown_class: 'dropdown-menu-selectable dropdown-menu-type js-filter-submit',
data: { data: todo_types_options, default_label: 'Type' } })
- .filter-item.inline.actions-filter
+ .filter-item.actions-filter.gl-m-2
- if params[:action_id].present?
= hidden_field_tag(:action_id, params[:action_id])
- = dropdown_tag(todo_actions_dropdown_label(params[:action_id], 'Action'), options: { toggle_class: 'js-action-search js-filter-submit', dropdown_class: 'dropdown-menu-selectable dropdown-menu-action js-filter-submit',
+ = dropdown_tag(todo_actions_dropdown_label(params[:action_id], 'Action'), options: { toggle_class: 'js-action-search js-filter-submit gl-xs-w-full!', dropdown_class: 'dropdown-menu-selectable dropdown-menu-action js-filter-submit',
data: { data: todo_actions_options, default_label: 'Action' } })
- .filter-item.sort-filter
+ .filter-item.sort-filter.gl-mt-3.gl-sm-mt-0.gl-mb-0.gl-sm-mb-0
.dropdown
%button.dropdown-menu-toggle.dropdown-menu-toggle-sort{ type: 'button', class: 'gl-xs-w-full!', 'data-toggle' => 'dropdown' }
%span.light
@@ -81,40 +81,45 @@
= link_to todos_filter_path(sort: sort_value_oldest_created) do
= sort_title_oldest_created
-.todos-list-container.js-todos-all
+.row.js-todos-all
- if @todos.any?
- .js-todos-list-container{ data: { qa_selector: "todos_list_container" } }
+ .col.js-todos-list-container{ data: { qa_selector: "todos_list_container" } }
.js-todos-options{ data: { per_page: @todos.limit_value, current_page: @todos.current_page, total_pages: @todos.total_pages } }
%ul.content-list.todos-list
= render @todos
= paginate @todos, theme: "gitlab"
- .js-nothing-here-container.todos-all-done.hidden.svg-content
- = image_tag 'illustrations/todos_all_done.svg'
- %h4.text-center
- You're all done!
+ .js-nothing-here-container.empty-state.hidden
+ .svg-content
+ = image_tag 'illustrations/todos_all_done.svg'
+ .text-content
+ %h4.text-center
+ You're all done!
- elsif current_user.todos.any?
- .todos-all-done
+ .col.todos-all-done.empty-state
.svg-content.svg-250
= image_tag 'illustrations/todos_all_done.svg'
- - if todos_filter_empty?
- %h4.text-center
- = Gitlab.config.gitlab.no_todos_messages.sample
- %p
- Are you looking for things to do? Take a look at
- = succeed "," do
- = link_to "open issues", issues_dashboard_path
- contribute to
- = link_to "a merge request\,", merge_requests_dashboard_path
- or mention someone in a comment to automatically assign them a new to-do item.
- - else
- %h4.text-center
- Nothing is on your to-do list. Nice work!
+ .text-content
+ - if todos_filter_empty?
+ %h4.text-center
+ = Gitlab.config.gitlab.no_todos_messages.sample
+ %p
+ Are you looking for things to do? Take a look at
+ = succeed "," do
+ %strong
+ = link_to "open issues", issues_dashboard_path
+ contribute to
+ %strong
+ = link_to "a merge request\,", merge_requests_dashboard_path
+ or mention someone in a comment to automatically assign them a new to-do item.
+ - else
+ %h4.text-center
+ Nothing is on your to-do list. Nice work!
- else
- .todos-empty
- .todos-empty-hero.svg-content
+ .col.empty-state
+ .svg-content
= image_tag 'illustrations/todos_empty.svg'
- .todos-empty-content.gl-mx-5
- %h4
+ .text-content
+ %h4.text-center
Your To-Do List shows what to work on next
%p
When an issue or merge request is assigned to you, or when you receive a
diff --git a/app/views/devise/confirmations/new.html.haml b/app/views/devise/confirmations/new.html.haml
index 024ccaddaa1..51354618aa4 100644
--- a/app/views/devise/confirmations/new.html.haml
+++ b/app/views/devise/confirmations/new.html.haml
@@ -6,9 +6,9 @@
= render "devise/shared/error_messages", resource: resource
.form-group
= f.label :email
- = f.email_field :email, class: "form-control gl-form-input", required: true, title: 'Please provide a valid email address.', value: nil
+ = f.email_field :email, class: "form-control gl-form-input", required: true, title: _('Please provide a valid email address.'), value: nil
.clearfix
- = f.submit "Resend", class: 'gl-button btn btn-confirm'
+ = f.submit _("Resend"), class: 'gl-button btn btn-confirm'
.clearfix.prepend-top-20
= render 'devise/shared/sign_in_link'
diff --git a/app/views/devise/mailer/_confirmation_instructions_secondary.html.haml b/app/views/devise/mailer/_confirmation_instructions_secondary.html.haml
index f14d50eaf71..97fdf0249da 100644
--- a/app/views/devise/mailer/_confirmation_instructions_secondary.html.haml
+++ b/app/views/devise/mailer/_confirmation_instructions_secondary.html.haml
@@ -1,8 +1,8 @@
#content
- = email_default_heading("#{sanitize_name(@resource.user.name)}, confirm your email address now!")
- %p Click the link below to confirm your email address (#{@resource.email})
+ = email_default_heading(_("%{name}, confirm your email address now!") % { name: sanitize_name(@resource.user.name) })
+ %p= _('Click the link below to confirm your email address (%{email})') % { email: @resource.email }
#cta
- = link_to 'Confirm your email address', confirmation_url(@resource, confirmation_token: @token)
+ = link_to _('Confirm your email address'), confirmation_url(@resource, confirmation_token: @token)
%p
- If this email was added in error, you can remove it here:
- = link_to "Emails", profile_emails_url
+ = _('If this email was added in error, you can remove it here:')
+ = link_to _("Emails"), profile_emails_url
diff --git a/app/views/devise/mailer/reset_password_instructions.html.haml b/app/views/devise/mailer/reset_password_instructions.html.haml
index 47e192afa52..717f51b662f 100644
--- a/app/views/devise/mailer/reset_password_instructions.html.haml
+++ b/app/views/devise/mailer/reset_password_instructions.html.haml
@@ -1,10 +1,9 @@
-= email_default_heading("Hello, #{@resource.name}!")
+= email_default_heading(_("Hello, %{name}!") % { name: @resource.name })
%p
- Someone, hopefully you, has requested to reset the password for your
- GitLab account on #{link_to(Gitlab.config.gitlab.url, Gitlab.config.gitlab.url)}.
+ = _('Someone, hopefully you, has requested to reset the password for your GitLab account on %{link_to_gitlab}.').html_safe % { link_to_gitlab: Gitlab.config.gitlab.url }
%p
- If you did not perform this request, you can safely ignore this email.
+ = _('If you did not perform this request, you can safely ignore this email.')
%p
- Otherwise, click the link below to complete the process.
+ = _('Otherwise, click the link below to complete the process.')
#cta
- = link_to('Reset password', edit_password_url(@resource, reset_password_token: @token))
+ = link_to(_('Reset password'), edit_password_url(@resource, reset_password_token: @token))
diff --git a/app/views/devise/mailer/reset_password_instructions.text.erb b/app/views/devise/mailer/reset_password_instructions.text.erb
index 116313ee11c..c8d86fe998e 100644
--- a/app/views/devise/mailer/reset_password_instructions.text.erb
+++ b/app/views/devise/mailer/reset_password_instructions.text.erb
@@ -1,10 +1,9 @@
-Hello, <%= @resource.name %>!
+<%= _("Hello, %{name}!") % { name: @resource.name } %>
-Someone, hopefully you, has requested to reset the password for your GitLab
-account on <%= Gitlab.config.gitlab.url %>
+<%= _("Someone, hopefully you, has requested to reset the password for your GitLab account on %{link_to_gitlab}.") % { link_to_gitlab: Gitlab.config.gitlab.url } %>
-If you did not perform this request, you can safely ignore this email.
+<%= _("If you did not perform this request, you can safely ignore this email.") %>
-Otherwise, click the link below to complete the process:
+<%= _("Otherwise, click the link below to complete the process:") %>
<%= edit_password_url(@resource, reset_password_token: @token) %>
diff --git a/app/views/devise/mailer/unlock_instructions.text.erb b/app/views/devise/mailer/unlock_instructions.text.erb
index 8d4abbf3500..9b1e2166cee 100644
--- a/app/views/devise/mailer/unlock_instructions.text.erb
+++ b/app/views/devise/mailer/unlock_instructions.text.erb
@@ -1,7 +1,5 @@
-Hello, <%= @resource.name %>!
+<%= _('Hello, %{name}!') % { name: @resource.name } %>
-Your GitLab account has been locked due to an excessive amount of unsuccessful
-sign in attempts. Your account will automatically unlock in <%= distance_of_time_in_words(Devise.unlock_in) %>
-or you may click the link below to unlock now.
+<%= _("Your GitLab account has been locked due to an excessive amount of unsuccessful sign in attempts. Your account will automatically unlock in %{duration} or you may click the link below to unlock now.") % { duration: distance_of_time_in_words(Devise.unlock_in) } %>
<%= unlock_url(@resource, unlock_token: @token) %>
diff --git a/app/views/devise/shared/_links.erb b/app/views/devise/shared/_links.erb
index cb934434c28..f0215f5ea42 100644
--- a/app/views/devise/shared/_links.erb
+++ b/app/views/devise/shared/_links.erb
@@ -1,19 +1,19 @@
<%- if controller_name != 'sessions' %>
- <%= link_to "Sign in", new_session_path(:user, redirect_to_referer: 'yes'), class: "btn" %><br />
+ <%= link_to _("Sign in"), new_session_path(:user, redirect_to_referer: 'yes'), class: "btn" %><br />
<% end -%>
<%- if devise_mapping.registerable? && controller_name != 'registrations' && allow_signup? %>
- <%= link_to "Sign up", new_registration_path(:user) %><br />
+ <%= link_to _("Sign up"), new_registration_path(:user) %><br />
<% end -%>
<%- if devise_mapping.recoverable? && controller_name != 'passwords' %>
-<%= link_to "Forgot your password?", new_password_path(:user), class: "btn" %><br />
+<%= link_to _("Forgot your password?"), new_password_path(:user), class: "btn" %><br />
<% end -%>
<%- if devise_mapping.confirmable? && controller_name != 'confirmations' %>
- <%= link_to "Didn't receive confirmation instructions?", new_confirmation_path(:user) %><br />
+ <%= link_to _("Didn't receive confirmation instructions?"), new_confirmation_path(:user) %><br />
<% end -%>
<%- if devise_mapping.lockable? && resource_class.unlock_strategy_enabled?(:email) && controller_name != 'unlocks' %>
- <%= link_to "Didn't receive unlock instructions?", new_unlock_path(:user) %><br />
+ <%= link_to _("Didn't receive unlock instructions?"), new_unlock_path(:user) %><br />
<% end -%>
diff --git a/app/views/devise/shared/_signup_box.html.haml b/app/views/devise/shared/_signup_box.html.haml
index 2fc89f18de6..56f74916d8f 100644
--- a/app/views/devise/shared/_signup_box.html.haml
+++ b/app/views/devise/shared/_signup_box.html.haml
@@ -37,6 +37,6 @@
= recaptcha_tags
.submit-container
= f.submit button_text, class: 'btn gl-button btn-confirm', data: { qa_selector: 'new_user_register_button' }
- = render 'devise/shared/terms_of_service_notice'
+ = render 'devise/shared/terms_of_service_notice', button_text: button_text
- if show_omniauth_providers && omniauth_providers_placement == :bottom
= render 'devise/shared/signup_omniauth_providers'
diff --git a/app/views/devise/shared/_signup_omniauth_providers_top.haml b/app/views/devise/shared/_signup_omniauth_providers_top.haml
index a2cf5165c1f..9a2629443ed 100644
--- a/app/views/devise/shared/_signup_omniauth_providers_top.haml
+++ b/app/views/devise/shared/_signup_omniauth_providers_top.haml
@@ -1,3 +1,3 @@
-= render 'devise/shared/signup_omniauth_provider_list', providers: trial_enabled_button_based_providers
+= render 'devise/shared/signup_omniauth_provider_list', providers: popular_enabled_button_based_providers
.omniauth-divider.d-flex.align-items-center.text-center
= _("or")
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 46b043b2831..75d567a03fd 100644
--- a/app/views/devise/shared/_terms_of_service_notice.html.haml
+++ b/app/views/devise/shared/_terms_of_service_notice.html.haml
@@ -1,5 +1,9 @@
-- company_name = Gitlab.com? ? 'GitLab' : ''
+- return unless Gitlab::CurrentSettings.current_application_settings.enforce_terms?
-- if Gitlab::CurrentSettings.current_application_settings.enforce_terms?
- %p.gl-text-gray-500.gl-mt-5.gl-mb-0
- = html_escape(_("By clicking Register, I agree that I have read and accepted the %{company_name} %{linkStart}Terms of Use and Privacy Policy%{linkEnd}")) % { linkStart: "<a href='#{terms_path}' target='_blank' rel='noreferrer noopener'>".html_safe, linkEnd: '</a>'.html_safe, company_name: company_name }
+%p.gl-text-gray-500.gl-mt-5.gl-mb-0
+ - if Gitlab.dev_env_or_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 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}, I agree that I have read and accepted the %{link_start}Terms of Use and Privacy 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/doorkeeper/authorizations/new.html.haml b/app/views/doorkeeper/authorizations/new.html.haml
index 5e93b1d89eb..f0e7a96f69f 100644
--- a/app/views/doorkeeper/authorizations/new.html.haml
+++ b/app/views/doorkeeper/authorizations/new.html.haml
@@ -17,10 +17,8 @@
= _("An application called %{link_to_client} is requesting access to your GitLab account.").html_safe % { link_to_client: link_to_client }
- auth_app_owner = @pre_auth.client.application.owner
- - if auth_app_owner
- - link_to_owner = link_to(auth_app_owner.name, user_path(auth_app_owner))
- = _("This application was created by %{link_to_owner}.").html_safe % { link_to_owner: link_to_owner }
+ = auth_app_owner_text(auth_app_owner)
= _("Please note that this application is not provided by GitLab and you should verify its authenticity before allowing access.")
- if @pre_auth.scopes
%p
diff --git a/app/views/explore/groups/_groups.html.haml b/app/views/explore/groups/_groups.html.haml
index a3249275d5e..0358fc524d3 100644
--- a/app/views/explore/groups/_groups.html.haml
+++ b/app/views/explore/groups/_groups.html.haml
@@ -1,4 +1,4 @@
.js-groups-list-holder
#js-groups-tree{ data: { hide_projects: 'true', endpoint: explore_groups_path(format: :json), path: explore_groups_path, form_sel: 'form#group-filter-form', filter_sel: '.js-groups-list-filter', holder_sel: '.js-groups-list-holder', dropdown_sel: '.js-group-filter-dropdown-wrap' } }
.loading-container.text-center.prepend-top-20
- .spinner.spinner-md
+ .gl-spinner.gl-spinner-md
diff --git a/app/views/groups/_activities.html.haml b/app/views/groups/_activities.html.haml
index b1a40bfc96b..1695d3b5539 100644
--- a/app/views/groups/_activities.html.haml
+++ b/app/views/groups/_activities.html.haml
@@ -6,4 +6,4 @@
.content_list
.loading
- .spinner.spinner-md
+ .gl-spinner.gl-spinner-md
diff --git a/app/views/groups/_archived_projects.html.haml b/app/views/groups/_archived_projects.html.haml
index 48e9f630050..959c26acae0 100644
--- a/app/views/groups/_archived_projects.html.haml
+++ b/app/views/groups/_archived_projects.html.haml
@@ -5,4 +5,4 @@
%ul.content-list{ data: { hide_projects: 'false', group_id: group.id, path: group_path(group) } }
.js-groups-list-holder
.loading-container.text-center.prepend-top-20
- .spinner.spinner-md
+ .gl-spinner.gl-spinner-md
diff --git a/app/views/groups/_import_group_from_another_instance_panel.html.haml b/app/views/groups/_import_group_from_another_instance_panel.html.haml
index 2c9d9349f14..2b9277c67e9 100644
--- a/app/views/groups/_import_group_from_another_instance_panel.html.haml
+++ b/app/views/groups/_import_group_from_another_instance_panel.html.haml
@@ -18,7 +18,8 @@
= f.text_field :bulk_import_gitlab_url, placeholder: 'https://gitlab.example.com', class: 'gl-form-input col-xs-12 col-sm-8',
required: true,
title: s_('GroupsNew|Please fill in GitLab source URL.'),
- id: 'import_gitlab_url'
+ id: 'import_gitlab_url',
+ data: { qa_selector: 'import_gitlab_url' }
.form-group.gl-display-flex.gl-flex-direction-column
= f.label :bulk_import_gitlab_access_token, s_('GroupsNew|Personal access token'), for: 'import_gitlab_token'
.gl-font-weight-normal
@@ -27,6 +28,7 @@
= f.text_field :bulk_import_gitlab_access_token, placeholder: s_('GroupsNew|e.g. h8d3f016698e...'), class: 'gl-form-input gl-mt-3 col-xs-12 col-sm-8',
required: true,
title: s_('GroupsNew|Please fill in your personal access token.'),
- id: 'import_gitlab_token'
+ id: 'import_gitlab_token',
+ data: { qa_selector: 'import_gitlab_token' }
.gl-border-gray-100.gl-border-solid.gl-border-1.gl-bg-gray-10.gl-p-5
- = f.submit s_('GroupsNew|Connect instance'), class: 'btn gl-button btn-confirm'
+ = f.submit s_('GroupsNew|Connect instance'), class: 'btn gl-button btn-confirm', data: { qa_selector: 'connect_instance_button' }
diff --git a/app/views/groups/_invite_members_modal.html.haml b/app/views/groups/_invite_members_modal.html.haml
index ba6dfcb70ff..69ed94e99cc 100644
--- a/app/views/groups/_invite_members_modal.html.haml
+++ b/app/views/groups/_invite_members_modal.html.haml
@@ -1,4 +1,4 @@
-- if can_invite_members_for_group?(group)
+- if can?(current_user, :admin_group_member, group)
.js-invite-members-modal{ data: { id: group.id,
name: group.name,
is_project: 'false',
diff --git a/app/views/groups/_shared_projects.html.haml b/app/views/groups/_shared_projects.html.haml
index 2769b69add3..bfd056ccdd2 100644
--- a/app/views/groups/_shared_projects.html.haml
+++ b/app/views/groups/_shared_projects.html.haml
@@ -5,4 +5,4 @@
%ul.content-list{ data: { hide_projects: 'false', group_id: group.id, path: group_path(group) } }
.js-groups-list-holder
.loading-container.text-center.prepend-top-20
- .spinner.spinner-md
+ .gl-spinner.gl-spinner-md
diff --git a/app/views/groups/_subgroups_and_projects.html.haml b/app/views/groups/_subgroups_and_projects.html.haml
index d9ab828a83b..651d182b9cc 100644
--- a/app/views/groups/_subgroups_and_projects.html.haml
+++ b/app/views/groups/_subgroups_and_projects.html.haml
@@ -5,4 +5,4 @@
%section{ data: { hide_projects: 'false', group_id: group.id, path: group_path(group) } }
.js-groups-list-holder{ data: { show_schema_markup: 'true'} }
.loading-container.text-center.prepend-top-20
- .spinner.spinner-md
+ .gl-spinner.gl-spinner-md
diff --git a/app/views/groups/boards/show.html.haml b/app/views/groups/boards/show.html.haml
index 92838fa4b11..dbbf78eed00 100644
--- a/app/views/groups/boards/show.html.haml
+++ b/app/views/groups/boards/show.html.haml
@@ -1 +1,3 @@
+= render 'shared/alerts/positioning_disabled'
+
= render "shared/boards/show", board: @board, group: true
diff --git a/app/views/groups/group_members/index.html.haml b/app/views/groups/group_members/index.html.haml
index 106a7832cc7..45488791272 100644
--- a/app/views/groups/group_members/index.html.haml
+++ b/app/views/groups/group_members/index.html.haml
@@ -1,27 +1,26 @@
- add_page_specific_style 'page_bundles/members'
- page_title _('Group members')
-- can_manage_members = can?(current_user, :admin_group_member, @group)
-- show_invited_members = can_manage_members && @invited_members.exists?
-- show_access_requests = can_manage_members && @requesters.exists?
+- show_invited_members = can_manage_members? && @invited_members.load.any?
+- show_access_requests = can_manage_members? && @requesters.load.any?
- invited_active = params[:search_invited].present? || params[:invited_members_page].present?
.js-remove-member-modal
.row.gl-mt-3
.col-lg-12
.gl-display-flex.gl-flex-wrap
- - if can_manage_members
+ - if can_manage_members?
.gl-w-half.gl-xs-w-full
%h4
= _('Group members')
%p
= html_escape(_('You can invite a new member to %{strong_start}%{group_name}%{strong_end}.')) % { group_name: @group.name, strong_start: '<strong>'.html_safe, strong_end: '</strong>'.html_safe }
- - if can_invite_members_for_group?(@group)
+ - if Feature.enabled?(:invite_members_group_modal, @group)
.gl-w-half.gl-xs-w-full
.gl-display-flex.gl-flex-wrap.gl-justify-content-end.gl-mb-3
.js-invite-group-trigger{ data: { classes: 'gl-mt-3 gl-sm-w-auto gl-w-full', display_text: _('Invite a group') } }
.js-invite-members-trigger{ data: { variant: 'success', classes: 'gl-mt-3 gl-sm-w-auto gl-w-full gl-sm-ml-3', display_text: _('Invite members') } }
= render 'groups/invite_members_modal', group: @group
- - if can_manage_members && !can_invite_members_for_group?(@group)
+ - if can_manage_members? && Feature.disabled?(:invite_members_group_modal, @group)
%hr.gl-mt-4
%ul.nav-links.nav.nav-tabs.gitlab-tabs{ role: 'tablist' }
%li.nav-tab{ role: 'presentation' }
@@ -42,7 +41,7 @@
%span
= _('Members')
%span.badge.gl-tab-counter-badge.badge-muted.badge-pill.gl-badge.sm= @members.total_count
- - if @group.shared_with_group_links.any?
+ - if @group.shared_with_group_links.present?
%li.nav-item
= link_to '#tab-groups', class: ['nav-link'] , data: { toggle: 'tab', qa_selector: 'groups_list_tab' } do
%span
@@ -62,23 +61,21 @@
%span.badge.gl-tab-counter-badge.badge-muted.badge-pill.gl-badge.sm= @requesters.count
.tab-content
#tab-members.tab-pane{ class: ('active' unless invited_active) }
- .js-group-members-list{ data: group_members_list_data_attributes(@group, @members) }
+ .js-group-members-list{ data: { members_data: group_members_list_data_json(@group, @members, { param_name: :page, params: { invited_members_page: nil, search_invited: nil } }) } }
.loading
- .spinner.spinner-md
- = paginate @members, theme: 'gitlab', params: { invited_members_page: nil, search_invited: nil }
- - if @group.shared_with_group_links.any?
+ .gl-spinner.gl-spinner-md
+ - if @group.shared_with_group_links.present?
#tab-groups.tab-pane
- .js-group-group-links-list{ data: group_group_links_list_data_attributes(@group) }
+ .js-group-group-links-list{ data: { members_data: group_group_links_list_data_json(@group) } }
.loading
- .spinner.spinner-md
+ .gl-spinner.gl-spinner-md
- if show_invited_members
#tab-invited-members.tab-pane{ class: ('active' if invited_active) }
- .js-group-invited-members-list{ data: group_members_list_data_attributes(@group, @invited_members) }
+ .js-group-invited-members-list{ data: { members_data: group_members_list_data_json(@group, @invited_members, { param_name: :invited_members_page, params: { page: nil } }) } }
.loading
- .spinner.spinner-md
- = paginate @invited_members, param_name: 'invited_members_page', theme: 'gitlab', params: { page: nil }
+ .gl-spinner.gl-spinner-md
- if show_access_requests
#tab-access-requests.tab-pane
- .js-group-access-requests-list{ data: group_members_list_data_attributes(@group, @requesters) }
+ .js-group-access-requests-list{ data: { members_data: group_members_list_data_json(@group, @requesters) } }
.loading
- .spinner.spinner-md
+ .gl-spinner.gl-spinner-md
diff --git a/app/views/groups/imports/show.html.haml b/app/views/groups/imports/show.html.haml
index ac8ca8797fe..79cac364016 100644
--- a/app/views/groups/imports/show.html.haml
+++ b/app/views/groups/imports/show.html.haml
@@ -4,7 +4,7 @@
.save-group-loader
.center
%h2
- %i.loading.spinner.spinner-sm
+ %i.loading.gl-spinner
= page_title
%p
= s_('GroupImport|Please wait while we import the group for you. Refresh at will.')
diff --git a/app/views/groups/issues.html.haml b/app/views/groups/issues.html.haml
index ae4b0807fc5..fdd6962eb21 100644
--- a/app/views/groups/issues.html.haml
+++ b/app/views/groups/issues.html.haml
@@ -1,4 +1,4 @@
-- @can_bulk_update = can?(current_user, :admin_issue, @group) && @group.feature_available?(:group_bulk_edit)
+- @can_bulk_update = can?(current_user, :admin_issue, @group) && @group.licensed_feature_available?(:group_bulk_edit)
- page_title _("Issues")
- add_page_specific_style 'page_bundles/issues_list'
diff --git a/app/views/groups/merge_requests.html.haml b/app/views/groups/merge_requests.html.haml
index 15864e18f7c..33f836c2de0 100644
--- a/app/views/groups/merge_requests.html.haml
+++ b/app/views/groups/merge_requests.html.haml
@@ -1,4 +1,4 @@
-- @can_bulk_update = can?(current_user, :admin_merge_request, @group) && @group.feature_available?(:group_bulk_edit)
+- @can_bulk_update = can?(current_user, :admin_merge_request, @group) && @group.licensed_feature_available?(:group_bulk_edit)
- page_title _("Merge requests")
diff --git a/app/views/groups/milestones/_form.html.haml b/app/views/groups/milestones/_form.html.haml
index d4d8a7a57ef..259e96901fd 100644
--- a/app/views/groups/milestones/_form.html.haml
+++ b/app/views/groups/milestones/_form.html.haml
@@ -12,7 +12,11 @@
= f.label :description, _("Description")
.col-sm-10
= render layout: 'shared/md_preview', locals: { url: group_preview_markdown_path } do
- = render 'shared/zen', f: f, attr: :description, classes: 'note-textarea', qa_selector: 'milestone_description_field', placeholder: _('Write milestone description...'), supports_autocomplete: false
+ = render 'shared/zen', f: f, attr: :description,
+ classes: 'note-textarea',
+ qa_selector: 'milestone_description_field',
+ supports_autocomplete: true,
+ placeholder: _('Write milestone description...')
.clearfix
.error-alert
= render "shared/milestones/form_dates", f: f
diff --git a/app/views/groups/milestones/_header_title.html.haml b/app/views/groups/milestones/_header_title.html.haml
index 24eb39b8e2f..f222dba1f90 100644
--- a/app/views/groups/milestones/_header_title.html.haml
+++ b/app/views/groups/milestones/_header_title.html.haml
@@ -1,2 +1,2 @@
- breadcrumb_title @milestone.title
-- add_to_breadcrumbs "Milestones", group_milestones_path(@group)
+- add_to_breadcrumbs _("Milestones"), group_milestones_path(@group)
diff --git a/app/views/groups/milestones/new.html.haml b/app/views/groups/milestones/new.html.haml
index 2c93b0e4efd..0d4565706d4 100644
--- a/app/views/groups/milestones/new.html.haml
+++ b/app/views/groups/milestones/new.html.haml
@@ -3,7 +3,7 @@
- page_title _("Milestones"), @milestone.name, _("Milestones")
%h3.page-title
- New Milestone
+ = _("New Milestone")
%hr
diff --git a/app/views/groups/runners/edit.html.haml b/app/views/groups/runners/edit.html.haml
index 3794c345aa6..a0d7b8acb47 100644
--- a/app/views/groups/runners/edit.html.haml
+++ b/app/views/groups/runners/edit.html.haml
@@ -1,4 +1,7 @@
-- page_title _('Edit'), "#{@runner.description} ##{@runner.id}", _('Runners')
+- breadcrumb_title _('Edit')
+- page_title _('Edit'), "##{@runner.id} (#{@runner.short_sha})"
+- add_to_breadcrumbs _('CI/CD Settings'), group_settings_ci_cd_path(@group)
+- add_to_breadcrumbs "#{@runner.short_sha}", group_runner_path(@group, @runner)
%h2.page-title
= s_('Runners|Runner #%{runner_id}' % { runner_id: @runner.id })
diff --git a/app/views/groups/runners/show.html.haml b/app/views/groups/runners/show.html.haml
new file mode 100644
index 00000000000..5cf83e8ccfd
--- /dev/null
+++ b/app/views/groups/runners/show.html.haml
@@ -0,0 +1,3 @@
+- add_to_breadcrumbs _('CI/CD Settings'), group_settings_ci_cd_path(@group)
+
+= render 'shared/runners/runner_details', runner: @runner
diff --git a/app/views/groups/settings/_lfs.html.haml b/app/views/groups/settings/_lfs.html.haml
index 77c84862316..b16c9faafa4 100644
--- a/app/views/groups/settings/_lfs.html.haml
+++ b/app/views/groups/settings/_lfs.html.haml
@@ -6,10 +6,8 @@
%p= s_('Check the %{docs_link_start}documentation%{docs_link_end}.').html_safe % { docs_link_start: docs_link_start, docs_link_end: '</a>'.html_safe }
.form-group.gl-mb-3
- .form-check
- = f.check_box :lfs_enabled, checked: @group.lfs_enabled?, class: 'form-check-input', data: { qa_selector: 'lfs_checkbox' }
- = f.label :lfs_enabled, class: 'form-check-label' do
- %span
- = _('Allow projects within this group to use Git LFS')
- %br/
- %span.text-muted= _('This setting can be overridden in each project.')
+ .gl-form-checkbox.custom-control.custom-checkbox
+ = f.check_box :lfs_enabled, checked: @group.lfs_enabled?, class: 'custom-control-input', data: { qa_selector: 'lfs_checkbox' }
+ = f.label :lfs_enabled, class: 'custom-control-label' do
+ = _('Allow projects within this group to use Git LFS')
+ %p.help-text= _('This setting can be overridden in each project.')
diff --git a/app/views/groups/settings/_two_factor_auth.html.haml b/app/views/groups/settings/_two_factor_auth.html.haml
index fac3df5237f..bd3b3283288 100644
--- a/app/views/groups/settings/_two_factor_auth.html.haml
+++ b/app/views/groups/settings/_two_factor_auth.html.haml
@@ -7,17 +7,17 @@
%p= s_('Check the %{docs_link_start}documentation%{docs_link_end}.').html_safe % { docs_link_start: docs_link_start, docs_link_end: '</a>'.html_safe }
.form-group
- .form-check
- = f.check_box :require_two_factor_authentication, class: 'form-check-input', data: { qa_selector: 'require_2fa_checkbox' }
- = f.label :require_two_factor_authentication, class: 'form-check-label' do
- %span= _('Require all users in this group to setup two-factor authentication')
+ .gl-form-checkbox.custom-control.custom-checkbox
+ = f.check_box :require_two_factor_authentication, class: 'custom-control-input', data: { qa_selector: 'require_2fa_checkbox' }
+ = f.label :require_two_factor_authentication, class: 'custom-control-label' do
+ = _('Require all users in this group to setup two-factor authentication')
.form-group
= f.label :two_factor_grace_period, _('Time before enforced'), class: 'label-bold'
= f.text_field :two_factor_grace_period, class: 'form-control form-control-sm w-auto'
.form-text.text-muted= _('Amount of time (in hours) that users are allowed to skip forced configuration of two-factor authentication')
- unless group.has_parent?
.form-group
- .form-check
- = f.check_box :allow_mfa_for_subgroups, class: 'form-check-input', checked: group.namespace_settings&.allow_mfa_for_subgroups
- = f.label :allow_mfa_for_subgroups, class: 'form-check-label' do
+ .gl-form-checkbox.custom-control.custom-checkbox
+ = f.check_box :allow_mfa_for_subgroups, class: 'custom-control-input', checked: group.namespace_settings&.allow_mfa_for_subgroups
+ = f.label :allow_mfa_for_subgroups, class: 'custom-control-label' do
= _('Allow subgroups to set up their own two-factor authentication rules')
diff --git a/app/views/groups/settings/packages_and_registries/index.html.haml b/app/views/groups/settings/packages_and_registries/show.html.haml
index 1a12ad4902b..1a12ad4902b 100644
--- a/app/views/groups/settings/packages_and_registries/index.html.haml
+++ b/app/views/groups/settings/packages_and_registries/show.html.haml
diff --git a/app/views/groups/settings/repository/_initial_branch_name.html.haml b/app/views/groups/settings/repository/_initial_branch_name.html.haml
index efe690a0c2d..23ac7d51e4f 100644
--- a/app/views/groups/settings/repository/_initial_branch_name.html.haml
+++ b/app/views/groups/settings/repository/_initial_branch_name.html.haml
@@ -9,12 +9,12 @@
.settings-content
= form_for @group, url: group_path(@group, anchor: 'js-default-branch-name'), html: { class: 'fieldset-form' } do |f|
= form_errors(@group)
- - fallback_branch_name = '<code>master</code>'
+ - fallback_branch_name = "<code>#{Gitlab::DefaultBranch.value(object: @group)}</code>"
%fieldset
.form-group
= f.label :default_branch_name, _('Default initial branch name'), class: 'label-light'
- = f.text_field :default_branch_name, value: group.namespace_settings&.default_branch_name, placeholder: 'master', class: 'form-control'
+ = f.text_field :default_branch_name, value: group.namespace_settings&.default_branch_name, placeholder: Gitlab::DefaultBranch.value(object: @group), class: 'form-control'
%span.form-text.text-muted
= (_("Changes affect new repositories only. If not specified, either the configured application-wide default or Git's default name %{branch_name_default} will be used.") % { branch_name_default: fallback_branch_name }).html_safe
diff --git a/app/views/groups/show.html.haml b/app/views/groups/show.html.haml
index a1557cda071..9f7f0a08df5 100644
--- a/app/views/groups/show.html.haml
+++ b/app/views/groups/show.html.haml
@@ -12,6 +12,7 @@
is_dismissed_key: "invite_#{@group.id}_#{current_user.id}",
track_label: 'invite_members_banner',
invite_members_path: group_group_members_path(@group) } }
+ = render 'groups/invite_members_modal', group: @group
= content_for :meta_tags do
= auto_discovery_link_tag(:atom, group_url(@group, rss_url_options), title: "#{@group.name} activity")
diff --git a/app/views/ide/_show.html.haml b/app/views/ide/_show.html.haml
index 70ac532e69f..755c4151115 100644
--- a/app/views/ide/_show.html.haml
+++ b/app/views/ide/_show.html.haml
@@ -4,7 +4,10 @@
- add_page_specific_style 'page_bundles/build'
- add_page_specific_style 'page_bundles/ide'
+- content_for :prefetch_asset_tags do
+ - webpack_preload_asset_tag('monaco')
+
#ide.ide-loading{ data: ide_data }
.text-center
- .spinner.spinner-md
+ .gl-spinner.gl-spinner-md
%h2.clgray= _('Loading the GitLab IDE...')
diff --git a/app/views/import/bitbucket_server/new.html.haml b/app/views/import/bitbucket_server/new.html.haml
index 308065da90a..8a3fe1a816c 100644
--- a/app/views/import/bitbucket_server/new.html.haml
+++ b/app/views/import/bitbucket_server/new.html.haml
@@ -15,14 +15,14 @@
.form-group.row
= label_tag :bitbucket_server_url, 'Bitbucket Server URL', class: 'col-form-label col-md-2'
.col-md-4
- = text_field_tag :bitbucket_server_url, '', class: 'form-control gl-mr-3', placeholder: _('https://your-bitbucket-server'), size: 40
+ = text_field_tag :bitbucket_server_url, '', class: 'form-control gl-form-input gl-mr-3', placeholder: _('https://your-bitbucket-server'), size: 40
.form-group.row
= label_tag :bitbucket_server_url, 'Username', class: 'col-form-label col-md-2'
.col-md-4
- = text_field_tag :bitbucket_server_username, '', class: 'form-control gl-mr-3', placeholder: _('username'), size: 40
+ = text_field_tag :bitbucket_server_username, '', class: 'form-control gl-form-input gl-mr-3', placeholder: _('username'), size: 40
.form-group.row
= label_tag :personal_access_token, 'Password/Personal Access Token', class: 'col-form-label col-md-2'
.col-md-4
- = password_field_tag :personal_access_token, '', class: 'form-control gl-mr-3', placeholder: _('Personal Access Token'), size: 40
+ = password_field_tag :personal_access_token, '', class: 'form-control gl-form-input gl-mr-3', placeholder: _('Personal Access Token'), size: 40
.form-actions
= submit_tag _('List your Bitbucket Server repositories'), class: 'gl-button btn btn-confirm'
diff --git a/app/views/import/bulk_imports/status.html.haml b/app/views/import/bulk_imports/status.html.haml
index 917d88af75a..cd90c76ed10 100644
--- a/app/views/import/bulk_imports/status.html.haml
+++ b/app/views/import/bulk_imports/status.html.haml
@@ -2,9 +2,6 @@
- add_page_specific_style 'page_bundles/import'
- breadcrumb_title _('Import groups')
-%h1.gl-my-0.gl-py-4.gl-font-size-h1.gl-border-solid.gl-border-gray-200.gl-border-0.gl-border-b-1
- = s_('BulkImport|Import groups from GitLab')
-
#import-groups-mount-element{ data: { status_path: status_import_bulk_imports_path(format: :json),
available_namespaces_path: import_available_namespaces_path(format: :json),
create_bulk_import_path: import_bulk_imports_path(format: :json),
diff --git a/app/views/import/fogbugz/new.html.haml b/app/views/import/fogbugz/new.html.haml
index c0abac0a633..ab836174024 100644
--- a/app/views/import/fogbugz/new.html.haml
+++ b/app/views/import/fogbugz/new.html.haml
@@ -12,14 +12,14 @@
.form-group.row
= label_tag :uri, _('FogBugz URL'), class: 'col-form-label col-md-2'
.col-md-4
- = text_field_tag :uri, nil, placeholder: 'https://mycompany.fogbugz.com', class: 'form-control'
+ = text_field_tag :uri, nil, placeholder: 'https://mycompany.fogbugz.com', class: 'form-control gl-form-input'
.form-group.row
= label_tag :email, _('FogBugz Email'), class: 'col-form-label col-md-2'
.col-md-4
- = text_field_tag :email, nil, class: 'form-control'
+ = text_field_tag :email, nil, class: 'form-control gl-form-input'
.form-group.row
= label_tag :password, _('FogBugz Password'), class: 'col-form-label col-md-2'
.col-md-4
- = password_field_tag :password, nil, class: 'form-control'
+ = password_field_tag :password, nil, class: 'form-control gl-form-input'
.form-actions
= submit_tag _('Continue to the next step'), class: 'gl-button btn btn-confirm'
diff --git a/app/views/import/gitea/new.html.haml b/app/views/import/gitea/new.html.haml
index 285d2fb23a3..27786806d17 100644
--- a/app/views/import/gitea/new.html.haml
+++ b/app/views/import/gitea/new.html.haml
@@ -13,10 +13,10 @@
.form-group.row
= label_tag :gitea_host_url, _('Gitea Host URL'), class: 'col-form-label col-sm-2'
.col-sm-4
- = text_field_tag :gitea_host_url, nil, placeholder: 'https://gitea.com', class: 'form-control'
+ = text_field_tag :gitea_host_url, nil, placeholder: 'https://gitea.com', class: 'form-control gl-form-input'
.form-group.row
= label_tag :personal_access_token, _('Personal Access Token'), class: 'col-form-label col-sm-2'
.col-sm-4
- = text_field_tag :personal_access_token, nil, class: 'form-control'
+ = text_field_tag :personal_access_token, nil, class: 'form-control gl-form-input'
.form-actions
= submit_tag _('List Your Gitea Repositories'), class: 'gl-button btn btn-confirm'
diff --git a/app/views/import/phabricator/new.html.haml b/app/views/import/phabricator/new.html.haml
index 69483512816..960d3df2c42 100644
--- a/app/views/import/phabricator/new.html.haml
+++ b/app/views/import/phabricator/new.html.haml
@@ -18,10 +18,10 @@
.form-group.row
= label_tag :phabricator_server_url, _('Phabricator Server URL'), class: 'col-form-label col-md-2'
.col-md-4
- = text_field_tag :phabricator_server_url, params[:phabricator_server_url], class: 'form-control gl-mr-3', placeholder: 'https://your-phabricator-server', size: 40
+ = text_field_tag :phabricator_server_url, params[:phabricator_server_url], class: 'form-control gl-form-input gl-mr-3', placeholder: 'https://your-phabricator-server', size: 40
.form-group.row
= label_tag :api_token, _('API Token'), class: 'col-form-label col-md-2'
.col-md-4
- = password_field_tag :api_token, params[:api_token], class: 'form-control gl-mr-3', placeholder: _('Personal Access Token'), size: 40
+ = password_field_tag :api_token, params[:api_token], class: 'form-control gl-form-input gl-mr-3', placeholder: _('Personal Access Token'), size: 40
.form-actions
= submit_tag _('Import tasks'), class: 'gl-button btn btn-confirm'
diff --git a/app/views/import/shared/_new_project_form.html.haml b/app/views/import/shared/_new_project_form.html.haml
index 561c14dc68a..7de8b0ee10f 100644
--- a/app/views/import/shared/_new_project_form.html.haml
+++ b/app/views/import/shared/_new_project_form.html.haml
@@ -1,7 +1,7 @@
.row
.form-group.project-name.col-sm-12
= label_tag :name, _('Project name'), class: 'label-bold'
- = text_field_tag :name, @name, placeholder: "My awesome project", class: "js-project-name form-control input-lg", autofocus: true, required: true, aria: { required: true }
+ = text_field_tag :name, @name, placeholder: "My awesome project", class: "js-project-name form-control gl-form-input input-lg", autofocus: true, required: true, aria: { required: true }
.form-group.col-12.col-sm-6
= label_tag :namespace_id, _('Project URL'), class: 'label-bold'
.form-group
@@ -18,4 +18,4 @@
= hidden_field_tag :namespace_id, current_user.namespace_id
.form-group.col-12.col-sm-6.project-path
= label_tag :path, _('Project slug'), class: 'label-bold'
- = text_field_tag :path, @path, placeholder: "my-awesome-project", class: "js-path-name form-control", required: true, aria: { required: true }
+ = text_field_tag :path, @path, placeholder: "my-awesome-project", class: "js-path-name form-control gl-form-input", required: true, aria: { required: true }
diff --git a/app/views/layouts/_head.html.haml b/app/views/layouts/_head.html.haml
index 6694ad5968a..b28cd47efcc 100644
--- a/app/views/layouts/_head.html.haml
+++ b/app/views/layouts/_head.html.haml
@@ -32,6 +32,8 @@
- if page_canonical_link
%link{ rel: 'canonical', href: page_canonical_link }
+ = yield :prefetch_asset_tags
+
= favicon_link_tag favicon, id: 'favicon', data: { original_href: favicon }, type: 'image/png'
= render 'layouts/startup_css'
diff --git a/app/views/layouts/_loading_hints.html.haml b/app/views/layouts/_loading_hints.html.haml
index 0ef50d1b122..cd1a236b6be 100644
--- a/app/views/layouts/_loading_hints.html.haml
+++ b/app/views/layouts/_loading_hints.html.haml
@@ -1,10 +1,11 @@
-- if ActionController::Base.asset_host
- %link{ rel: 'dns-prefetch', href: ActionController::Base.asset_host }
- %link{ rel: 'preconnect', href: ActionController::Base.asset_host, crossorigin: '' }
-- if user_application_theme == 'gl-dark'
- %link{ { rel: 'preload', href: stylesheet_url('application_dark'), as: 'style' }, ActionController::Base.asset_host ? { crossorigin: 'anonymous' } : {} }
-- else
- %link{ { rel: 'preload', href: stylesheet_url('application'), as: 'style' }, ActionController::Base.asset_host ? { crossorigin: 'anonymous' } : {} }
-%link{ { rel: 'preload', href: stylesheet_url("highlight/themes/#{user_color_scheme}"), as: 'style' }, ActionController::Base.asset_host ? { crossorigin: 'anonymous' } : {} }
-- if Gitlab::CurrentSettings.snowplow_enabled? && Gitlab::CurrentSettings.snowplow_collector_hostname
- %link{ rel: 'preconnect', href: Gitlab::CurrentSettings.snowplow_collector_hostname, crossorigin: '' }
+= cache_if(Feature.enabled?(:cached_loading_hints, current_user), [ActionController::Base.asset_host, user_application_theme, user_color_scheme], expires_in: 1.minute) do
+ - if ActionController::Base.asset_host
+ %link{ rel: 'dns-prefetch', href: ActionController::Base.asset_host }
+ %link{ rel: 'preconnect', href: ActionController::Base.asset_host, crossorigin: '' }
+ - if user_application_theme == 'gl-dark'
+ %link{ { rel: 'preload', href: stylesheet_url('application_dark'), as: 'style' }, ActionController::Base.asset_host ? { crossorigin: 'anonymous' } : {} }
+ - else
+ %link{ { rel: 'preload', href: stylesheet_url('application'), as: 'style' }, ActionController::Base.asset_host ? { crossorigin: 'anonymous' } : {} }
+ %link{ { rel: 'preload', href: stylesheet_url("highlight/themes/#{user_color_scheme}"), as: 'style' }, ActionController::Base.asset_host ? { crossorigin: 'anonymous' } : {} }
+ - if Gitlab::CurrentSettings.snowplow_enabled? && Gitlab::CurrentSettings.snowplow_collector_hostname
+ %link{ rel: 'preconnect', href: Gitlab::CurrentSettings.snowplow_collector_hostname, crossorigin: '' }
diff --git a/app/views/layouts/_page_title.html.haml b/app/views/layouts/_page_title.html.haml
deleted file mode 100644
index 54da5074763..00000000000
--- a/app/views/layouts/_page_title.html.haml
+++ /dev/null
@@ -1,2 +0,0 @@
-- if content_for?(:page-title)
- = yield :page-title
diff --git a/app/views/layouts/header/_current_user_dropdown.html.haml b/app/views/layouts/header/_current_user_dropdown.html.haml
index 0251a8b6d7c..6bb51b01c13 100644
--- a/app/views/layouts/header/_current_user_dropdown.html.haml
+++ b/app/views/layouts/header/_current_user_dropdown.html.haml
@@ -3,7 +3,7 @@
%ul
%li.current-user
- if current_user_menu?(:profile)
- = link_to current_user, class: 'gl-line-height-20!', data: { user: current_user.username, testid: 'user-profile-link' } do
+ = link_to current_user, class: 'gl-line-height-20!', data: { user: current_user.username, testid: 'user-profile-link', qa_selector: 'user_profile_link' } do
= render 'layouts/header/current_user_dropdown_item'
- else
.gl-py-3.gl-px-4
diff --git a/app/views/layouts/header/_default.html.haml b/app/views/layouts/header/_default.html.haml
index 481e83c9701..ae333cffb84 100644
--- a/app/views/layouts/header/_default.html.haml
+++ b/app/views/layouts/header/_default.html.haml
@@ -20,7 +20,7 @@
= _('Next')
- if Feature.enabled?(:combined_menu, current_user, default_enabled: :yaml)
- = render "layouts/nav/combined_menu"
+ = render "layouts/nav/top_nav"
- else
- if current_user
= render "layouts/nav/dashboard"
@@ -92,7 +92,7 @@
= link_to help_path, class: 'header-help-dropdown-toggle', data: { toggle: "dropdown" } do
%span.gl-sr-only
= s_('Nav|Help')
- = sprite_icon('question')
+ = sprite_icon('question-o')
%span.notification-dot.rounded-circle.gl-absolute
= sprite_icon('chevron-down', css_class: 'caret-down')
.dropdown-menu.dropdown-menu-right
diff --git a/app/views/layouts/header/_new_dropdown.html.haml b/app/views/layouts/header/_new_dropdown.html.haml
index 7b49e6f716e..ca90d2e02fa 100644
--- a/app/views/layouts/header/_new_dropdown.html.haml
+++ b/app/views/layouts/header/_new_dropdown.html.haml
@@ -1,3 +1,4 @@
+- new_repo_experiment_text = content_for(:new_repo_experiment)
%li.header-new.dropdown{ data: { track_label: "new_dropdown", track_event: "click_dropdown", track_experiment: "new_repo" } }
= link_to new_project_path, class: "header-new-dropdown-toggle has-tooltip qa-new-menu-toggle", id: "js-onboarding-new-project-link", title: _("New..."), ref: 'tooltip', aria: { label: _("New...") }, data: { toggle: 'dropdown', placement: 'bottom', container: 'body', display: 'static' } do
= sprite_icon('plus-square')
@@ -12,9 +13,9 @@
%li.dropdown-bold-header
= _('This group')
- if create_group_project
- %li= link_to _('New project'), new_project_path(namespace_id: @group.id)
+ %li= link_to new_repo_experiment_text, new_project_path(namespace_id: @group.id), data: { track_experiment: 'new_repo', track_event: 'click_link_new_project_group', track_label: 'plus_menu_dropdown' }
- if create_group_subgroup
- %li= link_to _('New subgroup'), new_group_path(parent_id: @group.id)
+ %li= link_to _('New subgroup'), new_group_path(parent_id: @group.id), data: { track_event: 'click_link_new_subgroup', track_label: 'plus_menu_dropdown' }
= render_if_exists 'layouts/header/create_epic_new_dropdown_item'
= render 'layouts/header/group_invite_members_new_dropdown_item'
%li.divider
@@ -29,16 +30,18 @@
%li.dropdown-bold-header
= _('This project')
- if create_project_issue
- %li= link_to _('New issue'), new_project_issue_path(@project)
+ %li= link_to _('New issue'), new_project_issue_path(@project), data: { track_event: 'click_link_new_issue', track_label: 'plus_menu_dropdown' }
- if merge_project
- %li= link_to _('New merge request'), project_new_merge_request_path(merge_project)
+ %li= link_to _('New merge request'), project_new_merge_request_path(merge_project), data: { track_event: 'click_link_new_mr', track_label: 'plus_menu_dropdown' }
+
- if create_project_snippet
- %li= link_to _('New snippet'), new_project_snippet_path(@project)
+ %li= link_to _('New snippet'), new_project_snippet_path(@project), data: { track_event: 'click_link_new_snippet_project', track_label: 'plus_menu_dropdown' }
= render 'layouts/header/project_invite_members_new_dropdown_item'
%li.divider
%li.dropdown-bold-header GitLab
- = content_for :new_repo_experiment
+ - if current_user.can_create_project?
+ %li= link_to new_repo_experiment_text, new_project_path, class: 'qa-global-new-project-link', data: { track_experiment: 'new_repo', track_event: 'click_link_new_project', track_label: 'plus_menu_dropdown' }
- if current_user.can_create_group?
- %li= link_to _('New group'), new_group_path
+ %li= link_to _('New group'), new_group_path, data: { track_event: 'click_link_new_group', track_label: 'plus_menu_dropdown' }
- if current_user.can?(:create_snippet)
- %li= link_to _('New snippet'), new_snippet_path, class: 'qa-global-new-snippet-link'
+ %li= link_to _('New snippet'), new_snippet_path, data: { track_event: 'click_link_new_snippet_parent', track_label: 'plus_menu_dropdown' }, class: 'qa-global-new-snippet-link'
diff --git a/app/views/layouts/header/_new_repo_experiment.html.haml b/app/views/layouts/header/_new_repo_experiment.html.haml
index 73f960844cb..aaa13d593cd 100644
--- a/app/views/layouts/header/_new_repo_experiment.html.haml
+++ b/app/views/layouts/header/_new_repo_experiment.html.haml
@@ -1,7 +1,6 @@
- content_for :new_repo_experiment do
- - if current_user&.can_create_project?
- - experiment(:new_repo, user: current_user) do |e|
- - e.use do
- %li= link_to _('New project'), new_project_path, class: 'qa-global-new-project-link', data: { track_experiment: 'new_repo', track_event: 'click_link', track_label: 'plus_menu_dropdown' }
- - e.try do
- %li= link_to _('New project/repository'), new_project_path, class: 'qa-global-new-project-link', data: { track_experiment: 'new_repo', track_event: 'click_link', track_label: 'plus_menu_dropdown' }
+ - experiment(:new_repo, user: current_user) do |e|
+ - e.use do
+ = _('New project')
+ - e.try do
+ = _('New project/repository')
diff --git a/app/views/layouts/header/_whats_new_dropdown_item.html.haml b/app/views/layouts/header/_whats_new_dropdown_item.html.haml
index 9fe98a54aae..377f0f3271d 100644
--- a/app/views/layouts/header/_whats_new_dropdown_item.html.haml
+++ b/app/views/layouts/header/_whats_new_dropdown_item.html.haml
@@ -2,5 +2,5 @@
%li
%button.gl-justify-content-space-between.gl-align-items-center.js-whats-new-trigger{ type: 'button', class: 'gl-display-flex!' }
= _("What's new")
- %span.js-whats-new-notification-count.whats-new-notification-count
+ %span.js-whats-new-notification-count.gl-badge.badge.sm.badge-dark.badge-pill
= whats_new_most_recent_release_items_count
diff --git a/app/views/layouts/nav/_combined_menu.html.haml b/app/views/layouts/nav/_combined_menu.html.haml
deleted file mode 100644
index db5a7012e8f..00000000000
--- a/app/views/layouts/nav/_combined_menu.html.haml
+++ /dev/null
@@ -1,3 +0,0 @@
-%button{ type: 'button', data: { toggle: "dropdown" } }
- = sprite_icon('ellipsis_v')
- = _('Projects')
diff --git a/app/views/layouts/nav/_dashboard.html.haml b/app/views/layouts/nav/_dashboard.html.haml
index 42e3ae7e717..718b2002422 100644
--- a/app/views/layouts/nav/_dashboard.html.haml
+++ b/app/views/layouts/nav/_dashboard.html.haml
@@ -1,5 +1,7 @@
--# WAIT! Before adding more items to the nav bar, please see
--# https://gitlab.com/gitlab-org/gitlab-foss/issues/49713 for more information.
+-# WARNING! This file is slated to be removed along with the `combined_menu`
+-# feature flag. The logic here will be migrated to an upcoming `top_nav_helper`.
+-# Please see [this MR][1] for more context.
+-# [1]: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/56587
%ul.list-unstyled.navbar-sub-nav
- if dashboard_nav_link?(:projects)
= nav_link(path: ['root#index', 'projects#trending', 'projects#starred', 'dashboard/projects#index'], html_options: { id: 'nav-projects-dropdown', class: "home dropdown header-projects qa-projects-dropdown", data: { track_label: "projects_dropdown", track_event: "click_dropdown", track_experiment: "new_repo" } }) do
diff --git a/app/views/layouts/nav/_explore.html.haml b/app/views/layouts/nav/_explore.html.haml
index 7d18cd8978b..5b47eb27b04 100644
--- a/app/views/layouts/nav/_explore.html.haml
+++ b/app/views/layouts/nav/_explore.html.haml
@@ -1,3 +1,7 @@
+-# WARNING! This file is slated to be removed along with the `combined_menu`
+-# feature flag. The logic here will be migrated to an upcoming `top_nav_helper`.
+-# Please see [this MR][1] for more context.
+-# [1]: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/56587
%ul.list-unstyled.navbar-sub-nav
- if explore_nav_link?(:projects)
= nav_link(path: ['dashboard#show', 'root#show', 'projects#trending', 'projects#starred', 'projects#index'], html_options: {class: 'home'}) do
diff --git a/app/views/layouts/nav/_top_nav.html.haml b/app/views/layouts/nav/_top_nav.html.haml
new file mode 100644
index 00000000000..50c003f8e13
--- /dev/null
+++ b/app/views/layouts/nav/_top_nav.html.haml
@@ -0,0 +1,7 @@
+- view_model = top_nav_view_model(project: @project, group: @group)
+%ul.list-unstyled.navbar-sub-nav#js-top-nav{ data: { view_model: view_model.to_json } }
+ %li
+ %a.top-nav-toggle{ href: '#', type: 'button', data: { toggle: "dropdown" } }
+ = sprite_icon('dot-grid', css_class: "dropdown-icon")
+ = view_model[:activeTitle]
+ = sprite_icon('chevron-down')
diff --git a/app/views/layouts/nav/groups_dropdown/_show.html.haml b/app/views/layouts/nav/groups_dropdown/_show.html.haml
index a9d88341a19..036647e2be1 100644
--- a/app/views/layouts/nav/groups_dropdown/_show.html.haml
+++ b/app/views/layouts/nav/groups_dropdown/_show.html.haml
@@ -1,5 +1,9 @@
+-# WARNING! This file is slated to be removed along with the `combined_menu`
+-# feature flag. The logic here will be migrated to an upcoming `top_nav_helper`.
+-# Please see [this MR][1] for more context.
+-# [1]: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/56587
- group_meta = { id: @group.id, name: @group.name, namespace: @group.full_name, web_url: group_path(@group), avatar_url: @group.avatar_url } if @group&.persisted?
-.frequent-items-dropdown-container
+.frequent-items-dropdown-container.with-deprecated-styles
.frequent-items-dropdown-sidebar.qa-groups-dropdown-sidebar
%ul
= nav_link(path: 'dashboard/groups#index') do
@@ -9,10 +13,10 @@
= link_to explore_groups_path, data: { track_label: "groups_dropdown_explore_groups", track_event: "click_link" } do
= _('Explore groups')
= nav_link(path: 'groups/new#create-group-pane', html_options: { class: 'gl-border-0 gl-border-t-1 gl-border-solid gl-border-gray-100' }) do
- = link_to new_group_path(anchor: 'create-group-pane'), data: { track_label: "groups_dropdown_create_group", track_event: "click_link" } do
+ = link_to new_group_path(anchor: 'create-group-pane'), data: { track_label: "groups_dropdown_create_group", track_event: "click_link", qa_selector: 'create_group_link' } do
= _('Create group')
= nav_link(path: 'groups/new#import-group-pane') do
- = link_to new_group_path(anchor: 'import-group-pane'), data: { track_label: "groups_dropdown_import_group", track_event: "click_link" } do
+ = link_to new_group_path(anchor: 'import-group-pane'), data: { track_label: "groups_dropdown_import_group", track_event: "click_link", qa_selector: 'import_group_link' } do
= _('Import group')
.frequent-items-dropdown-content
#js-groups-dropdown{ data: { user_name: current_user.username, group: group_meta } }
diff --git a/app/views/layouts/nav/projects_dropdown/_show.html.haml b/app/views/layouts/nav/projects_dropdown/_show.html.haml
index b95a9cdb00f..2517508ba6c 100644
--- a/app/views/layouts/nav/projects_dropdown/_show.html.haml
+++ b/app/views/layouts/nav/projects_dropdown/_show.html.haml
@@ -1,5 +1,9 @@
+-# WARNING! This file is slated to be removed along with the `combined_menu`
+-# feature flag. The logic here will be migrated to an upcoming `top_nav_helper`.
+-# Please see [this MR][1] for more context.
+-# [1]: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/56587
- project_meta = { id: @project.id, name: @project.name, namespace: @project.full_name, web_url: project_path(@project), avatar_url: @project.avatar_url } if @project&.persisted?
-.frequent-items-dropdown-container
+.frequent-items-dropdown-container.with-deprecated-styles
.frequent-items-dropdown-sidebar.qa-projects-dropdown-sidebar
%ul
= nav_link(path: 'dashboard/projects#index') do
diff --git a/app/views/layouts/nav/sidebar/_admin.html.haml b/app/views/layouts/nav/sidebar/_admin.html.haml
index d756867541b..b71866c9138 100644
--- a/app/views/layouts/nav/sidebar/_admin.html.haml
+++ b/app/views/layouts/nav/sidebar/_admin.html.haml
@@ -2,9 +2,9 @@
.nav-sidebar-inner-scroll
.context-header
= link_to admin_root_path, title: _('Admin Overview') do
- .avatar-container.s40.settings-avatar
+ %span.avatar-container.s40.settings-avatar
= sprite_icon('admin', size: 24)
- .sidebar-context-title
+ %span.sidebar-context-title
= _('Admin Area')
%ul.sidebar-top-level-items{ data: { qa_selector: 'admin_sidebar_overview_submenu_content' } }
= nav_link(controller: %w(dashboard admin admin/projects users groups jobs runners gitaly_servers), html_options: {class: 'home'}) do
@@ -202,17 +202,18 @@
= render_if_exists 'layouts/nav/sidebar/credentials_link'
- = nav_link(controller: :services) do
- = link_to admin_application_settings_services_path do
- .nav-icon-container
- = sprite_icon('template')
- %span.nav-item-name
- = _('Service Templates')
- %ul.sidebar-sub-level-items.is-fly-out-only
- = nav_link(controller: :services, html_options: { class: "fly-out-top-item" } ) do
- = link_to admin_application_settings_services_path do
- %strong.fly-out-top-item-name
- = _('Service Templates')
+ - if show_service_templates_nav_link?
+ = nav_link(controller: :services) do
+ = link_to admin_application_settings_services_path do
+ .nav-icon-container
+ = sprite_icon('template')
+ %span.nav-item-name
+ = _('Service Templates')
+ %ul.sidebar-sub-level-items.is-fly-out-only
+ = nav_link(controller: :services, html_options: { class: "fly-out-top-item" } ) do
+ = link_to admin_application_settings_services_path do
+ %strong.fly-out-top-item-name
+ = _('Service Templates')
= nav_link(controller: :labels) do
= link_to admin_labels_path do
diff --git a/app/views/layouts/nav/sidebar/_group.html.haml b/app/views/layouts/nav/sidebar/_group.html.haml
index 41bec996de1..757f95f864a 100644
--- a/app/views/layouts/nav/sidebar/_group.html.haml
+++ b/app/views/layouts/nav/sidebar/_group.html.haml
@@ -1,15 +1,14 @@
- issues_count = cached_issuables_count(@group, type: :issues)
- merge_requests_count = group_open_merge_requests_count(@group)
- aside_title = @group.subgroup? ? _('Subgroup navigation') : _('Group navigation')
-- overview_title = @group.subgroup? ? _('Subgroup overview') : _('Group overview')
%aside.nav-sidebar{ class: ("sidebar-collapsed-desktop" if collapsed_sidebar?), **sidebar_tracking_attributes_by_object(@group), 'aria-label': aside_title }
.nav-sidebar-inner-scroll
.context-header
= link_to group_path(@group), title: @group.name do
- .avatar-container.rect-avatar.s40.group-avatar
+ %span.avatar-container.rect-avatar.s40.group-avatar
= group_icon(@group, class: "avatar s40 avatar-tile")
- .sidebar-context-title
+ %span.sidebar-context-title
= @group.name
%ul.sidebar-top-level-items.qa-group-sidebar
= render_if_exists 'layouts/nav/sidebar/group_trial_status_widget', group: @group
@@ -19,21 +18,23 @@
= nav_link(path: paths, unless: -> { current_path?('groups/contribution_analytics#show') }, html_options: { class: 'home' }) do
= link_to group_path(@group) do
.nav-icon-container
- = sprite_icon('home')
+ - sprite = Feature.enabled?(:sidebar_refactor, current_user) ? 'group' : 'home'
+ = sprite_icon(sprite)
%span.nav-item-name
- = overview_title
+ = group_information_title(@group)
%ul.sidebar-sub-level-items
- = nav_link(path: ['groups#show', 'groups#details', 'groups#activity', 'groups#subgroups'], html_options: { class: "fly-out-top-item" } ) do
+ = nav_link(path: paths, html_options: { class: "fly-out-top-item" } ) do
= link_to group_path(@group) do
%strong.fly-out-top-item-name
- = overview_title
+ = group_information_title(@group)
%li.divider.fly-out-top-item
- = nav_link(path: ['groups#show', 'groups#details', 'groups#subgroups'], html_options: { class: 'home' }) do
- = link_to details_group_path(@group), title: _('Group details') do
- %span
- = _('Details')
+ - if Feature.disabled?(:sidebar_refactor, current_user)
+ = nav_link(path: ['groups#show', 'groups#details', 'groups#subgroups'], html_options: { class: 'home' }) do
+ = link_to details_group_path(@group), title: _('Group details') do
+ %span
+ = _('Details')
- if group_sidebar_link?(:activity)
= nav_link(path: 'groups#activity') do
@@ -41,6 +42,19 @@
%span
= _('Activity')
+ - if group_sidebar_link?(:labels) && Feature.enabled?(:sidebar_refactor, current_user, default_enabled: :yaml)
+ = nav_link(path: 'labels#index') do
+ = link_to group_labels_path(@group), title: _('Labels') do
+ %span
+ = _('Labels')
+
+ - if Feature.enabled?(:sidebar_refactor, current_user, default_enabled: :yaml)
+ - if group_sidebar_link?(:group_members)
+ = nav_link(path: 'group_members#index') do
+ = link_to group_group_members_path(@group), title: _('Members'), data: { qa_selector: 'group_members_item' } do
+ %span
+ = _('Members')
+
= render_if_exists "layouts/nav/ee/epic_link", group: @group
- if group_sidebar_link?(:issues)
@@ -53,7 +67,7 @@
%span.badge.badge-pill.count= issues_count
%ul.sidebar-sub-level-items{ data: { qa_selector: 'group_issues_sidebar_submenu'} }
- = nav_link(path: ['groups#issues', 'labels#index', 'milestones#index', 'iterations#index'], html_options: { class: "fly-out-top-item" } ) do
+ = nav_link(path: group_issues_sub_menu_items, html_options: { class: "fly-out-top-item" } ) do
= link_to issues_group_path(@group) do
%strong.fly-out-top-item-name
= _('Issues')
@@ -71,7 +85,7 @@
%span
= boards_link_text
- - if group_sidebar_link?(:labels)
+ - if group_sidebar_link?(:labels) && Feature.disabled?(:sidebar_refactor, current_user, default_enabled: :yaml)
= nav_link(path: 'labels#index') do
= link_to group_labels_path(@group), title: _('Labels') do
%span
@@ -124,25 +138,26 @@
- if group_sidebar_link?(:wiki)
= render 'layouts/nav/sidebar/wiki_link', wiki_url: @group.wiki.web_url
- - if group_sidebar_link?(:group_members)
- = nav_link(path: 'group_members#index') do
- = link_to group_group_members_path(@group) do
- .nav-icon-container
- = sprite_icon('users')
- %span.nav-item-name.qa-group-members-item
- = _('Members')
- %ul.sidebar-sub-level-items.is-fly-out-only
- = nav_link(path: 'group_members#index', html_options: { class: "fly-out-top-item" } ) do
- = link_to group_group_members_path(@group) do
- %strong.fly-out-top-item-name
- = _('Members')
+ - if Feature.disabled?(:sidebar_refactor, current_user, default_enabled: :yaml)
+ - if group_sidebar_link?(:group_members)
+ = nav_link(path: 'group_members#index') do
+ = link_to group_group_members_path(@group) do
+ .nav-icon-container
+ = sprite_icon('users')
+ %span.nav-item-name.qa-group-members-item
+ = _('Members')
+ %ul.sidebar-sub-level-items.is-fly-out-only
+ = nav_link(path: 'group_members#index', html_options: { class: "fly-out-top-item" } ) do
+ = link_to group_group_members_path(@group) do
+ %strong.fly-out-top-item-name
+ = _('Members')
- if group_sidebar_link?(:settings)
= nav_link(path: group_settings_nav_link_paths) do
= link_to edit_group_path(@group) do
.nav-icon-container
= sprite_icon('settings')
- %span.nav-item-name.qa-group-settings-item
+ %span.nav-item-name{ data: { qa_selector: 'group_settings' } }
= _('Settings')
%ul.sidebar-sub-level-items.qa-group-sidebar-submenu{ data: { testid: 'group-settings-menu' } }
= nav_link(path: %w[groups#projects groups#edit badges#index ci_cd#show groups/applications#index], html_options: { class: "fly-out-top-item" } ) do
@@ -170,7 +185,7 @@
%span
= _('Repository')
- = nav_link(controller: :ci_cd) do
+ = nav_link(controller: [:ci_cd, 'groups/runners']) do
= link_to group_settings_ci_cd_path(@group), title: _('CI/CD') do
%span
= _('CI/CD')
diff --git a/app/views/layouts/nav/sidebar/_profile.html.haml b/app/views/layouts/nav/sidebar/_profile.html.haml
index dda5e6b9636..63b97e3133c 100644
--- a/app/views/layouts/nav/sidebar/_profile.html.haml
+++ b/app/views/layouts/nav/sidebar/_profile.html.haml
@@ -2,9 +2,9 @@
.nav-sidebar-inner-scroll
.context-header
= link_to profile_path, title: _('Profile Settings') do
- .avatar-container.s40.settings-avatar
+ %span.avatar-container.s40.settings-avatar
= image_tag avatar_icon_for_user(current_user, 40), class: "avatar s40 avatar-tile js-sidebar-user-avatar", alt: current_user.name, data: { testid: 'sidebar-user-avatar' }
- .sidebar-context-title= _('User Settings')
+ %span.sidebar-context-title= _('User Settings')
%ul.sidebar-top-level-items
= nav_link(path: 'profiles#show', html_options: {class: 'home'}) do
= link_to profile_path do
diff --git a/app/views/layouts/nav/sidebar/_project.html.haml b/app/views/layouts/nav/sidebar/_project.html.haml
index 3d0c6baffd5..a06f9f8d6ef 100644
--- a/app/views/layouts/nav/sidebar/_project.html.haml
+++ b/app/views/layouts/nav/sidebar/_project.html.haml
@@ -1,3 +1 @@
--# We're migration the project sidebar to a logical model based structure. If you need to update
--# any of the existing menus, you can find them in app/views/layouts/nav/sidebar/_project_menus.html.haml.
= render partial: 'shared/nav/sidebar', object: Sidebars::Projects::Panel.new(project_sidebar_context(@project, current_user, current_ref))
diff --git a/app/views/layouts/nav/sidebar/_project_menus.html.haml b/app/views/layouts/nav/sidebar/_project_menus.html.haml
deleted file mode 100644
index ed072c0f6a2..00000000000
--- a/app/views/layouts/nav/sidebar/_project_menus.html.haml
+++ /dev/null
@@ -1,380 +0,0 @@
-- if project_nav_tab? :issues
- = nav_link(controller: @project.issues_enabled? ? ['projects/issues', :labels, :milestones, :boards, :iterations] : 'projects/issues') do
- = link_to project_issues_path(@project), class: 'shortcuts-issues qa-issues-item' do
- .nav-icon-container
- = sprite_icon('issues')
- %span.nav-item-name#js-onboarding-issues-link
- = _('Issues')
- - if @project.issues_enabled?
- %span.badge.badge-pill.count.issue_counter
- = number_with_delimiter(@project.open_issues_count(current_user))
-
- %ul.sidebar-sub-level-items
- = nav_link(controller: 'projects/issues', action: :index, html_options: { class: "fly-out-top-item" } ) do
- = link_to project_issues_path(@project) do
- %strong.fly-out-top-item-name
- = _('Issues')
- - if @project.issues_enabled?
- %span.badge.badge-pill.count.issue_counter.fly-out-badge
- = number_with_delimiter(@project.open_issues_count(current_user))
- %li.divider.fly-out-top-item
- = nav_link(controller: :issues, action: :index) do
- = link_to project_issues_path(@project), title: _('Issues') do
- %span
- = _('List')
-
- = nav_link(controller: :boards) do
- = link_to project_boards_path(@project), title: boards_link_text, data: { qa_selector: "issue_boards_link" } do
- %span
- = boards_link_text
-
- = nav_link(controller: :labels) do
- = link_to project_labels_path(@project), title: _('Labels'), class: 'qa-labels-link' do
- %span
- = _('Labels')
-
- = render 'projects/sidebar/issues_service_desk'
-
- = nav_link(controller: :milestones) do
- = link_to project_milestones_path(@project), title: _('Milestones'), class: 'qa-milestones-link' do
- %span
- = _('Milestones')
-
- = render_if_exists 'layouts/nav/sidebar/project_iterations_link'
-
-- if project_nav_tab?(:external_issue_tracker)
- - issue_tracker = @project.external_issue_tracker
- - if issue_tracker.is_a?(JiraService) && project_jira_issues_integration?
- = render_if_exists 'layouts/nav/sidebar/project_jira_issues_link', issue_tracker: issue_tracker
- - else
- = nav_link do
- = link_to issue_tracker.issue_tracker_path, target: '_blank', rel: 'noopener noreferrer', class: 'shortcuts-external_tracker' do
- .nav-icon-container
- = sprite_icon('external-link')
- %span.nav-item-name
- = issue_tracker.title
- %ul.sidebar-sub-level-items.is-fly-out-only
- = nav_link(html_options: { class: "fly-out-top-item" } ) do
- = link_to issue_tracker.issue_tracker_path, target: '_blank', rel: 'noopener noreferrer' do
- %strong.fly-out-top-item-name
- = issue_tracker.title
-
-- if (project_nav_tab? :labels) && !@project.issues_enabled?
- = nav_link(controller: [:labels]) do
- = link_to project_labels_path(@project), title: _('Labels'), class: 'shortcuts-labels qa-labels-items' do
- .nav-icon-container
- = sprite_icon('label')
- %span.nav-item-name#js-onboarding-labels-link
- = _('Labels')
-
-- if project_nav_tab? :merge_requests
- = nav_link(controller: @project.issues_enabled? ? :merge_requests : [:merge_requests, :milestones]) do
- = link_to project_merge_requests_path(@project), class: 'shortcuts-merge_requests', data: { qa_selector: 'merge_requests_link' } do
- .nav-icon-container
- = sprite_icon('git-merge')
- %span.nav-item-name#js-onboarding-mr-link
- = _('Merge requests')
- %span.badge.badge-pill.count.merge_counter.js-merge-counter
- = number_with_delimiter(@project.open_merge_requests_count)
- %ul.sidebar-sub-level-items.is-fly-out-only
- = nav_link(controller: :merge_requests, html_options: { class: "fly-out-top-item" } ) do
- = link_to project_merge_requests_path(@project) do
- %strong.fly-out-top-item-name
- = _('Merge requests')
- %span.badge.badge-pill.count.merge_counter.js-merge-counter.fly-out-badge
- = number_with_delimiter(@project.open_merge_requests_count)
-
-= render_if_exists "layouts/nav/requirements_link", project: @project
-
-- if project_nav_tab? :pipelines
- = nav_link(controller: [:pipelines, :builds, :jobs, :pipeline_schedules, :artifacts, :test_cases, :pipeline_editor], unless: -> { current_path?('projects/pipelines#charts') }) do
- = link_to project_pipelines_path(@project), class: 'shortcuts-pipelines qa-link-pipelines rspec-link-pipelines', data: { qa_selector: 'ci_cd_link' } do
- .nav-icon-container
- = sprite_icon('rocket')
- %span.nav-item-name#js-onboarding-pipelines-link
- = _('CI/CD')
-
- %ul.sidebar-sub-level-items
- = nav_link(controller: [:pipelines, :builds, :jobs, :pipeline_schedules, :artifacts, :test_cases, :pipeline_editor], html_options: { class: "fly-out-top-item" }) do
- = link_to project_pipelines_path(@project) do
- %strong.fly-out-top-item-name
- = _('CI/CD')
- %li.divider.fly-out-top-item
- - if project_nav_tab? :pipelines
- = nav_link(path: ['pipelines#index', 'pipelines#show']) do
- = link_to project_pipelines_path(@project), title: _('Pipelines'), class: 'shortcuts-pipelines' do
- %span
- = _('Pipelines')
-
- - if can_view_pipeline_editor?(@project)
- = nav_link(controller: :pipeline_editor, action: :show) do
- = link_to project_ci_pipeline_editor_path(@project), title: s_('Pipelines|Editor') do
- %span
- = s_('Pipelines|Editor')
-
- - if project_nav_tab? :builds
- = nav_link(controller: :jobs) do
- = link_to project_jobs_path(@project), title: _('Jobs'), class: 'shortcuts-builds' do
- %span
- = _('Jobs')
-
- - if Feature.enabled?(:artifacts_management_page, @project)
- = nav_link(controller: :artifacts, action: :index) do
- = link_to project_artifacts_path(@project), title: _('Artifacts'), class: 'shortcuts-builds' do
- %span
- = _('Artifacts')
-
- - if project_nav_tab?(:pipelines)
- = nav_link(controller: :pipeline_schedules) do
- = link_to pipeline_schedules_path(@project), title: _('Schedules'), class: 'shortcuts-builds' do
- %span
- = _('Schedules')
-
- = render_if_exists "layouts/nav/test_cases_link", project: @project
-
-- if project_nav_tab? :security_and_compliance
- = render_if_exists 'layouts/nav/sidebar/project_security_link' # EE-specific
-
-- if project_nav_tab? :operations
- = nav_link(controller: sidebar_operations_paths) do
- = link_to sidebar_operations_link_path, class: 'shortcuts-operations', data: { qa_selector: 'operations_link' } do
- .nav-icon-container
- = sprite_icon('cloud-gear')
- %span.nav-item-name
- = _('Operations')
-
- %ul.sidebar-sub-level-items
- = nav_link(controller: sidebar_operations_paths, html_options: { class: "fly-out-top-item" } ) do
- = link_to sidebar_operations_link_path do
- %strong.fly-out-top-item-name
- = _('Operations')
- %li.divider.fly-out-top-item
-
- - if project_nav_tab? :metrics_dashboards
- = nav_link(controller: :metrics_dashboard, action: [:show]) do
- = link_to project_metrics_dashboard_path(@project), title: _('Metrics'), class: 'shortcuts-metrics', data: { qa_selector: 'operations_metrics_link' } do
- %span
- = _('Metrics')
-
- - if project_nav_tab?(:environments) && can?(current_user, :read_pod_logs, @project)
- = nav_link(controller: :logs, action: [:index]) do
- = link_to project_logs_path(@project), title: _('Logs') do
- %span
- = _('Logs')
-
- - if project_nav_tab? :environments
- = render "layouts/nav/sidebar/tracing_link"
-
- - if project_nav_tab?(:error_tracking)
- = nav_link(controller: :error_tracking) do
- = link_to project_error_tracking_index_path(@project), title: _('Error Tracking') do
- %span
- = _('Error Tracking')
-
- - if project_nav_tab?(:alert_management)
- = nav_link(controller: :alert_management) do
- = link_to project_alert_management_index_path(@project), title: _('Alerts') do
- %span
- = _('Alerts')
-
- - if project_nav_tab?(:incidents)
- = nav_link(controller: :incidents) do
- = link_to project_incidents_path(@project), title: _('Incidents'), data: { qa_selector: 'operations_incidents_link' } do
- %span
- = _('Incidents')
-
- = render_if_exists 'projects/sidebar/oncall_schedules'
-
- - if project_nav_tab? :serverless
- = nav_link(controller: :functions) do
- = link_to project_serverless_functions_path(@project), title: _('Serverless') do
- %span
- = _('Serverless')
-
- - if project_nav_tab? :terraform
- = nav_link(controller: :terraform) do
- = link_to project_terraform_index_path(@project), title: _('Terraform') do
- %span
- = _('Terraform')
-
- - if project_nav_tab? :clusters
- - show_cluster_hint = show_gke_cluster_integration_callout?(@project)
- = nav_link(controller: [:cluster_agents, :clusters]) do
- = link_to project_clusters_path(@project), title: _('Kubernetes'), class: 'shortcuts-kubernetes' do
- %span
- = _('Kubernetes')
- - if show_cluster_hint
- .js-feature-highlight{ disabled: true,
- data: { trigger: 'manual',
- container: 'body',
- placement: 'right',
- highlight: UserCalloutsHelper::GKE_CLUSTER_INTEGRATION,
- highlight_priority: UserCallout.feature_names[:GKE_CLUSTER_INTEGRATION],
- dismiss_endpoint: user_callouts_path,
- auto_devops_help_path: help_page_path('topics/autodevops/index.md') } }
- - if project_nav_tab? :environments
- = nav_link(controller: :environments, action: [:index, :folder, :show, :new, :edit, :create, :update, :stop, :terminal]) do
- = link_to project_environments_path(@project), title: _('Environments'), class: 'shortcuts-environments qa-operations-environments-link' do
- %span
- = _('Environments')
-
- - if project_nav_tab? :feature_flags
- = nav_link(controller: :feature_flags) do
- = link_to project_feature_flags_path(@project), title: _('Feature Flags'), class: 'shortcuts-feature-flags' do
- %span
- = _('Feature Flags')
-
- - if project_nav_tab?(:product_analytics)
- = nav_link(controller: :product_analytics) do
- = link_to project_product_analytics_path(@project), title: _('Product Analytics') do
- %span
- = _('Product Analytics')
-
-= render_if_exists 'layouts/nav/sidebar/project_packages_link'
-
-- if project_nav_tab? :analytics
- = render 'layouts/nav/sidebar/analytics_links', links: project_analytics_navbar_links(@project, current_user)
-
-- if project_nav_tab?(:confluence)
- - confluence_url = project_wikis_confluence_path(@project)
- = nav_link do
- = link_to confluence_url, class: 'shortcuts-confluence' do
- .nav-icon-container
- = image_tag 'confluence.svg', alt: _('Confluence')
- %span.nav-item-name
- = _('Confluence')
- %ul.sidebar-sub-level-items.is-fly-out-only
- = nav_link(html_options: { class: 'fly-out-top-item' } ) do
- = link_to confluence_url, target: '_blank', rel: 'noopener noreferrer' do
- %strong.fly-out-top-item-name
- = _('Confluence')
-
-- if project_nav_tab? :wiki
- = render 'layouts/nav/sidebar/wiki_link', wiki_url: wiki_path(@project.wiki)
-
-- if project_nav_tab?(:external_wiki)
- - external_wiki_url = @project.external_wiki.external_wiki_url
- = nav_link do
- = link_to external_wiki_url, class: 'shortcuts-external_wiki' do
- .nav-icon-container
- = sprite_icon('external-link')
- %span.nav-item-name
- = s_('ExternalWikiService|External wiki')
- %ul.sidebar-sub-level-items.is-fly-out-only
- = nav_link(html_options: { class: "fly-out-top-item" } ) do
- = link_to external_wiki_url do
- %strong.fly-out-top-item-name
- = s_('ExternalWikiService|External wiki')
-
-- if project_nav_tab? :snippets
- = nav_link(controller: :snippets) do
- = link_to project_snippets_path(@project), class: 'shortcuts-snippets', data: { qa_selector: 'snippets_link' } do
- .nav-icon-container
- = sprite_icon('snippet')
- %span.nav-item-name
- = _('Snippets')
- %ul.sidebar-sub-level-items.is-fly-out-only
- = nav_link(controller: :snippets, html_options: { class: "fly-out-top-item" } ) do
- = link_to project_snippets_path(@project) do
- %strong.fly-out-top-item-name
- = _('Snippets')
-
-= nav_link(controller: :project_members) do
- = link_to project_project_members_path(@project), title: _('Members'), class: 'qa-members-link', id: 'js-onboarding-members-link' do
- .nav-icon-container
- = sprite_icon('users')
- %span.nav-item-name
- = _('Members')
- %ul.sidebar-sub-level-items.is-fly-out-only
- = nav_link(path: %w[members#show], html_options: { class: "fly-out-top-item" } ) do
- = link_to project_project_members_path(@project) do
- %strong.fly-out-top-item-name
- = _('Members')
-
-- if project_nav_tab? :settings
- = nav_link(path: sidebar_settings_paths) do
- = link_to edit_project_path(@project) do
- .nav-icon-container
- = sprite_icon('settings')
- %span.nav-item-name.qa-settings-item#js-onboarding-settings-link
- = _('Settings')
-
- %ul.sidebar-sub-level-items
- - can_edit = can?(current_user, :admin_project, @project)
- - if can_edit
- = nav_link(path: sidebar_settings_paths, html_options: { class: "fly-out-top-item" } ) do
- = link_to edit_project_path(@project) do
- %strong.fly-out-top-item-name
- = _('Settings')
- %li.divider.fly-out-top-item
- = nav_link(path: %w[projects#edit]) do
- = link_to edit_project_path(@project), title: _('General'), class: 'qa-general-settings-link' do
- %span
- = _('General')
- - if can_edit
- = nav_link(controller: [:integrations, :services]) do
- = link_to project_settings_integrations_path(@project), title: _('Integrations'), data: { qa_selector: 'integrations_settings_link' } do
- %span
- = _('Integrations')
- = nav_link(controller: [:hooks, :hook_logs]) do
- = link_to project_hooks_path(@project), title: _('Webhooks'), data: { qa_selector: 'webhooks_settings_link' } do
- %span
- = _('Webhooks')
- - if can?(current_user, :read_resource_access_tokens, @project)
- = nav_link(controller: [:access_tokens]) do
- = link_to project_settings_access_tokens_path(@project), title: _('Access Tokens'), data: { qa_selector: 'access_tokens_settings_link' } do
- %span
- = _('Access Tokens')
- = nav_link(controller: :repository) do
- = link_to project_settings_repository_path(@project), title: _('Repository') do
- %span
- = _('Repository')
- - if !@project.archived? && @project.feature_available?(:builds, current_user)
- = nav_link(controller: :ci_cd) do
- = link_to project_settings_ci_cd_path(@project), title: _('CI/CD') do
- %span
- = _('CI/CD')
- - if settings_operations_available?
- = nav_link(controller: [:operations]) do
- = link_to project_settings_operations_path(@project), title: _('Operations'), data: { qa_selector: 'operations_settings_link' } do
- = _('Operations')
- - if @project.pages_available?
- = nav_link(controller: :pages) do
- = link_to project_pages_path(@project), title: _('Pages') do
- %span
- = _('Pages')
-
--# Shortcut to Project > Activity
-%li.hidden
- = link_to activity_project_path(@project), title: _('Activity'), class: 'shortcuts-project-activity' do
- %span
- = _('Activity')
-
--# Shortcut to Repository > Graph (formerly, Network)
-- if project_nav_tab? :network
- %li.hidden
- = link_to project_network_path(@project, current_ref), title: _('Network'), class: 'shortcuts-network' do
- = _('Graph')
-
--# Shortcut to Issues > New Issue
-- if project_nav_tab?(:issues)
- %li.hidden
- = link_to new_project_issue_path(@project), class: 'shortcuts-new-issue' do
- = _('Create a new issue')
-
--# Shortcut to Pipelines > Jobs
-- if project_nav_tab? :builds
- %li.hidden
- = link_to project_jobs_path(@project), title: _('Jobs'), class: 'shortcuts-builds' do
- = _('Jobs')
-
--# Shortcut to commits page
-- if project_nav_tab? :commits
- %li.hidden
- = link_to project_commits_path(@project), title: _('Commits'), class: 'shortcuts-commits' do
- = _('Commits')
-
--# Shortcut to issue boards
-- if project_nav_tab?(:issues)
- %li.hidden
- = link_to _('Issue Boards'), project_boards_path(@project), title: _('Issue Boards'), class: 'shortcuts-issue-boards'
diff --git a/app/views/layouts/nav/sidebar/_project_packages_link.html.haml b/app/views/layouts/nav/sidebar/_project_packages_link.html.haml
deleted file mode 100644
index b28468a7969..00000000000
--- a/app/views/layouts/nav/sidebar/_project_packages_link.html.haml
+++ /dev/null
@@ -1,27 +0,0 @@
-- packages_link = project_nav_tab?(:packages) ? project_packages_path(@project) : project_container_registry_index_path(@project)
-
-- if (project_nav_tab?(:packages) || project_nav_tab?(:container_registry))
- = nav_link controller: [:packages, :repositories, :infrastructure_registry] do
- = link_to packages_link, data: { qa_selector: 'packages_link' } do
- .nav-icon-container
- = sprite_icon('package')
- %span.nav-item-name
- = _('Packages & Registries')
- %ul.sidebar-sub-level-items
- = nav_link(controller: [:packages, :repositories, :infrastructure_registry], html_options: { class: "fly-out-top-item" } ) do
- = link_to packages_link do
- %strong.fly-out-top-item-name
- = _('Packages & Registries')
- %li.divider.fly-out-top-item
- - if project_nav_tab? :packages
- = nav_link controller: :packages do
- = link_to project_packages_path(@project), title: _('Package Registry') do
- %span= _('Package Registry')
- - if project_nav_tab? :container_registry
- = nav_link controller: :repositories do
- = link_to project_container_registry_index_path(@project), class: 'shortcuts-container-registry', title: _('Container Registry') do
- %span= _('Container Registry')
- - if project_nav_tab? :infrastructure_registry
- = nav_link controller: :infrastructure_registry do
- = link_to project_infrastructure_registry_index_path(@project), title: _('Infrastructure Registry') do
- %span= _('Infrastructure Registry')
diff --git a/app/views/layouts/nav/sidebar/_project_security_link.html.haml b/app/views/layouts/nav/sidebar/_project_security_link.html.haml
deleted file mode 100644
index 426845639e3..00000000000
--- a/app/views/layouts/nav/sidebar/_project_security_link.html.haml
+++ /dev/null
@@ -1,21 +0,0 @@
-- top_level_link = project_security_configuration_path(@project)
-- top_level_qa_selector = 'security_configuration_link'
-- if any_project_nav_tab?([:security_configuration])
- = nav_link(path: sidebar_security_paths) do
- = link_to top_level_link, data: { qa_selector: top_level_qa_selector } do
- .nav-icon-container
- = sprite_icon('shield')
- %span.nav-item-name
- = _('Security & Compliance')
-
- %ul.sidebar-sub-level-items
- = nav_link(path: sidebar_security_paths, html_options: { class: "fly-out-top-item" } ) do
- = link_to top_level_link do
- %strong.fly-out-top-item-name
- = _('Security & Compliance')
-
- %li.divider.fly-out-top-item
- - if project_nav_tab?(:security_configuration)
- = nav_link(path: sidebar_security_configuration_paths) do
- = link_to project_security_configuration_path(@project), title: _('Configuration'), data: { qa_selector: 'security_configuration_link'} do
- %span= _('Configuration')
diff --git a/app/views/layouts/nav/sidebar/_tracing_link.html.haml b/app/views/layouts/nav/sidebar/_tracing_link.html.haml
deleted file mode 100644
index 7a31a20f5f0..00000000000
--- a/app/views/layouts/nav/sidebar/_tracing_link.html.haml
+++ /dev/null
@@ -1,7 +0,0 @@
-- return unless can?(current_user, :read_environment, @project)
-
-- if project_nav_tab? :settings
- = nav_link(controller: :tracings, action: [:show]) do
- = link_to project_tracing_path(@project), title: _('Tracing') do
- %span
- = _('Tracing')
diff --git a/app/views/layouts/simple_registration.html.haml b/app/views/layouts/simple_registration.html.haml
new file mode 100644
index 00000000000..dc7ec25c96e
--- /dev/null
+++ b/app/views/layouts/simple_registration.html.haml
@@ -0,0 +1,10 @@
+!!! 5
+%html{ lang: "en" }
+ = render "layouts/head"
+ %body.login-page.application.navless{ class: user_application_theme, data: { page: body_data_page } }
+ = render "layouts/header/logo_with_title"
+ = render "layouts/broadcast"
+ .container.navless-container.pt-0
+ .content.mw-460.mx-auto
+ = render "layouts/flash"
+ = yield
diff --git a/app/views/notify/change_in_merge_request_draft_status_email.html.haml b/app/views/notify/change_in_merge_request_draft_status_email.html.haml
index 5604a30d9f1..64ceb77e85c 100644
--- a/app/views/notify/change_in_merge_request_draft_status_email.html.haml
+++ b/app/views/notify/change_in_merge_request_draft_status_email.html.haml
@@ -1,2 +1,2 @@
-%p
- = _('%{username} changed the draft status of merge request %{mr_reference}' % {username: sanitize_name(@updated_by_user.name), mr_reference: @merge_request.to_reference })
+%p= html_escape(_('%{username} changed the draft status of merge request %{mr_link}')) % { username: link_to(@updated_by_user.name, user_url(@updated_by_user)),
+ mr_link: merge_request_reference_link(@merge_request) }
diff --git a/app/views/notify/in_product_marketing_email.html.haml b/app/views/notify/in_product_marketing_email.html.haml
index 015a12bbb6d..a1c3ecfb87e 100644
--- a/app/views/notify/in_product_marketing_email.html.haml
+++ b/app/views/notify/in_product_marketing_email.html.haml
@@ -163,43 +163,43 @@
%table{ border: "0", cellpadding: "0", cellspacing: "0", role: "presentation", width: "100%" }
%tr
%td{ align: "left", style: "padding: 0 20px;" }
- = about_link('mailers/in_product_marketing', 'gitlab-logo-gray-rgb.png', 200)
+ = about_link('mailers/in_product_marketing/gitlab-logo-gray-rgb.png', 200)
%tr
%td{ "aria-hidden" => "true", height: "30", style: "font-size: 0; line-height: 0;" }
%tr{ style: "background-color: #ffffff;" }
%td{ style: "color: #424242; padding: 10px 30px; text-align: center; font-family: 'Source Sans Pro', helvetica, arial, sans-serif;font-size: 16px; line-height: 22px; border: 1px solid #dddddd" }
%p
- = in_product_marketing_progress(@track, @series, format: :html).html_safe
+ = @message.progress.html_safe
%tr
%td{ bgcolor: "#ffffff", height: "auto", style: "max-width: 600px; width: 100%; text-align: center; height: 200px; padding: 25px 15px; mso-line-height-rule: exactly; min-height: 40px; font-family: 'Source Sans Pro', helvetica, arial, sans-serif;", valign: "middle", width: "100%" }
- = in_product_marketing_logo(@track, @series)
+ = inline_image_link(@message.logo_path, { width: '150', style: 'width: 150px;' })
%h1{ style: "font-size: 40px; line-height: 46x; color: #000000; padding: 20px 0 0 0; font-weight: normal;" }
- = in_product_marketing_title(@track, @series)
+ = @message.title
%h2{ style: "font-size: 28px; line-height: 34px; color: #000000; padding: 0; font-weight: 400;" }
- = in_product_marketing_subtitle(@track, @series)
+ = @message.subtitle
%tr
%td{ style: "padding: 10px 20px 30px 20px; font-family: 'Source Sans Pro', helvetica, arial, sans-serif; color:#000000; font-size: 18px; line-height: 24px;" }
%p{ style: "margin: 0 0 20px 0;" }
- = in_product_marketing_body_line1(@track, @series, format: :html).html_safe
- - in_product_marketing_body_line2(@track, @series, format: :html)&.tap do |line|
+ = @message.body_line1.html_safe
+ - @message.body_line2&.tap do |line|
%p{ style: "margin: 0 0 20px 0;" }
= line.html_safe
%tr
%td{ align: "center", style: "padding: 10px 20px 80px 20px; font-family: 'Source Sans Pro', helvetica, arial, sans-serif;" }
- .cta_link= cta_link(@track, @series, @group, format: :html)
+ .cta_link= @message.cta_link
%tr{ style: "background-color: #ffffff;" }
%td{ align: "center", style: "padding:75px 20px 25px;" }
- = about_link('', 'gitlab_logo.png', 80)
+ = about_link('gitlab_logo.png', 80)
%tr{ style: "background-color: #ffffff;" }
%td{ align: "center", style: "padding:0px ;" }
%tr{ style: "background-color: #ffffff;" }
%td{ align: "center", style: "padding:0px 10px; font-family: 'Source Sans Pro', helvetica, arial, sans-serif; " }
%span.footernav{ style: "color: #6e49cb; font-size: 16px; line-height: 26px; font-family: 'Source Sans Pro', helvetica, arial, sans-serif;" }
- = footer_links(format: :html).join('&nbsp;' * 3 + '|' + '&nbsp;' * 4).html_safe
+ = @message.footer_links.join('&nbsp;' * 3 + '|' + '&nbsp;' * 4).html_safe
%tr{ style: "background-color:#ffffff;" }
%td{ align: "center", style: "padding: 40px 30px 20px 30px; font-family: 'Source Sans Pro', helvetica, arial, sans-serif;" }
- .address= address(format: :html)
+ .address= @message.address
%tr{ style: "background-color: #ffffff;" }
%td{ align: "left", style: "padding:20px 30px 20px 30px;" }
%span.footernav{ style: "color: #6e49cb; font-size: 14px; line-height: 20px; font-family: 'Source Sans Pro', helvetica, arial, sans-serif; color:#424242;" }
- = unsubscribe(@track, @series, format: :html).html_safe
+ = @message.unsubscribe.html_safe
diff --git a/app/views/notify/in_product_marketing_email.text.erb b/app/views/notify/in_product_marketing_email.text.erb
index bc8315e49a0..7d0fe7aec6d 100644
--- a/app/views/notify/in_product_marketing_email.text.erb
+++ b/app/views/notify/in_product_marketing_email.text.erb
@@ -1,14 +1,14 @@
-<%= in_product_marketing_tagline(@track, @series) %>
+<%= @message.tagline %>
-<%= in_product_marketing_title(@track, @series) %>
-<%= in_product_marketing_subtitle(@track, @series) %>
+<%= @message.title %>
+<%= @message.subtitle %>
-<%= in_product_marketing_body_line1(@track, @series) %>
+<%= @message.body_line1 %>
-<%= in_product_marketing_body_line2(@track, @series) %>
+<%= @message.body_line2 %>
-<%= cta_link(@track, @series, @group) %>
+<%= @message.cta_link %>
@@ -16,8 +16,8 @@
-<%= footer_links %>
+<%= @message.footer_links %>
-<%= address %>
+<%= @message.address %>
-<%= unsubscribe(@track, @series) %>
+<%= @message.unsubscribe %>
diff --git a/app/views/notify/new_issue_email.html.haml b/app/views/notify/new_issue_email.html.haml
index 7f0a50e9248..3219ee34736 100644
--- a/app/views/notify/new_issue_email.html.haml
+++ b/app/views/notify/new_issue_email.html.haml
@@ -1,5 +1,6 @@
%p.details
- #{link_to @issue.author_name, user_url(@issue.author)} created an issue #{issue_reference_link(@issue)}:
+ = html_escape(_('%{user} created an issue: %{issue_link}')) % { user: link_to(@issue.author_name, user_url(@issue.author)),
+ issue_link: issue_reference_link(@issue) }
- if @issue.assignees.any?
%p
diff --git a/app/views/notify/new_issue_email.text.erb b/app/views/notify/new_issue_email.text.erb
index bd61db3ee76..7c78d67316d 100644
--- a/app/views/notify/new_issue_email.text.erb
+++ b/app/views/notify/new_issue_email.text.erb
@@ -1,4 +1,5 @@
-<%= sanitize_name(@issue.author_name) %> <%= 'created an issue:' %> <%= url_for(project_issue_url(@issue.project, @issue)) %>
+<%= _('%{user} created an issue: %{issue_link}') % { user: sanitize_name(@issue.author_name),
+ issue_link: url_for(project_issue_url(@issue.project, @issue)) } %>
<%= assignees_label(@issue) if @issue.assignees.any? %>
diff --git a/app/views/notify/new_merge_request_email.html.haml b/app/views/notify/new_merge_request_email.html.haml
index 8fdba10e7a1..c8a0a6591a6 100644
--- a/app/views/notify/new_merge_request_email.html.haml
+++ b/app/views/notify/new_merge_request_email.html.haml
@@ -1,8 +1,6 @@
%p.details
- = html_escape(_('%{userLinkStart}%{user}%{linkEnd} created a %{mrLinkStart}merge request%{linkEnd}:')) % {userLinkStart: "<a href=\"#{user_url(@merge_request.author)}\">".html_safe,
- user: @merge_request.author_name,
- mrLinkStart: "<a href=\"#{@target_url}\">".html_safe,
- linkEnd: '</a>'.html_safe}
+ = html_escape(_('%{user} created a merge request: %{mr_link}')) % { user: link_to(@merge_request.author_name, user_url(@merge_request.author)),
+ mr_link: merge_request_reference_link(@merge_request) }
%p
.branch
diff --git a/app/views/notify/new_merge_request_email.text.erb b/app/views/notify/new_merge_request_email.text.erb
index 6148af4890e..09e8ca36225 100644
--- a/app/views/notify/new_merge_request_email.text.erb
+++ b/app/views/notify/new_merge_request_email.text.erb
@@ -1,7 +1,9 @@
-<%= sanitize_name(@merge_request.author_name) %> <%= 'created a merge request:' %> <%= url_for(project_merge_request_url(@merge_request.target_project, @merge_request)) %>
+<%= _('%{user} created a merge request: %{mr_link}') % { user: sanitize_name(@merge_request.author_name),
+ mr_link: url_for(project_merge_request_url(@merge_request.target_project, @merge_request)) }
+%>
<%= merge_path_description(@merge_request, 'to') %>
-<%= 'Author:' %> <%= @merge_request.author_name %>
+<%= "#{_('Author')}: #{sanitize_name(@merge_request.author_name)}" %>
<%= assignees_label(@merge_request) if @merge_request.assignees.any? %>
<%= reviewers_label(@merge_request) if @merge_request.reviewers.any? %>
<%= render_if_exists 'notify/merge_request_approvers', presenter: @mr_presenter %>
diff --git a/app/views/profiles/chat_names/_chat_name.html.haml b/app/views/profiles/chat_names/_chat_name.html.haml
index ca895972b71..24c25bc1ab2 100644
--- a/app/views/profiles/chat_names/_chat_name.html.haml
+++ b/app/views/profiles/chat_names/_chat_name.html.haml
@@ -1,5 +1,5 @@
-- service = chat_name.service
-- project = service.project
+- integration = chat_name.integration
+- project = integration.project
%tr
%td
%strong
@@ -10,9 +10,9 @@
%td
%strong
- if can?(current_user, :admin_project, project)
- = link_to service.title, edit_project_service_path(project, service)
+ = link_to integration.title, edit_project_service_path(project, integration)
- else
- = service.title
+ = integration.title
%td
= chat_name.team_domain
%td
diff --git a/app/views/profiles/keys/_form.html.haml b/app/views/profiles/keys/_form.html.haml
index 35335f3ef80..74b48115d0e 100644
--- a/app/views/profiles/keys/_form.html.haml
+++ b/app/views/profiles/keys/_form.html.haml
@@ -5,12 +5,12 @@
.form-group
= f.label :key, s_('Profiles|Key'), class: 'label-bold'
%p= _("Paste your public SSH key, which is usually contained in the file '~/.ssh/id_ed25519.pub' or '~/.ssh/id_rsa.pub' and begins with 'ssh-ed25519' or 'ssh-rsa'. Do not paste your private SSH key, as that can compromise your identity.")
- = f.text_area :key, class: "form-control js-add-ssh-key-validation-input qa-key-public-key-field", rows: 8, required: true, placeholder: s_('Profiles|Typically starts with "ssh-ed25519 …" or "ssh-rsa …"')
+ = f.text_area :key, class: "form-control gl-form-input js-add-ssh-key-validation-input qa-key-public-key-field", rows: 8, required: true, placeholder: s_('Profiles|Typically starts with "ssh-ed25519 …" or "ssh-rsa …"')
.form-row
.col.form-group
= f.label :title, _('Title'), class: 'label-bold'
- = f.text_field :title, class: "form-control input-lg qa-key-title-field", required: true, placeholder: s_('Profiles|e.g. My MacBook key')
- %p.form-text.text-muted= s_('Profiles|Give your individual key a title.')
+ = f.text_field :title, class: "form-control gl-form-input input-lg qa-key-title-field", required: true, placeholder: s_('Profiles|e.g. My MacBook key')
+ %p.form-text.text-muted= s_('Profiles|Give your individual key a title. This will be publicly visible.')
.col.form-group
= f.label :expires_at, s_('Profiles|Expires at'), class: 'label-bold'
diff --git a/app/views/profiles/keys/_key.html.haml b/app/views/profiles/keys/_key.html.haml
index 4eb321050ad..178ed01c766 100644
--- a/app/views/profiles/keys/_key.html.haml
+++ b/app/views/profiles/keys/_key.html.haml
@@ -28,4 +28,4 @@
%span.key-created-at.gl-display-flex.gl-align-items-center
- if key.can_delete?
.gl-ml-3
- = render 'shared/ssh_keys/key_delete', html_class: "btn gl-button btn-icon btn-danger js-confirm-modal-button", button_data: ssh_key_delete_modal_data(key, path_to_key(key, is_admin))
+ = render 'shared/ssh_keys/key_delete', html_class: "btn gl-button btn-icon btn-default js-confirm-modal-button", button_data: ssh_key_delete_modal_data(key, path_to_key(key, is_admin))
diff --git a/app/views/profiles/passwords/new.html.haml b/app/views/profiles/passwords/new.html.haml
index efcd0bb621f..7780ffe0cb4 100644
--- a/app/views/profiles/passwords/new.html.haml
+++ b/app/views/profiles/passwords/new.html.haml
@@ -16,16 +16,16 @@
.col-sm-2.col-form-label
= f.label :current_password, _('Current password')
.col-sm-10
- = f.password_field :current_password, required: true, class: 'form-control gl-form-input'
+ = f.password_field :current_password, required: true, class: 'form-control gl-form-input', data: { qa_selector: 'current_password_field' }
.form-group.row
.col-sm-2.col-form-label
= f.label :password, _('New password')
.col-sm-10
- = f.password_field :password, required: true, class: 'form-control gl-form-input'
+ = f.password_field :password, required: true, class: 'form-control gl-form-input', data: { qa_selector: 'new_password_field' }
.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, class: 'form-control gl-form-input'
+ = f.password_field :password_confirmation, required: true, class: 'form-control gl-form-input', data: { qa_selector: 'confirm_password_field' }
.form-actions
- = f.submit _('Set new password'), class: 'gl-button btn btn-confirm'
+ = f.submit _('Set new password'), class: 'gl-button btn btn-confirm', data: { qa_selector: 'set_new_password_button' }
diff --git a/app/views/profiles/preferences/show.html.haml b/app/views/profiles/preferences/show.html.haml
index 535964028f4..0adad6b64a0 100644
--- a/app/views/profiles/preferences/show.html.haml
+++ b/app/views/profiles/preferences/show.html.haml
@@ -100,7 +100,7 @@
.form-group
= f.label :tab_width, s_('Preferences|Tab width'), class: 'label-bold'
= f.number_field :tab_width,
- class: 'form-control',
+ class: 'form-control gl-form-input',
min: Gitlab::TabWidth::MIN,
max: Gitlab::TabWidth::MAX,
required: true
diff --git a/app/views/profiles/show.html.haml b/app/views/profiles/show.html.haml
index 15544fb9c45..c3ec2f7bab3 100644
--- a/app/views/profiles/show.html.haml
+++ b/app/views/profiles/show.html.haml
@@ -70,10 +70,9 @@
prepend: emoji_button,
append: reset_message_button,
placeholder: s_("Profiles|What's your status?")
- - if Feature.enabled?(:set_user_availability_status, @user, default_enabled: :yaml)
- .checkbox-icon-inline-wrapper
- = status_form.check_box :availability, { data: { testid: "user-availability-checkbox" }, label: s_("Profiles|Busy"), wrapper_class: 'gl-mr-0 gl-font-weight-bold' }, availability["busy"], availability["not_set"]
- .gl-text-gray-600.gl-ml-5= s_('Profiles|"Busy" will be shown next to your name')
+ .checkbox-icon-inline-wrapper
+ = status_form.check_box :availability, { data: { testid: "user-availability-checkbox" }, label: s_("Profiles|Busy"), wrapper_class: 'gl-mr-0 gl-font-weight-bold' }, availability["busy"], availability["not_set"]
+ .gl-text-gray-600.gl-ml-5= s_('Profiles|"Busy" will be shown next to your name')
- if Feature.enabled?(:user_time_settings)
.col-lg-12
%hr
diff --git a/app/views/profiles/two_factor_auths/show.html.haml b/app/views/profiles/two_factor_auths/show.html.haml
index a9134057777..71262f4bcb9 100644
--- a/app/views/profiles/two_factor_auths/show.html.haml
+++ b/app/views/profiles/two_factor_auths/show.html.haml
@@ -29,7 +29,7 @@
- register_2fa_token = _('We recommend cloud-based mobile authenticator apps such as Authy, Duo Mobile, and LastPass. They can restore access if you lose your hardware device.')
= register_2fa_token.html_safe
.row.gl-mb-3
- .col-md-4
+ .col-md-4.gl-pt-2{ style: 'background: #fff' }
= raw @qr_code
.col-md-8
.account-well
@@ -49,7 +49,7 @@
= @error
.form-group
= label_tag :pin_code, _('Pin code'), class: "label-bold"
- = text_field_tag :pin_code, nil, class: "form-control", required: true, data: { qa_selector: 'pin_code_field' }
+ = text_field_tag :pin_code, nil, class: "form-control gl-form-input", required: true, data: { qa_selector: 'pin_code_field' }
.gl-mt-3
= submit_tag _('Register with two-factor app'), class: 'gl-button btn btn-confirm', data: { qa_selector: 'register_2fa_app_button' }
diff --git a/app/views/projects/_activity.html.haml b/app/views/projects/_activity.html.haml
index db0f13843dd..c5a0b6a1428 100644
--- a/app/views/projects/_activity.html.haml
+++ b/app/views/projects/_activity.html.haml
@@ -11,4 +11,4 @@
.content_list.project-activity{ :"data-href" => activity_project_path(@project) }
.loading
- .spinner.spinner-md
+ .gl-spinner.gl-spinner-md
diff --git a/app/views/projects/_archived_notice.html.haml b/app/views/projects/_archived_notice.html.haml
index dcece8ab42f..5489e41d37b 100644
--- a/app/views/projects/_archived_notice.html.haml
+++ b/app/views/projects/_archived_notice.html.haml
@@ -2,4 +2,4 @@
.text-warning.center.prepend-top-20
%p
= sprite_icon('warning-solid')
- = _('Archived project! Repository and other project resources are read only')
+ = _('Archived project! Repository and other project resources are read-only')
diff --git a/app/views/projects/_commit_button.html.haml b/app/views/projects/_commit_button.html.haml
index 4b41231ba20..987ec74e4ba 100644
--- a/app/views/projects/_commit_button.html.haml
+++ b/app/views/projects/_commit_button.html.haml
@@ -1,7 +1,7 @@
-.form-actions
+.form-actions.gl-display-flex
= button_tag 'Commit changes', id: 'commit-changes', class: 'gl-button btn btn-confirm js-commit-button qa-commit-button'
= link_to 'Cancel', cancel_path,
- class: 'gl-button btn btn-default btn-cancel', data: {confirm: leave_edit_message}
+ class: 'gl-button btn btn-default gl-ml-3', data: {confirm: leave_edit_message}
= render 'shared/projects/edit_information'
diff --git a/app/views/projects/_files.html.haml b/app/views/projects/_files.html.haml
index 0369ee50c40..8642dc5fc8c 100644
--- a/app/views/projects/_files.html.haml
+++ b/app/views/projects/_files.html.haml
@@ -7,7 +7,7 @@
- add_page_startup_api_call project_blob_path(@project, tree_join(@ref, readme_path), viewer: "rich", format: "json")
#tree-holder.tree-holder.clearfix
- .nav-block
+ .nav-block.gl-display-flex.gl-align-items-center
= render 'projects/tree/tree_header', tree: @tree
#js-last-commit
diff --git a/app/views/projects/_fork_suggestion.html.haml b/app/views/projects/_fork_suggestion.html.haml
index 9888ce417f8..55e609c0ffb 100644
--- a/app/views/projects/_fork_suggestion.html.haml
+++ b/app/views/projects/_fork_suggestion.html.haml
@@ -1,10 +1,7 @@
+- message_base = s_("ForkSuggestion|You can’t %{edit_start}edit%{edit_end} files directly in this project. Fork this project and submit a merge request with your changes.").html_safe
+- message = message_base.html_safe % { edit_start: '<span class="js-file-fork-suggestion-section-action">'.html_safe, edit_end: '</span>'.html_safe }
.js-file-fork-suggestion-section.file-fork-suggestion.hidden
- %span.file-fork-suggestion-note
- You're not allowed to
- %span.js-file-fork-suggestion-section-action
- edit
- files in this project directly. Please fork this project,
- make your changes there, and submit a merge request.
- = link_to 'Fork', nil, method: :post, class: 'js-fork-suggestion-button gl-button btn btn-grouped btn-confirm-secondary'
+ %span.file-fork-suggestion-note= message
+ = link_to s_('ForkSuggestion|Fork'), nil, method: :post, class: 'js-fork-suggestion-button gl-button btn btn-grouped btn-confirm-secondary'
%button.js-cancel-fork-suggestion-button.gl-button.btn.btn-grouped{ type: 'button' }
- Cancel
+ = s_('ForkSuggestion|Cancel')
diff --git a/app/views/projects/_home_panel.html.haml b/app/views/projects/_home_panel.html.haml
index b2380a3ba57..a70679dab5f 100644
--- a/app/views/projects/_home_panel.html.haml
+++ b/app/views/projects/_home_panel.html.haml
@@ -2,6 +2,7 @@
- show_auto_devops_callout = show_auto_devops_callout?(@project)
- max_project_topic_length = 15
- emails_disabled = @project.emails_disabled?
+- cache_enabled = Feature.enabled?(:cache_home_panel, @project, type: :development, default_enabled: :yaml)
.project-home-panel.js-show-on-project-root.gl-my-5{ class: [("empty-project" if empty_repo)] }
.gl-display-flex.gl-justify-content-space-between.gl-flex-wrap.gl-sm-flex-direction-column.gl-mb-3
@@ -23,42 +24,45 @@
- if current_user
%span.access-request-links.gl-ml-3
= render 'shared/members/access_request_links', source: @project
- - if @project.tag_list.present?
- %span.home-panel-topic-list.mt-2.w-100.d-inline-flex.gl-font-base.gl-font-weight-normal.gl-align-items-center
- = sprite_icon('tag', css_class: 'icon gl-relative gl-mr-2')
- - @project.topics_to_show.each do |topic|
- - project_topics_classes = "badge badge-pill badge-secondary gl-mr-2"
- - explore_project_topic_path = explore_projects_path(tag: topic)
- - if topic.length > max_project_topic_length
- %a{ class: "#{ project_topics_classes } str-truncated-30 has-tooltip", data: { container: "body" }, title: topic, href: explore_project_topic_path, itemprop: 'keywords' }
- = topic.titleize
- - else
- %a{ class: project_topics_classes, href: explore_project_topic_path, itemprop: 'keywords' }
- = topic.titleize
+ - if @project.tag_list.present?
+ = cache_if(cache_enabled, [@project, :tag_list], expires_in: 1.day) do
+ %span.home-panel-topic-list.mt-2.w-100.d-inline-flex.gl-font-base.gl-font-weight-normal.gl-align-items-center
+ = sprite_icon('tag', css_class: 'icon gl-relative gl-mr-2')
- - if @project.has_extra_topics?
- .text-nowrap.has-tooltip{ data: { container: 'body' }, title: @project.has_extra_topics? ? @project.topics_not_shown.join(', ') : nil }
- = _("+ %{count} more") % { count: @project.count_of_extra_topics_not_shown }
+ - @project.topics_to_show.each do |topic|
+ - project_topics_classes = "badge badge-pill badge-secondary gl-mr-2"
+ - explore_project_topic_path = explore_projects_path(tag: topic)
+ - if topic.length > max_project_topic_length
+ %a{ class: "#{ project_topics_classes } str-truncated-30 has-tooltip", data: { container: "body" }, title: topic, href: explore_project_topic_path, itemprop: 'keywords' }
+ = topic.titleize
+ - else
+ %a{ class: project_topics_classes, href: explore_project_topic_path, itemprop: 'keywords' }
+ = topic.titleize
+ - if @project.has_extra_topics?
+ .text-nowrap.has-tooltip{ data: { container: 'body' }, title: @project.has_extra_topics? ? @project.topics_not_shown.join(', ') : nil }
+ = _("+ %{count} more") % { count: @project.count_of_extra_topics_not_shown }
- .project-repo-buttons.gl-display-flex.gl-justify-content-md-end.gl-align-items-start.gl-flex-wrap.gl-mt-5
- - if current_user
- .gl-display-flex.gl-align-items-start.gl-mr-3
- - if @notification_setting
- .js-vue-notification-dropdown{ data: { button_size: "small", disabled: emails_disabled.to_s, dropdown_items: notification_dropdown_items(@notification_setting).to_json, notification_level: @notification_setting.level, help_page_path: help_page_path('user/profile/notifications'), project_id: @project.id } }
+ = cache_if(cache_enabled, [@project, :buttons, current_user, @notification_setting], expires_in: 1.day) do
+ .project-repo-buttons.gl-display-flex.gl-justify-content-md-end.gl-align-items-start.gl-flex-wrap.gl-mt-5
+ - if current_user
+ .gl-display-flex.gl-align-items-start.gl-mr-3
+ - if @notification_setting
+ .js-vue-notification-dropdown{ data: { button_size: "small", disabled: emails_disabled.to_s, dropdown_items: notification_dropdown_items(@notification_setting).to_json, notification_level: @notification_setting.level, help_page_path: help_page_path('user/profile/notifications'), project_id: @project.id } }
- .count-buttons.gl-display-flex.gl-align-items-flex-start
- = render 'projects/buttons/star'
- = render 'projects/buttons/fork'
+ .count-buttons.gl-display-flex.gl-align-items-flex-start
+ = render 'projects/buttons/star'
+ = render 'projects/buttons/fork'
- if can?(current_user, :download_code, @project)
- %nav.project-stats
- .nav-links.quick-links
- - if @project.empty_repo?
- = render 'stat_anchor_list', anchors: @project.empty_repo_statistics_anchors
- - else
- = render 'stat_anchor_list', anchors: @project.statistics_anchors(show_auto_devops_callout: show_auto_devops_callout)
+ = cache_if(cache_enabled, [@project, :download_code], expires_in: 1.minute) do
+ %nav.project-stats
+ .nav-links.quick-links
+ - if @project.empty_repo?
+ = render 'stat_anchor_list', anchors: @project.empty_repo_statistics_anchors
+ - else
+ = render 'stat_anchor_list', anchors: @project.statistics_anchors(show_auto_devops_callout: show_auto_devops_callout)
.home-panel-home-desc.mt-1
- if @project.description.present?
@@ -80,11 +84,12 @@
= render_if_exists "projects/home_mirror"
- if @project.badges.present?
- .project-badges.mb-2
- - @project.badges.each do |badge|
- %a.gl-mr-3{ href: badge.rendered_link_url(@project),
- target: '_blank',
- rel: 'noopener noreferrer' }>
- %img.project-badge{ src: badge.rendered_image_url(@project),
- 'aria-hidden': true,
- alt: 'Project badge' }>
+ = cache_if(cache_enabled, [@project, :badges], expires_in: 1.day) do
+ .project-badges.mb-2
+ - @project.badges.each do |badge|
+ %a.gl-mr-3{ href: badge.rendered_link_url(@project),
+ target: '_blank',
+ rel: 'noopener noreferrer' }>
+ %img.project-badge{ src: badge.rendered_image_url(@project),
+ 'aria-hidden': true,
+ alt: 'Project badge' }>
diff --git a/app/views/projects/_import_project_pane.html.haml b/app/views/projects/_import_project_pane.html.haml
index e6ded3ad912..c0fe788b56a 100644
--- a/app/views/projects/_import_project_pane.html.haml
+++ b/app/views/projects/_import_project_pane.html.haml
@@ -83,7 +83,7 @@
.js-toggle-content.toggle-import-form{ class: ('hide' if active_tab != 'import') }
- = form_for @project, html: { class: 'new_project' } do |f|
+ = form_for @project, html: { class: 'new_project gl-show-field-errors' } 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
diff --git a/app/views/projects/_merge_request_merge_method_settings.html.haml b/app/views/projects/_merge_request_merge_method_settings.html.haml
index f55d840e14b..2d18285ba80 100644
--- a/app/views/projects/_merge_request_merge_method_settings.html.haml
+++ b/app/views/projects/_merge_request_merge_method_settings.html.haml
@@ -22,7 +22,7 @@
= s_('ProjectSettings|When there is a merge conflict, the user is given the option to rebase.')
.form-check.mb-2
- = form.radio_button :merge_method, :ff, class: "js-merge-method-radio form-check-input", data: { qa_selector: 'merge_ff_radio_button' }
+ = form.radio_button :merge_method, :ff, class: "js-merge-method-radio form-check-input", data: { qa_selector: 'merge_ff_radio' }
= label_tag :project_merge_method_ff, class: 'form-check-label' do
= s_('ProjectSettings|Fast-forward merge')
.text-secondary
diff --git a/app/views/projects/_merge_request_merge_suggestions_settings.html.haml b/app/views/projects/_merge_request_merge_suggestions_settings.html.haml
index 12ab905479a..6e3c366da82 100644
--- a/app/views/projects/_merge_request_merge_suggestions_settings.html.haml
+++ b/app/views/projects/_merge_request_merge_suggestions_settings.html.haml
@@ -3,7 +3,7 @@
.form-group
%b= s_('ProjectSettings|Merge suggestions')
%p.text-secondary
- - configure_the_commit_message_for_applied_suggestions_help_link_url = help_page_path('user/discussions/index.md', anchor: 'configure-the-commit-message-for-applied-suggestions')
+ - configure_the_commit_message_for_applied_suggestions_help_link_url = help_page_path('user/project/merge_requests/reviews/suggestions.md', anchor: 'configure-the-commit-message-for-applied-suggestions')
- configure_the_commit_message_for_applied_suggestions_help_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: configure_the_commit_message_for_applied_suggestions_help_link_url }
= s_('ProjectSettings|The commit message used when applying merge request suggestions. %{link_start}Learn more about suggestions.%{link_end}').html_safe % { link_start: configure_the_commit_message_for_applied_suggestions_help_link_start, link_end: '</a>'.html_safe }
.mb-2
diff --git a/app/views/projects/_new_project_fields.html.haml b/app/views/projects/_new_project_fields.html.haml
index 4695cd59f32..66fc313213a 100644
--- a/app/views/projects/_new_project_fields.html.haml
+++ b/app/views/projects/_new_project_fields.html.haml
@@ -8,7 +8,7 @@
.form-group.project-name.col-sm-12
= f.label :name, class: 'label-bold' do
%span= _("Project name")
- = f.text_field :name, placeholder: "My awesome project", class: "form-control input-lg", autofocus: true, data: { track_label: "#{track_label}", track_event: "activate_form_input", track_property: "project_name", track_value: "" }, required: true, aria: { required: true }
+ = f.text_field :name, placeholder: "My awesome project", class: "form-control gl-form-input input-lg", autofocus: true, data: { track_label: "#{track_label}", track_event: "activate_form_input", track_property: "project_name", track_value: "" }, required: true, aria: { required: true }
.form-group.project-path.col-sm-6
= f.label :namespace_id, class: 'label-bold' do
%span= s_("Project URL")
@@ -33,7 +33,7 @@
.form-group.project-path.col-sm-6
= f.label :path, class: 'label-bold' do
%span= _("Project slug")
- = f.text_field :path, placeholder: "my-awesome-project", class: "form-control", required: true, aria: { required: true }
+ = f.text_field :path, placeholder: "my-awesome-project", class: "form-control gl-form-input", required: true, aria: { required: true }
- if current_user.can_create_group?
.form-text.text-muted
- link_start_group_path = '<a href="%{path}">' % { path: new_group_path }
@@ -43,7 +43,7 @@
.form-group
= f.label :description, class: 'label-bold' do
= s_('ProjectsNew|Project description %{tag_start}(optional)%{tag_end}').html_safe % { tag_start: '<span>'.html_safe, tag_end: '</span>'.html_safe }
- = f.text_area :description, placeholder: s_('ProjectsNew|Description format'), class: "form-control", rows: 3, maxlength: 250, data: { track_label: "#{track_label}", track_event: "activate_form_input", track_property: "project_description", track_value: "" }
+ = f.text_area :description, placeholder: s_('ProjectsNew|Description format'), class: "form-control gl-form-input", rows: 3, maxlength: 250, data: { track_label: "#{track_label}", track_event: "activate_form_input", track_property: "project_description", track_value: "" }
= f.label :visibility_level, class: 'label-bold' do
= s_('ProjectsNew|Visibility Level')
diff --git a/app/views/projects/blob/_blob.html.haml b/app/views/projects/blob/_blob.html.haml
index 84f2d352bc9..e50b964a253 100644
--- a/app/views/projects/blob/_blob.html.haml
+++ b/app/views/projects/blob/_blob.html.haml
@@ -12,7 +12,7 @@
- if @code_navigation_path
#js-code-navigation{ data: { code_navigation_path: @code_navigation_path, blob_path: blob.path, definition_path_prefix: project_blob_path(@project, @ref) } }
- if Feature.enabled?(:refactor_blob_viewer, @project, default_enabled: :yaml)
- #js-view-blob-app{ data: { blob_path: blob.path } }
+ #js-view-blob-app{ data: { blob_path: blob.path, project_path: @project.full_path } }
.gl-spinner-container
= loading_icon(size: 'md')
- else
diff --git a/app/views/projects/blob/_editor.html.haml b/app/views/projects/blob/_editor.html.haml
index 7d3a0c4a026..f2f753b4e86 100644
--- a/app/views/projects/blob/_editor.html.haml
+++ b/app/views/projects/blob/_editor.html.haml
@@ -3,7 +3,7 @@
- is_markdown = Gitlab::MarkupHelper.gitlab_markdown?(file_name)
.file-holder-bottom-radius.file-holder.file.gl-mb-3
- .js-file-title.file-title.align-items-center.clearfix{ data: { current_action: action } }
+ .js-file-title.file-title.gl-display-flex.gl-align-items-center.clearfix{ data: { current_action: action } }
.editor-ref.block-truncated.has-tooltip{ title: ref }
= sprite_icon('fork', size: 12)
= ref
@@ -26,16 +26,18 @@
dismiss_key: @project.id,
human_access: human_access } }
- .file-buttons
+ .file-buttons.gl-display-flex.gl-align-items-center.gl-justify-content-end
- if is_markdown
= render 'shared/blob/markdown_buttons', show_fullscreen_button: false
- = button_tag class: 'soft-wrap-toggle btn gl-button', type: 'button', tabindex: '-1' do
- %span.no-wrap
- = custom_icon('icon_no_wrap')
- No wrap
- %span.soft-wrap
- = custom_icon('icon_soft_wrap')
- Soft wrap
+ = button_tag class: 'soft-wrap-toggle btn gl-button btn-default', type: 'button', tabindex: '-1' do
+ .no-wrap
+ = sprite_icon('soft-unwrap', css_class: 'gl-button-icon')
+ %span.gl-button-text
+ No wrap
+ .soft-wrap
+ = sprite_icon('soft-wrap', css_class: 'gl-button-icon')
+ %span.gl-button-text
+ Soft wrap
.file-editor.code
.js-edit-mode-pane.qa-editor#editor{ data: { 'editor-loading': true } }<
diff --git a/app/views/projects/blob/_template_selectors.html.haml b/app/views/projects/blob/_template_selectors.html.haml
index 24a4db010c8..a76e61bc3dd 100644
--- a/app/views/projects/blob/_template_selectors.html.haml
+++ b/app/views/projects/blob/_template_selectors.html.haml
@@ -11,8 +11,5 @@
= dropdown_tag(_("Apply a template"), options: { toggle_class: 'js-metrics-dashboard-selector qa-metrics-dashboard-dropdown', dropdown_class: 'dropdown-menu-selectable', filter: true, placeholder: "Filter", data: { data: metrics_dashboard_ymls(@project) } } )
#gitlab-ci-yml-selector.gitlab-ci-yml-selector.js-gitlab-ci-yml-selector-wrap.js-template-selector-wrap.hidden
= dropdown_tag(_("Apply a template"), options: { toggle_class: 'js-gitlab-ci-yml-selector qa-gitlab-ci-yml-dropdown', dropdown_class: 'dropdown-menu-selectable', filter: true, placeholder: "Filter", data: { data: gitlab_ci_ymls(@project), selected: params[:template] } } )
- - if experiment_enabled?(:ci_syntax_templates_b, subject: current_user) && @project.namespace.recent?
- .gitlab-ci-syntax-yml-selector.js-gitlab-ci-syntax-yml-selector-wrap.js-template-selector-wrap.hidden
- = dropdown_tag(_("Learn CI/CD syntax"), options: { toggle_class: 'js-gitlab-ci-syntax-yml-selector qa-gitlab-ci-syntax-yml-dropdown', dropdown_class: 'dropdown-menu-selectable', filter: true, placeholder: "Filter", data: { data: gitlab_ci_syntax_ymls(@project) } } )
.dockerfile-selector.js-dockerfile-selector-wrap.js-template-selector-wrap.hidden
= dropdown_tag(_("Apply a template"), options: { toggle_class: 'js-dockerfile-selector qa-dockerfile-dropdown', dropdown_class: 'dropdown-menu-selectable', filter: true, placeholder: "Filter", data: { data: dockerfile_names(@project) } } )
diff --git a/app/views/projects/blob/_upload.html.haml b/app/views/projects/blob/_upload.html.haml
index c42b54ec61d..28e33e3ac9b 100644
--- a/app/views/projects/blob/_upload.html.haml
+++ b/app/views/projects/blob/_upload.html.haml
@@ -21,7 +21,7 @@
.form-actions
= button_tag class: 'btn gl-button btn-confirm btn-upload-file', id: 'submit-all', type: 'button' do
- .spinner.spinner-sm.gl-mr-2.js-loading-icon.hidden
+ .gl-spinner.gl-mr-2.js-loading-icon.hidden
= button_title
= link_to _("Cancel"), '#', class: "btn gl-button btn-default btn-cancel", "data-dismiss" => "modal"
diff --git a/app/views/projects/blob/edit.html.haml b/app/views/projects/blob/edit.html.haml
index abfed450316..9f89981e7ca 100644
--- a/app/views/projects/blob/edit.html.haml
+++ b/app/views/projects/blob/edit.html.haml
@@ -1,5 +1,7 @@
- breadcrumb_title _("Repository")
- page_title _("Edit"), @blob.path, @ref
+- content_for :prefetch_asset_tags do
+ - webpack_preload_asset_tag('monaco')
- if @conflict
.gl-alert.gl-alert-danger.gl-mb-5.gl-mt-5
diff --git a/app/views/projects/blob/new.html.haml b/app/views/projects/blob/new.html.haml
index 8722819fe4f..2aeffa88c8f 100644
--- a/app/views/projects/blob/new.html.haml
+++ b/app/views/projects/blob/new.html.haml
@@ -1,16 +1,19 @@
- breadcrumb_title _("Repository")
- page_title _("New File"), @path.presence, @ref
-%h3.page-title.blob-new-page-title
- New file
+%h3.page-title.blob-new-page-title#js-code-quality-walkthrough
+ = _('New file')
+ .js-code-quality-walkthrough{ data: { step: 'commit_ci_file' } }
.file-editor
= form_tag(project_create_blob_path(@project, @id), method: :post, class: 'js-edit-blob-form js-new-blob-form js-quick-submit js-requires-input', data: blob_editor_paths(@project)) do
= render 'projects/blob/editor', ref: @ref
= render 'shared/new_commit_form', placeholder: "Add new file"
+ - if params[:code_quality_walkthrough]
+ = hidden_field_tag 'code_quality_walkthrough', 'true'
= hidden_field_tag 'content', '', id: 'file-content'
= render 'projects/commit_button', ref: @ref,
- cancel_path: project_tree_path(@project, @id)
+ cancel_path: project_tree_path(@project, @id)
- if should_suggest_gitlab_ci_yml?
.js-suggest-gitlab-ci-yml-commit-changes{ data: { target: '#commit-changes',
merge_request_path: params[:mr_path],
diff --git a/app/views/projects/blob/show.html.haml b/app/views/projects/blob/show.html.haml
index c66300aa947..1ba38808937 100644
--- a/app/views/projects/blob/show.html.haml
+++ b/app/views/projects/blob/show.html.haml
@@ -1,6 +1,8 @@
- breadcrumb_title "Repository"
- page_title @blob.path, @ref
- signatures_path = namespace_project_signatures_path(namespace_id: @project.namespace.full_path, project_id: @project.path, id: @last_commit, limit: 1)
+- content_for :prefetch_asset_tags do
+ - webpack_preload_asset_tag('monaco', prefetch: true)
.js-signature-container{ data: { 'signatures-path': signatures_path } }
diff --git a/app/views/projects/blob/viewers/_changelog.html.haml b/app/views/projects/blob/viewers/_changelog.html.haml
index 80ead53beff..cac858c1444 100644
--- a/app/views/projects/blob/viewers/_changelog.html.haml
+++ b/app/views/projects/blob/viewers/_changelog.html.haml
@@ -1,4 +1,3 @@
= sprite_icon('history', css_class: 'gl-mr-1 gl-vertical-align-text-bottom')
= succeed '.' do
- To find the state of this project's repository at the time of any of these versions, check out
- = link_to "the tags", project_tags_path(viewer.project)
+ = _("To find the state of this project's repository at the time of any of these versions, check out %{link_start}the tags%{link_end}.").html_safe % { link_start: "<a href='#{project_tags_path(viewer.project)}'>".html_safe, link_end: "</a>".html_safe }
diff --git a/app/views/projects/blob/viewers/_contributing.html.haml b/app/views/projects/blob/viewers/_contributing.html.haml
index 18559e2908f..eac8c17b7ff 100644
--- a/app/views/projects/blob/viewers/_contributing.html.haml
+++ b/app/views/projects/blob/viewers/_contributing.html.haml
@@ -1,9 +1,9 @@
= sprite_icon('book')
-After you've reviewed these contribution guidelines, you'll be all set to
+= _("After you've reviewed these contribution guidelines, you'll be all set to")
- options = contribution_options(viewer.project)
- if options.any?
= succeed '.' do
= Gitlab::Utils.to_exclusive_sentence(options).html_safe
- else
- contribute to this project.
+ = _("contribute to this project.")
diff --git a/app/views/projects/blob/viewers/_download.html.haml b/app/views/projects/blob/viewers/_download.html.haml
index fda4b9c92cd..61f64177be8 100644
--- a/app/views/projects/blob/viewers/_download.html.haml
+++ b/app/views/projects/blob/viewers/_download.html.haml
@@ -4,4 +4,4 @@
%h1.light
= sprite_icon('download')
%h4
- Download (#{number_to_human_size(viewer.blob.raw_size)})
+ = _('Download (%{size})').html_safe % { size: number_to_human_size(viewer.blob.raw_size) }
diff --git a/app/views/projects/blob/viewers/_license.html.haml b/app/views/projects/blob/viewers/_license.html.haml
index d2bd90a898a..320d7dd4b9f 100644
--- a/app/views/projects/blob/viewers/_license.html.haml
+++ b/app/views/projects/blob/viewers/_license.html.haml
@@ -1,8 +1,6 @@
- license = viewer.license
= sprite_icon('scale')
-This project is licensed under the
-= succeed '.' do
- %strong= license.name
+= _("This project is licensed under the %{strong_start}%{license_name}%{strong_end}.").html_safe % { license_name: license.name, strong_start: '<strong>'.html_safe, strong_end: '</strong>'.html_safe }
-= link_to 'Learn more', license.url, target: '_blank', rel: 'noopener noreferrer'
+= link_to _('Learn more'), license.url, target: '_blank', rel: 'noopener noreferrer'
diff --git a/app/views/projects/blob/viewers/_readme.html.haml b/app/views/projects/blob/viewers/_readme.html.haml
index 86f59146cda..e06ff4edf71 100644
--- a/app/views/projects/blob/viewers/_readme.html.haml
+++ b/app/views/projects/blob/viewers/_readme.html.haml
@@ -1,4 +1,4 @@
= sprite_icon('information-o', css_class: 'gl-vertical-align-middle! gl-mr-2')
= succeed '.' do
- To learn more about this project, read
- = link_to "the wiki", wiki_path(viewer.project.wiki)
+ - link_to_wiki = link_to(_("the wiki"), wiki_path(viewer.project.wiki))
+ = _("To learn more about this project, read %{link_to_wiki}.").html_safe % { link_to_wiki: link_to_wiki }
diff --git a/app/views/projects/buttons/_download.html.haml b/app/views/projects/buttons/_download.html.haml
index 3071e5ea5f8..2f89a3f62ed 100644
--- a/app/views/projects/buttons/_download.html.haml
+++ b/app/views/projects/buttons/_download.html.haml
@@ -4,9 +4,9 @@
- archive_prefix = "#{project.path}-#{ref.tr('/', '-')}"
.project-action-button.dropdown.inline>
%button.gl-button.btn.btn-default.has-tooltip{ title: s_('DownloadSource|Download'), 'data-toggle' => 'dropdown', 'aria-label' => s_('DownloadSource|Download'), 'data-display' => 'static', data: { qa_selector: 'download_source_code_button' } }
- = sprite_icon('download')
+ = sprite_icon('download', css_class: 'gl-icon')
%span.sr-only= _('Select Archive Format')
- = sprite_icon("chevron-down")
+ = sprite_icon('chevron-down', css_class: 'gl-icon')
.dropdown-menu.dropdown-menu-right{ role: 'menu' }
%section
%h5.m-0.dropdown-bold-header= _('Download source code')
diff --git a/app/views/projects/buttons/_dropdown.html.haml b/app/views/projects/buttons/_dropdown.html.haml
index 5effa5a9e92..12ce4667e1a 100644
--- a/app/views/projects/buttons/_dropdown.html.haml
+++ b/app/views/projects/buttons/_dropdown.html.haml
@@ -28,14 +28,14 @@
%li.dropdown-header= _('This repository')
- if can_push_code
- %li.qa-new-file-option= link_to _('New file'), project_new_blob_path(@project, @project.default_branch || 'master')
+ %li.qa-new-file-option= link_to _('New file'), project_new_blob_path(@project, @project.default_branch_or_main)
- unless @project.empty_repo?
%li= link_to _('New branch'), new_project_branch_path(@project)
%li= link_to _('New tag'), new_project_tag_path(@project)
- elsif can_collaborate_with_project?(@project)
- %li= link_to _('New file'), project_new_blob_path(@project, @project.default_branch || 'master')
+ %li= link_to _('New file'), project_new_blob_path(@project, @project.default_branch_or_main)
- elsif create_mr_from_new_fork
- - continue_params = { to: project_new_blob_path(@project, @project.default_branch || 'master'),
+ - continue_params = { to: project_new_blob_path(@project, @project.default_branch_or_main),
notice: edit_in_new_fork_notice,
notice_now: edit_in_new_fork_notice_now }
- fork_path = project_forks_path(@project, namespace_key: current_user.namespace.id, continue: continue_params)
diff --git a/app/views/projects/buttons/_remove_tag.html.haml b/app/views/projects/buttons/_remove_tag.html.haml
index cdf6336a259..58af0d91f30 100644
--- a/app/views/projects/buttons/_remove_tag.html.haml
+++ b/app/views/projects/buttons/_remove_tag.html.haml
@@ -2,5 +2,5 @@
- tag = local_assigns.fetch(:tag, nil)
- return unless project && tag
-%button{ type: "button", class: "js-remove-tag js-confirm-modal-button gl-button btn btn-danger btn-icon has-tooltip gl-ml-3 #{protected_tag?(project, tag) ? 'disabled' : ''}", title: s_('TagsPage|Delete tag'), data: { container: 'body', path: project_tag_path(@project, tag.name), modal_attributes: delete_tag_modal_attributes(tag.name) } }
- = sprite_icon("remove")
+%button{ type: "button", class: "js-remove-tag js-confirm-modal-button gl-button btn btn-default btn-icon has-tooltip gl-ml-3\! #{protected_tag?(project, tag) ? 'disabled' : ''}", title: s_('TagsPage|Delete tag'), data: { container: 'body', path: project_tag_path(@project, tag.name), modal_attributes: delete_tag_modal_attributes(tag.name) } }
+ = sprite_icon('remove', css_class: 'gl-icon')
diff --git a/app/views/projects/ci/pipeline_editor/show.html.haml b/app/views/projects/ci/pipeline_editor/show.html.haml
index eb588e150f7..674765e9f89 100644
--- a/app/views/projects/ci/pipeline_editor/show.html.haml
+++ b/app/views/projects/ci/pipeline_editor/show.html.haml
@@ -1,3 +1,5 @@
- page_title s_('Pipelines|Pipeline Editor')
+- content_for :prefetch_asset_tags do
+ - webpack_preload_asset_tag('monaco')
#js-pipeline-editor{ data: js_pipeline_editor_data(@project) }
diff --git a/app/views/projects/commit/_commit_box.html.haml b/app/views/projects/commit/_commit_box.html.haml
index 1b28136e82c..67007aa7448 100644
--- a/app/views/projects/commit/_commit_box.html.haml
+++ b/app/views/projects/commit/_commit_box.html.haml
@@ -37,13 +37,13 @@
- @commit.parents.each do |parent|
= link_to parent.short_id, project_commit_path(@project, parent), class: "commit-sha"
.commit-info.branches
- .spinner.vertical-align-middle
+ .gl-spinner.vertical-align-middle
.well-segment.merge-request-info
.icon-container
= custom_icon('mr_bold')
%span.commit-info.merge-requests{ 'data-project-commit-path' => merge_requests_project_commit_path(@project, @commit.id, format: :json) }
- .spinner.vertical-align-middle
+ .gl-spinner.vertical-align-middle
- if can?(current_user, :read_pipeline, @last_pipeline)
.well-segment.pipeline-info
diff --git a/app/views/projects/commit/_pipelines_list.haml b/app/views/projects/commit/_pipelines_list.haml
index 7f52e6ed7eb..16df743475d 100644
--- a/app/views/projects/commit/_pipelines_list.haml
+++ b/app/views/projects/commit/_pipelines_list.haml
@@ -1,7 +1,11 @@
- disable_initialization = local_assigns.fetch(:disable_initialization, false)
+- artifacts_endpoint_placeholder = ':pipeline_artifacts_id'
+
#commit-pipeline-table-view{ data: { disable_initialization: disable_initialization,
endpoint: endpoint,
"empty-state-svg-path" => image_path('illustrations/pipelines_empty.svg'),
"error-state-svg-path" => image_path('illustrations/pipelines_failed.svg'),
"project-id": @project.id,
+ "artifacts-endpoint" => downloadable_artifacts_project_pipeline_path(@project, artifacts_endpoint_placeholder, format: :json),
+ "artifacts-endpoint-placeholder" => artifacts_endpoint_placeholder,
} }
diff --git a/app/views/projects/commit/show.html.haml b/app/views/projects/commit/show.html.haml
index 5652b503a6d..c3fdfeb6f4e 100644
--- a/app/views/projects/commit/show.html.haml
+++ b/app/views/projects/commit/show.html.haml
@@ -12,7 +12,12 @@
.container-fluid{ class: [limited_container_width, container_class] }
= render "commit_box"
= render "ci_menu"
- = render "projects/diffs/diffs", diffs: @diffs, environment: @environment, diff_page_context: "is-commit", paginate_diffs: true
+ = render "projects/diffs/diffs",
+ diffs: @diffs,
+ environment: @environment,
+ diff_page_context: "is-commit",
+ paginate_diffs: true,
+ paginate_diffs_per_page: Projects::CommitController::COMMIT_DIFFS_PER_PAGE
.limited-width-notes
= render "shared/notes/notes_with_form", :autocomplete => true
diff --git a/app/views/projects/commits/_commit.html.haml b/app/views/projects/commits/_commit.html.haml
index ceb312450be..bc0d14743b9 100644
--- a/app/views/projects/commits/_commit.html.haml
+++ b/app/views/projects/commits/_commit.html.haml
@@ -3,22 +3,24 @@
- `assets/javascripts/diffs/components/commit_item.vue`
EXCEPTION WARNING - see above `.vue` file for de-sync drift
--#-----------------------------------------------------------------
-- view_details = local_assigns.fetch(:view_details, false)
-- merge_request = local_assigns.fetch(:merge_request, nil)
-- project = local_assigns.fetch(:project) { merge_request&.project }
-- ref = local_assigns.fetch(:ref) { merge_request&.source_branch }
-- commit = commit.present(current_user: current_user)
-- commit_status = commit.status_for(ref)
-- collapsible = local_assigns.fetch(:collapsible, true)
-- link_data_attrs = local_assigns.fetch(:link_data_attrs, {})
-
-- link = commit_path(project, commit, merge_request: merge_request)
+ WARNING: When introducing new content here, please consider what
+ changes may need to be made in the cache keys used to
+ wrap this view, found in
+ CommitsHelper#commit_partial_cache_key
+-#-----------------------------------------------------------------
+- view_details = local_assigns.fetch(:view_details, false)
+- merge_request = local_assigns.fetch(:merge_request, nil)
+- project = local_assigns.fetch(:project) { merge_request&.project }
+- ref = local_assigns.fetch(:ref) { merge_request&.source_branch }
+- commit = commit.present(current_user: current_user)
+- commit_status = commit.status_for(ref)
+- collapsible = local_assigns.fetch(:collapsible, true)
+- link_data_attrs = local_assigns.fetch(:link_data_attrs, {})
+- link = commit_path(project, commit, merge_request: merge_request)
- show_project_name = local_assigns.fetch(:show_project_name, false)
%li{ class: ["commit flex-row", ("js-toggle-container" if collapsible)], id: "commit-#{commit.short_id}" }
-
.avatar-cell.d-none.d-sm-block
= author_avatar(commit, size: 40, has_tooltip: false)
diff --git a/app/views/projects/commits/_commits.html.haml b/app/views/projects/commits/_commits.html.haml
index 9e2dca3ad71..e6c9a7166a9 100644
--- a/app/views/projects/commits/_commits.html.haml
+++ b/app/views/projects/commits/_commits.html.haml
@@ -3,8 +3,8 @@
- ref = local_assigns.fetch(:ref) { merge_request&.source_branch }
- can_update_merge_request = can?(current_user, :update_merge_request, @merge_request)
-- commits = @commits
-- context_commits = @context_commits
+- commits = @commits&.map { |commit| commit.present(current_user: current_user) }
+- context_commits = @context_commits&.map { |commit| commit.present(current_user: current_user) }
- hidden = @hidden_commit_count
- commits.chunk { |c| c.committed_date.in_time_zone.to_date }.each do |day, daily_commits|
@@ -14,7 +14,10 @@
%li.commits-row{ data: { day: day } }
%ul.content-list.commit-list.flex-list
- = render partial: 'projects/commits/commit', collection: daily_commits, locals: { project: project, ref: ref, merge_request: merge_request }
+ - if Feature.enabled?(:cached_commits, project, default_enabled: :yaml)
+ = render partial: 'projects/commits/commit', collection: daily_commits, locals: { project: project, ref: ref, merge_request: merge_request }, cached: -> (commit) { commit_partial_cache_key(commit, ref: ref, merge_request: merge_request, request: request) }
+ - else
+ = render partial: 'projects/commits/commit', collection: daily_commits, locals: { project: project, ref: ref, merge_request: merge_request }
- if context_commits.present?
%li.commit-header.js-commit-header
@@ -25,7 +28,10 @@
%li.commits-row
%ul.content-list.commit-list.flex-list
- = render partial: 'projects/commits/commit', collection: context_commits, locals: { project: project, ref: ref, merge_request: merge_request }
+ - if Feature.enabled?(:cached_commits, project, default_enabled: :yaml)
+ = render partial: 'projects/commits/commit', collection: context_commits, locals: { project: project, ref: ref, merge_request: merge_request }, cached: -> (commit) { commit_partial_cache_key(commit, ref: ref, merge_request: merge_request, request: request) }
+ - else
+ = render partial: 'projects/commits/commit', collection: context_commits, locals: { project: project, ref: ref, merge_request: merge_request }
- if hidden > 0
%li.gl-alert.gl-alert-warning
diff --git a/app/views/projects/compare/index.html.haml b/app/views/projects/compare/index.html.haml
index e3ab184ec6f..426d022da26 100644
--- a/app/views/projects/compare/index.html.haml
+++ b/app/views/projects/compare/index.html.haml
@@ -4,11 +4,11 @@
%h3.page-title
= _("Compare Git revisions")
.sub-header-block
- - example_master = capture do
- %code.ref-name master
+ - example_branch = capture do
+ %code.ref-name= @project.default_branch_or_main
- example_sha = capture do
%code.ref-name 4eedf23
- = html_escape(_("Choose a branch/tag (e.g. %{master}) or enter a commit (e.g. %{sha}) to see what's changed or to create a merge request.")) % { master: example_master.html_safe, sha: example_sha.html_safe }
+ = html_escape(_("Choose a branch/tag (e.g. %{branch}) or enter a commit (e.g. %{sha}) to see what's changed or to create a merge request.")) % { branch: example_branch.html_safe, sha: example_sha.html_safe }
%br
= html_escape(_("Changes are shown as if the %{b_open}source%{b_close} revision was being merged into the %{b_open}target%{b_close} revision.")) % { b_open: '<b>'.html_safe, b_close: '</b>'.html_safe }
diff --git a/app/views/projects/compare/show.html.haml b/app/views/projects/compare/show.html.haml
index 9e9c271e7be..1fc067b6be1 100644
--- a/app/views/projects/compare/show.html.haml
+++ b/app/views/projects/compare/show.html.haml
@@ -6,8 +6,15 @@
#js-compare-selector{ data: project_compare_selector_data(@project, @merge_request, params) }
- if @commits.present?
- = render "projects/commits/commit_list"
- = render "projects/diffs/diffs", diffs: @diffs, environment: @environment, diff_page_context: "is-compare"
+ -# Only show commit list in the first page
+ - hide_commit_list = params[:page].present? && params[:page] != '1'
+ = render "projects/commits/commit_list" unless hide_commit_list
+ = render "projects/diffs/diffs",
+ diffs: @diffs,
+ environment: @environment,
+ diff_page_context: "is-compare",
+ paginate_diffs: true,
+ paginate_diffs_per_page: Projects::CompareController::COMMIT_DIFFS_PER_PAGE
- else
.card.bg-light
.center
diff --git a/app/views/projects/diffs/_diffs.html.haml b/app/views/projects/diffs/_diffs.html.haml
index 1c7a9ffe0bb..bb2682bb7c0 100644
--- a/app/views/projects/diffs/_diffs.html.haml
+++ b/app/views/projects/diffs/_diffs.html.haml
@@ -4,7 +4,8 @@
- diff_page_context = local_assigns.fetch(:diff_page_context, nil)
- load_diff_files_async = Feature.enabled?(:async_commit_diff_files, @project) && diff_page_context == "is-commit"
- paginate_diffs = local_assigns.fetch(:paginate_diffs, false) && !load_diff_files_async
-- diff_files = conditionally_paginate_diff_files(diffs, paginate: paginate_diffs)
+- paginate_diffs_per_page = local_assigns.fetch(:paginate_diffs_per_page, nil)
+- diff_files = conditionally_paginate_diff_files(diffs, paginate: paginate_diffs, per: paginate_diffs_per_page)
.content-block.oneline-block.files-changed.diff-files-changed.js-diff-files-changed
.files-changed-inner
@@ -33,7 +34,7 @@
- url = url_for(safe_params.merge(action: 'diff_files'))
.js-diffs-batch{ data: { diff_files_path: url } }
.text-center
- %span.spinner.spinner-md
+ %span.gl-spinner.gl-spinner-md
- else
= render partial: 'projects/diffs/file', collection: diff_files, as: :diff_file, locals: { project: diffs.project, environment: environment, diff_page_context: diff_page_context }
diff --git a/app/views/projects/edit.html.haml b/app/views/projects/edit.html.haml
index ecaf3467cd2..187fe608a68 100644
--- a/app/views/projects/edit.html.haml
+++ b/app/views/projects/edit.html.haml
@@ -106,7 +106,7 @@
.save-project-loader.hide
.center
%h2
- .spinner.spinner-md.align-text-bottom
+ .gl-spinner.gl-spinner-md.align-text-bottom
= _('Saving project.')
%p= _('Please wait a moment, this page will automatically refresh when ready.')
diff --git a/app/views/projects/empty.html.haml b/app/views/projects/empty.html.haml
index 171222368d6..b76f6b27aa8 100644
--- a/app/views/projects/empty.html.haml
+++ b/app/views/projects/empty.html.haml
@@ -1,5 +1,5 @@
- @content_class = "limit-container-width" unless fluid_layout
-- default_branch_name = @project.default_branch_or_master
+- default_branch_name = @project.default_branch_or_main
- @skip_current_level_breadcrumb = true
= render partial: 'flash_messages', locals: { project: @project }
diff --git a/app/views/projects/environments/index.html.haml b/app/views/projects/environments/index.html.haml
index 06a2ed46805..0136184f80d 100644
--- a/app/views/projects/environments/index.html.haml
+++ b/app/views/projects/environments/index.html.haml
@@ -7,4 +7,4 @@
"new-environment-path" => new_project_environment_path(@project),
"help-page-path" => help_page_path("ci/environments/index.md"),
"project-path" => @project.full_path,
- "default-branch-name" => @project.default_branch_or_master } }
+ "default-branch-name" => @project.default_branch_or_main } }
diff --git a/app/views/projects/feature_flags/edit.html.haml b/app/views/projects/feature_flags/edit.html.haml
index 028595aba0b..1549f5cf6d6 100644
--- a/app/views/projects/feature_flags/edit.html.haml
+++ b/app/views/projects/feature_flags/edit.html.haml
@@ -12,5 +12,5 @@
user_callout_id: UserCalloutsHelper::FEATURE_FLAGS_NEW_VERSION,
show_user_callout: show_feature_flags_new_version?.to_s,
strategy_type_docs_page_path: help_page_path('operations/feature_flags', anchor: 'feature-flag-strategies'),
- environments_scope_docs_path: help_page_path('ci/environments', anchor: 'scoping-environments-with-specs'),
+ environments_scope_docs_path: help_page_path('ci/environments/index.md', anchor: 'scoping-environments-with-specs'),
feature_flag_issues_endpoint: feature_flag_issues_links_endpoint(@project, @feature_flag, current_user) } }
diff --git a/app/views/projects/feature_flags/new.html.haml b/app/views/projects/feature_flags/new.html.haml
index 3bad1d9773c..bc52f52ecf7 100644
--- a/app/views/projects/feature_flags/new.html.haml
+++ b/app/views/projects/feature_flags/new.html.haml
@@ -10,5 +10,5 @@
user_callout_id: UserCalloutsHelper::FEATURE_FLAGS_NEW_VERSION,
show_user_callout: show_feature_flags_new_version?.to_s,
strategy_type_docs_page_path: help_page_path('operations/feature_flags', anchor: 'feature-flag-strategies'),
- environments_scope_docs_path: help_page_path('ci/environments', anchor: 'scoping-environments-with-specs'),
+ environments_scope_docs_path: help_page_path('ci/environments/index.md', anchor: 'scoping-environments-with-specs'),
project_id: @project.id } }
diff --git a/app/views/projects/hook_logs/_index.html.haml b/app/views/projects/hook_logs/_index.html.haml
index a8a4eef65b3..ee4dbf5c05c 100644
--- a/app/views/projects/hook_logs/_index.html.haml
+++ b/app/views/projects/hook_logs/_index.html.haml
@@ -4,7 +4,7 @@
Recent Deliveries
%p When an event in GitLab triggers a webhook, you can use the request details to figure out if something went wrong.
.col-lg-9
- - if hook_logs.any?
+ - if hook_logs.present?
%table.table
%thead
%tr
diff --git a/app/views/projects/issues/_issue.html.haml b/app/views/projects/issues/_issue.html.haml
index 838b4538cad..9c01d93f7d0 100644
--- a/app/views/projects/issues/_issue.html.haml
+++ b/app/views/projects/issues/_issue.html.haml
@@ -3,7 +3,9 @@
.issuable-info-container
- if @can_bulk_update
.issue-check.hidden
- = check_box_tag dom_id(issue, "selected"), nil, false, 'data-id' => issue.id, class: "selected-issuable"
+ - checkbox_id = dom_id(issue, "selected")
+ %label.gl-sr-only{ for: checkbox_id }= issue.title
+ = check_box_tag checkbox_id, nil, false, 'data-id' => issue.id, class: "selected-issuable"
.issuable-main-info
.issue-title.title
%span.issue-title-text.js-onboarding-issue-item{ dir: "auto" }
diff --git a/app/views/projects/issues/_issues.html.haml b/app/views/projects/issues/_issues.html.haml
index ef602da72e5..e4d072a9472 100644
--- a/app/views/projects/issues/_issues.html.haml
+++ b/app/views/projects/issues/_issues.html.haml
@@ -1,4 +1,5 @@
- is_project_overview = local_assigns.fetch(:is_project_overview, false)
+= render 'shared/alerts/positioning_disabled'
- if Feature.enabled?(:vue_issuables_list, @project) && !is_project_overview
- data_endpoint = local_assigns.fetch(:data_endpoint, expose_path(api_v4_projects_issues_path(id: @project.id)))
@@ -15,7 +16,7 @@
'scoped-labels-available': scoped_labels_available?(@project).to_json } }
- else
- empty_state_path = local_assigns.fetch(:empty_state_path, 'shared/empty_states/issues')
- %ul.content-list.issues-list.issuable-list{ class: ("manual-ordering" if @sort == 'relative_position') }
+ %ul.content-list.issues-list.issuable-list{ class: issue_manual_ordering_class }
= render partial: "projects/issues/issue", collection: @issues
- if @issues.blank?
= render empty_state_path
diff --git a/app/views/projects/issues/_new_branch.html.haml b/app/views/projects/issues/_new_branch.html.haml
index 45b2f86c03d..07fec195899 100644
--- a/app/views/projects/issues/_new_branch.html.haml
+++ b/app/views/projects/issues/_new_branch.html.haml
@@ -13,13 +13,13 @@
.create-mr-dropdown-wrap.d-inline-block.full-width-mobile.js-create-mr{ data: { project_path: @project.full_path, project_id: @project.id, can_create_path: can_create_path, create_mr_path: create_mr_path, create_branch_path: create_branch_path, refs_path: refs_path, is_confidential: can_create_confidential_merge_request?.to_s } }
.btn-group.unavailable
%button.gl-button.btn{ type: 'button', disabled: 'disabled' }
- .spinner.align-text-bottom.gl-button-icon.hide
+ .gl-spinner.align-text-bottom.gl-button-icon.hide
%span.text
Checking branch availability…
.btn-group.available.hidden
%button.gl-button.btn.js-create-merge-request.btn-confirm{ type: 'button', data: { action: data_action } }
- .spinner.js-spinner.gl-mr-2.gl-display-none
+ .gl-spinner.js-spinner.gl-mr-2.gl-display-none
= value
%button.gl-button.btn.btn-confirm.btn-icon.dropdown-toggle.create-merge-request-dropdown-toggle.js-dropdown-toggle{ type: 'button', data: { dropdown: { trigger: '#create-merge-request-dropdown' }, display: 'static' } }
diff --git a/app/views/projects/issues/index.html.haml b/app/views/projects/issues/index.html.haml
index 9b043ea3c47..3e8442eee86 100644
--- a/app/views/projects/issues/index.html.haml
+++ b/app/views/projects/issues/index.html.haml
@@ -29,7 +29,7 @@
.issues-holder
= render 'issues'
- if new_issue_email
- .issuable-footer.text-center
+ .gl-text-center.gl-pt-5.gl-pb-7
.js-issueable-by-email{ data: { initial_email: new_issue_email, issuable_type: issuable_type, emails_help_page_path: help_page_path('development/emails', anchor: 'email-namespace'), quick_actions_help_path: help_page_path('user/project/quick_actions'), markdown_help_path: help_page_path('user/markdown'), reset_path: new_issuable_address_project_path(@project, issuable_type: issuable_type) } }
- else
- new_project_issue_button_path = @project.archived? ? false : new_project_issue_path(@project)
diff --git a/app/views/projects/jobs/index.html.haml b/app/views/projects/jobs/index.html.haml
index f2aab3d9394..1da3881c104 100644
--- a/app/views/projects/jobs/index.html.haml
+++ b/app/views/projects/jobs/index.html.haml
@@ -2,7 +2,7 @@
- add_page_specific_style 'page_bundles/ci_status'
- if Feature.enabled?(:jobs_table_vue, @project, default_enabled: :yaml)
- #js-jobs-table{ data: { full_path: @project.full_path, job_counts: job_counts.to_json, job_statuses: job_statuses.to_json } }
+ #js-jobs-table{ data: { full_path: @project.full_path, job_counts: job_counts.to_json, job_statuses: job_statuses.to_json, pipeline_editor_path: project_ci_pipeline_editor_path(@project), empty_state_svg_path: image_path('jobs-empty-state.svg') } }
- else
.top-area
- build_path_proc = ->(scope) { project_jobs_path(@project, scope: scope) }
diff --git a/app/views/projects/learn_gitlab/index.html.haml b/app/views/projects/learn_gitlab/index.html.haml
index 94023b21aab..4935b72d3fa 100644
--- a/app/views/projects/learn_gitlab/index.html.haml
+++ b/app/views/projects/learn_gitlab/index.html.haml
@@ -2,4 +2,4 @@
- page_title _("Learn GitLab")
- add_page_specific_style 'page_bundles/learn_gitlab'
-#js-learn-gitlab-app{ data: { actions: onboarding_actions_data(@project).to_json } }
+#js-learn-gitlab-app{ data: { actions: onboarding_actions_data(@project).to_json, sections: onboarding_sections_data.to_json } }
diff --git a/app/views/projects/merge_requests/_description.html.haml b/app/views/projects/merge_requests/_description.html.haml
index c20479662dd..1dd4cc6495c 100644
--- a/app/views/projects/merge_requests/_description.html.haml
+++ b/app/views/projects/merge_requests/_description.html.haml
@@ -1,6 +1,6 @@
%div
- if @merge_request.description.present?
- .description.qa-description{ class: can?(current_user, :update_merge_request, @merge_request) ? 'js-task-list-container' : '' }
+ .description{ class: can?(current_user, :update_merge_request, @merge_request) ? 'js-task-list-container' : '' , data: { qa_selector: 'description_content' } }
.md
= markdown_field(@merge_request, :description)
%textarea.hidden.js-task-list-field{ data: { value: @merge_request.description } }
diff --git a/app/views/projects/merge_requests/_merge_request.html.haml b/app/views/projects/merge_requests/_merge_request.html.haml
index 6c0fc9575fc..b70bc740175 100644
--- a/app/views/projects/merge_requests/_merge_request.html.haml
+++ b/app/views/projects/merge_requests/_merge_request.html.haml
@@ -1,7 +1,9 @@
%li{ id: dom_id(merge_request), class: mr_css_classes(merge_request), data: { labels: merge_request.label_ids, id: merge_request.id } }
- if @can_bulk_update
.issue-check.hidden
- = check_box_tag dom_id(merge_request, "selected"), nil, false, 'data-id' => merge_request.id, class: "selected-issuable"
+ - checkbox_id = dom_id(merge_request, "selected")
+ %label.gl-sr-only{ for: checkbox_id }= merge_request.title
+ = check_box_tag checkbox_id, nil, false, 'data-id' => merge_request.id, class: "selected-issuable"
.issuable-info-container
.issuable-main-info
diff --git a/app/views/projects/merge_requests/_mr_box.html.haml b/app/views/projects/merge_requests/_mr_box.html.haml
index c38cf62b36c..916b841e350 100644
--- a/app/views/projects/merge_requests/_mr_box.html.haml
+++ b/app/views/projects/merge_requests/_mr_box.html.haml
@@ -1,3 +1,3 @@
.detail-page-description.py-2
- %h2.title.qa-title.mb-0
+ %h2.title.mb-0{ data: { qa_selector: 'title_content' } }
= markdown_field(@merge_request, :title)
diff --git a/app/views/projects/merge_requests/_mr_title.html.haml b/app/views/projects/merge_requests/_mr_title.html.haml
index 26d8e571973..e42032fef66 100644
--- a/app/views/projects/merge_requests/_mr_title.html.haml
+++ b/app/views/projects/merge_requests/_mr_title.html.haml
@@ -1,53 +1,51 @@
- @no_breadcrumb_border = true
- can_update_merge_request = can?(current_user, :update_merge_request, @merge_request)
- can_reopen_merge_request = can?(current_user, :reopen_merge_request, @merge_request)
-- state_human_name, state_icon_name = state_name_with_icon(@merge_request)
- are_close_and_open_buttons_hidden = merge_request_button_hidden?(@merge_request, true) && merge_request_button_hidden?(@merge_request, false)
+- cache_key = [@project, @merge_request, can_update_merge_request, can_reopen_merge_request, are_close_and_open_buttons_hidden]
-- if @merge_request.closed_or_merged_without_fork?
- .gl-alert.gl-alert-danger.gl-mb-5
- = sprite_icon('error', size: 16, css_class: 'gl-icon gl-alert-icon gl-alert-icon-no-title')
- .gl-alert-body
- The source project of this merge request has been removed.
+= cache_if(Feature.enabled?(:cached_mr_title, @project, default_enabled: :yaml), cache_key, expires_in: 1.day) do
+ - if @merge_request.closed_or_merged_without_fork?
+ .gl-alert.gl-alert-danger.gl-mb-5
+ = sprite_icon('error', size: 16, css_class: 'gl-icon gl-alert-icon gl-alert-icon-no-title')
+ .gl-alert-body
+ The source project of this merge request has been removed.
-.detail-page-header.border-bottom-0.pt-0.pb-0
- .detail-page-header-body
- .issuable-status-box.status-box.js-mr-status-box{ class: status_box_class(@merge_request), data: { state: @merge_request.state } }
- = sprite_icon(state_icon_name, css_class: 'gl-display-block gl-sm-display-none!')
- %span.gl-display-none.gl-sm-display-block
- = state_human_name
+ .detail-page-header.border-bottom-0.pt-0.pb-0
+ .detail-page-header-body
+ = render "shared/issuable/status_box", issuable: @merge_request
- .issuable-meta
- #js-issuable-header-warnings
- = issuable_meta(@merge_request, @project)
+ .issuable-meta
+ #js-issuable-header-warnings
+ = issuable_meta(@merge_request, @project)
- %a.gl-button.btn.btn-default.btn-icon.float-right.d-block.d-sm-none.gutter-toggle.issuable-gutter-toggle.js-sidebar-toggle{ href: "#" }
- = sprite_icon('chevron-double-lg-left')
+ %a.gl-button.btn.btn-default.btn-icon.float-right.d-block.d-sm-none.gutter-toggle.issuable-gutter-toggle.js-sidebar-toggle{ href: "#" }
+ = sprite_icon('chevron-double-lg-left')
- .detail-page-header-actions.js-issuable-actions
- .clearfix.dropdown
- %button.gl-button.btn.btn-default.float-left.gl-md-display-none.gl-w-full{ type: "button", data: { toggle: "dropdown" } }
- Options
- = sprite_icon('chevron-down', css_class: 'gl-text-gray-500')
- .dropdown-menu.dropdown-menu-right
- %ul
- - if can_update_merge_request
- %li= link_to 'Edit', edit_namespace_project_merge_request_path(@project.namespace, @project, @merge_request)
- - if @merge_request.opened?
- %li
- = link_to @merge_request.work_in_progress? ? _('Mark as ready') : _('Mark as draft'), toggle_draft_merge_request_path(@merge_request), method: :put, class: "js-draft-toggle-button"
- %li{ class: [merge_request_button_visibility(@merge_request, true), 'js-close-item'] }
- = link_to 'Close', merge_request_path(@merge_request, merge_request: { state_event: :close }), method: :put, title: 'Close merge request'
- - if can_reopen_merge_request
- %li{ class: merge_request_button_visibility(@merge_request, false) }
- = link_to 'Reopen', merge_request_path(@merge_request, merge_request: { state_event: :reopen }), method: :put, title: 'Reopen merge request'
- - unless @merge_request.merged? || current_user == @merge_request.author
- %li= link_to 'Report abuse', new_abuse_report_path(user_id: @merge_request.author.id, ref_url: merge_request_url(@merge_request))
+ .detail-page-header-actions.js-issuable-actions
+ .clearfix.dropdown
+ %button.gl-button.btn.btn-default.float-left.gl-md-display-none.gl-w-full{ type: "button", data: { toggle: "dropdown" } }
+ Options
+ = sprite_icon('chevron-down', css_class: 'gl-text-gray-500')
+ .dropdown-menu.dropdown-menu-right
+ %ul
+ - if can_update_merge_request
+ %li= link_to 'Edit', edit_namespace_project_merge_request_path(@project.namespace, @project, @merge_request)
+ - if @merge_request.opened?
+ %li
+ = link_to @merge_request.work_in_progress? ? _('Mark as ready') : _('Mark as draft'), toggle_draft_merge_request_path(@merge_request), method: :put, class: "js-draft-toggle-button"
+ %li{ class: [merge_request_button_visibility(@merge_request, true), 'js-close-item'] }
+ = link_to 'Close', merge_request_path(@merge_request, merge_request: { state_event: :close }), method: :put, title: 'Close merge request'
+ - if can_reopen_merge_request
+ %li{ class: merge_request_button_visibility(@merge_request, false) }
+ = link_to 'Reopen', merge_request_path(@merge_request, merge_request: { state_event: :reopen }), method: :put, title: 'Reopen merge request'
+ - unless @merge_request.merged? || current_user == @merge_request.author
+ %li= link_to 'Report abuse', new_abuse_report_path(user_id: @merge_request.author.id, ref_url: merge_request_url(@merge_request))
- - if can_update_merge_request
- = link_to 'Edit', edit_project_merge_request_path(@project, @merge_request), class: "d-none d-md-block btn gl-button btn-default btn-grouped js-issuable-edit", data: { qa_selector: "edit_button" }
+ - if can_update_merge_request
+ = link_to 'Edit', edit_project_merge_request_path(@project, @merge_request), class: "d-none d-md-block btn gl-button btn-default btn-grouped js-issuable-edit", data: { qa_selector: "edit_button" }
- - if can_update_merge_request && !are_close_and_open_buttons_hidden
- = render 'projects/merge_requests/close_reopen_draft_report_toggle'
- - elsif !@merge_request.merged?
- = link_to _('Report abuse'), new_abuse_report_path(user_id: @merge_request.author.id, ref_url: merge_request_url(@merge_request)), class: 'gl-display-none gl-md-display-block gl-button btn btn-default float-right gl-ml-3', title: _('Report abuse')
+ - if can_update_merge_request && !are_close_and_open_buttons_hidden
+ = render 'projects/merge_requests/close_reopen_draft_report_toggle'
+ - elsif !@merge_request.merged?
+ = link_to _('Report abuse'), new_abuse_report_path(user_id: @merge_request.author.id, ref_url: merge_request_url(@merge_request)), class: 'gl-display-none gl-md-display-block gl-button btn btn-default float-right gl-ml-3', title: _('Report abuse')
diff --git a/app/views/projects/merge_requests/_widget.html.haml b/app/views/projects/merge_requests/_widget.html.haml
index 6e6046eba14..606442d71a9 100644
--- a/app/views/projects/merge_requests/_widget.html.haml
+++ b/app/views/projects/merge_requests/_widget.html.haml
@@ -1,11 +1,15 @@
+- artifacts_endpoint_placeholder = ':pipeline_artifacts_id'
+
= javascript_tag do
:plain
window.gl = window.gl || {};
window.gl.mrWidgetData = #{serialize_issuable(@merge_request, serializer: 'widget', issues_links: true)}
+ window.gl.mrWidgetData.artifacts_endpoint = '#{downloadable_artifacts_project_pipeline_path(@project, artifacts_endpoint_placeholder, format: :json)}';
+ window.gl.mrWidgetData.artifacts_endpoint_placeholder = '#{artifacts_endpoint_placeholder}';
window.gl.mrWidgetData.squash_before_merge_help_path = '#{help_page_path("user/project/merge_requests/squash_and_merge")}';
window.gl.mrWidgetData.ci_troubleshooting_docs_path = '#{help_page_path('ci/troubleshooting.md')}';
- window.gl.mrWidgetData.mr_troubleshooting_docs_path = '#{help_page_path('user/project/merge_requests/reviewing_and_managing_merge_requests.md', anchor: 'troubleshooting')}';
+ window.gl.mrWidgetData.mr_troubleshooting_docs_path = '#{help_page_path('user/project/merge_requests/reviews/index.md', anchor: 'troubleshooting')}';
window.gl.mrWidgetData.pipeline_must_succeed_docs_path = '#{help_page_path('user/project/merge_requests/merge_when_pipeline_succeeds.md', anchor: 'only-allow-merge-requests-to-be-merged-if-the-pipeline-succeeds')}';
window.gl.mrWidgetData.security_approvals_help_page_path = '#{help_page_path('user/application_security/index.md', anchor: 'security-approvals-in-merge-requests')}';
window.gl.mrWidgetData.license_compliance_docs_path = '#{help_page_path('user/compliance/license_compliance/index.md', anchor: 'policies')}';
diff --git a/app/views/projects/merge_requests/creations/_new_compare.html.haml b/app/views/projects/merge_requests/creations/_new_compare.html.haml
index 7082bf4b8b0..b99714c1794 100644
--- a/app/views/projects/merge_requests/creations/_new_compare.html.haml
+++ b/app/views/projects/merge_requests/creations/_new_compare.html.haml
@@ -30,7 +30,7 @@
= dropdown_loading
.card-footer
.text-center
- .js-source-loading.mt-1.spinner.spinner-sm
+ .js-source-loading.mt-1.gl-spinner
%ul.list-unstyled.mr_source_commit
.col-lg-6
@@ -59,7 +59,7 @@
= dropdown_loading
.card-footer
.text-center
- .js-target-loading.mt-1.spinner.spinner-sm
+ .js-target-loading.mt-1.gl-spinner
%ul.list-unstyled.mr_target_commit
- if @merge_request.errors.any?
diff --git a/app/views/projects/merge_requests/creations/_new_submit.html.haml b/app/views/projects/merge_requests/creations/_new_submit.html.haml
index a8facf1c6fd..7e1ca19d9b6 100644
--- a/app/views/projects/merge_requests/creations/_new_submit.html.haml
+++ b/app/views/projects/merge_requests/creations/_new_submit.html.haml
@@ -26,16 +26,16 @@
%li.commits-tab.new-tab
= link_to url_for(safe_params), data: {target: 'div#commits', action: 'new', toggle: 'tabvue'} do
Commits
- %span.badge.badge-pill= @total_commit_count
+ %span.badge.gl-tab-counter-badge.badge-muted.badge-pill.gl-badge.sm= @total_commit_count
- if @pipelines.any?
%li.builds-tab
= link_to url_for(safe_params.merge(action: 'pipelines')), data: {target: 'div#pipelines', action: 'pipelines', toggle: 'tabvue'} do
Pipelines
- %span.badge.badge-pill= @pipelines.size
+ %span.badge.gl-tab-counter-badge.badge-muted.badge-pill.gl-badge.sm= @pipelines.size
%li.diffs-tab
= link_to url_for(safe_params.merge(action: 'diffs')), data: {target: 'div#diffs', action: 'diffs', toggle: 'tabvue', qa_selector: 'diffs_tab'} do
Changes
- %span.badge.badge-pill= @merge_request.diff_size
+ %span.badge.gl-tab-counter-badge.badge-muted.badge-pill.gl-badge.sm= @merge_request.diff_size
#diff-notes-app.tab-content
#new.commits.tab-pane.active
@@ -48,4 +48,4 @@
.mr-loading-status
.loading.hide
- .spinner.spinner-md
+ .gl-spinner.gl-spinner-md
diff --git a/app/views/projects/merge_requests/index.html.haml b/app/views/projects/merge_requests/index.html.haml
index 22d78418c5b..289f88c9705 100644
--- a/app/views/projects/merge_requests/index.html.haml
+++ b/app/views/projects/merge_requests/index.html.haml
@@ -22,7 +22,7 @@
.merge-requests-holder
= render 'merge_requests'
- if new_merge_request_email
- .issuable-footer.text-center
+ .gl-text-center.gl-pt-5.gl-pb-7
.js-issueable-by-email{ data: { initial_email: new_merge_request_email, issuable_type: issuable_type, emails_help_page_path: help_page_path('development/emails', anchor: 'email-namespace'), quick_actions_help_path: help_page_path('user/project/quick_actions'), markdown_help_path: help_page_path('user/markdown'), reset_path: new_issuable_address_project_path(@project, issuable_type: issuable_type) } }
- else
= render 'shared/empty_states/merge_requests', button_path: new_merge_request_path
diff --git a/app/views/projects/merge_requests/show.html.haml b/app/views/projects/merge_requests/show.html.haml
index 416cb932ec9..49f2795538c 100644
--- a/app/views/projects/merge_requests/show.html.haml
+++ b/app/views/projects/merge_requests/show.html.haml
@@ -5,7 +5,7 @@
- page_title "#{@merge_request.title} (#{@merge_request.to_reference})", _("Merge requests")
- page_description @merge_request.description_html
- page_card_attributes @merge_request.card_attributes
-- suggest_changes_help_path = help_page_path('user/discussions/index.md', anchor: 'suggest-changes')
+- suggest_changes_help_path = help_page_path('user/project/merge_requests/reviews/suggestions.md')
- number_of_pipelines = @pipelines.size
- mr_action = j(params[:tab].presence || 'show')
- add_page_specific_style 'page_bundles/merge_requests'
@@ -40,7 +40,7 @@
= render "projects/merge_requests/tabs/tab", name: "diffs", class: "diffs-tab", id: "diffs-tab", qa_selector: "diffs_tab" do
= tab_link_for @merge_request, :diffs do
= _("Changes")
- %span.badge.badge-pill.gl-badge.badge-muted.sm= @merge_request.diff_size
+ %span.badge.badge-pill.gl-badge.badge-muted.sm= @diffs_count
.d-flex.flex-wrap.align-items-center.justify-content-lg-end
#js-vue-discussion-counter
@@ -85,7 +85,7 @@
.mr-loading-status
.loading.hide
- .spinner.spinner-md
+ .gl-spinner.gl-spinner-md
= render 'shared/issuable/sidebar', issuable_sidebar: @issuable_sidebar, assignees: @merge_request.assignees, reviewers: @merge_request.reviewers, source_branch: @merge_request.source_branch
diff --git a/app/views/projects/milestones/_form.html.haml b/app/views/projects/milestones/_form.html.haml
index 56906eb6e66..dfb9defb91c 100644
--- a/app/views/projects/milestones/_form.html.haml
+++ b/app/views/projects/milestones/_form.html.haml
@@ -7,13 +7,17 @@
.col-form-label.col-sm-2
= f.label :title, _('Title')
.col-sm-10
- = f.text_field :title, maxlength: 255, class: 'form-control', data: { qa_selector: 'milestone_title_field' }, required: true, autofocus: true
+ = f.text_field :title, maxlength: 255, class: 'form-control gl-form-input', data: { qa_selector: 'milestone_title_field' }, required: true, autofocus: true
.form-group.row.milestone-description
.col-form-label.col-sm-2
= f.label :description, _('Description')
.col-sm-10
= render layout: 'shared/md_preview', locals: { url: preview_markdown_path(@project) } do
- = render 'shared/zen', f: f, attr: :description, classes: 'note-textarea', qa_selector: 'milestone_description_field', placeholder: _('Write milestone description...')
+ = render 'shared/zen', f: f, attr: :description,
+ classes: 'note-textarea',
+ qa_selector: 'milestone_description_field',
+ supports_autocomplete: true,
+ placeholder: _('Write milestone description...')
= render 'shared/notes/hints'
.clearfix
.error-alert
diff --git a/app/views/projects/milestones/show.html.haml b/app/views/projects/milestones/show.html.haml
index 2185df3a994..5a6c2c5faaf 100644
--- a/app/views/projects/milestones/show.html.haml
+++ b/app/views/projects/milestones/show.html.haml
@@ -4,6 +4,8 @@
- page_description @milestone.description_html
- add_page_specific_style 'page_bundles/milestone'
+- add_page_startup_api_call milestone_tab_path(@milestone, 'issues', show_project_name: false)
+
= render 'shared/milestones/header', milestone: @milestone
= render 'shared/milestones/description', milestone: @milestone
diff --git a/app/views/projects/mirrors/_ssh_host_keys.html.haml b/app/views/projects/mirrors/_ssh_host_keys.html.haml
index 4e3cd609d75..4411bc474b8 100644
--- a/app/views/projects/mirrors/_ssh_host_keys.html.haml
+++ b/app/views/projects/mirrors/_ssh_host_keys.html.haml
@@ -4,7 +4,7 @@
.form-group.js-ssh-host-keys-section{ class: ('collapse' unless mirror.ssh_mirror_url?) }
%button.btn.gl-button.btn-inverted.btn-secondary.inline.js-detect-host-keys.gl-mr-3{ type: 'button', data: { qa_selector: 'detect_host_keys' } }
- .js-spinner.d-none.spinner.mr-1
+ .js-spinner.d-none.gl-spinner.mr-1
= _('Detect host keys')
.fingerprint-ssh-info.js-fingerprint-ssh-info.gl-mt-3.gl-mb-3{ class: ('collapse' unless mirror.ssh_mirror_url?) }
%label.label-bold
diff --git a/app/views/projects/network/show.html.haml b/app/views/projects/network/show.html.haml
index 3cff85a4979..4cabb930433 100644
--- a/app/views/projects/network/show.html.haml
+++ b/app/views/projects/network/show.html.haml
@@ -17,4 +17,4 @@
- if @commit
.network-graph.gl-bg-white.gl-overflow-scroll.gl-overflow-x-hidden{ data: { url: @url, commit_url: @commit_url, ref: @ref, commit_id: @commit.id } }
.text-center.gl-mt-3
- .spinner.spinner-md
+ .gl-spinner.gl-spinner-md
diff --git a/app/views/projects/new.html.haml b/app/views/projects/new.html.haml
index 059d6eb28c5..c62853145b6 100644
--- a/app/views/projects/new.html.haml
+++ b/app/views/projects/new.html.haml
@@ -2,80 +2,38 @@
- @hide_top_links = true
- page_title _('New Project')
- header_title _("Projects"), dashboard_projects_path
-- active_tab = local_assigns.fetch(:active_tab, 'blank')
+- add_page_specific_style 'page_bundles/new_namespace'
.project-edit-container.gl-mt-5
.project-edit-errors
= render 'projects/errors'
- .js-experiment-new-project-creation{ data: { is_ci_cd_available: (ci_cd_projects_available? if Gitlab.ee?), has_errors: @project.errors.any?, new_project_guidelines: brand_new_project_guidelines, push_to_create_project_command: push_to_create_project_command, working_with_projects_help_path: help_page_path("user/project/working_with_projects") } }
+ .js-new-project-creation{ data: { is_ci_cd_available: (ci_cd_projects_available? if Gitlab.ee?).to_s, has_errors: @project.errors.any?.to_s, new_project_guidelines: brand_new_project_guidelines, push_to_create_project_command: push_to_create_project_command, working_with_projects_help_path: help_page_path("user/project/working_with_projects") } }
.row{ 'v-cloak': true }
- .col-lg-3.profile-settings-sidebar
- %h4.gl-mt-0
- = _('New project')
- %p
- - among_other_things_link = link_to _('among other things'), help_page_path("user/project/index.md", anchor: "project-features"), target: '_blank'
- = _('A project is where you house your files (repository), plan your work (issues), and publish your documentation (wiki), %{among_other_things_link}.').html_safe % { among_other_things_link: among_other_things_link }
- %p
- = _('All features are enabled for blank projects, from templates, or when importing, but you can disable them afterward in the project settings.')
- = render_if_exists 'projects/new_ci_cd_banner_external_repo'
- %p
- - pages_getting_started_guide = link_to _('Pages getting started guide'), help_page_path("user/project/pages/index", anchor: "getting-started"), target: '_blank'
- = _('Information about additional Pages templates and how to install them can be found in our %{pages_getting_started_guide}.').html_safe % { pages_getting_started_guide: pages_getting_started_guide }
- .md
- = brand_new_project_guidelines
- %p
- %strong= _("Tip:")
- = _("You can also create a project from the command line.")
-
- .col-lg-9.js-toggle-container
- %ul.nav.nav-tabs.nav-links.gitlab-tabs{ role: 'tablist' }
- %li.nav-item{ role: 'presentation' }
- %a.nav-link.active{ href: '#blank-project-pane', id: 'blank-project-tab', data: { toggle: 'tab', experiment_track_label: 'blank_project' }, role: 'tab' }
- %span.d-none.d-sm-block= s_('ProjectsNew|Blank project')
- %span.d-block.d-sm-none= s_('ProjectsNew|Blank')
- %li.nav-item{ role: 'presentation' }
- %a.nav-link{ href: '#create-from-template-pane', id: 'create-from-template-tab', data: { toggle: 'tab', experiment_track_label: 'create_from_template' }, role: 'tab' }
- %span.d-none.d-sm-block.qa-project-create-from-template-tab= s_('ProjectsNew|Create from template')
- %span.d-block.d-sm-none= s_('ProjectsNew|Template')
- %li.nav-item{ role: 'presentation' }
- %a.nav-link{ href: '#import-project-pane', id: 'import-project-tab', data: { toggle: 'tab', experiment_track_label: 'import_project' }, role: 'tab' }
- %span.d-none.d-sm-block= s_('ProjectsNew|Import project')
- %span.d-block.d-sm-none= s_('ProjectsNew|Import')
- = render_if_exists 'projects/new_ci_cd_only_project_tab', active_tab: active_tab
-
- .tab-content.gitlab-tab-content
- .tab-pane.js-toggle-container{ id: 'blank-project-pane', class: active_when(active_tab == 'blank'), role: 'tabpanel' }
- = form_for @project, html: { class: 'new_project' } do |f|
- = render 'new_project_fields', f: f, project_name_id: "blank-project-name"
-
- #create-from-template-pane.tab-pane.js-toggle-container.px-0.pb-0{ class: active_when(active_tab == 'template'), role: 'tabpanel' }
- .card.card-slim.m-4.p-4
+ #blank-project-pane.tab-pane.active
+ = form_for @project, html: { class: 'new_project' } do |f|
+ = render 'new_project_fields', f: f, project_name_id: "blank-project-name"
+
+ #create-from-template-pane.tab-pane
+ .gl-card.gl-my-5
+ .gl-card-body
+ %div
+ - contributing_templates_url = 'https://gitlab.com/gitlab-org/project-templates/contributing'
+ - link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: contributing_templates_url }
+ = _('Learn how to %{link_start}contribute to the built-in templates%{link_end}').html_safe % { link_start: link_start, link_end: '</a>'.html_safe }
+ = form_for @project, html: { class: 'new_project' } do |f|
+ .project-template
+ .form-group
%div
- - contributing_templates_url = 'https://gitlab.com/gitlab-org/project-templates/contributing'
- - link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: contributing_templates_url }
- = _('Learn how to %{link_start}contribute to the built-in templates%{link_end}').html_safe % { link_start: link_start, link_end: '</a>'.html_safe }
- = form_for @project, html: { class: 'new_project' } do |f|
- .project-template
- .form-group
- %div
- = render 'project_templates', f: f, project: @project
-
- .tab-pane.import-project-pane.js-toggle-container{ id: 'import-project-pane', class: active_when(active_tab == 'import'), role: 'tabpanel' }
- - if import_sources_enabled?
- = render 'import_project_pane', active_tab: active_tab
- - else
- .nothing-here-block
- %h4= s_('ProjectsNew|No import options available')
- %p= s_('ProjectsNew|Contact an administrator to enable options for importing your project.')
+ = render 'project_templates', f: f, project: @project
- = render_if_exists 'projects/new_ci_cd_only_project_pane', active_tab: active_tab
+ #import-project-pane.tab-pane.js-toggle-container
+ - if import_sources_enabled?
+ = render 'import_project_pane'
+ - else
+ .nothing-here-block
+ %h4= s_('ProjectsNew|No import options available')
+ %p= s_('ProjectsNew|Contact an administrator to enable options for importing your project.')
-.save-project-loader.d-none
- .center
- %h2
- .spinner.spinner-md.align-text-bottom
- = s_('ProjectsNew|Creating project & repository.')
- %p
- = s_('ProjectsNew|Please wait a moment, this page will automatically refresh when ready.')
+ = render_if_exists 'projects/new_ci_cd_only_project_pane'
diff --git a/app/views/projects/pipeline_schedules/_tabs.html.haml b/app/views/projects/pipeline_schedules/_tabs.html.haml
index 61f6ad34052..f69041e1eb1 100644
--- a/app/views/projects/pipeline_schedules/_tabs.html.haml
+++ b/app/views/projects/pipeline_schedules/_tabs.html.haml
@@ -2,17 +2,17 @@
%li{ class: active_when(scope.nil?) }>
= link_to schedule_path_proc.call(nil) do
= s_("PipelineSchedules|All")
- %span.badge.badge-pill.js-totalbuilds-count
+ %span.badge.gl-tab-counter-badge.badge-muted.badge-pill.gl-badge.sm.js-totalbuilds-count
= number_with_delimiter(all_schedules.count(:id))
%li{ class: active_when(scope == 'active') }>
= link_to schedule_path_proc.call('active') do
= s_("PipelineSchedules|Active")
- %span.badge.badge-pill
+ %span.badge.gl-tab-counter-badge.badge-muted.badge-pill.gl-badge.sm
= number_with_delimiter(all_schedules.active.count(:id))
%li{ class: active_when(scope == 'inactive') }>
= link_to schedule_path_proc.call('inactive') do
= s_("PipelineSchedules|Inactive")
- %span.badge.badge-pill
+ %span.badge.gl-tab-counter-badge.badge-muted.badge-pill.gl-badge.sm
= number_with_delimiter(all_schedules.inactive.count(:id))
diff --git a/app/views/projects/pipelines/_with_tabs.html.haml b/app/views/projects/pipelines/_with_tabs.html.haml
index f0b2349c493..e56a240c487 100644
--- a/app/views/projects/pipelines/_with_tabs.html.haml
+++ b/app/views/projects/pipelines/_with_tabs.html.haml
@@ -11,16 +11,16 @@
%li.js-builds-tab-link
= link_to builds_project_pipeline_path(@project, @pipeline), data: { target: '#js-tab-builds', action: 'builds', toggle: 'tab' }, class: 'builds-tab' do
= _('Jobs')
- %span.badge.badge-pill.js-builds-counter= pipeline.total_size
+ %span.badge.badge-pill.gl-badge.badge-muted.sm.js-builds-counter= pipeline.total_size
- if @pipeline.failed_builds.present?
%li.js-failures-tab-link
= link_to failures_project_pipeline_path(@project, @pipeline), data: { target: '#js-tab-failures', action: 'failures', toggle: 'tab' }, class: 'failures-tab' do
= _('Failed Jobs')
- %span.badge.badge-pill.js-failures-counter= @pipeline.failed_builds.count
+ %span.badge.badge-pill.gl-badge.badge-muted.sm.js-failures-counter= @pipeline.failed_builds.count
%li.js-tests-tab-link
= link_to test_report_project_pipeline_path(@project, @pipeline), data: { target: '#js-tab-tests', action: 'test_report', toggle: 'tab' }, class: 'test-tab' do
= s_('TestReports|Tests')
- %span.badge.badge-pill.js-test-report-badge-counter= @pipeline.test_report_summary.total[:count]
+ %span.badge.badge-pill.gl-badge.badge-muted.sm.js-test-report-badge-counter= @pipeline.test_report_summary.total[:count]
= render_if_exists "projects/pipelines/tabs_holder", pipeline: @pipeline, project: @project
.tab-content
@@ -83,5 +83,7 @@
#js-tab-tests.tab-pane
#js-pipeline-tests-detail{ data: { summary_endpoint: summary_project_pipeline_tests_path(@project, @pipeline, format: :json),
suite_endpoint: project_pipeline_test_path(@project, @pipeline, suite_name: 'suite', format: :json),
- blob_path: project_blob_path(@project, @pipeline.sha) } }
+ blob_path: project_blob_path(@project, @pipeline.sha),
+ has_test_report: @pipeline.has_reports?(Ci::JobArtifact.test_reports).to_s,
+ empty_state_image_path: image_path('illustrations/empty-state/empty-test-cases-lg.svg') } }
= render_if_exists "projects/pipelines/tabs_content", pipeline: @pipeline, project: @project
diff --git a/app/views/projects/pipelines/index.html.haml b/app/views/projects/pipelines/index.html.haml
index 4b0487f4685..42bb8117766 100644
--- a/app/views/projects/pipelines/index.html.haml
+++ b/app/views/projects/pipelines/index.html.haml
@@ -1,12 +1,15 @@
- page_title _('Pipelines')
- add_page_specific_style 'page_bundles/pipelines'
- add_page_specific_style 'page_bundles/ci_status'
+- artifacts_endpoint_placeholder = ':pipeline_artifacts_id'
= render_if_exists "shared/shared_runners_minutes_limit_flash_message"
-#pipelines-list-vue{ data: { endpoint: project_pipelines_path(@project, format: :json),
+#pipelines-list-vue{ data: { endpoint: project_pipelines_path(@project, format: :json, code_quality_walkthrough: params[:code_quality_walkthrough]),
project_id: @project.id,
params: params.to_json,
+ "artifacts-endpoint" => downloadable_artifacts_project_pipeline_path(@project, artifacts_endpoint_placeholder, format: :json),
+ "artifacts-endpoint-placeholder" => artifacts_endpoint_placeholder,
"pipeline-schedule-url" => pipeline_schedules_path(@project),
"empty-state-svg-path" => image_path('illustrations/pipelines_empty.svg'),
"error-state-svg-path" => image_path('illustrations/pipelines_failed.svg'),
@@ -17,4 +20,5 @@
"reset-cache-path" => can?(current_user, :admin_pipeline, @project) && reset_cache_project_settings_ci_cd_path(@project),
"has-gitlab-ci" => has_gitlab_ci?(@project).to_s,
"add-ci-yml-path" => can?(current_user, :create_pipeline, @project) && @project.present(current_user: current_user).add_ci_yml_path,
- "suggested-ci-templates" => experiment_suggested_ci_templates.to_json } }
+ "suggested-ci-templates" => experiment_suggested_ci_templates.to_json,
+ "code-quality-page-path" => @project.present(current_user: current_user).add_code_quality_ci_yml_path } }
diff --git a/app/views/projects/pipelines/new.html.haml b/app/views/projects/pipelines/new.html.haml
index 14de982e239..e92f14fcc63 100644
--- a/app/views/projects/pipelines/new.html.haml
+++ b/app/views/projects/pipelines/new.html.haml
@@ -1,55 +1,17 @@
- breadcrumb_title _('Pipelines')
- page_title s_('Pipeline|Run pipeline')
-- settings_link = link_to _('CI/CD settings'), project_settings_ci_cd_path(@project)
%h3.page-title
= s_('Pipeline|Run pipeline')
%hr
-- if Feature.enabled?(:new_pipeline_form, @project, default_enabled: :yaml)
- #js-new-pipeline{ data: { project_id: @project.id,
- pipelines_path: project_pipelines_path(@project),
- config_variables_path: config_variables_namespace_project_pipelines_path(@project.namespace, @project),
- default_branch: @project.default_branch,
- ref_param: params[:ref] || @project.default_branch,
- var_param: params[:var].to_json,
- file_param: params[:file_var].to_json,
- project_refs_endpoint: refs_project_path(@project, sort: 'updated_desc'),
- settings_link: project_settings_ci_cd_path(@project),
- max_warnings: ::Gitlab::Ci::Warnings::MAX_LIMIT } }
-
-- else
- = form_for @pipeline, as: :pipeline, url: project_pipelines_path(@project), html: { id: "new-pipeline-form", class: "js-new-pipeline-form js-requires-input" } do |f|
- = form_errors(@pipeline)
- = pipeline_warnings(@pipeline)
- .form-group.row
- .col-sm-12
- = f.label :ref, s_('Pipeline|Run for'), class: 'col-form-label'
- = hidden_field_tag 'pipeline[ref]', params[:ref] || @project.default_branch
- = dropdown_tag(params[:ref] || @project.default_branch,
- options: { toggle_class: 'js-branch-select wide monospace',
- filter: true, dropdown_class: "dropdown-menu-selectable git-revision-dropdown", placeholder: s_("Pipeline|Search branches"),
- data: { selected: params[:ref] || @project.default_branch, field_name: 'pipeline[ref]' } })
- .form-text.text-muted
- = s_("Pipeline|Existing branch name or tag")
-
- .col-sm-12.gl-mt-3.js-ci-variable-list-section
- %label
- = s_('Pipeline|Variables')
- %ul.ci-variable-list
- - if params[:var]
- - params[:var].each do |variable|
- = render 'ci/variables/url_query_variable_row', form_field: 'pipeline', variable: variable
- - if params[:file_var]
- - params[:file_var].each do |variable|
- - variable.push("file")
- = render 'ci/variables/url_query_variable_row', form_field: 'pipeline', variable: variable
- = render 'ci/variables/variable_row', form_field: 'pipeline', only_key_value: true
- .form-text.text-muted
- = (s_("Pipeline|Specify variable values to be used in this run. The values specified in %{settings_link} will be used by default.") % {settings_link: settings_link}).html_safe
-
- .form-actions
- = f.submit s_('Pipeline|Run pipeline'), class: 'btn gl-button btn-confirm gl-mr-3 js-variables-save-button'
- = link_to _('Cancel'), project_pipelines_path(@project), class: 'btn gl-button btn-default'
-
- %script#availableRefs{ type: "application/json" }= @project.repository.ref_names.to_json.html_safe
+#js-new-pipeline{ data: { project_id: @project.id,
+ pipelines_path: project_pipelines_path(@project),
+ config_variables_path: config_variables_namespace_project_pipelines_path(@project.namespace, @project),
+ default_branch: @project.default_branch,
+ ref_param: params[:ref] || @project.default_branch,
+ var_param: params[:var].to_json,
+ file_param: params[:file_var].to_json,
+ project_refs_endpoint: refs_project_path(@project, sort: 'updated_desc'),
+ settings_link: project_settings_ci_cd_path(@project),
+ max_warnings: ::Gitlab::Ci::Warnings::MAX_LIMIT } }
diff --git a/app/views/projects/pipelines/show.html.haml b/app/views/projects/pipelines/show.html.haml
index 98b1c5adcb5..93b0a525191 100644
--- a/app/views/projects/pipelines/show.html.haml
+++ b/app/views/projects/pipelines/show.html.haml
@@ -11,6 +11,10 @@
.js-pipeline-container{ data: { controller_action: "#{controller.action_name}" } }
#js-pipeline-header-vue.pipeline-header-container{ data: { full_path: @project.full_path, pipeline_iid: @pipeline.iid, pipeline_id: @pipeline.id, pipelines_path: project_pipelines_path(@project) } }
+
+ - if @pipeline.failed? && @pipeline.user_not_verified?
+ #js-cc-validation-required-alert
+
- if @pipeline.commit.present?
= render "projects/pipelines/info", commit: @pipeline.commit
diff --git a/app/views/projects/project_members/index.html.haml b/app/views/projects/project_members/index.html.haml
index 22bf61b6873..0fa9fb7079b 100644
--- a/app/views/projects/project_members/index.html.haml
+++ b/app/views/projects/project_members/index.html.haml
@@ -4,7 +4,7 @@
.js-remove-member-modal
.row.gl-mt-3
.col-lg-12
- - if can_invite_members_for_project?(@project)
+ - if can_invite_members_for_project?(@project) || can_invite_group_for_project?(@project)
.row
.col-md-12.col-lg-6.gl-display-flex
.gl-flex-direction-column.gl-flex-wrap.align-items-baseline
@@ -18,8 +18,15 @@
= html_escape(_("Members can be added by project %{i_open}Maintainers%{i_close} or %{i_open}Owners%{i_close}")) % { i_open: '<i>'.html_safe, i_close: '</i>'.html_safe }
.col-md-12.col-lg-6
.gl-display-flex.gl-flex-wrap.gl-justify-content-end
- .js-invite-group-trigger{ data: { classes: 'gl-mt-3 gl-sm-w-auto gl-w-full', display_text: _('Invite a group') } }
- .js-invite-members-trigger{ data: { variant: 'success', classes: 'gl-mt-3 gl-sm-w-auto gl-w-full gl-sm-ml-3', display_text: _('Invite members') } }
+ - if can_import_members?
+ = link_to _("Import a project"),
+ import_project_project_members_path(@project),
+ class: "btn btn-default btn-md gl-button gl-mt-3 gl-sm-w-auto gl-w-full",
+ title: _("Import members from another project")
+ - if @project.allowed_to_share_with_group?
+ .js-invite-group-trigger{ data: { classes: 'gl-mt-3 gl-sm-w-auto gl-w-full gl-sm-ml-3', display_text: _('Invite a group') } }
+ - if !membership_locked?
+ .js-invite-members-trigger{ data: { variant: 'success', classes: 'gl-mt-3 gl-sm-w-auto gl-w-full gl-sm-ml-3', display_text: _('Invite members') } }
= render 'projects/invite_members_modal', project: @project
- else
@@ -32,7 +39,7 @@
%p
= html_escape(_("Members can be added by project %{i_open}Maintainers%{i_close} or %{i_open}Owners%{i_close}")) % { i_open: '<i>'.html_safe, i_close: '</i>'.html_safe }
- - if !can_invite_members_for_project?(@project) && can_manage_project_members?(@project) && project_can_be_shared?
+ - if Feature.disabled?(:invite_members_group_modal, @project.group) && can_manage_project_members?(@project) && project_can_be_shared?
- if !membership_locked? && @project.allowed_to_share_with_group?
%ul.nav-links.nav.nav-tabs.gitlab-tabs{ role: 'tablist' }
%li.nav-tab{ role: 'presentation' }
@@ -75,22 +82,21 @@
%span.badge.gl-tab-counter-badge.badge-muted.badge-pill.gl-badge.sm= @requesters.count
.tab-content
#tab-members.tab-pane{ class: ('active' unless groups_tab_active?) }
- .js-project-members-list{ data: project_members_list_data_attributes(@project, @project_members) }
+ .js-project-members-list{ data: { members_data: project_members_list_data_json(@project, @project_members, { param_name: :page, params: { search_groups: nil } }) } }
.loading
- .spinner.spinner-md
- = paginate @project_members, theme: "gitlab", params: { search_groups: nil }
+ .gl-spinner.gl-spinner-md
- if show_groups?(@group_links)
#tab-groups.tab-pane{ class: ('active' if groups_tab_active?) }
- .js-project-group-links-list{ data: project_group_links_list_data_attributes(@project, @group_links) }
+ .js-project-group-links-list{ data: { members_data: project_group_links_list_data_json(@project, @group_links) } }
.loading
- .spinner.spinner-md
+ .gl-spinner.gl-spinner-md
- if show_invited_members?(@project, @invited_members)
#tab-invited-members.tab-pane
- .js-project-invited-members-list{ data: project_members_list_data_attributes(@project, @invited_members) }
+ .js-project-invited-members-list{ data: { members_data: project_members_list_data_json(@project, @invited_members) } }
.loading
- .spinner.spinner-md
+ .gl-spinner.gl-spinner-md
- if show_access_requests?(@project, @requesters)
#tab-access-requests.tab-pane
- .js-project-access-requests-list{ data: project_members_list_data_attributes(@project, @requesters) }
+ .js-project-access-requests-list{ data: { members_data: project_members_list_data_json(@project, @requesters) } }
.loading
- .spinner.spinner-md
+ .gl-spinner.gl-spinner-md
diff --git a/app/views/projects/project_templates/_template.html.haml b/app/views/projects/project_templates/_template.html.haml
index e2bfd0881b5..827ff62f8c3 100644
--- a/app/views/projects/project_templates/_template.html.haml
+++ b/app/views/projects/project_templates/_template.html.haml
@@ -10,7 +10,7 @@
.controls.d-flex.align-items-center
%a.btn.gl-button.btn-default.gl-mr-3{ href: template.preview, rel: 'noopener noreferrer', target: '_blank', data: { track_label: "template_preview", track_property: template.name, track_event: "click_button", track_value: "" } }
= _("Preview")
- %label.btn.gl-button.btn-success.template-button.choose-template.gl-mb-0{ for: template.name }
+ %label.btn.gl-button.btn-confirm.template-button.choose-template.gl-mb-0{ for: template.name }
%input{ type: "radio", autocomplete: "off", name: "project[template_name]", id: template.name, value: template.name, data: { track_label: "template_use", track_property: template.name, track_event: "click_button", track_value: "" } }
%span{ data: { qa_selector: 'use_template_button' } }
= _("Use template")
diff --git a/app/views/projects/registry/repositories/index.html.haml b/app/views/projects/registry/repositories/index.html.haml
index bbef5150a62..f56fd7f557d 100644
--- a/app/views/projects/registry/repositories/index.html.haml
+++ b/app/views/projects/registry/repositories/index.html.haml
@@ -12,7 +12,7 @@
"containers_error_image" => image_path('illustrations/docker-error-state.svg'),
"repository_url" => escape_once(@project.container_registry_url),
"registry_host_url_with_port" => escape_once(registry_config.host_port),
- "expiration_policy_help_page_path" => help_page_path('user/packages/container_registry/index', anchor: 'expiration-policy'),
+ "expiration_policy_help_page_path" => help_page_path('user/packages/container_registry/index.md', anchor: 'cleanup-policy'),
"garbage_collection_help_page_path" => help_page_path('administration/packages/container_registry', anchor: 'container-registry-garbage-collection'),
"run_cleanup_policies_help_page_path" => help_page_path('administration/packages/container_registry', anchor: 'run-the-cleanup-policy-now'),
"project_path": @project.full_path,
diff --git a/app/views/projects/runners/_group_runners.html.haml b/app/views/projects/runners/_group_runners.html.haml
index b37b530c33f..5d737bb3901 100644
--- a/app/views/projects/runners/_group_runners.html.haml
+++ b/app/views/projects/runners/_group_runners.html.haml
@@ -13,7 +13,7 @@
%br
%br
- if @project.group_runners_enabled?
- = link_to toggle_group_runners_project_runners_path(@project), class: 'btn gl-button btn-warning-secondary', method: :post do
+ = link_to toggle_group_runners_project_runners_path(@project), class: 'btn gl-button btn-default', method: :post do
= _('Disable group runners')
- else
= link_to toggle_group_runners_project_runners_path(@project), class: 'btn gl-button btn-confirm-secondary', method: :post do
diff --git a/app/views/projects/runners/_shared_runners.html.haml b/app/views/projects/runners/_shared_runners.html.haml
index fccfca38013..3df4f3a0bd0 100644
--- a/app/views/projects/runners/_shared_runners.html.haml
+++ b/app/views/projects/runners/_shared_runners.html.haml
@@ -1,23 +1,6 @@
-- isVueifySharedRunnersToggleEnabled = Feature.enabled?(:vueify_shared_runners_toggle, @project)
+= render 'shared/runners/shared_runners_description'
-= render layout: 'shared/runners/shared_runners_description' do
- - if !isVueifySharedRunnersToggleEnabled
- %br
- %br
- - if @project.group&.shared_runners_setting == 'disabled_and_unoverridable'
- %h5.gl-text-red-500
- = _('Shared runners disabled on group level')
- - else
- - if @project.shared_runners_enabled?
- = link_to toggle_shared_runners_project_runners_path(@project), class: 'btn gl-button btn-warning-secondary', method: :post do
- = _('Disable shared runners')
- - else
- = link_to toggle_shared_runners_project_runners_path(@project), class: 'btn gl-button btn-confirm', method: :post do
- = _('Enable shared runners')
- &nbsp; for this project
-
-- if isVueifySharedRunnersToggleEnabled
- #toggle-shared-runners-form{ data: toggle_shared_runners_settings_data(@project) }
+#toggle-shared-runners-form{ data: toggle_shared_runners_settings_data(@project) }
- if @shared_runners_count == 0
= _('This GitLab instance does not provide any shared runners yet. Instance administrators can register shared runners in the admin area.')
diff --git a/app/views/projects/runners/edit.html.haml b/app/views/projects/runners/edit.html.haml
index 77150715158..e87c52ff1a8 100644
--- a/app/views/projects/runners/edit.html.haml
+++ b/app/views/projects/runners/edit.html.haml
@@ -1,4 +1,7 @@
-- page_title _('Edit'), "#{@runner.description} ##{@runner.id}", _('Runners')
+- breadcrumb_title _('Edit')
+- page_title _('Edit'), "##{@runner.id} (#{@runner.short_sha})"
+- add_to_breadcrumbs _('CI/CD Settings'), project_settings_ci_cd_path(@project)
+- add_to_breadcrumbs "#{@runner.short_sha}", project_runner_path(@project, @runner)
%h2.page-title
= s_('Runners|Runner #%{runner_id}' % { runner_id: @runner.id })
diff --git a/app/views/projects/runners/show.html.haml b/app/views/projects/runners/show.html.haml
new file mode 100644
index 00000000000..cb7984729c8
--- /dev/null
+++ b/app/views/projects/runners/show.html.haml
@@ -0,0 +1,3 @@
+- add_to_breadcrumbs _('CI/CD Settings'), project_settings_ci_cd_path(@project)
+
+= render 'shared/runners/runner_details', runner: @runner
diff --git a/app/views/projects/settings/_archive.html.haml b/app/views/projects/settings/_archive.html.haml
index 5e0f24cea21..be9bd3dfc01 100644
--- a/app/views/projects/settings/_archive.html.haml
+++ b/app/views/projects/settings/_archive.html.haml
@@ -14,7 +14,7 @@
method: :post, class: "gl-button btn btn-confirm"
- else
- link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: help_page_path('user/project/settings/index', anchor: 'archiving-a-project') }
- %p= _("Archiving the project will make it entirely read only. It is hidden from the dashboard and doesn't show up in searches. %{strong_start}The repository cannot be committed to, and no issues, comments, or other entities can be created.%{strong_end} %{link_start}Learn more.%{link_end}").html_safe % { strong_start: '<strong>'.html_safe, strong_end: '</strong>'.html_safe, link_start: link_start, link_end: '</a>'.html_safe }
+ %p= _("Archiving the project will make it entirely read-only. It is hidden from the dashboard and doesn't show up in searches. %{strong_start}The repository cannot be committed to, and no issues, comments, or other entities can be created.%{strong_end} %{link_start}Learn more.%{link_end}").html_safe % { strong_start: '<strong>'.html_safe, strong_end: '</strong>'.html_safe, link_start: link_start, link_end: '</a>'.html_safe }
= link_to _('Archive project'), archive_project_path(@project),
data: { confirm: _("Are you sure that you want to archive this project?"), qa_selector: 'archive_project_link' },
method: :post, class: "gl-button btn btn-warning"
diff --git a/app/views/projects/settings/access_tokens/index.html.haml b/app/views/projects/settings/access_tokens/index.html.haml
index 01f3e441eef..1bf252b6282 100644
--- a/app/views/projects/settings/access_tokens/index.html.haml
+++ b/app/views/projects/settings/access_tokens/index.html.haml
@@ -9,13 +9,13 @@
%h4.gl-mt-0
= page_title
%p
+ - link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: help_page_path('user/project/settings/project_access_tokens') }
- if current_user.can?(:create_resource_access_tokens, @project)
- = _('You can generate an access token scoped to this project for each application to use the GitLab API.')
- -# Commented out until https://gitlab.com/gitlab-org/gitlab/-/issues/219551 is fixed
- -# %p
- -# = _('You can also use project access tokens to authenticate against Git over HTTP.')
+ = _('Generate project access tokens scoped to this project for your applications that need access to the GitLab API.')
+ %p
+ = _('You can also use project access tokens with Git to authenticate over HTTP(S). %{link_start}Learn more.%{link_end}').html_safe % { link_start: link_start, link_end: '</a>'.html_safe }
- else
- = _('Project access token creation is disabled in this group. You can still use and manage existing tokens.')
+ = _('Project access token creation is disabled in this group. You can still use and manage existing tokens. %{link_start}Learn more.%{link_end}').html_safe % { link_start: link_start, link_end: '</a>'.html_safe }
%p
- root_group = @project.group.root_ancestor
- if current_user.can?(:admin_group, root_group)
@@ -23,7 +23,6 @@
- link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: group_settings_link }
= _('You can enable project access token creation in %{link_start}group settings%{link_end}.').html_safe % { link_start: link_start, link_end: '</a>'.html_safe }
-
.col-lg-8
- if @new_project_access_token
= render 'shared/access_tokens/created_container',
diff --git a/app/views/projects/settings/operations/_configuration_banner.html.haml b/app/views/projects/settings/operations/_configuration_banner.html.haml
index 8551aa5380e..6fa6b23b0da 100644
--- a/app/views/projects/settings/operations/_configuration_banner.html.haml
+++ b/app/views/projects/settings/operations/_configuration_banner.html.haml
@@ -14,7 +14,7 @@
.col-sm-10
%p.text-success.gl-mt-3
= s_('PrometheusService|GitLab manages Prometheus on your clusters.')
- = link_to s_('PrometheusService|Manage clusters'), project_clusters_path(project), class: 'btn'
+ = link_to s_('PrometheusService|Manage clusters'), project_clusters_path(project), class: 'gl-button btn btn-default'
- else
.col-sm-2
= image_tag 'illustrations/monitoring/loading.svg'
diff --git a/app/views/projects/settings/operations/_error_tracking.html.haml b/app/views/projects/settings/operations/_error_tracking.html.haml
index 1e77f37ebb4..4ef9e1bd6fb 100644
--- a/app/views/projects/settings/operations/_error_tracking.html.haml
+++ b/app/views/projects/settings/operations/_error_tracking.html.haml
@@ -9,8 +9,8 @@
%button.gl-button.btn.btn-default.js-settings-toggle{ type: 'button' }
= _('Expand')
%p
- = _('To link Sentry to GitLab, enter your Sentry URL and Auth Token.')
- = link_to _('More information'), help_page_path('operations/error_tracking'), target: '_blank', rel: 'noopener noreferrer'
+ = _('Link Sentry to GitLab to discover and view the errors your application generates.')
+ = link_to _('Learn more.'), help_page_path('operations/error_tracking'), target: '_blank', rel: 'noopener noreferrer'
.settings-content
.js-error-tracking-form{ data: { list_projects_endpoint: project_error_tracking_projects_path(@project, format: :json),
operations_settings_endpoint: project_settings_operations_path(@project),
diff --git a/app/views/projects/settings/operations/show.html.haml b/app/views/projects/settings/operations/show.html.haml
index 73722a5a789..af183046e1e 100644
--- a/app/views/projects/settings/operations/show.html.haml
+++ b/app/views/projects/settings/operations/show.html.haml
@@ -1,6 +1,7 @@
- @content_class = 'limit-container-width' unless fluid_layout
-- page_title _('Operations Settings')
-- breadcrumb_title _('Operations Settings')
+- title = Feature.enabled?(:sidebar_refactor, current_user, default_enabled: :yaml) ? _('Monitor Settings') : _('Operations Settings')
+- page_title title
+- breadcrumb_title title
= render 'projects/settings/operations/alert_management'
= render 'projects/settings/operations/incidents'
diff --git a/app/views/projects/settings/packages_and_registries/show.html.haml b/app/views/projects/settings/packages_and_registries/show.html.haml
new file mode 100644
index 00000000000..561ac7b347d
--- /dev/null
+++ b/app/views/projects/settings/packages_and_registries/show.html.haml
@@ -0,0 +1,16 @@
+- breadcrumb_title _('Packages & Registries')
+- page_title _('Packages & Registries')
+- @content_class = 'limit-container-width' unless fluid_layout
+- expanded = true
+
+%section.settings.no-animate#js-registry-policies{ class: ('expanded' if expanded) }
+ .settings-header
+ %h4.settings-title.js-settings-toggle.js-settings-toggle-trigger-only
+ = _("Clean up image tags")
+ %button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' }
+ = expanded ? _('Collapse') : _('Expand')
+ %p
+ = _("Save space and find images in the Container Registry. Remove unneeded tags and keep only the ones you want.")
+ = link_to _('How does cleanup work?'), help_page_path('user/packages/container_registry/index', anchor: 'cleanup-policy'), target: '_blank', rel: 'noopener noreferrer'
+ .settings-content
+ = render 'projects/registry/settings/index'
diff --git a/app/views/projects/sidebar/_issues_service_desk.html.haml b/app/views/projects/sidebar/_issues_service_desk.html.haml
deleted file mode 100644
index 2730fe37f28..00000000000
--- a/app/views/projects/sidebar/_issues_service_desk.html.haml
+++ /dev/null
@@ -1,3 +0,0 @@
-= nav_link(controller: :issues, action: :service_desk ) do
- = link_to service_desk_project_issues_path(@project), title: 'Service Desk' do
- = _('Service Desk')
diff --git a/app/views/projects/snippets/show.html.haml b/app/views/projects/snippets/show.html.haml
index 726ab7d2372..a296394a2e0 100644
--- a/app/views/projects/snippets/show.html.haml
+++ b/app/views/projects/snippets/show.html.haml
@@ -6,6 +6,6 @@
#js-snippet-view{ data: {'qa-selector': 'snippet_view', 'snippet-gid': @snippet.to_global_id} }
.row-content-block.top-block.content-component-block
- = render 'award_emoji/awards_block', awardable: @snippet, inline: true
+ = render 'award_emoji/awards_block', awardable: @snippet, inline: true, api_awards_path: project_snippets_award_api_path(@snippet)
#notes.limited-width-notes= render "shared/notes/notes_with_form", :autocomplete => true
diff --git a/app/views/projects/tags/_tag.html.haml b/app/views/projects/tags/_tag.html.haml
index 1072d5bce06..83a3cac487f 100644
--- a/app/views/projects/tags/_tag.html.haml
+++ b/app/views/projects/tags/_tag.html.haml
@@ -8,7 +8,7 @@
= link_to tag.name, project_tag_path(@project, tag.name), class: 'item-title ref-name'
- if protected_tag?(@project, tag)
- %span.badge.badge-success.gl-ml-2
+ %span.badge.badge-success.gl-ml-2.gl-badge.sm.badge-pill
= s_('TagsPage|protected')
- if tag.message.present?
@@ -42,5 +42,5 @@
- if can?(current_user, :admin_tag, @project)
= link_to edit_project_tag_release_path(@project, tag.name), class: 'btn gl-button btn-default btn-icon btn-edit has-tooltip', title: s_('TagsPage|Edit release notes'), data: { container: "body" } do
- = sprite_icon("pencil")
+ = sprite_icon('pencil', css_class: 'gl-icon')
= render 'projects/buttons/remove_tag', project: @project, tag: tag
diff --git a/app/views/projects/tags/index.html.haml b/app/views/projects/tags/index.html.haml
index 229f13d0ff3..79205a51d71 100644
--- a/app/views/projects/tags/index.html.haml
+++ b/app/views/projects/tags/index.html.haml
@@ -9,28 +9,12 @@
= s_('TagsPage|Tags give the ability to mark specific points in history as being important')
.nav-controls
- - unless Gitlab::Ci::Features.gldropdown_tags_enabled?
- = form_tag(filter_tags_path, method: :get) do
- = search_field_tag :search, params[:search], { placeholder: s_('TagsPage|Filter by tag name'), id: 'tag-search', class: 'form-control search-text-input input-short', spellcheck: false }
-
- .dropdown
- %button.dropdown-menu-toggle{ type: 'button', data: { toggle: 'dropdown'} }
- %span.light
- = tags_sort_options_hash[@sort]
- = sprite_icon('chevron-down', css_class: 'dropdown-menu-toggle-icon gl-top-3')
- %ul.dropdown-menu.dropdown-menu-right.dropdown-menu-selectable
- %li.dropdown-header
- = s_('TagsPage|Sort by')
- - tags_sort_options_hash.each do |value, title|
- %li
- = link_to title, filter_tags_path(sort: value), class: ("is-active" if @sort == value)
- - else
- #js-tags-sort-dropdown{ data: { filter_tags_path: filter_tags_path, sort_options: tags_sort_options_hash.to_json } }
+ #js-tags-sort-dropdown{ data: { filter_tags_path: filter_tags_path, sort_options: tags_sort_options_hash.to_json } }
+ = link_to project_tags_path(@project, rss_url_options), title: _("Tags feed"), class: 'btn gl-button btn-default btn-icon has-tooltip gl-ml-auto' do
+ = sprite_icon('rss', css_class: 'gl-icon qa-rss-icon')
- if can?(current_user, :admin_tag, @project)
= link_to new_project_tag_path(@project), class: 'btn gl-button btn-confirm', data: { qa_selector: "new_tag_button" } do
= s_('TagsPage|New tag')
- = link_to project_tags_path(@project, rss_url_options), title: _("Tags feed"), class: 'btn gl-button btn-default btn-icon d-none d-sm-inline-block has-tooltip' do
- = sprite_icon('rss', css_class: 'qa-rss-icon')
= render_if_exists 'projects/commits/mirror_status'
diff --git a/app/views/projects/tags/new.html.haml b/app/views/projects/tags/new.html.haml
index 2ef1891089f..fe00772d1d6 100644
--- a/app/views/projects/tags/new.html.haml
+++ b/app/views/projects/tags/new.html.haml
@@ -51,7 +51,7 @@
= render layout: 'shared/md_preview', locals: { url: preview_markdown_path(@project), referenced_users: true } do
= render 'shared/zen', attr: :release_description, classes: 'note-textarea', placeholder: s_('TagsPage|Write your release notes or drag files here…'), current_text: @release_description, qa_selector: 'release_notes_field'
= render 'shared/notes/hints'
- .form-actions
- = button_tag s_('TagsPage|Create tag'), class: 'gl-button btn btn-confirm', data: { qa_selector: "create_tag_button" }
+ .form-actions.gl-display-flex
+ = button_tag s_('TagsPage|Create tag'), class: 'gl-button btn btn-confirm gl-mr-3', data: { qa_selector: "create_tag_button" }
= link_to s_('TagsPage|Cancel'), project_tags_path(@project), class: 'gl-button btn btn-default btn-cancel'
%script#availableRefs{ type: "application/json" }= @project.repository.ref_names.to_json.html_safe
diff --git a/app/views/projects/tags/releases/edit.html.haml b/app/views/projects/tags/releases/edit.html.haml
index f181212b328..88594209c3b 100644
--- a/app/views/projects/tags/releases/edit.html.haml
+++ b/app/views/projects/tags/releases/edit.html.haml
@@ -14,6 +14,6 @@
= render 'shared/zen', f: f, attr: :description, classes: 'note-textarea', placeholder: "Write your release notes or drag files here…"
= render 'shared/notes/hints'
.error-alert
- .gl-mt-3
- = f.submit 'Save changes', class: 'btn gl-button btn-confirm'
+ .gl-mt-5.gl-display-flex
+ = f.submit 'Save changes', class: 'btn gl-button btn-confirm gl-mr-3'
= link_to "Cancel", project_tag_path(@project, @tag.name), class: "btn gl-button btn-default btn-cancel"
diff --git a/app/views/projects/triggers/_trigger.html.haml b/app/views/projects/triggers/_trigger.html.haml
index 2def6c06458..081afacdaa6 100644
--- a/app/views/projects/triggers/_trigger.html.haml
+++ b/app/views/projects/triggers/_trigger.html.haml
@@ -30,8 +30,8 @@
%td.text-right.trigger-actions
- revoke_trigger_confirmation = "By revoking a trigger you will break any processes making use of it. Are you sure?"
- if can?(current_user, :admin_trigger, trigger)
- = link_to edit_project_trigger_path(@project, trigger), method: :get, title: "Edit", class: "gl-button btn btn-default btn-sm" do
+ = link_to edit_project_trigger_path(@project, trigger), method: :get, title: "Edit", class: "gl-button btn btn-default btn-icon" do
= sprite_icon('pencil')
- if can?(current_user, :manage_trigger, trigger)
- = link_to project_trigger_path(@project, trigger), data: { confirm: revoke_trigger_confirmation, testid: 'trigger_revoke_button' }, method: :delete, title: "Revoke", class: "gl-button btn btn-default btn-sm btn-trigger-revoke" do
+ = link_to project_trigger_path(@project, trigger), data: { confirm: revoke_trigger_confirmation, testid: 'trigger_revoke_button' }, method: :delete, title: "Revoke", class: "gl-button btn btn-default btn-icon btn-trigger-revoke gl-ml-3" do
= sprite_icon('remove')
diff --git a/app/views/registrations/invites/new.html.haml b/app/views/registrations/invites/new.html.haml
new file mode 100644
index 00000000000..6e6ff7aaeee
--- /dev/null
+++ b/app/views/registrations/invites/new.html.haml
@@ -0,0 +1,18 @@
+- page_title _('Join your team')
+- add_page_specific_style 'page_bundles/signup'
+- content_for :page_specific_javascripts do
+ = render "layouts/google_tag_manager_head"
+= render "layouts/google_tag_manager_body"
+
+%h2.center.pt-6.pb-3.gl-mb-0
+ = _('Join your team')
+%p.gl-text-center= _('Create your own profile to collaborate with your teammates in issues, merge requests, and more.')
+
+.signup-page
+ = render 'devise/shared/signup_box',
+ url: users_sign_up_invites_path,
+ button_text: _('Continue'),
+ show_omniauth_providers: social_signin_enabled?,
+ omniauth_providers_placement: :top,
+ suggestion_path: nil
+ = render 'devise/shared/sign_in_link'
diff --git a/app/views/registrations/welcome/show.html.haml b/app/views/registrations/welcome/show.html.haml
index bf5e35a1224..e85ce1ba6ac 100644
--- a/app/views/registrations/welcome/show.html.haml
+++ b/app/views/registrations/welcome/show.html.haml
@@ -25,6 +25,7 @@
= f.text_field :other_role, class: 'form-control'
= render_if_exists "registrations/welcome/setup_for_company", f: f
= render 'devise/shared/email_opted_in', f: f
+ = render_if_exists "registrations/welcome/jobs_to_be_done", f: f
.row
.form-group.col-sm-12.gl-mb-0
- if partial_exists? "registrations/welcome/button"
diff --git a/app/views/search/_category.html.haml b/app/views/search/_category.html.haml
index f094a6f5e3b..7f8a530deb8 100644
--- a/app/views/search/_category.html.haml
+++ b/app/views/search/_category.html.haml
@@ -13,23 +13,25 @@
= search_filter_link 'issues', _("Issues")
- if project_search_tabs?(:merge_requests)
= search_filter_link 'merge_requests', _("Merge requests")
- - if project_search_tabs?(:milestones)
- = search_filter_link 'milestones', _("Milestones")
- - if project_search_tabs?(:notes)
- = search_filter_link 'notes', _("Comments")
- if project_search_tabs?(:wiki)
= search_filter_link 'wiki_blobs', _("Wiki")
- if project_search_tabs?(:commits)
= search_filter_link 'commits', _("Commits")
+ - if project_search_tabs?(:notes)
+ = search_filter_link 'notes', _("Comments")
+ - if project_search_tabs?(:milestones)
+ = search_filter_link 'milestones', _("Milestones")
= users
- elsif @show_snippets
= search_filter_link 'snippet_titles', _("Titles and Descriptions"), search: { snippets: true, group_id: nil, project_id: nil }
- else
= search_filter_link 'projects', _("Projects"), data: { qa_selector: 'projects_tab' }
+ = render_if_exists 'search/category_code'
+ = render_if_exists 'search/epics_filter_link'
= search_filter_link 'issues', _("Issues")
= search_filter_link 'merge_requests', _("Merge requests")
- = search_filter_link 'milestones', _("Milestones")
- = render_if_exists 'search/epics_filter_link'
+ = render_if_exists 'search/category_wiki'
= render_if_exists 'search/category_elasticsearch'
+ = search_filter_link 'milestones', _("Milestones")
= users
diff --git a/app/views/search/results/_user.html.haml b/app/views/search/results/_user.html.haml
index 8060a1577e4..9e70d9c9baa 100644
--- a/app/views/search/results/_user.html.haml
+++ b/app/views/search/results/_user.html.haml
@@ -1,9 +1,9 @@
%ul.content-list
%li
- .avatar-cell.d-none.d-sm-block
- = user_avatar(user: user, user_name: user.name, css_class: 'd-none d-sm-inline avatar s40')
+ .avatar-cell
+ = user_avatar(user: user, size: 40, user_name: user.name)
.user-info
- = link_to user_path(user), class: 'd-none d-sm-inline' do
+ = link_to user_path(user) do
.item-title
= user.name
= user_status(user)
diff --git a/app/views/shared/_allow_request_access.html.haml b/app/views/shared/_allow_request_access.html.haml
index ca82f2f3377..93868f13e58 100644
--- a/app/views/shared/_allow_request_access.html.haml
+++ b/app/views/shared/_allow_request_access.html.haml
@@ -1,6 +1,6 @@
- label_class = local_assigns.fetch(:bold_label, false) ? 'font-weight-bold' : ''
-.form-check
- = form.check_box :request_access_enabled, class: 'form-check-input', data: { qa_selector: 'request_access_checkbox' }
- = form.label :request_access_enabled, class: 'form-check-label' do
+.gl-form-checkbox.custom-control.custom-checkbox
+ = form.check_box :request_access_enabled, class: 'custom-control-input', data: { qa_selector: 'request_access_checkbox' }
+ = form.label :request_access_enabled, class: 'custom-control-label' do
%span{ class: label_class }= _('Allow users to request access (if visibility is public or internal)')
diff --git a/app/views/shared/_commit_message_container.html.haml b/app/views/shared/_commit_message_container.html.haml
index 47ecc75af1f..904854c3fb7 100644
--- a/app/views/shared/_commit_message_container.html.haml
+++ b/app/views/shared/_commit_message_container.html.haml
@@ -7,11 +7,13 @@
.commit-message-container
.max-width-marker
= text_area_tag 'commit_message',
- (params[:commit_message] || local_assigns[:text] || local_assigns[:placeholder]),
- class: 'form-control gl-form-input js-commit-message', placeholder: local_assigns[:placeholder],
- data: descriptions,
- required: true, rows: (local_assigns[:rows] || 3),
- id: "commit_message-#{nonce}"
+ (params[:commit_message] || local_assigns[:text] || local_assigns[:placeholder]),
+ class: 'form-control gl-form-input js-commit-message',
+ placeholder: local_assigns[:placeholder],
+ data: descriptions,
+ 'data-qa-selector': 'commit_message_field',
+ required: true, rows: (local_assigns[:rows] || 3),
+ id: "commit_message-#{nonce}"
- if local_assigns[:hint]
%p.hint
= _('Try to keep the first line under 52 characters and the others under 72.')
diff --git a/app/views/shared/_confirm_fork_modal.html.haml b/app/views/shared/_confirm_fork_modal.html.haml
index 265396d3d8b..ed52aa01047 100644
--- a/app/views/shared/_confirm_fork_modal.html.haml
+++ b/app/views/shared/_confirm_fork_modal.html.haml
@@ -6,7 +6,7 @@
%button.close{ type: "button", "data-dismiss": "modal", "aria-label" => _('Close') }
%span{ "aria-hidden": true } &times;
.modal-body.p-3
- %p= _("You're not allowed to %{tag_start}edit%{tag_end} files in this project directly. Please fork this project, make your changes there, and submit a merge request.") % { tag_start: '', tag_end: ''}
+ %p= _("You can’t %{tag_start}edit%{tag_end} files directly in this project. Fork this project and submit a merge request with your changes.") % { tag_start: '', tag_end: ''}
.modal-footer
= link_to _('Cancel'), '#', class: "btn gl-button btn-default", "data-dismiss" => "modal"
= link_to _('Fork project'), fork_path, class: 'btn gl-button btn-confirm', data: { qa_selector: 'fork_project_button' }, method: :post
diff --git a/app/views/shared/_group_form.html.haml b/app/views/shared/_group_form.html.haml
index eea0c5f37de..7055dc8142a 100644
--- a/app/views/shared/_group_form.html.haml
+++ b/app/views/shared/_group_form.html.haml
@@ -6,7 +6,7 @@
.form-group.group-name-holder.col-sm-12
= f.label :name, class: 'label-bold' do
= _("Group name")
- = f.text_field :name, placeholder: _('My Awesome Group'), class: 'js-autofill-group-name form-control input-lg',
+ = f.text_field :name, placeholder: _('My Awesome Group'), class: 'js-autofill-group-name form-control input-lg', data: { qa_selector: 'group_name_field' },
required: true,
title: _('Please fill in a descriptive name for your group.'),
autofocus: true
@@ -22,7 +22,7 @@
- if parent
%strong= parent.full_path + '/'
= f.hidden_field :parent_id
- = f.text_field :path, placeholder: _('my-awesome-group'), class: 'form-control js-validate-group-path js-autofill-group-path',
+ = f.text_field :path, placeholder: _('my-awesome-group'), class: 'form-control js-validate-group-path js-autofill-group-path', data: { qa_selector: 'group_path_field' },
autofocus: local_assigns[:autofocus] || false, required: true,
pattern: Gitlab::PathRegex::NAMESPACE_FORMAT_REGEX_JS,
title: _('Please choose a group URL with no special characters.'),
diff --git a/app/views/shared/_import_form.html.haml b/app/views/shared/_import_form.html.haml
index 36d8aab6d53..cf9ee1a5231 100644
--- a/app/views/shared/_import_form.html.haml
+++ b/app/views/shared/_import_form.html.haml
@@ -6,21 +6,27 @@
= f.label :import_url, class: 'label-bold' do
%span
= _('Git repository URL')
- = f.text_field :import_url, value: import_url.sanitized_url,
- autocomplete: 'off', class: 'form-control', placeholder: 'https://gitlab.company.com/group/project.git', required: true
+ = f.text_field :import_url,
+ value: import_url.sanitized_url,
+ autocomplete: 'off',
+ class: 'form-control gl-form-input',
+ placeholder: 'https://gitlab.company.com/group/project.git',
+ required: true,
+ pattern: '(?:git|https?):\/\/.*/.*\.git$',
+ title: _('Please provide a valid URL ending with .git')
.row
.form-group.col-md-6
= f.label :import_url_user, class: 'label-bold' do
%span
= _('Username (optional)')
- = f.text_field :import_url_user, value: import_url.user, class: 'form-control', required: false, autocomplete: 'new-password'
+ = f.text_field :import_url_user, value: import_url.user, class: 'form-control gl-form-input', required: false, autocomplete: 'new-password'
.form-group.col-md-6
= f.label :import_url_password, class: 'label-bold' do
%span
= _('Password (optional)')
- = f.password_field :import_url_password, class: 'form-control', required: false, autocomplete: 'new-password'
+ = f.password_field :import_url_password, class: 'form-control gl-form-input', required: false, autocomplete: 'new-password'
.info-well.prepend-top-20
.well-segment
diff --git a/app/views/shared/_issuable_meta_data.html.haml b/app/views/shared/_issuable_meta_data.html.haml
index 6c3e15cbace..01ab7bf9cd4 100644
--- a/app/views/shared/_issuable_meta_data.html.haml
+++ b/app/views/shared/_issuable_meta_data.html.haml
@@ -6,7 +6,7 @@
- issuable_mr = @issuable_meta_data[issuable.id].merge_requests_count
- if issuable_mr > 0
- %li.issuable-mr.gl-display-none.gl-sm-display-block.has-tooltip{ title: _('Related merge requests') }
+ %li.issuable-mr.gl-display-none.gl-sm-display-block.has-tooltip{ title: _('Related merge requests'), data: { testid: 'merge-requests' } }
= sprite_icon('merge-request', css_class: "gl-vertical-align-middle")
= issuable_mr
diff --git a/app/views/shared/_issues.html.haml b/app/views/shared/_issues.html.haml
index eb12e9d463c..6eb736b0710 100644
--- a/app/views/shared/_issues.html.haml
+++ b/app/views/shared/_issues.html.haml
@@ -1,5 +1,7 @@
+= render 'shared/alerts/positioning_disabled'
+
- if @issues.to_a.any?
- %ul.content-list.issues-list.issuable-list{ class: ("manual-ordering" if @sort == 'relative_position'), data: { group_full_path: @group&.full_path } }
+ %ul.content-list.issues-list.issuable-list{ class: issue_manual_ordering_class, data: { group_full_path: @group&.full_path } }
= render partial: 'projects/issues/issue', collection: @issues
= paginate @issues, theme: "gitlab"
- else
diff --git a/app/views/shared/access_tokens/_table.html.haml b/app/views/shared/access_tokens/_table.html.haml
index 2a2a1a911af..9c59d5ae1fa 100644
--- a/app/views/shared/access_tokens/_table.html.haml
+++ b/app/views/shared/access_tokens/_table.html.haml
@@ -18,7 +18,7 @@
%th= s_('AccessTokens|Created')
%th
= _('Last Used')
- = link_to sprite_icon('question-o'), help_page_path('user/profile/personal_access_tokens.md', anchor: 'token-activity'), target: '_blank'
+ = link_to sprite_icon('question-o'), help_page_path('user/profile/personal_access_tokens.md', anchor: 'view-the-last-time-a-token-was-used'), target: '_blank'
%th= _('Expires')
%th= _('Scopes')
%th
diff --git a/app/views/shared/alerts/_positioning_disabled.html.haml b/app/views/shared/alerts/_positioning_disabled.html.haml
new file mode 100644
index 00000000000..91c1d3463d8
--- /dev/null
+++ b/app/views/shared/alerts/_positioning_disabled.html.haml
@@ -0,0 +1,2 @@
+- if issue_repositioning_disabled?
+ = render 'shared/alert_info', body: _('Issues manual ordering is temporarily disabled for technical reasons.')
diff --git a/app/views/shared/blob/_markdown_buttons.html.haml b/app/views/shared/blob/_markdown_buttons.html.haml
index 73f3d2a8fcd..033ed69da41 100644
--- a/app/views/shared/blob/_markdown_buttons.html.haml
+++ b/app/views/shared/blob/_markdown_buttons.html.haml
@@ -19,6 +19,9 @@
= markdown_toolbar_button({ icon: "list-bulleted", data: { "md-tag" => "- ", "md-prepend" => true }, title: _("Add a bullet list") })
= markdown_toolbar_button({ icon: "list-numbered", data: { "md-tag" => "1. ", "md-prepend" => true }, title: _("Add a numbered list") })
= markdown_toolbar_button({ icon: "list-task", data: { "md-tag" => "- [ ] ", "md-prepend" => true }, title: _("Add a task list") })
+ = markdown_toolbar_button({ icon: "details-block",
+ data: { "md-tag" => "<details><summary>Click to expand</summary>\n{text}\n</details>", "md-prepend" => true, "md-select" => "Click to expand" },
+ title: _("Add a collapsible section") })
= markdown_toolbar_button({ icon: "table", data: { "md-tag" => "| header | header |\n| ------ | ------ |\n| cell | cell |\n| cell | cell |", "md-prepend" => true }, title: _("Add a table") })
- if show_fullscreen_button
%button.toolbar-btn.toolbar-fullscreen-btn.js-zen-enter.has-tooltip{ type: "button", tabindex: -1, "aria-label": "Go full screen", title: _("Go full screen"), data: { container: "body" } }
diff --git a/app/views/shared/boards/_show.html.haml b/app/views/shared/boards/_show.html.haml
index bf70149812a..c1a50cfe718 100644
--- a/app/views/shared/boards/_show.html.haml
+++ b/app/views/shared/boards/_show.html.haml
@@ -7,6 +7,8 @@
- breadcrumb_title _("Epic Boards")
- else
- breadcrumb_title _("Issue Boards")
+ = render 'shared/alerts/positioning_disabled'
+
- page_title("#{board.name}", _("Boards"))
- add_page_specific_style 'page_bundles/boards'
diff --git a/app/views/shared/boards/components/sidebar/_assignee.html.haml b/app/views/shared/boards/components/sidebar/_assignee.html.haml
index c36f2c7c969..79817025565 100644
--- a/app/views/shared/boards/components/sidebar/_assignee.html.haml
+++ b/app/views/shared/boards/components/sidebar/_assignee.html.haml
@@ -1,9 +1,10 @@
- dropdown_options = assignees_dropdown_options('issue')
+- relative_url = Gitlab.config.gitlab.relative_url_root || '/'
.block.assignee{ ref: "assigneeBlock" }
%template{ "v-if" => "issue.assignees" }
%sidebar-assignees-widget{ ":iid" => "String(issue.iid)",
- ":full-path" => "issue.path.split('/-/')[0].substring(1)",
+ ":full-path" => "issue.path.split('/-/')[0].substring(1).replace(`#{relative_url}`, '')",
":initial-assignees" => "issue.assignees",
- ":multiple-assignees" => "!Boolean(#{dropdown_options[:data][:"max-select"]})",
+ ":allow-multiple-assignees" => "!Boolean(#{dropdown_options[:data][:"max-select"]})",
"@assignees-updated" => "setAssignees" }
diff --git a/app/views/shared/builds/_tabs.html.haml b/app/views/shared/builds/_tabs.html.haml
index 5c74e71b644..4973309edf5 100644
--- a/app/views/shared/builds/_tabs.html.haml
+++ b/app/views/shared/builds/_tabs.html.haml
@@ -2,23 +2,23 @@
%li{ class: active_when(scope.nil?) }>
= link_to build_path_proc.call(nil) do
All
- %span.badge.badge-pill.js-totalbuilds-count
+ %span.badge.gl-tab-counter-badge.badge-muted.badge-pill.gl-badge.sm.js-totalbuilds-count
= limited_counter_with_delimiter(all_builds)
%li{ class: active_when(scope == 'pending') }>
= link_to build_path_proc.call('pending') do
Pending
- %span.badge.badge-pill
+ %span.badge.gl-tab-counter-badge.badge-muted.badge-pill.gl-badge.sm
= limited_counter_with_delimiter(all_builds.pending)
%li{ class: active_when(scope == 'running') }>
= link_to build_path_proc.call('running') do
Running
- %span.badge.badge-pill
+ %span.badge.gl-tab-counter-badge.badge-muted.badge-pill.gl-badge.sm
= limited_counter_with_delimiter(all_builds.running)
%li{ class: active_when(scope == 'finished') }>
= link_to build_path_proc.call('finished') do
Finished
- %span.badge.badge-pill
+ %span.badge.gl-tab-counter-badge.badge-muted.badge-pill.gl-badge.sm
= limited_counter_with_delimiter(all_builds.finished)
diff --git a/app/views/shared/deploy_keys/_form.html.haml b/app/views/shared/deploy_keys/_form.html.haml
index 37a56057268..452e54f9cd4 100644
--- a/app/views/shared/deploy_keys/_form.html.haml
+++ b/app/views/shared/deploy_keys/_form.html.haml
@@ -6,7 +6,7 @@
.form-group
= form.label :title, class: 'col-form-label col-sm-2'
- .col-sm-10= form.text_field :title, class: 'form-control gl-form-input', readonly: ('readonly' unless can?(current_user, :update_deploy_key, deploy_key))
+ .col-sm-10= form.text_field :title, class: 'form-control gl-form-input', data: { qa_selector: 'deploy_key_title_field' }, readonly: ('readonly' unless can?(current_user, :update_deploy_key, deploy_key))
.form-group
- if deploy_key.new_record?
@@ -16,7 +16,7 @@
- link_start = "<a href='#{help_page_path('ssh/README')}' target='_blank' rel='noreferrer noopener'>".html_safe
- link_end = '</a>'
= _('Paste a public key here. %{link_start}How do I generate it?%{link_end}').html_safe % { link_start: link_start, link_end: link_end.html_safe }
- = form.text_area :key, class: 'form-control gl-form-input thin_area', rows: 5
+ = form.text_area :key, class: 'form-control gl-form-input thin_area', rows: 5, data: { qa_selector: 'deploy_key_field' }
- else
= form.label :fingerprint, class: 'col-form-label col-sm-2'
.col-sm-10
diff --git a/app/views/shared/deploy_keys/_index.html.haml b/app/views/shared/deploy_keys/_index.html.haml
index be6fe94e497..388fe75e833 100644
--- a/app/views/shared/deploy_keys/_index.html.haml
+++ b/app/views/shared/deploy_keys/_index.html.haml
@@ -1,5 +1,5 @@
- expanded = expanded_by_default?
-%section.qa-deploy-keys-settings.settings.no-animate#js-deploy-keys-settings{ class: ('expanded' if expanded), data: { qa_selector: 'deploy_keys_settings_content' } }
+%section.rspec-deploy-keys-settings.settings.no-animate#js-deploy-keys-settings{ class: ('expanded' if expanded), data: { qa_selector: 'deploy_keys_settings_content' } }
.settings-header
%h4.settings-title.js-settings-toggle.js-settings-toggle-trigger-only= _('Deploy keys')
%button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' }
diff --git a/app/views/shared/deploy_keys/_project_group_form.html.haml b/app/views/shared/deploy_keys/_project_group_form.html.haml
index 25357ccdc65..0c671b4a1c0 100644
--- a/app/views/shared/deploy_keys/_project_group_form.html.haml
+++ b/app/views/shared/deploy_keys/_project_group_form.html.haml
@@ -2,10 +2,10 @@
= form_errors(@deploy_keys.new_key)
.form-group.row
= f.label :title, class: "label-bold"
- = f.text_field :title, class: 'form-control gl-form-input', required: true
+ = f.text_field :title, class: 'form-control gl-form-input', required: true, data: { qa_selector: 'deploy_key_title_field' }
.form-group.row
= f.label :key, class: "label-bold"
- = f.text_area :key, class: 'form-control gl-form-input', rows: 5, required: true
+ = f.text_area :key, class: 'form-control gl-form-input', rows: 5, required: true, data: { qa_selector: 'deploy_key_field' }
.form-group.row
%p.light.gl-mb-0
= _('Paste a public key here.')
@@ -21,4 +21,4 @@
= _('Allow this key to push to this repository')
.form-group.row
- = f.submit _("Add key"), class: "btn gl-button btn-confirm"
+ = f.submit _("Add key"), class: "btn gl-button btn-confirm", data: { qa_selector: "add_deploy_key_button"}
diff --git a/app/views/shared/deploy_tokens/_form.html.haml b/app/views/shared/deploy_tokens/_form.html.haml
index 4d0858165a2..976776ccc62 100644
--- a/app/views/shared/deploy_tokens/_form.html.haml
+++ b/app/views/shared/deploy_tokens/_form.html.haml
@@ -6,28 +6,28 @@
.form-group
= f.label :name, class: 'label-bold'
- = f.text_field :name, class: 'form-control gl-form-input qa-deploy-token-name', required: true
+ = f.text_field :name, class: 'form-control gl-form-input', data: { qa_selector: 'deploy_token_name_field' }, required: true
.form-group
= f.label :expires_at, _('Expires at (optional)'), class: 'label-bold'
- = f.text_field :expires_at, class: 'datepicker form-control qa-deploy-token-expires-at', value: f.object.expires_at
+ = f.text_field :expires_at, class: 'datepicker form-control', data: { qa_selector: 'deploy_token_expires_at_field' }, value: f.object.expires_at
.text-secondary= s_('DeployTokens|Unless you enter a date, the token does not expire.')
.form-group
= f.label :username, _('Username (optional)'), class: 'label-bold'
- = f.text_field :username, class: 'form-control qa-deploy-token-username'
+ = f.text_field :username, class: 'form-control'
.text-secondary= s_('DeployTokens|Unless you specify a username, it is set to "gitlab+deploy-token-{n}".')
.form-group
= f.label :scopes, _('Scopes [Select 1 or more]'), class: 'label-bold'
%fieldset.form-group.form-check
- = f.check_box :read_repository, class: 'form-check-input qa-deploy-token-read-repository'
+ = f.check_box :read_repository, class: 'form-check-input', data: { qa_selector: 'deploy_token_read_repository_checkbox' }
= f.label :read_repository, 'read_repository', class: 'label-bold form-check-label'
.text-secondary= s_('DeployTokens|Allows read-only access to the repository.')
- if container_registry_enabled?(group_or_project)
%fieldset.form-group.form-check
- = f.check_box :read_registry, class: 'form-check-input qa-deploy-token-read-registry'
+ = f.check_box :read_registry, class: 'form-check-input', data: { qa_selector: 'deploy_token_read_registry_checkbox' }
= f.label :read_registry, 'read_registry', class: 'label-bold form-check-label'
.text-secondary= s_('DeployTokens|Allows read-only access to registry images.')
@@ -48,4 +48,4 @@
.text-secondary= s_('DeployTokens|Allows write access to the package registry.')
.gl-mt-3
- = f.submit s_('DeployTokens|Create deploy token'), class: 'btn gl-button btn-confirm qa-create-deploy-token'
+ = f.submit s_('DeployTokens|Create deploy token'), class: 'btn gl-button btn-confirm', data: { qa_selector: 'create_deploy_token_button' }
diff --git a/app/views/shared/deploy_tokens/_index.html.haml b/app/views/shared/deploy_tokens/_index.html.haml
index 9d1a24d4c24..3e8368b7b78 100644
--- a/app/views/shared/deploy_tokens/_index.html.haml
+++ b/app/views/shared/deploy_tokens/_index.html.haml
@@ -1,9 +1,9 @@
- expanded = expand_deploy_tokens_section?(@new_deploy_token)
-%section.qa-deploy-tokens-settings.settings.no-animate#js-deploy-tokens{ class: ('expanded' if expanded), data: { qa_selector: 'deploy_tokens_settings_content' } }
+%section.settings.no-animate#js-deploy-tokens{ class: ('expanded' if expanded), data: { qa_selector: 'deploy_tokens_settings_content' } }
.settings-header
%h4.settings-title.js-settings-toggle.js-settings-toggle-trigger-only= s_('DeployTokens|Deploy tokens')
- %button.btn.gl-button.btn-default.js-settings-toggle.qa-expand-deploy-keys{ type: 'button' }
+ %button.btn.gl-button.btn-default.js-settings-toggle
= expanded ? 'Collapse' : 'Expand'
%p
= description
diff --git a/app/views/shared/deploy_tokens/_new_deploy_token.html.haml b/app/views/shared/deploy_tokens/_new_deploy_token.html.haml
index 41e50138220..9c82d5685f8 100644
--- a/app/views/shared/deploy_tokens/_new_deploy_token.html.haml
+++ b/app/views/shared/deploy_tokens/_new_deploy_token.html.haml
@@ -1,11 +1,11 @@
-.qa-created-deploy-token-section.created-deploy-token-container.info-well
+.created-deploy-token-container.info-well{ data: { qa_selector: '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 qa-deploy-token-user'
+ = text_field_tag 'deploy-token-user', deploy_token.username, readonly: true, class: 'deploy-token-field form-control js-select-on-focus', data: { qa_selector: 'deploy_token_user_field' }
.input-group-append
= clipboard_button(text: deploy_token.username, title: s_('DeployTokens|Copy username'), placement: 'left')
%span.deploy-token-help-block.gl-mt-2.text-success
@@ -15,7 +15,7 @@
.form-group
.input-group
- = text_field_tag 'deploy-token', deploy_token.token, readonly: true, class: 'deploy-token-field form-control js-select-on-focus qa-deploy-token'
+ = text_field_tag 'deploy-token', deploy_token.token, readonly: true, class: 'deploy-token-field form-control js-select-on-focus', data: { qa_selector: 'deploy_token_field' }
.input-group-append
= clipboard_button(text: deploy_token.token, title: s_('DeployTokens|Copy deploy token'), placement: 'left')
%span.deploy-token-help-block.gl-mt-2.text-danger
diff --git a/app/views/shared/icons/_dev_ops_report_no_data.svg b/app/views/shared/icons/_dev_ops_report_no_data.svg
deleted file mode 100644
index 5de929859ae..00000000000
--- a/app/views/shared/icons/_dev_ops_report_no_data.svg
+++ /dev/null
@@ -1,39 +0,0 @@
-<svg xmlns="http://www.w3.org/2000/svg" width="360" height="220" viewBox="0 0 360 220">
- <g fill="none" fill-rule="evenodd">
- <path fill="#000" fill-opacity=".02" d="M125 44V24.003C125 18.48 129.483 14 135.005 14h89.99C230.52 14 235 18.477 235 24.003V43h84.992C326.624 43 332 48.372 332 55.002v144.996c0 6.63-5.38 12.002-12.008 12.002h-85.984c-6.632 0-12.008-5.372-12.008-12.002V183h-78v17.002c0 6.626-5.38 11.998-12.008 11.998H46.008C39.376 212 34 206.624 34 200.002V55.998C34 49.372 39.38 44 46.008 44H125z"/>
- <g transform="translate(214 36)">
- <rect width="110" height="168" x="2" y="2" fill="#FFF" rx="10"/>
- <path fill="#EEE" fill-rule="nonzero" d="M4 12.006c0-2.208.896-4.27 2.457-5.77.796-.766.82-2.032.055-2.828-.766-.796-2.032-.82-2.828-.055C1.347 5.6 0 8.7 0 12.006c0 1.105.895 2 2 2s2-.895 2-2zM14.388 4h8c1.104 0 2-.895 2-2s-.896-2-2-2h-8c-1.105 0-2 .895-2 2s.895 2 2 2zm18 0h8c1.104 0 2-.895 2-2s-.896-2-2-2h-8c-1.105 0-2 .895-2 2s.895 2 2 2zm18 0h8c1.104 0 2-.895 2-2s-.896-2-2-2h-8c-1.105 0-2 .895-2 2s.895 2 2 2zm18 0h8c1.104 0 2-.895 2-2s-.896-2-2-2h-8c-1.105 0-2 .895-2 2s.895 2 2 2zm18 0h8c1.104 0 2-.895 2-2s-.896-2-2-2h-8c-1.105 0-2 .895-2 2s.895 2 2 2zm17.51.227c2.115.514 3.93 1.88 5.022 3.756.556.955 1.78 1.28 2.735.724.954-.556 1.278-1.78.723-2.735-1.636-2.813-4.356-4.86-7.534-5.632-1.073-.26-2.155.397-2.416 1.47-.26 1.074.397 2.156 1.47 2.417zM110 16.78v8c0 1.104.895 2 2 2s2-.896 2-2v-8c0-1.105-.895-2-2-2s-2 .895-2 2zm0 18v8c0 1.104.895 2 2 2s2-.896 2-2v-8c0-1.105-.895-2-2-2s-2 .895-2 2zm0 18v8c0 1.104.895 2 2 2s2-.896 2-2v-8c0-1.105-.895-2-2-2s-2 .895-2 2zm0 18v8c0 1.104.895 2 2 2s2-.896 2-2v-8c0-1.105-.895-2-2-2s-2 .895-2 2zm0 18v8c0 1.104.895 2 2 2s2-.896 2-2v-8c0-1.105-.895-2-2-2s-2 .895-2 2zm0 18v8c0 1.104.895 2 2 2s2-.896 2-2v-8c0-1.105-.895-2-2-2s-2 .895-2 2zm0 18v8c0 1.104.895 2 2 2s2-.896 2-2v-8c0-1.105-.895-2-2-2s-2 .895-2 2zm0 18v8c0 1.104.895 2 2 2s2-.896 2-2v-8c0-1.105-.895-2-2-2s-2 .895-2 2zm-.024 17.844c-.17 2.186-1.227 4.18-2.903 5.558-.853.702-.976 1.962-.275 2.815.7.854 1.962.977 2.815.275 2.51-2.062 4.096-5.056 4.35-8.338.086-1.1-.737-2.063-1.838-2.15-1.102-.084-2.064.74-2.15 1.84zM98.826 168h-8c-1.104 0-2 .895-2 2s.896 2 2 2h8c1.105 0 2-.895 2-2s-.895-2-2-2zm-18 0h-8c-1.104 0-2 .895-2 2s.896 2 2 2h8c1.105 0 2-.895 2-2s-.895-2-2-2zm-18 0h-8c-1.104 0-2 .895-2 2s.896 2 2 2h8c1.105 0 2-.895 2-2s-.895-2-2-2zm-18 0h-8c-1.104 0-2 .895-2 2s.896 2 2 2h8c1.105 0 2-.895 2-2s-.895-2-2-2zm-18 0h-8c-1.104 0-2 .895-2 2s.896 2 2 2h8c1.105 0 2-.895 2-2s-.895-2-2-2zm-17.334-.4c-2.063-.68-3.77-2.186-4.71-4.143-.477-.996-1.67-1.416-2.667-.938-.996.476-1.416 1.67-.938 2.667 1.41 2.936 3.964 5.19 7.063 6.21 1.05.347 2.18-.223 2.526-1.272.346-1.05-.224-2.18-1.274-2.526zM4 154.434v-8c0-1.104-.895-2-2-2s-2 .896-2 2v8c0 1.105.895 2 2 2s2-.895 2-2zm0-18v-8c0-1.104-.895-2-2-2s-2 .896-2 2v8c0 1.105.895 2 2 2s2-.895 2-2zm0-18v-8c0-1.104-.895-2-2-2s-2 .896-2 2v8c0 1.105.895 2 2 2s2-.895 2-2zm0-18v-8c0-1.104-.895-2-2-2s-2 .896-2 2v8c0 1.105.895 2 2 2s2-.895 2-2zm0-18v-8c0-1.104-.895-2-2-2s-2 .896-2 2v8c0 1.105.895 2 2 2s2-.895 2-2zm0-18v-8c0-1.104-.895-2-2-2s-2 .896-2 2v8c0 1.105.895 2 2 2s2-.895 2-2zm0-18v-8c0-1.104-.895-2-2-2s-2 .896-2 2v8c0 1.105.895 2 2 2s2-.895 2-2zm0-18v-8c0-1.104-.895-2-2-2s-2 .896-2 2v8c0 1.105.895 2 2 2s2-.895 2-2z"/>
- <path fill="#F0EDF8" fill-rule="nonzero" d="M57 111c-11.598 0-21-9.402-21-21s9.402-21 21-21 21 9.402 21 21-9.402 21-21 21zm0-4c9.39 0 17-7.61 17-17s-7.61-17-17-17-17 7.61-17 17 7.61 17 17 17z"/>
- <path fill="#6B4FBB" d="M58 88v-6.997c0-1.11-.895-2.003-2-2.003-1.112 0-2 .897-2 2.003v8.994c0 1.11.895 2.003 2 2.003.174 0 .343-.022.503-.063.162.04.33.063.506.063h7.98C66.1 92 67 91.105 67 90c0-1.112-.9-2-2.01-2H58z"/>
- <rect width="8" height="4" x="8" y="14" fill="#EEE" rx="2"/>
- <path fill="#EEE" d="M21 16c0-1.105.887-2 1.998-2h4.004c1.103 0 1.998.888 1.998 2 0 1.105-.887 2-1.998 2h-4.004C21.895 18 21 17.112 21 16zm13 0c0-1.105.887-2 1.998-2h4.004c1.103 0 1.998.888 1.998 2 0 1.105-.887 2-1.998 2h-4.004C34.895 18 34 17.112 34 16zm13 0c0-1.105.887-2 1.998-2h4.004c1.103 0 1.998.888 1.998 2 0 1.105-.887 2-1.998 2h-4.004C47.895 18 47 17.112 47 16zm13 0c0-1.105.887-2 1.998-2h4.004c1.103 0 1.998.888 1.998 2 0 1.105-.887 2-1.998 2h-4.004C60.895 18 60 17.112 60 16zm13 0c0-1.105.887-2 1.998-2h4.004c1.103 0 1.998.888 1.998 2 0 1.105-.887 2-1.998 2h-4.004C73.895 18 73 17.112 73 16zm13 0c0-1.105.887-2 1.998-2h4.004c1.103 0 1.998.888 1.998 2 0 1.105-.887 2-1.998 2h-4.004C86.895 18 86 17.112 86 16zm13 0c0-1.105.887-2 1.998-2h4.004c1.103 0 1.998.888 1.998 2 0 1.105-.887 2-1.998 2h-4.004C99.895 18 99 17.112 99 16z"/>
- </g>
- <g transform="translate(118 7)">
- <rect width="110" height="168" x="2" y="2" fill="#FFF" rx="10"/>
- <path fill="#EEE" fill-rule="nonzero" d="M4 12.006c0-2.208.896-4.27 2.457-5.77.796-.766.82-2.032.055-2.828-.766-.796-2.032-.82-2.828-.055C1.347 5.6 0 8.7 0 12.006c0 1.105.895 2 2 2s2-.895 2-2zM14.388 4h8c1.104 0 2-.895 2-2s-.896-2-2-2h-8c-1.105 0-2 .895-2 2s.895 2 2 2zm18 0h8c1.104 0 2-.895 2-2s-.896-2-2-2h-8c-1.105 0-2 .895-2 2s.895 2 2 2zm18 0h8c1.104 0 2-.895 2-2s-.896-2-2-2h-8c-1.105 0-2 .895-2 2s.895 2 2 2zm18 0h8c1.104 0 2-.895 2-2s-.896-2-2-2h-8c-1.105 0-2 .895-2 2s.895 2 2 2zm18 0h8c1.104 0 2-.895 2-2s-.896-2-2-2h-8c-1.105 0-2 .895-2 2s.895 2 2 2zm17.51.227c2.115.514 3.93 1.88 5.022 3.756.556.955 1.78 1.28 2.735.724.954-.556 1.278-1.78.723-2.735-1.636-2.813-4.356-4.86-7.534-5.632-1.073-.26-2.155.397-2.416 1.47-.26 1.074.397 2.156 1.47 2.417zM110 16.78v8c0 1.104.895 2 2 2s2-.896 2-2v-8c0-1.105-.895-2-2-2s-2 .895-2 2zm0 18v8c0 1.104.895 2 2 2s2-.896 2-2v-8c0-1.105-.895-2-2-2s-2 .895-2 2zm0 18v8c0 1.104.895 2 2 2s2-.896 2-2v-8c0-1.105-.895-2-2-2s-2 .895-2 2zm0 18v8c0 1.104.895 2 2 2s2-.896 2-2v-8c0-1.105-.895-2-2-2s-2 .895-2 2zm0 18v8c0 1.104.895 2 2 2s2-.896 2-2v-8c0-1.105-.895-2-2-2s-2 .895-2 2zm0 18v8c0 1.104.895 2 2 2s2-.896 2-2v-8c0-1.105-.895-2-2-2s-2 .895-2 2zm0 18v8c0 1.104.895 2 2 2s2-.896 2-2v-8c0-1.105-.895-2-2-2s-2 .895-2 2zm0 18v8c0 1.104.895 2 2 2s2-.896 2-2v-8c0-1.105-.895-2-2-2s-2 .895-2 2zm-.024 17.844c-.17 2.186-1.227 4.18-2.903 5.558-.853.702-.976 1.962-.275 2.815.7.854 1.962.977 2.815.275 2.51-2.062 4.096-5.056 4.35-8.338.086-1.1-.737-2.063-1.838-2.15-1.102-.084-2.064.74-2.15 1.84zM98.826 168h-8c-1.104 0-2 .895-2 2s.896 2 2 2h8c1.105 0 2-.895 2-2s-.895-2-2-2zm-18 0h-8c-1.104 0-2 .895-2 2s.896 2 2 2h8c1.105 0 2-.895 2-2s-.895-2-2-2zm-18 0h-8c-1.104 0-2 .895-2 2s.896 2 2 2h8c1.105 0 2-.895 2-2s-.895-2-2-2zm-18 0h-8c-1.104 0-2 .895-2 2s.896 2 2 2h8c1.105 0 2-.895 2-2s-.895-2-2-2zm-18 0h-8c-1.104 0-2 .895-2 2s.896 2 2 2h8c1.105 0 2-.895 2-2s-.895-2-2-2zm-17.334-.4c-2.063-.68-3.77-2.186-4.71-4.143-.477-.996-1.67-1.416-2.667-.938-.996.476-1.416 1.67-.938 2.667 1.41 2.936 3.964 5.19 7.063 6.21 1.05.347 2.18-.223 2.526-1.272.346-1.05-.224-2.18-1.274-2.526zM4 154.434v-8c0-1.104-.895-2-2-2s-2 .896-2 2v8c0 1.105.895 2 2 2s2-.895 2-2zm0-18v-8c0-1.104-.895-2-2-2s-2 .896-2 2v8c0 1.105.895 2 2 2s2-.895 2-2zm0-18v-8c0-1.104-.895-2-2-2s-2 .896-2 2v8c0 1.105.895 2 2 2s2-.895 2-2zm0-18v-8c0-1.104-.895-2-2-2s-2 .896-2 2v8c0 1.105.895 2 2 2s2-.895 2-2zm0-18v-8c0-1.104-.895-2-2-2s-2 .896-2 2v8c0 1.105.895 2 2 2s2-.895 2-2zm0-18v-8c0-1.104-.895-2-2-2s-2 .896-2 2v8c0 1.105.895 2 2 2s2-.895 2-2zm0-18v-8c0-1.104-.895-2-2-2s-2 .896-2 2v8c0 1.105.895 2 2 2s2-.895 2-2zm0-18v-8c0-1.104-.895-2-2-2s-2 .896-2 2v8c0 1.105.895 2 2 2s2-.895 2-2z"/>
- <g fill-rule="nonzero">
- <path fill="#F0EDF8" d="M57 112c-12.15 0-22-9.85-22-22s9.85-22 22-22 22 9.85 22 22-9.85 22-22 22zm0-6c8.837 0 16-7.163 16-16s-7.163-16-16-16-16 7.163-16 16 7.163 16 16 16z"/>
- <path fill="#6B4FBB" d="M41.692 105.8C45.768 109.75 51.21 112 57 112c12.15 0 22-9.85 22-22s-9.85-22-22-22v6c8.837 0 16 7.163 16 16s-7.163 16-16 16c-4.215 0-8.166-1.633-11.133-4.508l-4.175 4.31z"/>
- </g>
- <path fill="#EEE" d="M8 16c0-1.105.887-2 1.998-2h4.004c1.103 0 1.998.888 1.998 2 0 1.105-.887 2-1.998 2H9.998C8.895 18 8 17.112 8 16zm13 0c0-1.105.887-2 1.998-2h4.004c1.103 0 1.998.888 1.998 2 0 1.105-.887 2-1.998 2h-4.004C21.895 18 21 17.112 21 16zm13 0c0-1.105.887-2 1.998-2h4.004c1.103 0 1.998.888 1.998 2 0 1.105-.887 2-1.998 2h-4.004C34.895 18 34 17.112 34 16zm13 0c0-1.105.887-2 1.998-2h4.004c1.103 0 1.998.888 1.998 2 0 1.105-.887 2-1.998 2h-4.004C47.895 18 47 17.112 47 16zm13 0c0-1.105.887-2 1.998-2h4.004c1.103 0 1.998.888 1.998 2 0 1.105-.887 2-1.998 2h-4.004C60.895 18 60 17.112 60 16zm13 0c0-1.105.887-2 1.998-2h4.004c1.103 0 1.998.888 1.998 2 0 1.105-.887 2-1.998 2h-4.004C73.895 18 73 17.112 73 16zm13 0c0-1.105.887-2 1.998-2h4.004c1.103 0 1.998.888 1.998 2 0 1.105-.887 2-1.998 2h-4.004C86.895 18 86 17.112 86 16zm13 0c0-1.105.887-2 1.998-2h4.004c1.103 0 1.998.888 1.998 2 0 1.105-.887 2-1.998 2h-4.004C99.895 18 99 17.112 99 16z"/>
- </g>
- <g transform="translate(26 36)">
- <rect width="110" height="168" x="2" y="2" fill="#FFF" rx="10"/>
- <path fill="#EEE" fill-rule="nonzero" d="M4 12.006v147.988C4 164.42 7.58 168 12.005 168h89.99c4.42 0 8.005-3.586 8.005-8.006V12.006C110 7.58 106.42 4 101.995 4h-89.99C7.585 4 4 7.586 4 12.006zm-4 0C0 5.376 5.377 0 12.005 0h89.99C108.628 0 114 5.37 114 12.006v147.988c0 6.63-5.377 12.006-12.005 12.006h-89.99C5.372 172 0 166.63 0 159.994V12.006z"/>
- <g transform="translate(21 82)">
- <rect width="24" height="4" y="10" fill="#F0EDF8" rx="2"/>
- <rect width="14" height="4" x="5" fill="#6B4FBB" rx="2"/>
- </g>
- <g transform="translate(69 82)">
- <rect width="24" height="4" y="10" fill="#F0EDF8" rx="2"/>
- <rect width="14" height="4" x="5" fill="#6B4FBB" rx="2"/>
- </g>
- <g transform="translate(38 42)">
- <rect width="22" height="4" x="8" fill="#FEE1D3" rx="2"/>
- <rect width="38" height="4" y="12" fill="#FB722E" rx="2"/>
- </g>
- <path fill="#EEE" d="M4 14h106v4H4z"/>
- </g>
- </g>
-</svg>
diff --git a/app/views/shared/issuable/_search_bar.html.haml b/app/views/shared/issuable/_search_bar.html.haml
index 1e340f033a1..3e89969f46e 100644
--- a/app/views/shared/issuable/_search_bar.html.haml
+++ b/app/views/shared/issuable/_search_bar.html.haml
@@ -20,9 +20,11 @@
= hidden_field_tag :search, params[:search]
- if @can_bulk_update
.check-all-holder.d-none.d-sm-block.hidden
- = check_box_tag "check-all-issues", nil, false, class: "check-all-issues left"
+ - checkbox_id = 'check-all-issues'
+ %label.gl-sr-only{ for: checkbox_id }= _('Select all')
+ = check_box_tag checkbox_id, nil, false, class: "check-all-issues left"
- if Feature.enabled?(:boards_filtered_search, @group) && is_epic_board
- #js-board-filtered-search
+ #js-board-filtered-search{ data: { full_path: @group&.full_path } }
- else
.issues-other-filters.filtered-search-wrapper.d-flex.flex-column.flex-md-row
.filtered-search-box
diff --git a/app/views/shared/issuable/_sidebar_assignees.html.haml b/app/views/shared/issuable/_sidebar_assignees.html.haml
index 47e7ff0e4bc..86369b32e98 100644
--- a/app/views/shared/issuable/_sidebar_assignees.html.haml
+++ b/app/views/shared/issuable/_sidebar_assignees.html.haml
@@ -1,7 +1,10 @@
- issuable_type = issuable_sidebar[:type]
- dropdown_options = assignees_dropdown_options(issuable_type)
-#js-vue-sidebar-assignees{ data: { field: issuable_type, signed_in: signed_in, max_assignees: dropdown_options[:data][:"max-select"], directly_invite_members: directly_invite_members?, indirectly_invite_members: indirectly_invite_members? } }
+#js-vue-sidebar-assignees{ data: { field: issuable_type,
+ signed_in: signed_in,
+ max_assignees: dropdown_options[:data][:"max-select"],
+ directly_invite_members: directly_invite_members? } }
.title.hide-collapsed
= _('Assignee')
= loading_icon(css_class: 'gl-vertical-align-text-bottom')
@@ -39,12 +42,12 @@
- data['max-select'] = dropdown_options[:data][:'max-select'] if dropdown_options[:data][:'max-select']
- options[:data].merge!(data)
- - if directly_invite_members? || indirectly_invite_members?
+ - if directly_invite_members?
- options[:dropdown_class] += ' dropdown-extended-height'
- options[:footer_content] = true
- options[:wrapper_class] = 'js-sidebar-assignee-dropdown'
- options[:toggle_class] += ' js-invite-members-track'
- - data['track-event'] = show_invite_members_track_event
+ - data['track-event'] = 'show_invite_members'
- options[:data].merge!(data)
- invite_text = _('Invite Members')
- track_label = 'edit_assignee'
@@ -52,15 +55,9 @@
= dropdown_tag(title, options: options) do
%ul.dropdown-footer-list
%li
- - if directly_invite_members?
- .js-invite-members-trigger{ data: { trigger_element: 'anchor',
- display_text: invite_text,
- event: 'click_invite_members',
- label: track_label } }
- - else
- .js-invite-member-trigger{ data: { display_text: invite_text, event: 'click_invite_members_version_b', label: track_label } }
+ .js-invite-members-trigger{ data: { trigger_element: 'anchor',
+ display_text: invite_text,
+ event: 'click_invite_members',
+ label: track_label } }
- else
= dropdown_tag(title, options: options)
-
-- if indirectly_invite_members?
- .js-invite-member-modal{ data: { members_path: project_project_members_path(@project, sort: :access_level_desc) } }
diff --git a/app/views/shared/issuable/_status_box.html.haml b/app/views/shared/issuable/_status_box.html.haml
new file mode 100644
index 00000000000..c0e972684d2
--- /dev/null
+++ b/app/views/shared/issuable/_status_box.html.haml
@@ -0,0 +1,6 @@
+- state_human_name, state_icon_name = state_name_with_icon(issuable)
+
+.issuable-status-box.status-box.js-mr-status-box{ class: status_box_class(issuable), data: { project_path: issuable.project.path_with_namespace, iid: issuable.iid, state: issuable.state } }
+ = sprite_icon(state_icon_name, css_class: 'gl-display-block gl-sm-display-none!')
+ %span.gl-display-none.gl-sm-display-block
+ = state_human_name
diff --git a/app/views/shared/issuable/form/_title.html.haml b/app/views/shared/issuable/form/_title.html.haml
index 94d0c395fa6..561ca0afd60 100644
--- a/app/views/shared/issuable/form/_title.html.haml
+++ b/app/views/shared/issuable/form/_title.html.haml
@@ -5,11 +5,8 @@
- div_class = no_issuable_templates ? 'col-sm-10' : 'col-sm-7 col-lg-8'
- toggle_wip_link_start = '<a href="" class="js-toggle-wip">'
- toggle_wip_link_end = '</a>'
-- draft_snippet = '<code>Draft:</code>'.html_safe
-- wip_snippet = '<code>WIP:</code>'.html_safe
-- draft_or_wip_snippet = '<code>Draft/WIP</code>'.html_safe
-- add_wip_text = (_('%{link_start}Start the title with %{draft_snippet} or %{wip_snippet}%{link_end} to prevent a merge request that is a work in progress from being merged before it\'s ready.') % { link_start: toggle_wip_link_start, link_end: toggle_wip_link_end, draft_snippet: draft_snippet, wip_snippet: wip_snippet } ).html_safe
-- remove_wip_text = (_('%{link_start}Remove the %{draft_or_wip_snippet} prefix%{link_end} from the title to allow this merge request to be merged when it\'s ready.' ) % { link_start: toggle_wip_link_start, link_end: toggle_wip_link_end, draft_or_wip_snippet: draft_or_wip_snippet } ).html_safe
+- add_wip_text = (_('%{link_start}Start the title with %{draft_snippet}%{link_end} to prevent a merge request that is a work in progress from being merged before it\'s ready.') % { link_start: toggle_wip_link_start, link_end: toggle_wip_link_end, draft_snippet: '<code>Draft:</code>'.html_safe } ).html_safe
+- remove_wip_text = (_('%{link_start}Remove the %{draft_snippet} prefix%{link_end} from the title to allow this merge request to be merged when it\'s ready.' ) % { link_start: toggle_wip_link_start, link_end: toggle_wip_link_end, draft_snippet: '<code>Draft</code>'.html_safe } ).html_safe
%div{ class: div_class }
= form.text_field :title, required: true, maxlength: 255, autofocus: true,
diff --git a/app/views/shared/issue_type/_details_header.html.haml b/app/views/shared/issue_type/_details_header.html.haml
index 36a68dfdaa7..a25e35cdcd4 100644
--- a/app/views/shared/issue_type/_details_header.html.haml
+++ b/app/views/shared/issue_type/_details_header.html.haml
@@ -1,12 +1,17 @@
+- link = issue_closed_link(@issue, current_user, css_class: 'text-white text-underline')
+
.detail-page-header
.detail-page-header-body
.issuable-status-box.status-box.status-box-issue-closed{ class: issue_status_visibility(issuable, status_box: :closed) }
= sprite_icon('issue-close', css_class: 'gl-display-block gl-sm-display-none!')
- .gl-display-none.gl-sm-display-block!
+ .gl-display-none.gl-sm-display-block
= issue_closed_text(issuable, current_user)
+ - if link
+ %span.text-white.gl-pl-2.gl-sm-display-none
+ = "(#{link})"
.issuable-status-box.status-box.status-box-open{ class: issue_status_visibility(issuable, status_box: :open) }
= sprite_icon('issue-open-m', css_class: 'gl-display-block gl-sm-display-none!')
- %span.gl-display-none.gl-sm-display-block!
+ %span.gl-display-none.gl-sm-display-block
= _('Open')
.issuable-meta
diff --git a/app/views/shared/members/_invite_member.html.haml b/app/views/shared/members/_invite_member.html.haml
index ad0ba6dcedf..49111c821b1 100644
--- a/app/views/shared/members/_invite_member.html.haml
+++ b/app/views/shared/members/_invite_member.html.haml
@@ -23,6 +23,6 @@
.clearable-input
= text_field_tag :expires_at, nil, class: 'form-control js-access-expiration-date', placeholder: 'Expiration date'
= sprite_icon('close', size: 16, css_class: 'clear-icon js-clear-input gl-text-gray-200')
- = submit_tag _("Invite"), class: "gl-button btn btn-confirm gl-mr-3", data: { qa_selector: 'invite_member_button' }
+ = submit_tag _("Invite"), class: "gl-button btn btn-confirm gl-mr-2", data: { qa_selector: 'invite_member_button' }
- if can_import_members
= link_to _("Import"), import_path, class: "gl-button btn btn-default", title: _("Import members from another project")
diff --git a/app/views/shared/milestones/_delete_button.html.haml b/app/views/shared/milestones/_delete_button.html.haml
index 09c783a0b24..6d4ff255f06 100644
--- a/app/views/shared/milestones/_delete_button.html.haml
+++ b/app/views/shared/milestones/_delete_button.html.haml
@@ -7,6 +7,6 @@
milestone_merge_request_count: @milestone.merge_requests.count },
disabled: true }
= _('Delete')
- .spinner.js-loading-icon.hidden
+ .gl-spinner.js-loading-icon.hidden
#js-delete-milestone-modal
diff --git a/app/views/shared/milestones/_form_dates.html.haml b/app/views/shared/milestones/_form_dates.html.haml
index e995584309a..e0664c1feba 100644
--- a/app/views/shared/milestones/_form_dates.html.haml
+++ b/app/views/shared/milestones/_form_dates.html.haml
@@ -3,11 +3,11 @@
.col-form-label.col-sm-2
= f.label :start_date, _('Start Date')
.col-sm-10
- = f.text_field :start_date, class: "datepicker form-control", data: { qa_selector: "start_date_field" }, placeholder: _('Select start date'), autocomplete: 'off'
+ = f.text_field :start_date, class: "datepicker form-control gl-form-input", data: { qa_selector: "start_date_field" }, placeholder: _('Select start date'), autocomplete: 'off'
%a.inline.float-right.gl-mt-2.js-clear-start-date{ href: "#" }= _('Clear start date')
.form-group.row
.col-form-label.col-sm-2
= f.label :due_date, _('Due Date')
.col-sm-10
- = f.text_field :due_date, class: "datepicker form-control", data: { qa_selector: "due_date_field" }, placeholder: _('Select due date'), autocomplete: 'off'
+ = f.text_field :due_date, class: "datepicker form-control gl-form-input", data: { qa_selector: "due_date_field" }, placeholder: _('Select due date'), autocomplete: 'off'
%a.inline.float-right.gl-mt-2.js-clear-due-date{ href: "#" }= _('Clear due date')
diff --git a/app/views/shared/milestones/_search_form.html.haml b/app/views/shared/milestones/_search_form.html.haml
index 403a0224a85..1c51f1ad09d 100644
--- a/app/views/shared/milestones/_search_form.html.haml
+++ b/app/views/shared/milestones/_search_form.html.haml
@@ -1,7 +1,7 @@
= form_tag request.path, method: :get do |f|
= search_field_tag :search_title, params[:search_title],
placeholder: _('Filter by milestone name'),
- class: 'form-control input-short',
+ class: 'form-control gl-form-input input-short',
spellcheck: false
= hidden_field_tag :state, params[:state]
= hidden_field_tag :sort, params[:sort]
diff --git a/app/views/shared/milestones/_sidebar.html.haml b/app/views/shared/milestones/_sidebar.html.haml
index 0e54f1a7672..0088cd35781 100644
--- a/app/views/shared/milestones/_sidebar.html.haml
+++ b/app/views/shared/milestones/_sidebar.html.haml
@@ -79,7 +79,7 @@
%span= milestone.issues_visible_to_user(current_user).count
.title.hide-collapsed
= s_('MilestoneSidebar|Issues')
- %span.badge.badge-pill= milestone.issues_visible_to_user(current_user).count
+ %span.badge.badge-muted.badge-pill.gl-badge.sm= milestone.issues_visible_to_user(current_user).count
- if show_new_issue_link?(project)
= link_to new_project_issue_path(project, issue: { milestone_id: milestone.id }), class: "float-right", title: s_('MilestoneSidebar|New Issue') do
= s_('MilestoneSidebar|New issue')
@@ -110,7 +110,7 @@
%span= milestone.merge_requests.count
.title.hide-collapsed
= s_('MilestoneSidebar|Merge requests')
- %span.badge.badge-pill= milestone.merge_requests.count
+ %span.badge.badge-muted.badge-pill.gl-badge.sm= milestone.merge_requests.count
.value.hide-collapsed.bold
- if !project || can?(current_user, :read_merge_request, project)
%span.milestone-stat
diff --git a/app/views/shared/milestones/_tab_loading.html.haml b/app/views/shared/milestones/_tab_loading.html.haml
index fe1184114e9..b19e994ef80 100644
--- a/app/views/shared/milestones/_tab_loading.html.haml
+++ b/app/views/shared/milestones/_tab_loading.html.haml
@@ -1,2 +1,2 @@
.text-center.gl-mt-3
- .spinner.spinner-md
+ .gl-spinner.gl-spinner-md
diff --git a/app/views/shared/namespaces/cascading_settings/_enforcement_checkbox.html.haml b/app/views/shared/namespaces/cascading_settings/_enforcement_checkbox.html.haml
index 1e9aa4ec5ff..ab4d8816ec9 100644
--- a/app/views/shared/namespaces/cascading_settings/_enforcement_checkbox.html.haml
+++ b/app/views/shared/namespaces/cascading_settings/_enforcement_checkbox.html.haml
@@ -1,14 +1,17 @@
- attribute = local_assigns.fetch(:attribute, nil)
-- group = local_assigns.fetch(:group, nil)
- form = local_assigns.fetch(:form, nil)
+- setting_locked = local_assigns.fetch(:setting_locked, false)
+- help_text = local_assigns.fetch(:help_text, s_('CascadingSettings|Subgroups cannot change this setting.'))
- return unless attribute && group && form && cascading_namespace_settings_enabled?
-- return if group.namespace_settings.public_send("#{attribute}_locked?")
+- return if setting_locked
- lock_attribute = "lock_#{attribute}"
.gl-form-checkbox.custom-control.custom-checkbox
= form.check_box lock_attribute, checked: group.namespace_settings.public_send(lock_attribute), class: 'custom-control-input', data: { testid: 'enforce-for-all-subgroups-checkbox' }
= form.label lock_attribute, class: 'custom-control-label' do
- %span= s_('CascadingSettings|Enforce for all subgroups')
- %p.help-text= s_('CascadingSettings|Subgroups cannot change this setting.')
+ %span
+ = yield.presence || s_('CascadingSettings|Enforce for all subgroups')
+ %p.help-text
+ = help_text
diff --git a/app/views/shared/namespaces/cascading_settings/_lock_icon.html.haml b/app/views/shared/namespaces/cascading_settings/_lock_icon.html.haml
new file mode 100644
index 00000000000..4e3b6b2afc4
--- /dev/null
+++ b/app/views/shared/namespaces/cascading_settings/_lock_icon.html.haml
@@ -0,0 +1,4 @@
+%button.position-absolute.gl-top-3.gl-right-0.gl-translate-y-n50.gl-cursor-default.btn.btn-default.btn-sm.gl-button.btn-default-tertiary.js-cascading-settings-lock-popover-target{ class: 'gl-p-1! gl-text-gray-600! gl-bg-transparent!',
+ type: 'button',
+ data: cascading_namespace_settings_popover_data(attribute, group, settings_path_helper) }
+ = sprite_icon('lock', size: 16)
diff --git a/app/views/shared/namespaces/cascading_settings/_setting_label.html.haml b/app/views/shared/namespaces/cascading_settings/_setting_label.html.haml
deleted file mode 100644
index 6596ce2bc73..00000000000
--- a/app/views/shared/namespaces/cascading_settings/_setting_label.html.haml
+++ /dev/null
@@ -1,21 +0,0 @@
-- attribute = local_assigns.fetch(:attribute, nil)
-- group = local_assigns.fetch(:group, nil)
-- form = local_assigns.fetch(:form, nil)
-- settings_path_helper = local_assigns.fetch(:settings_path_helper, nil)
-- help_text = local_assigns.fetch(:help_text, nil)
-
-- return unless attribute && group && form && settings_path_helper
-
-- setting_locked = group.namespace_settings.public_send("#{attribute}_locked?")
-
-= form.label attribute, class: 'custom-control-label', aria: { disabled: setting_locked } do
- %span.position-relative.gl-pr-6.gl-display-inline-flex
- = yield
- - if setting_locked
- %button.position-absolute.gl-top-3.gl-right-0.gl-translate-y-n50.gl-cursor-default.btn.btn-default.btn-sm.gl-button.btn-default-tertiary.js-cascading-settings-lock-popover-target{ class: 'gl-p-1! gl-text-gray-600! gl-bg-transparent!',
- type: 'button',
- data: cascading_namespace_settings_popover_data(attribute, group, settings_path_helper) }
- = sprite_icon('lock', size: 16)
- - if help_text
- %p.help-text
- = help_text
diff --git a/app/views/shared/namespaces/cascading_settings/_setting_label_checkbox.html.haml b/app/views/shared/namespaces/cascading_settings/_setting_label_checkbox.html.haml
new file mode 100644
index 00000000000..d27b3641637
--- /dev/null
+++ b/app/views/shared/namespaces/cascading_settings/_setting_label_checkbox.html.haml
@@ -0,0 +1,16 @@
+- attribute = local_assigns.fetch(:attribute, nil)
+- settings_path_helper = local_assigns.fetch(:settings_path_helper, nil)
+- form = local_assigns.fetch(:form, nil)
+- setting_locked = local_assigns.fetch(:setting_locked, false)
+- help_text = local_assigns.fetch(:help_text, nil)
+
+- return unless attribute && form && settings_path_helper
+
+= form.label attribute, class: 'custom-control-label', aria: { disabled: setting_locked } do
+ = render 'shared/namespaces/cascading_settings/setting_label_container' do
+ = yield
+ - if setting_locked
+ = render 'shared/namespaces/cascading_settings/lock_icon', local_assigns
+ - if help_text
+ %p.help-text
+ = help_text
diff --git a/app/views/shared/namespaces/cascading_settings/_setting_label_container.html.haml b/app/views/shared/namespaces/cascading_settings/_setting_label_container.html.haml
new file mode 100644
index 00000000000..7323295f1fe
--- /dev/null
+++ b/app/views/shared/namespaces/cascading_settings/_setting_label_container.html.haml
@@ -0,0 +1,2 @@
+%span.position-relative.gl-pr-6.gl-display-inline-flex
+ = yield
diff --git a/app/views/shared/namespaces/cascading_settings/_setting_label_fieldset.html.haml b/app/views/shared/namespaces/cascading_settings/_setting_label_fieldset.html.haml
new file mode 100644
index 00000000000..4a2ec9f30fd
--- /dev/null
+++ b/app/views/shared/namespaces/cascading_settings/_setting_label_fieldset.html.haml
@@ -0,0 +1,15 @@
+- attribute = local_assigns.fetch(:attribute, nil)
+- settings_path_helper = local_assigns.fetch(:settings_path_helper, nil)
+- setting_locked = local_assigns.fetch(:setting_locked, false)
+- help_text = local_assigns.fetch(:help_text, nil)
+
+- return unless attribute && settings_path_helper
+
+%legend.h5.gl-border-none.gl-m-0
+ = render 'shared/namespaces/cascading_settings/setting_label_container' do
+ = yield
+ - if setting_locked
+ = render 'shared/namespaces/cascading_settings/lock_icon', local_assigns
+- if help_text
+ %p.gl-text-gray-500
+ = help_text
diff --git a/app/views/shared/nav/_scope_menu.html.haml b/app/views/shared/nav/_scope_menu.html.haml
index 270587f48a8..2f10914ef3d 100644
--- a/app/views/shared/nav/_scope_menu.html.haml
+++ b/app/views/shared/nav/_scope_menu.html.haml
@@ -1,6 +1,6 @@
.context-header
= link_to scope_menu.link, **scope_menu.container_html_options do
- .avatar-container.rect-avatar.s40.project-avatar
+ %span.avatar-container.rect-avatar.s40.project-avatar
= source_icon(scope_menu.container, alt: scope_menu.title, class: 'avatar s40 avatar-tile', width: 40, height: 40)
- .sidebar-context-title
+ %span.sidebar-context-title
= scope_menu.title
diff --git a/app/views/shared/nav/_sidebar.html.haml b/app/views/shared/nav/_sidebar.html.haml
index 1c06fc9eebf..552dcbfd6fd 100644
--- a/app/views/shared/nav/_sidebar.html.haml
+++ b/app/views/shared/nav/_sidebar.html.haml
@@ -11,4 +11,5 @@
- if sidebar.render_raw_menus_partial
= render sidebar.render_raw_menus_partial
+ = render partial: 'shared/nav/sidebar_hidden_menu_item', collection: sidebar.hidden_menu&.renderable_items
= render 'shared/sidebar_toggle_button'
diff --git a/app/views/shared/nav/_sidebar_hidden_menu_item.html.haml b/app/views/shared/nav/_sidebar_hidden_menu_item.html.haml
new file mode 100644
index 00000000000..953f7a8ae60
--- /dev/null
+++ b/app/views/shared/nav/_sidebar_hidden_menu_item.html.haml
@@ -0,0 +1,3 @@
+%li.hidden
+ = link_to sidebar_hidden_menu_item.link, **sidebar_hidden_menu_item.container_html_options do
+ = sidebar_hidden_menu_item.title
diff --git a/app/views/shared/nav/_sidebar_menu.html.haml b/app/views/shared/nav/_sidebar_menu.html.haml
index c6e86a90ba7..67c775d1a85 100644
--- a/app/views/shared/nav/_sidebar_menu.html.haml
+++ b/app/views/shared/nav/_sidebar_menu.html.haml
@@ -1,7 +1,7 @@
= nav_link(**sidebar_menu.all_active_routes, html_options: sidebar_menu.nav_link_html_options) do
= link_to sidebar_menu.link, **sidebar_menu.container_html_options, data: { qa_selector: 'sidebar_menu_link', qa_menu_item: sidebar_menu.title } do
- if sidebar_menu.icon_or_image?
- .nav-icon-container
+ %span.nav-icon-container
- if sidebar_menu.image_path
= image_tag(sidebar_menu.image_path, **sidebar_menu.image_html_options)
- elsif sidebar_menu.sprite_icon
@@ -13,15 +13,15 @@
%span.badge.badge-pill.count{ **sidebar_menu.pill_html_options }
= number_with_delimiter(sidebar_menu.pill_count)
- %ul.sidebar-sub-level-items{ class: ('is-fly-out-only' unless sidebar_menu.has_items?) }
+ %ul.sidebar-sub-level-items{ class: ('is-fly-out-only' unless sidebar_menu.has_renderable_items?) }
= nav_link(**sidebar_menu.all_active_routes, html_options: { class: 'fly-out-top-item' } ) do
- = link_to sidebar_menu.link, aria: { label: sidebar_menu.title } do
+ = link_to sidebar_menu.link, **sidebar_menu.collapsed_container_html_options do
%strong.fly-out-top-item-name
= sidebar_menu.title
- if sidebar_menu.has_pill?
%span.badge.badge-pill.count.fly-out-badge{ **sidebar_menu.pill_html_options }
= number_with_delimiter(sidebar_menu.pill_count)
- - if sidebar_menu.has_renderable_items?
+ - if sidebar_menu.has_items?
%li.divider.fly-out-top-item
= render partial: 'shared/nav/sidebar_menu_item', collection: sidebar_menu.renderable_items
diff --git a/app/views/shared/runners/show.html.haml b/app/views/shared/runners/_runner_details.html.haml
index 757ec870f79..672f0b6a83f 100644
--- a/app/views/shared/runners/show.html.haml
+++ b/app/views/shared/runners/_runner_details.html.haml
@@ -1,8 +1,9 @@
-- page_title "#{@runner.description} ##{@runner.id}", _("Runners")
+- breadcrumb_title runner.short_sha
+- page_title "##{runner.id} (#{runner.short_sha})"
%h2.page-title
- = s_('Runners|Runner #%{runner_id}' % { runner_id: @runner.id })
- = render 'shared/runners/runner_type_badge', runner: @runner
+ = s_('Runners|Runner #%{runner_id}' % { runner_id: runner.id })
+ = render 'shared/runners/runner_type_badge', runner: runner
.table-holder
%table.table
@@ -12,51 +13,51 @@
%th= s_('Runners|Value')
%tr
%td= s_('Runners|Active')
- %td= @runner.active? ? _('Yes') : _('No')
+ %td= runner.active? ? _('Yes') : _('No')
%tr
%td= s_('Runners|Protected')
- %td= @runner.ref_protected? ? _('Yes') : _('No')
+ %td= runner.ref_protected? ? _('Yes') : _('No')
%tr
%td= s_('Runners|Can run untagged jobs')
- %td= @runner.run_untagged? ? _('Yes') : _('No')
- - unless @runner.group_type?
+ %td= runner.run_untagged? ? _('Yes') : _('No')
+ - unless runner.group_type?
%tr
%td= s_('Runners|Locked to this project')
- %td= @runner.locked? ? _('Yes') : _('No')
+ %td= runner.locked? ? _('Yes') : _('No')
%tr
%td= s_('Runners|Tags')
%td
- - @runner.tag_list.sort.each do |tag|
+ - runner.tag_list.sort.each do |tag|
%span.badge.badge-primary
= tag
%tr
%td= s_('Runners|Name')
- %td= @runner.name
+ %td= runner.name
%tr
%td= s_('Runners|Version')
- %td= @runner.version
+ %td= runner.version
%tr
%td= s_('Runners|IP Address')
- %td= @runner.ip_address
+ %td= runner.ip_address
%tr
%td= s_('Runners|Revision')
- %td= @runner.revision
+ %td= runner.revision
%tr
%td= s_('Runners|Platform')
- %td= @runner.platform
+ %td= runner.platform
%tr
%td= s_('Runners|Architecture')
- %td= @runner.architecture
+ %td= runner.architecture
%tr
%td= s_('Runners|Description')
- %td= @runner.description
+ %td= runner.description
%tr
%td= s_('Runners|Maximum job timeout')
- %td= @runner.maximum_timeout_human_readable
+ %td= runner.maximum_timeout_human_readable
%tr
%td= s_('Runners|Last contact')
%td
- - if @runner.contacted_at
- = time_ago_with_tooltip @runner.contacted_at
+ - if runner.contacted_at
+ = time_ago_with_tooltip runner.contacted_at
- else
= s_('Never')
diff --git a/app/views/shared/runners/_shared_runners_description.html.haml b/app/views/shared/runners/_shared_runners_description.html.haml
index 92564ec48bd..a276f725576 100644
--- a/app/views/shared/runners/_shared_runners_description.html.haml
+++ b/app/views/shared/runners/_shared_runners_description.html.haml
@@ -3,11 +3,9 @@
%h4
= _('Shared runners')
-.bs-callout.shared-runners-description
- = _('These runners are shared across this GitLab instance.')
- %p
+.bs-callout{ data: { testid: 'shared-runners-description' } }
+ %p= _('These runners are shared across this GitLab instance.')
- if Gitlab::CurrentSettings.shared_runners_text.present?
- = markdown_field(Gitlab::CurrentSettings.current_application_settings, :shared_runners_text)
+ = markdown(Gitlab::CurrentSettings.current_application_settings.shared_runners_text)
- else
- = _('The same shared runner executes code from multiple projects, unless you configure autoscaling with %{link} set to 1 (which it is on GitLab.com).').html_safe % { link: link }
- = yield
+ %p= _('The same shared runner executes code from multiple projects, unless you configure autoscaling with %{link} set to 1 (which it is on GitLab.com).').html_safe % { link: link }
diff --git a/app/views/shared/snippets/_snippet.html.haml b/app/views/shared/snippets/_snippet.html.haml
index 52cf0248f21..4e373dda013 100644
--- a/app/views/shared/snippets/_snippet.html.haml
+++ b/app/views/shared/snippets/_snippet.html.haml
@@ -8,7 +8,7 @@
= link_to gitlab_snippet_path(snippet) do
= snippet.title
- %ul.controls
+ %ul.controls{ data: { qa_selector: 'snippet_file_count_content', qa_snippet_files: snippet.statistics&.file_count } }
%li
= snippet_file_count(snippet)
%li
@@ -16,7 +16,7 @@
= sprite_icon('comments', css_class: 'gl-vertical-align-text-bottom')
= notes_count
%li
- %span.sr-only
+ %span.sr-only{ data: { qa_selector: 'snippet_visibility_content', qa_snippet_visibility: visibility_level_label(snippet.visibility_level) } }
= visibility_level_label(snippet.visibility_level)
= visibility_level_icon(snippet.visibility_level)
diff --git a/app/views/shared/ssh_keys/_key_delete.html.haml b/app/views/shared/ssh_keys/_key_delete.html.haml
index 1526e5d3eda..f8bb0e21f67 100644
--- a/app/views/shared/ssh_keys/_key_delete.html.haml
+++ b/app/views/shared/ssh_keys/_key_delete.html.haml
@@ -1,6 +1,9 @@
+- title = _('Delete Key')
+- aria = { label: title }
+
- if defined?(text)
- = button_to text, '#', class: html_class, data: button_data
+ = button_to text, '#', class: html_class, data: button_data, title: title, aria: aria
- else
- = button_to '#', class: html_class, data: button_data do
+ = button_to '#', class: html_class, data: button_data, title: title, aria: aria do
%span.sr-only= _('Delete')
= sprite_icon('remove')
diff --git a/app/views/shared/tokens/_scopes_form.html.haml b/app/views/shared/tokens/_scopes_form.html.haml
index 1c8e300fa8a..33e95446bd7 100644
--- a/app/views/shared/tokens/_scopes_form.html.haml
+++ b/app/views/shared/tokens/_scopes_form.html.haml
@@ -4,6 +4,6 @@
- scopes.each do |scope|
%fieldset.form-group.form-check
- = check_box_tag "#{prefix}[scopes][]", scope, token.scopes.include?(scope), id: "#{prefix}_scopes_#{scope}", class: "form-check-input qa-#{scope}-radio"
+ = check_box_tag "#{prefix}[scopes][]", scope, token.scopes.include?(scope), id: "#{prefix}_scopes_#{scope}", class: "form-check-input", data: { qa_selector: "#{scope}_checkbox" }
= label_tag "#{prefix}_scopes_#{scope}", scope, class: 'label-bold form-check-label'
.text-secondary= t scope, scope: scope_description(prefix)
diff --git a/app/views/shared/users/_user.html.haml b/app/views/shared/users/_user.html.haml
index f92c12102bb..7f7cd31591e 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 }
+ = 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 }
.block-truncated
%span.gl-text-gray-900= user.to_reference
diff --git a/app/views/shared/web_hooks/_form.html.haml b/app/views/shared/web_hooks/_form.html.haml
index ad84ce1d343..18912bf149f 100644
--- a/app/views/shared/web_hooks/_form.html.haml
+++ b/app/views/shared/web_hooks/_form.html.haml
@@ -43,13 +43,13 @@
= form.label :issues_events, class: 'list-label form-check-label gl-ml-1' do
%strong= s_('Webhooks|Issues events')
%p.text-muted.gl-ml-1
- = s_('Webhooks|URL is triggered when an issue is created, updated, or merged')
+ = s_('Webhooks|URL is triggered when an issue is created, updated, closed, or reopened')
%li
= form.check_box :confidential_issues_events, class: 'form-check-input'
= form.label :confidential_issues_events, class: 'list-label form-check-label gl-ml-1' do
%strong= s_('Webhooks|Confidential issues events')
%p.text-muted.gl-ml-1
- = s_('Webhooks|URL is triggered when a confidential issue is created, updated, or merged')
+ = s_('Webhooks|URL is triggered when a confidential issue is created, updated, closed, or reopened')
- if @group
= render_if_exists 'groups/hooks/member_events', form: form
= render_if_exists 'groups/hooks/subgroup_events', form: form
diff --git a/app/views/shared/wikis/history.html.haml b/app/views/shared/wikis/history.html.haml
index 079b9768730..afbed3b0f42 100644
--- a/app/views/shared/wikis/history.html.haml
+++ b/app/views/shared/wikis/history.html.haml
@@ -20,7 +20,7 @@
%th= _('Changes')
%th= _('Last updated')
%tbody
- - @page_versions.each do |commit|
+ - @commits.each do |commit|
%tr
%td
= link_to wiki_page_path(@wiki, @page, version_id: commit.id) do
@@ -33,6 +33,6 @@
= commit.message
%td
= time_ago_with_tooltip(commit.authored_date)
- = paginate @page_versions, theme: 'gitlab'
+ = paginate @commits, theme: 'gitlab'
= render 'shared/wikis/sidebar'
diff --git a/app/views/sherlock/queries/show.html.haml b/app/views/sherlock/queries/show.html.haml
index e4a48943115..eea13d105d8 100644
--- a/app/views/sherlock/queries/show.html.haml
+++ b/app/views/sherlock/queries/show.html.haml
@@ -11,7 +11,7 @@
.row-content-block
.float-right
- = link_to(sherlock_transaction_path(@transaction), class: 'btn') do
+ = link_to(sherlock_transaction_path(@transaction), class: 'btn gl-button btn-default') do
= sprite_icon('arrow-left')
= t('sherlock.transaction')
.oneline
diff --git a/app/views/snippets/_snippets_scope_menu.html.haml b/app/views/snippets/_snippets_scope_menu.html.haml
index e9c9ca6e856..ac6dac8b322 100644
--- a/app/views/snippets/_snippets_scope_menu.html.haml
+++ b/app/views/snippets/_snippets_scope_menu.html.haml
@@ -5,7 +5,7 @@
%li{ class: active_when(params[:scope].nil?) }
= link_to subject_snippets_path(subject) do
= _("All")
- %span.badge.badge-pill
+ %span.badge.badge-muted.badge-pill.gl-badge.sm
- if include_private
= counts[:total]
- else
@@ -15,17 +15,17 @@
%li{ class: active_when(params[:scope] == "are_private") }
= link_to subject_snippets_path(subject, scope: 'are_private') do
= _("Private")
- %span.badge.badge-pill
+ %span.badge.badge-muted.badge-pill.gl-badge.sm
= counts[:are_private]
%li{ class: active_when(params[:scope] == "are_internal") }
= link_to subject_snippets_path(subject, scope: 'are_internal') do
= _("Internal")
- %span.badge.badge-pill
+ %span.badge.badge-muted.badge-pill.gl-badge.sm
= counts[:are_internal]
%li{ class: active_when(params[:scope] == "are_public") }
= link_to subject_snippets_path(subject, scope: 'are_public') do
= _("Public")
- %span.badge.badge-pill
+ %span.badge.badge-muted.badge-pill.gl-badge.sm
= counts[:are_public]
diff --git a/app/views/snippets/edit.html.haml b/app/views/snippets/edit.html.haml
index 66f5e8148e1..f737e347c39 100644
--- a/app/views/snippets/edit.html.haml
+++ b/app/views/snippets/edit.html.haml
@@ -1,5 +1,7 @@
- page_title _("Edit"), "#{@snippet.title} (#{@snippet.to_reference})", _("Snippets")
- @content_class = "limit-container-width" unless fluid_layout
+- content_for :prefetch_asset_tags do
+ - webpack_preload_asset_tag('monaco')
%h3.page-title
= _("Edit Snippet")
diff --git a/app/views/snippets/show.html.haml b/app/views/snippets/show.html.haml
index beb4cf4a6aa..4fdb9e70742 100644
--- a/app/views/snippets/show.html.haml
+++ b/app/views/snippets/show.html.haml
@@ -9,6 +9,8 @@
- add_to_breadcrumbs _("Snippets"), dashboard_snippets_path
- breadcrumb_title @snippet.to_reference
- page_title "#{@snippet.title} (#{@snippet.to_reference})", _("Snippets")
+- content_for :prefetch_asset_tags do
+ - webpack_preload_asset_tag('monaco', prefetch: true)
#js-snippet-view{ data: {'qa-selector': 'snippet_view', 'snippet-gid': @snippet.to_global_id} }
diff --git a/app/views/users/_overview.html.haml b/app/views/users/_overview.html.haml
index a78971967ff..2e6d335a98d 100644
--- a/app/views/users/_overview.html.haml
+++ b/app/views/users/_overview.html.haml
@@ -3,7 +3,7 @@
.row.d-none.d-sm-flex
.col-12.calendar-block.gl-my-3
.user-calendar.light{ data: { calendar_path: user_calendar_path(@user, :json), calendar_activities_path: user_calendar_activities_path, utc_offset: Time.zone.utc_offset } }
- .spinner.spinner-md.gl-my-8
+ .gl-spinner.gl-spinner-md.gl-my-8
.user-calendar-error.invisible
= _('There was an error loading users activity calendar.')
%a.js-retry-load{ href: '#' }
@@ -18,9 +18,9 @@
%h4.gl-flex-grow-1
= Feature.enabled?(:security_auto_fix) && @user.bot? ? s_('UserProfile|Bot activity') : s_('UserProfile|Activity')
= link_to s_('UserProfile|View all'), user_activity_path, class: "hide js-view-all"
- .overview-content-list{ data: { href: user_activity_path } }
+ .overview-content-list{ data: { href: user_activity_path, qa_selector: 'user_activity_content' } }
.center.light.loading
- .spinner.spinner-md
+ .gl-spinner.gl-spinner-md
- unless Feature.enabled?(:security_auto_fix) && @user.bot?
.col-md-12.col-lg-6
@@ -32,4 +32,4 @@
= link_to s_('UserProfile|View all'), user_projects_path, class: "hide js-view-all"
.overview-content-list{ data: { href: user_projects_path } }
.center.light.loading
- .spinner.spinner-md
+ .gl-spinner.gl-spinner-md
diff --git a/app/views/users/show.html.haml b/app/views/users/show.html.haml
index daa41e0ebfe..a5b95883361 100644
--- a/app/views/users/show.html.haml
+++ b/app/views/users/show.html.haml
@@ -39,7 +39,7 @@
= link_to user_unfollow_path(@user, :json) , class: link_classes + 'btn gl-button btn-default', method: :post do
= _('Unfollow')
- else
- = link_to user_follow_path(@user, :json) , class: link_classes + 'btn gl-button btn-confirm', method: :post do
+ = link_to user_follow_path(@user, :json) , class: link_classes + 'btn gl-button btn-confirm', method: :post, data: { qa_selector: 'follow_user_link' } do
= _('Follow')
.profile-header{ class: [('with-no-profile-tabs' if profile_tabs.empty?)] }
@@ -103,7 +103,7 @@
- count = @user.followers.count
= n_('1 follower', '%{count} followers', count) % { count: count }
.profile-link-holder.middle-dot-divider
- = link_to user_following_path, class: 'text-link' do
+ = link_to user_following_path, class: 'text-link', data: { qa_selector: 'following_link' } do
= @user.followees.count
= _('following')
- if @user.bio.present?
@@ -169,7 +169,7 @@
= s_('UserProfile|Most Recent Activity')
.content_list{ data: { href: user_activity_path } }
.loading
- .spinner.spinner-md
+ .gl-spinner.gl-spinner-md
- unless @user.bot?
- if profile_tab?(:groups)
#groups.tab-pane
@@ -200,7 +200,7 @@
-# This tab is always loaded via AJAX
.loading.hide
- .spinner.spinner-md
+ .gl-spinner.gl-spinner-md
- if profile_tabs.empty?
.svg-content