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:
Diffstat (limited to 'app/views')
-rw-r--r--app/views/admin/application_settings/_ci_cd.html.haml2
-rw-r--r--app/views/admin/application_settings/_gitaly.html.haml18
-rw-r--r--app/views/admin/application_settings/_help_page.html.haml6
-rw-r--r--app/views/admin/application_settings/_initial_branch_name.html.haml2
-rw-r--r--app/views/admin/application_settings/_localization.html.haml5
-rw-r--r--app/views/admin/application_settings/_mailgun.html.haml25
-rw-r--r--app/views/admin/application_settings/_repository_check.html.haml23
-rw-r--r--app/views/admin/application_settings/_repository_mirrors_form.html.haml7
-rw-r--r--app/views/admin/application_settings/_repository_storage.html.haml14
-rw-r--r--app/views/admin/application_settings/_runner_registrars_form.html.haml16
-rw-r--r--app/views/admin/application_settings/_snowplow.html.haml15
-rw-r--r--app/views/admin/application_settings/_third_party_offers.html.haml6
-rw-r--r--app/views/admin/application_settings/_usage.html.haml41
-rw-r--r--app/views/admin/application_settings/ci/_header.html.haml4
-rw-r--r--app/views/admin/application_settings/ci_cd.html.haml12
-rw-r--r--app/views/admin/application_settings/general.html.haml1
-rw-r--r--app/views/admin/application_settings/integrations.html.haml8
-rw-r--r--app/views/admin/application_settings/metrics_and_profiling.html.haml4
-rw-r--r--app/views/admin/application_settings/preferences.html.haml13
-rw-r--r--app/views/admin/application_settings/repository.html.haml12
-rw-r--r--app/views/admin/background_migrations/_migration.html.haml9
-rw-r--r--app/views/admin/background_migrations/index.html.haml1
-rw-r--r--app/views/admin/dashboard/index.html.haml5
-rw-r--r--app/views/admin/dev_ops_report/_callout.html.haml2
-rw-r--r--app/views/admin/dev_ops_report/_report.html.haml9
-rw-r--r--app/views/admin/groups/show.html.haml6
-rw-r--r--app/views/admin/identities/index.html.haml2
-rw-r--r--app/views/admin/impersonation_tokens/index.html.haml5
-rw-r--r--app/views/admin/projects/show.html.haml21
-rw-r--r--app/views/admin/runners/_runner.html.haml10
-rw-r--r--app/views/admin/runners/index.html.haml12
-rw-r--r--app/views/admin/users/_approve_user.html.haml7
-rw-r--r--app/views/admin/users/_ban_user.html.haml9
-rw-r--r--app/views/admin/users/_block_user.html.haml8
-rw-r--r--app/views/admin/users/_head.html.haml63
-rw-r--r--app/views/admin/users/_reject_pending_user.html.haml7
-rw-r--r--app/views/admin/users/_user_activation_effects.html.haml6
-rw-r--r--app/views/admin/users/_user_approve_effects.html.haml11
-rw-r--r--app/views/admin/users/_user_detail_note.html.haml4
-rw-r--r--app/views/admin/users/_user_reject_effects.html.haml10
-rw-r--r--app/views/admin/users/keys.html.haml1
-rw-r--r--app/views/admin/users/projects.html.haml2
-rw-r--r--app/views/admin/users/show.html.haml129
-rw-r--r--app/views/ci/token_access/_index.html.haml1
-rw-r--r--app/views/ci/variables/_content.html.haml4
-rw-r--r--app/views/ci/variables/_index.html.haml6
-rw-r--r--app/views/ci/variables/_variable_row.html.haml2
-rw-r--r--app/views/clusters/clusters/_applications.html.haml1
-rw-r--r--app/views/clusters/clusters/_applications_tab.html.haml5
-rw-r--r--app/views/clusters/clusters/_banner.html.haml18
-rw-r--r--app/views/clusters/clusters/_multiple_clusters_message.html.haml2
-rw-r--r--app/views/clusters/clusters/_provider_details_form.html.haml4
-rw-r--r--app/views/clusters/clusters/aws/_new.html.haml8
-rw-r--r--app/views/clusters/clusters/gcp/_form.html.haml4
-rw-r--r--app/views/clusters/clusters/show.html.haml17
-rw-r--r--app/views/clusters/clusters/user/_form.html.haml4
-rw-r--r--app/views/dashboard/projects/index.html.haml9
-rw-r--r--app/views/devise/shared/_signup_box.html.haml2
-rw-r--r--app/views/groups/_delete_project_button.html.haml1
-rw-r--r--app/views/groups/_home_panel.html.haml4
-rw-r--r--app/views/groups/_import_group_from_file_panel.html.haml3
-rw-r--r--app/views/groups/_invite_members_modal.html.haml15
-rw-r--r--app/views/groups/_project_badges.html.haml2
-rw-r--r--app/views/groups/merge_requests.html.haml2
-rw-r--r--app/views/groups/milestones/_form.html.haml38
-rw-r--r--app/views/groups/projects.html.haml5
-rw-r--r--app/views/groups/runners/_group_runners.html.haml35
-rw-r--r--app/views/groups/runners/_runner.html.haml8
-rw-r--r--app/views/groups/runners/_settings.html.haml (renamed from app/views/groups/runners/_index.html.haml)0
-rw-r--r--app/views/groups/settings/_advanced.html.haml17
-rw-r--r--app/views/groups/settings/_pages_settings.html.haml2
-rw-r--r--app/views/groups/settings/_transfer.html.haml22
-rw-r--r--app/views/groups/settings/ci_cd/show.html.haml4
-rw-r--r--app/views/groups/settings/integrations/index.html.haml8
-rw-r--r--app/views/groups/settings/repository/_initial_branch_name.html.haml4
-rw-r--r--app/views/groups/show.html.haml2
-rw-r--r--app/views/help/index.html.haml2
-rw-r--r--app/views/import/gitlab_projects/new.html.haml2
-rw-r--r--app/views/import/shared/_new_project_form.html.haml4
-rw-r--r--app/views/layouts/_flash.html.haml2
-rw-r--r--app/views/layouts/_loading_hints.html.haml2
-rw-r--r--app/views/layouts/_page.html.haml4
-rw-r--r--app/views/layouts/_search.html.haml4
-rw-r--r--app/views/layouts/_snowplow.html.haml2
-rw-r--r--app/views/layouts/application.html.haml1
-rw-r--r--app/views/layouts/devise.html.haml25
-rw-r--r--app/views/layouts/header/_new_dropdown.html.haml2
-rw-r--r--app/views/layouts/header/_registration_enabled_callout.html.haml4
-rw-r--r--app/views/layouts/minimal.html.haml18
-rw-r--r--app/views/layouts/nav/_dashboard.html.haml2
-rw-r--r--app/views/layouts/nav/projects_dropdown/_show.html.haml21
-rw-r--r--app/views/layouts/nav/sidebar/_admin.html.haml20
-rw-r--r--app/views/layouts/nav/sidebar/_analytics_links.html.haml2
-rw-r--r--app/views/layouts/nav/sidebar/_context_menu_body.html.haml9
-rw-r--r--app/views/layouts/nav/sidebar/_group.html.haml210
-rw-r--r--app/views/layouts/nav/sidebar/_group_menus.html.haml166
-rw-r--r--app/views/layouts/nav/sidebar/_profile.html.haml7
-rw-r--r--app/views/layouts/welcome.html.haml8
-rw-r--r--app/views/notify/access_token_about_to_expire_email.html.haml2
-rw-r--r--app/views/notify/access_token_about_to_expire_email.text.erb2
-rw-r--r--app/views/notify/access_token_expired_email.html.haml2
-rw-r--r--app/views/notify/access_token_expired_email.text.erb2
-rw-r--r--app/views/notify/in_product_marketing_email.html.haml2
-rw-r--r--app/views/notify/send_admin_notification.html.haml7
-rw-r--r--app/views/notify/send_admin_notification.text.haml6
-rw-r--r--app/views/notify/send_unsubscribed_notification.html.haml2
-rw-r--r--app/views/notify/send_unsubscribed_notification.text.haml1
-rw-r--r--app/views/notify/user_deactivated_email.html.haml17
-rw-r--r--app/views/notify/user_deactivated_email.text.erb10
-rw-r--r--app/views/profiles/accounts/show.html.haml16
-rw-r--r--app/views/profiles/keys/index.html.haml4
-rw-r--r--app/views/profiles/personal_access_tokens/index.html.haml3
-rw-r--r--app/views/profiles/preferences/show.html.haml46
-rw-r--r--app/views/profiles/show.html.haml5
-rw-r--r--app/views/profiles/two_factor_auths/show.html.haml3
-rw-r--r--app/views/projects/_flash_messages.html.haml1
-rw-r--r--app/views/projects/_home_panel.html.haml4
-rw-r--r--app/views/projects/_import_project_pane.html.haml2
-rw-r--r--app/views/projects/_invite_members_empty_project.html.haml (renamed from app/views/projects/_invite_members.html.haml)3
-rw-r--r--app/views/projects/_invite_members_modal.html.haml15
-rw-r--r--app/views/projects/_merge_request_merge_checks_settings.html.haml2
-rw-r--r--app/views/projects/_new_project_fields.html.haml2
-rw-r--r--app/views/projects/_remove.html.haml2
-rw-r--r--app/views/projects/_terraform_banner.html.haml5
-rw-r--r--app/views/projects/blame/show.html.haml5
-rw-r--r--app/views/projects/blob/_pipeline_tour_success.html.haml2
-rw-r--r--app/views/projects/blob/viewers/_csv.html.haml1
-rw-r--r--app/views/projects/branches/new.html.haml8
-rw-r--r--app/views/projects/cycle_analytics/show.html.haml2
-rw-r--r--app/views/projects/default_branch/_show.html.haml4
-rw-r--r--app/views/projects/diffs/_warning.html.haml11
-rw-r--r--app/views/projects/empty.html.haml2
-rw-r--r--app/views/projects/feature_flags/edit.html.haml3
-rw-r--r--app/views/projects/forks/error.html.haml15
-rw-r--r--app/views/projects/forks/new.html.haml2
-rw-r--r--app/views/projects/import/jira/show.html.haml2
-rw-r--r--app/views/projects/issues/_alert_moved_from_service_desk.html.haml9
-rw-r--r--app/views/projects/issues/index.html.haml2
-rw-r--r--app/views/projects/issues/show.html.haml2
-rw-r--r--app/views/projects/mattermosts/_no_teams.html.haml2
-rw-r--r--app/views/projects/mattermosts/_team_selection.html.haml4
-rw-r--r--app/views/projects/merge_requests/show.html.haml2
-rw-r--r--app/views/projects/milestones/_form.html.haml40
-rw-r--r--app/views/projects/milestones/show.html.haml24
-rw-r--r--app/views/projects/packages/packages/show.html.haml24
-rw-r--r--app/views/projects/pages/_pages_settings.html.haml7
-rw-r--r--app/views/projects/pipelines/_with_tabs.html.haml2
-rw-r--r--app/views/projects/pipelines/index.html.haml4
-rw-r--r--app/views/projects/prometheus/metrics/edit.html.haml2
-rw-r--r--app/views/projects/prometheus/metrics/new.html.haml2
-rw-r--r--app/views/projects/protected_branches/shared/_create_protected_branch.html.haml2
-rw-r--r--app/views/projects/protected_branches/shared/_index.html.haml13
-rw-r--r--app/views/projects/protected_tags/shared/_index.html.haml12
-rw-r--r--app/views/projects/registry/settings/_index.haml9
-rw-r--r--app/views/projects/releases/index.html.haml2
-rw-r--r--app/views/projects/runners/_settings.html.haml (renamed from app/views/projects/runners/_index.html.haml)0
-rw-r--r--app/views/projects/runners/_specific_runners.html.haml34
-rw-r--r--app/views/projects/security/configuration/show.html.haml2
-rw-r--r--app/views/projects/settings/access_tokens/index.html.haml7
-rw-r--r--app/views/projects/settings/ci_cd/_autodevops_form.html.haml2
-rw-r--r--app/views/projects/settings/ci_cd/_form.html.haml12
-rw-r--r--app/views/projects/settings/ci_cd/show.html.haml22
-rw-r--r--app/views/projects/settings/operations/show.html.haml7
-rw-r--r--app/views/registrations/experience_levels/show.html.haml1
-rw-r--r--app/views/registrations/invites/new.html.haml17
-rw-r--r--app/views/registrations/welcome/show.html.haml5
-rw-r--r--app/views/root/index.html.haml10
-rw-r--r--app/views/search/_results.html.haml24
-rw-r--r--app/views/search/results/_blob_data.html.haml1
-rw-r--r--app/views/search/results/_issuable.html.haml33
-rw-r--r--app/views/search/results/_timeout.html.haml10
-rw-r--r--app/views/shared/_auto_devops_implicitly_enabled_banner.html.haml4
-rw-r--r--app/views/shared/_confirm_your_email_alert.html.haml7
-rw-r--r--app/views/shared/_global_alert.html.haml16
-rw-r--r--app/views/shared/_group_form.html.haml3
-rw-r--r--app/views/shared/_import_form.html.haml11
-rw-r--r--app/views/shared/_new_project_item_select.html.haml2
-rw-r--r--app/views/shared/_project_limit.html.haml16
-rw-r--r--app/views/shared/_service_ping_consent.html.haml (renamed from app/views/shared/_ping_consent.html.haml)8
-rw-r--r--app/views/shared/_sidebar_toggle_button.html.haml2
-rw-r--r--app/views/shared/access_tokens/_form.html.haml29
-rw-r--r--app/views/shared/access_tokens/_table.html.haml17
-rw-r--r--app/views/shared/boards/_show.html.haml4
-rw-r--r--app/views/shared/deploy_keys/_form.html.haml2
-rw-r--r--app/views/shared/deploy_keys/_project_group_form.html.haml2
-rw-r--r--app/views/shared/deploy_tokens/_form.html.haml2
-rw-r--r--app/views/shared/empty_states/_issues.html.haml2
-rw-r--r--app/views/shared/issuable/_bulk_update_sidebar.html.haml12
-rw-r--r--app/views/shared/issuable/_form.html.haml15
-rw-r--r--app/views/shared/issuable/_invite_members_trigger.html.haml8
-rw-r--r--app/views/shared/issuable/_search_bar.html.haml2
-rw-r--r--app/views/shared/issuable/_sidebar.html.haml41
-rw-r--r--app/views/shared/issuable/_sidebar_todo.html.haml15
-rw-r--r--app/views/shared/issuable/_sort_dropdown.html.haml2
-rw-r--r--app/views/shared/issue_type/_details_content.html.haml3
-rw-r--r--app/views/shared/members/_group.html.haml50
-rw-r--r--app/views/shared/members/_manage_access_button.html.haml7
-rw-r--r--app/views/shared/members/_member.html.haml72
-rw-r--r--app/views/shared/members/_requests.html.haml5
-rw-r--r--app/views/shared/members/_search_field.html.haml6
-rw-r--r--app/views/shared/members/_sort_dropdown.html.haml19
-rw-r--r--app/views/shared/milestones/_form_dates.html.haml24
-rw-r--r--app/views/shared/milestones/_issuable.html.haml2
-rw-r--r--app/views/shared/milestones/_issuables.html.haml14
-rw-r--r--app/views/shared/milestones/_milestone_complete_alert.html.haml10
-rw-r--r--app/views/shared/milestones/_top.html.haml9
-rw-r--r--app/views/shared/namespaces/cascading_settings/_enforcement_checkbox.html.haml3
-rw-r--r--app/views/shared/namespaces/cascading_settings/_setting_label_checkbox.html.haml3
-rw-r--r--app/views/shared/namespaces/cascading_settings/_setting_label_fieldset.html.haml3
-rw-r--r--app/views/shared/nav/_scope_menu.html.haml12
-rw-r--r--app/views/shared/nav/_scope_menu_body.html.haml8
-rw-r--r--app/views/shared/nav/_sidebar.html.haml13
-rw-r--r--app/views/shared/nav/_sidebar_menu.html.haml12
-rw-r--r--app/views/shared/nav/_sidebar_menu_collapsed.html.haml5
-rw-r--r--app/views/shared/snippets/_embed.html.haml4
-rw-r--r--app/views/shared/wikis/edit.html.haml2
-rw-r--r--app/views/users/unsubscribes/show.html.haml11
217 files changed, 1118 insertions, 1324 deletions
diff --git a/app/views/admin/application_settings/_ci_cd.html.haml b/app/views/admin/application_settings/_ci_cd.html.haml
index 5ae45d5a9da..fb530e18b03 100644
--- a/app/views/admin/application_settings/_ci_cd.html.haml
+++ b/app/views/admin/application_settings/_ci_cd.html.haml
@@ -64,6 +64,6 @@
= f.text_field :default_ci_config_path, class: 'form-control gl-form-input', placeholder: '.gitlab-ci.yml'
%p.form-text.text-muted
= _("The default CI/CD configuration file and path for new projects.").html_safe
- = link_to sprite_icon('question-o'), help_page_path('ci/pipelines/settings', anchor: 'custom-cicd-configuration-file'), target: '_blank'
+ = link_to sprite_icon('question-o'), help_page_path('ci/pipelines/settings', anchor: 'specify-a-custom-cicd-configuration-file'), target: '_blank'
= f.submit _('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 b28a53d8bf6..ade6dac606a 100644
--- a/app/views/admin/application_settings/_gitaly.html.haml
+++ b/app/views/admin/application_settings/_gitaly.html.haml
@@ -3,25 +3,19 @@
%fieldset
.form-group
- = f.label :gitaly_timeout_default, _('Default Timeout Period'), class: 'label-bold'
+ = f.label :gitaly_timeout_default, _('Default timeout'), 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
- for git fetch/push operations or Sidekiq jobs.
- This timeout should be less than the worker timeout. If a Gitaly call timeout would exceed the
- worker timeout, the remaining time from the worker timeout would be used to avoid having to terminate
- the worker.
+ = _('Timeout for most Gitaly operations (in seconds).')
.form-group
- = f.label :gitaly_timeout_fast, _('Fast Timeout Period'), class: 'label-bold'
+ = f.label :gitaly_timeout_fast, _('Fast timeout'), 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.
+ = _('Timeout for the fastest Gitaly operations (in seconds).')
.form-group
- = f.label :gitaly_timeout_medium, _('Medium Timeout Period'), class: 'label-bold'
+ = f.label :gitaly_timeout_medium, _('Medium timeout'), 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.
+ = _('Timeout for moderately fast Gitaly operations (in seconds). Provide a value between Default timeout and Fast timeout.')
= f.submit _('Save changes'), class: "gl-button btn btn-confirm"
diff --git a/app/views/admin/application_settings/_help_page.html.haml b/app/views/admin/application_settings/_help_page.html.haml
index e7816f5a1c0..b71e8ca831e 100644
--- a/app/views/admin/application_settings/_help_page.html.haml
+++ b/app/views/admin/application_settings/_help_page.html.haml
@@ -5,18 +5,18 @@
= render_if_exists 'admin/application_settings/help_text_setting', form: f
.form-group
- = f.label :help_page_text, class: 'label-bold'
+ = f.label :help_page_text, _('Additional text to show on the Help page'), class: 'label-bold'
= f.text_area :help_page_text, class: 'form-control gl-form-input', rows: 4
.form-text.text-muted= _('Markdown enabled')
.form-group
.form-check
= f.check_box :help_page_hide_commercial_content, class: 'form-check-input'
= f.label :help_page_hide_commercial_content, class: 'form-check-label' do
- = _('Hide marketing-related entries from help')
+ = _('Hide marketing-related entries from the Help page.')
.form-group
= f.label :help_page_support_url, _('Support page URL'), class: 'label-bold'
= f.text_field :help_page_support_url, class: 'form-control gl-form-input', placeholder: 'http://company.example.com/getting-help', :'aria-describedby' => 'support_help_block'
- %span.form-text.text-muted#support_help_block= _('Alternate support URL for help page and help dropdown')
+ %span.form-text.text-muted#support_help_block= _('Alternate support URL for Help page and Help dropdown')
- if show_documentation_base_url_field?
.form-group
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 f881808e51f..34c40892467 100644
--- a/app/views/admin/application_settings/_initial_branch_name.html.haml
+++ b/app/views/admin/application_settings/_initial_branch_name.html.haml
@@ -8,6 +8,6 @@
= f.label :default_branch_name, _('Default initial branch name'), class: 'label-light'
= 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
+ = (s_("AdminSettings|If not specified at the group or instance level, the default is %{default_initial_branch_name}. Does not affect existing repositories.") % { default_initial_branch_name: fallback_branch_name } ).html_safe
= f.submit _('Save changes'), class: 'gl-button btn-confirm'
diff --git a/app/views/admin/application_settings/_localization.html.haml b/app/views/admin/application_settings/_localization.html.haml
index fdb91937ec3..5c8f3379fce 100644
--- a/app/views/admin/application_settings/_localization.html.haml
+++ b/app/views/admin/application_settings/_localization.html.haml
@@ -7,6 +7,7 @@
= f.select :first_day_of_week, first_day_of_week_choices, {}, class: 'form-control'
.form-text.text-muted
= _('Default first day of the week in calendars and date pickers.')
+ = link_to _('Learn more.'), help_page_path('user/admin_area/settings/index.md', anchor: 'default-first-day-of-the-week'), target: '_blank'
.form-group
= f.label :time_tracking, _('Time tracking'), class: 'label-bold'
@@ -14,5 +15,9 @@
= f.check_box :time_tracking_limit_to_hours, class: 'form-check-input'
= f.label :time_tracking_limit_to_hours, class: 'form-check-label' do
= _('Limit display of time tracking units to hours.')
+ .form-text.text-muted
+ = _('Display time tracking in issues in total hours only.')
+ = link_to _('What is time tracking?'), help_page_path('user/project/time_tracking.md'), target: '_blank'
= f.submit _('Save changes'), class: "gl-button btn btn-confirm"
+
diff --git a/app/views/admin/application_settings/_mailgun.html.haml b/app/views/admin/application_settings/_mailgun.html.haml
new file mode 100644
index 00000000000..6204f7df5dc
--- /dev/null
+++ b/app/views/admin/application_settings/_mailgun.html.haml
@@ -0,0 +1,25 @@
+- return unless Feature.enabled?(:mailgun_events_receiver)
+
+- expanded = integration_expanded?('mailgun_')
+%section.settings.as-mailgun.no-animate#js-mailgun-settings{ class: ('expanded' if expanded) }
+ .settings-header
+ %h4
+ = _('Mailgun')
+ %button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' }
+ = expanded ? _('Collapse') : _('Expand')
+ %p
+ = _('Configure the %{link} integration.').html_safe % { link: link_to(_('Mailgun events'), 'https://documentation.mailgun.com/en/latest/user_manual.html#webhooks', target: '_blank') }
+ .settings-content
+ = form_for @application_setting, url: general_admin_application_settings_path(anchor: 'js-mailgun-settings'), html: { class: 'fieldset-form', id: 'mailgun-settings' } do |f|
+ = form_errors(@application_setting) if expanded
+
+ %fieldset
+ .form-group
+ .form-check
+ = f.check_box :mailgun_events_enabled, class: 'form-check-input'
+ = f.label :mailgun_events_enabled, _('Enable Mailgun event receiver'), class: 'form-check-label'
+ .form-group
+ = f.label :mailgun_signing_key, _('Mailgun HTTP webhook signing key'), class: 'label-light'
+ = f.text_field :mailgun_signing_key, class: 'form-control gl-form-input'
+
+ = 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 31576d54a04..6df1be9f6cb 100644
--- a/app/views/admin/application_settings/_repository_check.html.haml
+++ b/app/views/admin/application_settings/_repository_check.html.haml
@@ -8,15 +8,14 @@
.form-check
= f.check_box :repository_checks_enabled, class: 'form-check-input'
= f.label :repository_checks_enabled, class: 'form-check-label' do
- = _("Enable Repository Checks")
+ = _("Enable repository checks")
.form-text.text-muted
- - link_to_git_fsck = link_to('git fsck', 'https://git-scm.com/docs/git-fsck', target: '_blank')
- = _("GitLab will periodically run %{link_to_git_fsck} in all project and wiki repositories to look for silent disk corruption issues.").html_safe % { link_to_git_fsck: link_to_git_fsck }
+ = html_escape(s_('Run %{code_start}git fsck%{code_end} periodically in all project and wiki repositories to look for silent disk corruption issues.')) % { code_start: '<code>'.html_safe, code_end: '</code>'.html_safe }
.form-group
.form-text.text-muted
- = _("If you got a lot of false alarms from repository checks you can choose to clear all repository check information from the database.")
+ = _("If you get a lot of false alarms from repository checks, you can 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?')
+ - clear_repository_checks_message = _('This clears repository check states for all projects in the database and 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 gl-mt-3"
.sub-section
@@ -25,29 +24,31 @@
.form-check
= f.check_box :housekeeping_enabled, class: 'form-check-input'
= f.label :housekeeping_enabled, class: 'form-check-label' do
- = _("Enable automatic repository housekeeping (git repack, git gc)")
+ = _("Enable automatic repository housekeeping")
.form-text.text-muted
- = _("If you keep automatic housekeeping disabled for a long time Git repository access on your GitLab server will become slower and your repositories will use more disk space. We recommend to always leave this enabled.")
+ = _("Leaving this setting enabled is recommended.")
+ = link_to s_('Learn more.'), help_page_path('administration/housekeeping.md', anchor: 'housekeeping-options'), target: '_blank', rel: 'noopener noreferrer'
.form-check
= f.check_box :housekeeping_bitmaps_enabled, class: 'form-check-input'
= f.label :housekeeping_bitmaps_enabled, class: 'form-check-label' do
= _("Enable Git pack file bitmap creation")
.form-text.text-muted
- = _("Creating pack file bitmaps makes housekeeping take a little longer but bitmaps should accelerate 'git clone' performance.")
+ = _("Improves Git cloning performance.")
+ = link_to s_('Learn more.'), help_page_path('administration/housekeeping.md', anchor: 'housekeeping-options'), target: '_blank', rel: 'noopener noreferrer'
.form-group
= f.label :housekeeping_incremental_repack_period, 'Incremental repack period', class: 'label-bold'
= f.number_field :housekeeping_incremental_repack_period, class: 'form-control gl-form-input'
.form-text.text-muted
- = _("Number of Git pushes after which an incremental 'git repack' is run.")
+ = html_escape(s_('Number of Git pushes after which an incremental %{code_start}git repack%{code_end} is run.')) % { code_start: '<code>'.html_safe, code_end: '</code>'.html_safe }
.form-group
= f.label :housekeeping_full_repack_period, 'Full repack period', class: 'label-bold'
= f.number_field :housekeeping_full_repack_period, class: 'form-control gl-form-input'
.form-text.text-muted
- = _("Number of Git pushes after which a full 'git repack' is run.")
+ = html_escape(s_('Number of Git pushes after which a full %{code_start}git repack%{code_end} is run.')) % { code_start: '<code>'.html_safe, code_end: '</code>'.html_safe }
.form-group
= f.label :housekeeping_gc_period, _('Git GC period'), class: 'label-bold'
= f.number_field :housekeeping_gc_period, class: 'form-control gl-form-input'
.form-text.text-muted
- = _("Number of Git pushes after which 'git gc' is run.")
+ = html_escape(s_('Number of Git pushes after which %{code_start}git gc%{code_end} is run.')) % { code_start: '<code>'.html_safe, code_end: '</code>'.html_safe }
= f.submit _('Save changes'), class: "gl-button btn btn-confirm"
diff --git a/app/views/admin/application_settings/_repository_mirrors_form.html.haml b/app/views/admin/application_settings/_repository_mirrors_form.html.haml
index a0076a2f75d..0c9b04c02d1 100644
--- a/app/views/admin/application_settings/_repository_mirrors_form.html.haml
+++ b/app/views/admin/application_settings/_repository_mirrors_form.html.haml
@@ -3,14 +3,13 @@
%fieldset
.form-group
- = f.label :mirror_available, _('Enable mirror configuration'), class: 'label-bold'
+ = f.label :mirror_available, _('Repository mirroring configuration'), class: 'label-bold'
.form-check
= f.check_box :mirror_available, class: 'form-check-input'
= f.label :mirror_available, class: 'form-check-label' do
- = _('Allow repository mirroring to be configured by project maintainers')
+ = _('Allow project maintainers to configure repository mirroring')
%span.form-text.text-muted
- = _('If disabled, only admins will be able to configure repository mirroring.')
- = link_to sprite_icon('question-o'), help_page_path('user/project/repository/repository_mirroring.md')
+ = _('If disabled, only administrators can configure repository mirroring.')
= render_if_exists 'admin/application_settings/mirror_settings', form: f
diff --git a/app/views/admin/application_settings/_repository_storage.html.haml b/app/views/admin/application_settings/_repository_storage.html.haml
index ab1b2bab573..62a90e173ec 100644
--- a/app/views/admin/application_settings/_repository_storage.html.haml
+++ b/app/views/admin/application_settings/_repository_storage.html.haml
@@ -3,20 +3,24 @@
%fieldset
.sub-section
- %h4= _("Hashed repository storage paths")
+ %h4= _('Hashed repository storage paths')
.form-group
.form-check
= f.check_box :hashed_storage_enabled, class: 'form-check-input qa-hashed-storage-checkbox', disabled: @application_setting.hashed_storage_enabled?
- = f.label :hashed_storage_enabled, _("Use hashed storage"), class: 'label-bold form-check-label'
+ = f.label :hashed_storage_enabled, _('Use hashed storage'), class: 'label-bold form-check-label'
.form-text.text-muted
- = _("Use hashed storage paths for newly created and renamed repositories. Enable immutable, hash-based paths and repository names to store repositories on disk. This prevents repositories from having to be moved or renamed when the Repository URL changes and may improve disk I/O performance. (Always enabled since 13.0)")
+ = _('Use hashed storage paths for newly created and renamed repositories. Always enabled since 13.0.')
+ = link_to s_('Learn more.'), help_page_path('administration/repository_storage_types.md', anchor: 'hashed-storage'), target: '_blank', rel: 'noopener noreferrer'
+
.sub-section
%h4= _("Storage nodes for new repositories")
.form-group
.form-text
%p.text-secondary
- = _('Enter weights for storages for new repositories.')
- = link_to sprite_icon('question-o'), help_page_path('administration/repository_storage_paths')
+ - weights_link_url = help_page_path('administration/repository_storage_paths.md', anchor: 'configure-where-new-repositories-are-stored')
+ - weights_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: weights_link_url }
+ = html_escape(s_('Enter %{weights_link_start}weights%{weights_link_end} for storages for new repositories. Configured storages appear below.')) % { weights_link_start: weights_link_start, weights_link_end: '</a>'.html_safe }
+ = link_to s_('Learn more.'), help_page_path('administration/repository_storage_paths.md'), target: '_blank', rel: 'noopener noreferrer'
.form-check
= f.fields_for :repository_storages_weighted, storage_weights do |storage_form|
- Gitlab.config.repositories.storages.keys.each do |storage|
diff --git a/app/views/admin/application_settings/_runner_registrars_form.html.haml b/app/views/admin/application_settings/_runner_registrars_form.html.haml
new file mode 100644
index 00000000000..b7ab896533b
--- /dev/null
+++ b/app/views/admin/application_settings/_runner_registrars_form.html.haml
@@ -0,0 +1,16 @@
+= form_for @application_setting, url: ci_cd_admin_application_settings_path(anchor: 'js-runner-settings'), html: { class: 'fieldset-form' } do |f|
+ = form_errors(@application_setting)
+
+ %fieldset
+ .form-group
+ = hidden_field_tag "application_setting[valid_runner_registrars][]", nil
+ - ApplicationSetting::VALID_RUNNER_REGISTRAR_TYPES.each do |type|
+ .form-check
+ = f.check_box(:valid_runner_registrars, { multiple: true, checked: valid_runner_registrars.include?(type), class: 'form-check-input' }, type, nil)
+ = f.label :valid_runner_registrars, class: 'form-check-label' do
+ = s_("Runners|Members of the %{type} can register runners") % { type: type }
+ %span.form-text.gl-text-gray-600
+ = _('If no options are selected, only administrators can register runners.')
+ = link_to _('Learn more.'), help_page_path('user/admin_area/settings/continuous_integration', anchor: 'runner-registration'), target: '_blank', rel: 'noopener noreferrer'
+
+ = f.submit _('Save changes'), class: "gl-button btn btn-confirm"
diff --git a/app/views/admin/application_settings/_snowplow.html.haml b/app/views/admin/application_settings/_snowplow.html.haml
index 5daf220d81c..8c98778147e 100644
--- a/app/views/admin/application_settings/_snowplow.html.haml
+++ b/app/views/admin/application_settings/_snowplow.html.haml
@@ -6,7 +6,8 @@
%button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' }
= expanded ? _('Collapse') : _('Expand')
%p
- = _('Configure the %{link} integration.').html_safe % { link: link_to('Snowplow', 'https://snowplowanalytics.com/', target: '_blank') }
+ - link_start = '<a href="%{url}">'.html_safe % { url: help_page_path('development/snowplow/index') }
+ = html_escape(_('Configure %{link} to track events. %{link_start}Learn more.%{link_end}')) % { link: link_to('Snowplow', 'https://snowplowanalytics.com/', target: '_blank').html_safe, link_start: link_start, link_end: '</a>'.html_safe }
.settings-content
= form_for @application_setting, url: general_admin_application_settings_path(anchor: 'js-snowplow-settings'), html: { class: 'fieldset-form', id: 'snowplow-settings' } do |f|
= form_errors(@application_setting) if expanded
@@ -15,15 +16,21 @@
.form-group
.form-check
= f.check_box :snowplow_enabled, class: 'form-check-input'
- = f.label :snowplow_enabled, _('Enable snowplow tracking'), class: 'form-check-label'
+ = f.label :snowplow_enabled, _('Enable Snowplow tracking'), class: 'form-check-label'
.form-group
= f.label :snowplow_collector_hostname, _('Collector hostname'), class: 'label-light'
= f.text_field :snowplow_collector_hostname, class: 'form-control gl-form-input', placeholder: 'snowplow.example.com'
+ .form-text.text-muted
+ = _('The hostname of your Snowplow collector.')
.form-group
= f.label :snowplow_app_id, _('App ID'), class: 'label-light'
- = f.text_field :snowplow_app_id, class: 'form-control gl-form-input'
+ = f.text_field :snowplow_app_id, class: 'form-control gl-form-input', placeholder: 'gitlab'
+ .form-text.text-muted
+ = _('The ID of the application.')
.form-group
= f.label :snowplow_cookie_domain, _('Cookie domain'), class: 'label-light'
- = f.text_field :snowplow_cookie_domain, class: 'form-control gl-form-input'
+ = f.text_field :snowplow_cookie_domain, class: 'form-control gl-form-input', placeholder: '.your-gitlab-instance.com'
+ .form-text.text-muted
+ = _('The Snowplow cookie domain.')
= f.submit _('Save changes'), class: 'gl-button btn btn-confirm'
diff --git a/app/views/admin/application_settings/_third_party_offers.html.haml b/app/views/admin/application_settings/_third_party_offers.html.haml
index 5df2454ed2e..9a34400092e 100644
--- a/app/views/admin/application_settings/_third_party_offers.html.haml
+++ b/app/views/admin/application_settings/_third_party_offers.html.haml
@@ -2,11 +2,11 @@
%section.settings.as-third-party-offers.no-animate#js-third-party-offers-settings{ class: ('expanded' if expanded) }
.settings-header
%h4
- = _('Third party offers')
+ = _('Third-party offers')
%button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' }
= expanded ? _('Collapse') : _('Expand')
%p
- = _('Control the display of third party offers.')
+ = _('Control whether to display third-party offers in GitLab.')
.settings-content
= form_for @application_setting, url: general_admin_application_settings_path(anchor: 'js-third-party-offers-settings'), html: { class: 'fieldset-form', id: 'third-party-offers-settings' } do |f|
= form_errors(@application_setting) if expanded
@@ -15,6 +15,6 @@
.form-group
.form-check
= f.check_box :hide_third_party_offers, class: 'form-check-input'
- = f.label :hide_third_party_offers, _('Do not display offers from third parties within GitLab'), class: 'form-check-label'
+ = f.label :hide_third_party_offers, _('Do not display offers from third parties'), class: 'form-check-label'
= 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 64e8751bf31..ddd0abb4c34 100644
--- a/app/views/admin/application_settings/_usage.html.haml
+++ b/app/views/admin/application_settings/_usage.html.haml
@@ -1,4 +1,4 @@
-- payload_class = 'js-usage-ping-payload'
+- payload_class = 'js-service-ping-payload'
= form_for @application_setting, url: metrics_and_profiling_admin_application_settings_path(anchor: 'js-usage-settings'), html: { class: 'fieldset-form' } do |f|
= form_errors(@application_setting)
@@ -17,23 +17,44 @@
.form-check
= f.check_box :usage_ping_enabled, disabled: !can_be_configured, class: 'form-check-input'
= f.label :usage_ping_enabled, class: 'form-check-label' do
- = _('Enable usage ping')
+ = _('Enable service ping')
.form-text.text-muted
- if can_be_configured
%p.mb-2= _('To help improve GitLab and its user experience, GitLab will periodically collect usage information.')
- - usage_ping_path = help_page_path('user/admin_area/settings/usage_statistics', anchor: 'usage-ping')
- - usage_ping_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: usage_ping_path }
- %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 }
+ - service_ping_path = help_page_path('user/admin_area/settings/usage_statistics', anchor: 'service-ping')
+ - service_ping_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: service_ping_path }
+ %p.mb-2= s_('%{service_ping_link_start}Learn more%{service_ping_link_end} about what information is shared with GitLab Inc.').html_safe % { service_ping_link_start: service_ping_link_start, service_ping_link_end: '</a>'.html_safe }
%button.gl-button.btn.btn-default.js-payload-preview-trigger{ type: 'button', data: { payload_selector: ".#{payload_class}" } }
.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) } }
+ %pre.service-data-payload-container.js-syntax-highlight.code.highlight.mt-2.d-none{ class: payload_class, data: { endpoint: usage_data_admin_application_settings_path(format: :html) } }
- else
- = _('The usage ping is disabled, and cannot be configured through this form.')
- - deactivating_usage_ping_path = help_page_path('development/usage_ping/index.md', anchor: 'disable-usage-ping')
- - 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 }
+ = _('Service ping is disabled in your configuration file, and cannot be enabled through this form.')
+ - deactivating_service_ping_path = help_page_path('development/service_ping/index.md', anchor: 'disable-service-ping-using-the-configuration-file')
+ - deactivating_service_ping_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: deactivating_service_ping_path }
+ = s_('For more information, see the documentation on %{deactivating_service_ping_link_start}deactivating service ping%{deactivating_service_ping_link_end}.').html_safe % { deactivating_service_ping_link_start: deactivating_service_ping_link_start, deactivating_service_ping_link_end: '</a>'.html_safe }
+ .form-group
+ - usage_ping_enabled = @application_setting.usage_ping_enabled?
+ .form-check
+ = f.check_box :usage_ping_features_enabled?, disabled: !usage_ping_enabled, class: 'form-check-input'
+ = f.label :usage_ping_features_enabled?, class: 'form-check-label gl-cursor-not-allowed', id: 'service_ping_features_label' do
+ = _('Enable Registration Features')
+ = link_to sprite_icon('question-o'), help_page_path('development/service_ping/index.md', anchor: 'registration-features-program')
+ .form-text.text-muted
+ - if usage_ping_enabled
+ %p.gl-mb-3.text-muted{ id: 'service_ping_features_helper_text' }= _('You can enable Registration Features because Service Ping is enabled. To continue using Registration Features in the future, you will also need to register with GitLab via a new cloud licensing service.')
+ - else
+ %p.gl-mb-3.text-muted{ id: 'service_ping_features_helper_text' }= _('To enable Registration Features, make sure "Enable service ping" is checked.')
+
+ %p.gl-mb-3.text-muted= _('Registration Features include:')
+ .form-text
+ - email_from_gitlab_path = help_page_path('tools/email.md')
+ - link_end = '</a>'.html_safe
+ - email_from_gitlab_link = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: email_from_gitlab_path }
+ %ul
+ %li
+ = _('Email from GitLab - email users right from the Admin Area. %{link_start}Learn more%{link_end}.').html_safe % { link_start: email_from_gitlab_link, link_end: link_end }
= f.submit _('Save changes'), class: "gl-button btn btn-confirm"
diff --git a/app/views/admin/application_settings/ci/_header.html.haml b/app/views/admin/application_settings/ci/_header.html.haml
index 40486e9a9e6..1298be9a6cb 100644
--- a/app/views/admin/application_settings/ci/_header.html.haml
+++ b/app/views/admin/application_settings/ci/_header.html.haml
@@ -8,7 +8,7 @@
%p
= _('Variables store information, like passwords and secret keys, that you can use in job scripts. All projects on the instance can use these variables.')
- = link_to s_('Learn more.'), help_page_path('ci/variables/README', anchor: 'add-a-cicd-variable-to-an-instance'), target: '_blank', rel: 'noopener noreferrer'
+ = link_to s_('Learn more.'), help_page_path('ci/variables/index', anchor: 'add-a-cicd-variable-to-an-instance'), target: '_blank', rel: 'noopener noreferrer'
%p
= _('Variables can be:')
%ul
@@ -16,4 +16,4 @@
= html_escape(_('%{code_open}Protected:%{code_close} Only exposed to protected branches or tags.')) % { code_open: '<code>'.html_safe, code_close: '</code>'.html_safe }
%li
= html_escape(_('%{code_open}Masked:%{code_close} Hidden in job logs. Must match masking requirements.')) % { code_open: '<code>'.html_safe, code_close: '</code>'.html_safe }
- = link_to _('Learn more.'), help_page_path('ci/variables/README', anchor: 'mask-a-cicd-variable'), target: '_blank', rel: 'noopener noreferrer'
+ = link_to _('Learn more.'), help_page_path('ci/variables/index', anchor: 'mask-a-cicd-variable'), target: '_blank', rel: 'noopener noreferrer'
diff --git a/app/views/admin/application_settings/ci_cd.html.haml b/app/views/admin/application_settings/ci_cd.html.haml
index 127ab8ea1f4..18ec43407c3 100644
--- a/app/views/admin/application_settings/ci_cd.html.haml
+++ b/app/views/admin/application_settings/ci_cd.html.haml
@@ -8,7 +8,7 @@
.settings-content
- if ci_variable_protected_by_default?
%p.settings-message.text-center
- - link_start = '<a href="%{url}">'.html_safe % { url: help_page_path('ci/variables/README', anchor: 'protect-a-cicd-variable') }
+ - link_start = '<a href="%{url}">'.html_safe % { url: help_page_path('ci/variables/index', anchor: 'protect-a-cicd-variable') }
= s_('Environment variables on this GitLab instance are configured to be %{link_start}protected%{link_end} by default.').html_safe % { link_start: link_start, link_end: '</a>'.html_safe }
#js-instance-variables{ data: { endpoint: admin_ci_variables_path, group: 'true', maskable_regex: ci_variable_maskable_regex, protected_by_default: ci_variable_protected_by_default?.to_s} }
@@ -38,3 +38,13 @@
= _('Various container registry settings.')
.settings-content
= render 'registry'
+
+- if Feature.enabled?(:runner_registration_control)
+ %section.settings.as-runner.no-animate#js-runner-settings{ class: ('expanded' if expanded_by_default?) }
+ .settings-header
+ %h4
+ = s_('Runners|Runner registration')
+ %button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' }
+ = expanded_by_default? ? 'Collapse' : 'Expand'
+ .settings-content
+ = render 'runner_registrars_form'
diff --git a/app/views/admin/application_settings/general.html.haml b/app/views/admin/application_settings/general.html.haml
index 0fbbef02613..53bdbcd7137 100644
--- a/app/views/admin/application_settings/general.html.haml
+++ b/app/views/admin/application_settings/general.html.haml
@@ -107,6 +107,7 @@
= render_if_exists 'admin/application_settings/maintenance_mode_settings_form'
= render 'admin/application_settings/gitpod'
= render 'admin/application_settings/kroki'
+= render 'admin/application_settings/mailgun'
= render 'admin/application_settings/plantuml'
= render 'admin/application_settings/sourcegraph'
= render_if_exists 'admin/application_settings/slack'
diff --git a/app/views/admin/application_settings/integrations.html.haml b/app/views/admin/application_settings/integrations.html.haml
index 7a81d53c085..d818c587b79 100644
--- a/app/views/admin/application_settings/integrations.html.haml
+++ b/app/views/admin/application_settings/integrations.html.haml
@@ -1,9 +1,9 @@
-- breadcrumb_title _('Integrations')
-- page_title _('Integrations')
+- breadcrumb_title s_('Integrations|Instance-level integration management')
+- page_title s_('Integrations|Instance-level integration management')
- @content_class = 'limit-container-width' unless fluid_layout
-%h3= s_('Integrations|Project integration management')
+%h3= s_('Integrations|Instance-level integration management')
- integrations_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: integrations_help_page_path }
-%p= s_("Integrations|GitLab administrators can set up integrations that all projects inherit and use by default. These integrations apply to all projects that don't already use custom settings. You can override custom settings for a group or project if the settings are necessary at that level. Learn more about %{integrations_link_start}project integration management%{link_end}.").html_safe % { integrations_link_start: integrations_link_start, link_end: "</a>".html_safe }
+%p= s_("Integrations|GitLab administrators can set up integrations that all groups and projects inherit and use by default. These integrations apply to all groups and projects that don't already use custom settings. You can override custom settings for a group or project if the settings are necessary at that level. Learn more about %{integrations_link_start}instance-level integration management%{link_end}.").html_safe % { integrations_link_start: integrations_link_start, link_end: "</a>".html_safe }
= render 'shared/integrations/index', integrations: @integrations
diff --git a/app/views/admin/application_settings/metrics_and_profiling.html.haml b/app/views/admin/application_settings/metrics_and_profiling.html.haml
index 113ff20e910..14483e4e55e 100644
--- a/app/views/admin/application_settings/metrics_and_profiling.html.haml
+++ b/app/views/admin/application_settings/metrics_and_profiling.html.haml
@@ -47,10 +47,8 @@
%button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' }
= expanded_by_default? ? _('Collapse') : _('Expand')
%p
- = _('Enable or disable version check and usage ping.')
+ = _('Enable or disable version check and service ping.')
.settings-content
= render 'usage'
-= render_if_exists 'admin/application_settings/seat_link_setting', expanded: expanded_by_default?
-
= render_if_exists 'admin/application_settings/pseudonymizer_settings', expanded: expanded_by_default?
diff --git a/app/views/admin/application_settings/preferences.html.haml b/app/views/admin/application_settings/preferences.html.haml
index 17bf9ba84a2..0dfc3d7a60d 100644
--- a/app/views/admin/application_settings/preferences.html.haml
+++ b/app/views/admin/application_settings/preferences.html.haml
@@ -20,18 +20,19 @@
%button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' }
= expanded_by_default? ? _('Collapse') : _('Expand')
%p
- = _("Configure What's new drawer and content.")
+ = _("Configure %{italic_start}What's new%{italic_end} drawer and content.").html_safe % { italic_start: '<i>'.html_safe, italic_end: '</i>'.html_safe }
.settings-content
= render 'whats_new'
%section.settings.as-help-page.no-animate#js-help-settings{ class: ('expanded' if expanded_by_default?) }
.settings-header
%h4
- = _('Help page')
+ = _('Sign-in and Help page')
%button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' }
= expanded_by_default? ? _('Collapse') : _('Expand')
%p
- = _('Help page text and support page url.')
+ = _('Additional text for the sign-in and Help page.')
+ = link_to s_('Learn more.'), help_page_path('user/admin_area/settings/help_page.md'), target: '_blank', rel: 'noopener noreferrer'
.settings-content
= render 'help_page'
@@ -60,11 +61,13 @@
%section.settings.as-gitaly.no-animate#js-gitaly-settings{ class: ('expanded' if expanded_by_default?) }
.settings-header
%h4
- = _('Gitaly')
+ = _('Gitaly timeouts')
%button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' }
= expanded_by_default? ? _('Collapse') : _('Expand')
%p
= _('Configure Gitaly timeouts.')
+ %span
+ = link_to _('Learn more.'), help_page_path('user/admin_area/settings/gitaly_timeouts.md'), target: '_blank', rel: 'noopener noreferrer'
.settings-content
= render 'gitaly'
@@ -75,6 +78,6 @@
%button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' }
= expanded_by_default? ? _('Collapse') : _('Expand')
%p
- = _('Various localization settings.')
+ = _('Configure the default first day of the week and time tracking units.')
.settings-content
= render 'localization'
diff --git a/app/views/admin/application_settings/repository.html.haml b/app/views/admin/application_settings/repository.html.haml
index 111cc9c5d7c..2a9fba1aef6 100644
--- a/app/views/admin/application_settings/repository.html.haml
+++ b/app/views/admin/application_settings/repository.html.haml
@@ -9,7 +9,7 @@
%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.')
+ = s_('AdminSettings|The default name for the initial branch of new repositories created in the instance.')
.settings-content
= render 'initial_branch_name'
@@ -21,6 +21,7 @@
= expanded_by_default? ? 'Collapse' : 'Expand'
%p
= _('Configure repository mirroring.')
+ = link_to s_('Learn more.'), help_page_path('user/project/repository/repository_mirroring.md'), target: '_blank', rel: 'noopener noreferrer'
.settings-content
= render partial: 'repository_mirrors_form'
@@ -31,7 +32,8 @@
%button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' }
= expanded_by_default? ? _('Collapse') : _('Expand')
%p
- = _('Configure storage path settings.')
+ = _('Configure repository storage.')
+ = link_to s_('Learn more.'), help_page_path('administration/repository_storage_paths.md'), target: '_blank', rel: 'noopener noreferrer'
.settings-content
= render 'repository_storage'
@@ -42,7 +44,11 @@
%button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' }
= expanded_by_default? ? _('Collapse') : _('Expand')
%p
- = _('Configure automatic git checks and housekeeping on repositories.')
+ - repository_checks_link_url = help_page_path('administration/repository_checks.md')
+ - repository_checks_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: repository_checks_link_url }
+ - housekeeping_link_url = help_page_path('administration/housekeeping.md')
+ - housekeeping_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: housekeeping_link_url }
+ = html_escape(s_('Configure %{repository_checks_link_start}repository checks%{link_end} and %{housekeeping_link_start}housekeeping%{link_end} on repositories.')) % { repository_checks_link_start: repository_checks_link_start, housekeeping_link_start: housekeeping_link_start, link_end: '</a>'.html_safe }
.settings-content
= render 'repository_check'
diff --git a/app/views/admin/background_migrations/_migration.html.haml b/app/views/admin/background_migrations/_migration.html.haml
index 40860ea9400..ddb2eb27705 100644
--- a/app/views/admin/background_migrations/_migration.html.haml
+++ b/app/views/admin/background_migrations/_migration.html.haml
@@ -8,3 +8,12 @@
= _('Unknown')
%td{ role: 'cell', data: { label: _('Status') } }
%span.badge.badge-pill.gl-badge.sm{ class: batched_migration_status_badge_class_name(migration) }= migration.status.humanize
+ %td{ role: 'cell', data: { label: _('Action') } }
+ - if migration.active?
+ = button_to pause_admin_background_migration_path(migration),
+ class: 'gl-button btn btn-icon has-tooltip', title: _('Pause'), 'aria-label' => _('Pause') do
+ = sprite_icon('pause', css_class: 'gl-button-icon gl-icon')
+ - elsif migration.paused?
+ = button_to resume_admin_background_migration_path(migration),
+ class: 'gl-button btn btn-icon has-tooltip', title: _('Resume'), 'aria-label' => _('Resume') do
+ = sprite_icon('play', css_class: 'gl-button-icon gl-icon')
diff --git a/app/views/admin/background_migrations/index.html.haml b/app/views/admin/background_migrations/index.html.haml
index 2a372c89912..9ccbdfb5f20 100644
--- a/app/views/admin/background_migrations/index.html.haml
+++ b/app/views/admin/background_migrations/index.html.haml
@@ -29,6 +29,7 @@
%th.table-th-transparent.border-bottom{ role: 'cell' }= _('Migration')
%th.table-th-transparent.border-bottom{ role: 'cell' }= _('Progress')
%th.table-th-transparent.border-bottom{ role: 'cell' }= _('Status')
+ %th.table-th-transparent.border-bottom{ role: 'cell' }
%tbody{ role: 'rowgroup' }
= render partial: 'migration', collection: @migrations
diff --git a/app/views/admin/dashboard/index.html.haml b/app/views/admin/dashboard/index.html.haml
index 58c65bdc8c7..ec3daf6c494 100644
--- a/app/views/admin/dashboard/index.html.haml
+++ b/app/views/admin/dashboard/index.html.haml
@@ -3,15 +3,14 @@
- billable_users_url = help_page_path('subscriptions/self_managed/index', anchor: 'billable-users')
- billable_users_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer nofollow">'.html_safe % { url: billable_users_url }
+= render_if_exists 'shared/qrtly_reconciliation_alert'
+
- if @notices
- @notices.each do |notice|
.js-vue-alert{ 'v-cloak': true, data: { variant: notice[:type],
dismissible: true.to_s } }
= notice[:message].html_safe
-- if Gitlab.ee? && display_upcoming_reconciliation_alert?
- #js-qrtly-reconciliation-alert{ data: upcoming_reconciliation_hash }
-
- if @license.present?
.license-panel.gl-mt-5
= render_if_exists 'admin/licenses/summary'
diff --git a/app/views/admin/dev_ops_report/_callout.html.haml b/app/views/admin/dev_ops_report/_callout.html.haml
index f313865478d..2b4c258a00c 100644
--- a/app/views/admin/dev_ops_report/_callout.html.haml
+++ b/app/views/admin/dev_ops_report/_callout.html.haml
@@ -8,6 +8,6 @@
%h4
= _('Introducing Your DevOps Report')
%p
- = _('Your DevOps Report gives an overview of how you are using GitLab from a feature perspective. View how you compare with other organizations, discover features you are not using, and learn best practices through blog posts and white papers.')
+ = _('Your DevOps Report gives an overview of how you are using GitLab from a feature perspective. Use it to view how you compare with other organizations.')
.svg-container.devops
= custom_icon('dev_ops_report_overview')
diff --git a/app/views/admin/dev_ops_report/_report.html.haml b/app/views/admin/dev_ops_report/_report.html.haml
index dbd0020e382..0b26548d6e6 100644
--- a/app/views/admin/dev_ops_report/_report.html.haml
+++ b/app/views/admin/dev_ops_report/_report.html.haml
@@ -1,10 +1,9 @@
-- usage_ping_enabled = Gitlab::CurrentSettings.usage_ping_enabled
+- service_ping_enabled = Gitlab::CurrentSettings.usage_ping_enabled
-- if usage_ping_enabled && show_callout?('dev_ops_report_intro_callout_dismissed')
+- if service_ping_enabled && show_callout?('dev_ops_report_intro_callout_dismissed')
= render 'callout'
-- if !usage_ping_enabled
- #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') } }
+- if !service_ping_enabled
+ #js-devops-service-ping-disabled{ data: { is_admin: current_user&.admin.to_s, empty_state_svg_path: image_path('illustrations/convdev/convdev_no_index.svg'), enable_service_ping_path: metrics_and_profiling_admin_application_settings_path(anchor: 'js-usage-settings'), docs_link: help_page_path('development/service_ping/index.md') } }
- else
#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') } }
-
diff --git a/app/views/admin/groups/show.html.haml b/app/views/admin/groups/show.html.haml
index 5f8ec5086bd..9b42e1b4967 100644
--- a/app/views/admin/groups/show.html.haml
+++ b/app/views/admin/groups/show.html.haml
@@ -128,16 +128,12 @@
.card-header
= html_escape(_("%{group_name} group members")) % { group_name: "<strong>#{html_escape(@group.name)}</strong>".html_safe }
%span.badge.badge-pill= @group.users_count
- .float-right
- = link_to group_group_members_path(@group), class: 'btn btn-default gl-button btn-sm' do
- = sprite_icon('pencil-square', css_class: 'gl-icon')
- = _('Manage access')
+ = render 'shared/members/manage_access_button', path: group_group_members_path(@group)
%ul.content-list.group-users-list.content-list.members-list
= render partial: 'shared/members/member',
collection: @members, as: :member,
locals: { membership_source: @group,
group: @group,
- show_controls: false,
current_user_is_group_owner: current_user_is_group_owner }
- unless @members.size < Kaminari.config.default_per_page
.card-footer
diff --git a/app/views/admin/identities/index.html.haml b/app/views/admin/identities/index.html.haml
index a6d562dad31..d85ab476693 100644
--- a/app/views/admin/identities/index.html.haml
+++ b/app/views/admin/identities/index.html.haml
@@ -15,3 +15,5 @@
= render @identities
- else
%h4= _('This user has no identities')
+
+= render partial: 'admin/users/modals'
diff --git a/app/views/admin/impersonation_tokens/index.html.haml b/app/views/admin/impersonation_tokens/index.html.haml
index ec393fdd794..1609687fc8d 100644
--- a/app/views/admin/impersonation_tokens/index.html.haml
+++ b/app/views/admin/impersonation_tokens/index.html.haml
@@ -19,7 +19,8 @@
path: admin_user_impersonation_tokens_path,
impersonation: true,
token: @impersonation_token,
- scopes: @scopes
+ scopes: @scopes,
+ help_path: help_page_path('api/index', anchor: 'impersonation-tokens')
= render 'shared/access_tokens/table',
type: type,
@@ -27,3 +28,5 @@
impersonation: true,
active_tokens: @active_impersonation_tokens,
revoke_route_helper: ->(token) { revoke_admin_user_impersonation_token_path(token.user, token) }
+
+= render partial: 'admin/users/modals'
diff --git a/app/views/admin/projects/show.html.haml b/app/views/admin/projects/show.html.haml
index 40443fb3406..5c92cbf957e 100644
--- a/app/views/admin/projects/show.html.haml
+++ b/app/views/admin/projects/show.html.haml
@@ -15,8 +15,11 @@
- if @project.last_repository_check_failed?
.row
.col-md-12
- .gl-alert.gl-alert-danger.gl-mb-5{ data: { testid: 'last-repository-check-failed-alert' } }
- = sprite_icon('error', size: 16, css_class: 'gl-icon gl-alert-icon gl-alert-icon-no-title')
+ = render 'shared/global_alert',
+ variant: :danger,
+ alert_class: 'gl-mb-5',
+ alert_data: { testid: 'last-repository-check-failed-alert' },
+ is_container: true do
.gl-alert-body
- last_check_message = _("Last repository check (%{last_check_timestamp}) failed. See the 'repocheck.log' file for error messages.")
- last_check_message = last_check_message % { last_check_timestamp: time_ago_with_tooltip(@project.last_repository_check_at) }
@@ -180,37 +183,29 @@
%strong= @group.name
= _('group members')
%span.badge.badge-pill= @group_members.size
- .float-right
- = link_to admin_group_path(@group), class: 'btn btn-default gl-button btn-sm' do
- = sprite_icon('pencil-square', css_class: 'gl-icon')
- = _('Manage access')
+ = render 'shared/members/manage_access_button', path: group_group_members_path(@group)
%ul.content-list.members-list
= render partial: 'shared/members/member',
collection: @group_members, as: :member,
locals: { membership_source: @project,
group: @group,
- show_controls: false,
current_user_is_group_owner: current_user_is_group_owner }
.card-footer
= paginate @group_members, param_name: 'group_members_page', theme: 'gitlab'
- = render 'shared/members/requests', membership_source: @project, group: @group, requesters: @requesters, force_mobile_view: true
+ = render 'shared/members/requests', membership_source: @project, group: @group, requesters: @requesters
.card
.card-header
%strong= @project.name
= _('project members')
%span.badge.badge-pill= @project.users.size
- .float-right
- = link_to project_project_members_path(@project), class: 'btn btn-default gl-button btn-sm' do
- = sprite_icon('pencil-square', css_class: 'gl-icon')
- = _('Manage access')
+ = render 'shared/members/manage_access_button', path: project_project_members_path(@project)
%ul.content-list.project_members.members-list
= render partial: 'shared/members/member',
collection: @project_members, as: :member,
locals: { membership_source: @project,
group: @group,
- show_controls: false,
current_user_is_group_owner: current_user_is_group_owner }
.card-footer
= paginate @project_members, param_name: 'project_members_page', theme: 'gitlab'
diff --git a/app/views/admin/runners/_runner.html.haml b/app/views/admin/runners/_runner.html.haml
index da2fcd5a4a6..ce143a6b155 100644
--- a/app/views/admin/runners/_runner.html.haml
+++ b/app/views/admin/runners/_runner.html.haml
@@ -6,15 +6,15 @@
.table-mobile-header{ role: 'rowheader' }= _('Type')
.table-mobile-content
- if runner.instance_type?
- %span.badge.badge-pill.gl-badge.sm.badge-success= _("shared")
+ %span.badge.badge-pill.gl-badge.sm.badge-success= s_('Runners|shared')
- elsif runner.group_type?
- %span.badge.badge-pill.gl-badge.sm.badge-success= _("group")
+ %span.badge.badge-pill.gl-badge.sm.badge-success= s_('Runners|group')
- else
- %span.badge.badge-pill.gl-badge.sm.badge-info= _("specific")
+ %span.badge.badge-pill.gl-badge.sm.badge-info= s_('Runners|specific')
- if runner.locked?
- %span.badge.badge-pill.gl-badge.sm.badge-warning= _("locked")
+ %span.badge.badge-pill.gl-badge.sm.badge-warning= s_('Runners|locked')
- unless runner.active?
- %span.badge.badge-pill.gl-badge.sm.badge-danger= _("paused")
+ %span.badge.badge-pill.gl-badge.sm.badge-danger= s_('Runners|paused')
.table-section.section-30
.table-mobile-header{ role: 'rowheader' }= s_('Runners|Runner')
diff --git a/app/views/admin/runners/index.html.haml b/app/views/admin/runners/index.html.haml
index 07fbc3e5398..f9c52d9316b 100644
--- a/app/views/admin/runners/index.html.haml
+++ b/app/views/admin/runners/index.html.haml
@@ -17,23 +17,23 @@
%span= _('Runners can be:')
%ul
%li
- %span.badge.badge-pill.gl-badge.sm.badge-success shared
+ %span.badge.badge-pill.gl-badge.sm.badge-success= s_('Runners|shared')
\-
= _('Runs jobs from all unassigned projects.')
%li
- %span.badge.badge-pill.gl-badge.sm.badge-success group
+ %span.badge.badge-pill.gl-badge.sm.badge-success= s_('Runners|group')
\-
= _('Runs jobs from all unassigned projects in its group.')
%li
- %span.badge.badge-pill.gl-badge.sm.badge-info specific
+ %span.badge.badge-pill.gl-badge.sm.badge-info= s_('Runners|specific')
\-
= _('Runs jobs from assigned projects.')
%li
- %span.badge.badge-pill.gl-badge.sm.badge-warning locked
+ %span.badge.badge-pill.gl-badge.sm.badge-warning= s_('Runners|locked')
\-
= _('Cannot be assigned to other projects.')
%li
- %span.badge.badge-pill.gl-badge.sm.badge-danger paused
+ %span.badge.badge-pill.gl-badge.sm.badge-danger= s_('Runners|paused')
\-
= _('Not available to run jobs.')
@@ -41,7 +41,7 @@
.bs-callout
= render partial: 'ci/runner/how_to_setup_runner',
locals: { registration_token: Gitlab::CurrentSettings.runners_registration_token,
- type: 'shared',
+ type: s_('Runners|shared'),
reset_token_url: reset_registration_token_admin_application_settings_path,
project_path: '',
group_path: '' }
diff --git a/app/views/admin/users/_approve_user.html.haml b/app/views/admin/users/_approve_user.html.haml
deleted file mode 100644
index f61c9fa4b80..00000000000
--- a/app/views/admin/users/_approve_user.html.haml
+++ /dev/null
@@ -1,7 +0,0 @@
-.card.border-info
- .card-header.gl-bg-blue-500.gl-text-white
- = s_('AdminUsers|This user has requested access')
- .card-body
- = render partial: 'admin/users/user_approve_effects'
- %br
- = link_to s_('AdminUsers|Approve user'), approve_admin_user_path(user), method: :put, class: "btn gl-button btn-info", data: { confirm: s_('AdminUsers|Are you sure?'), qa_selector: 'approve_user_button' }
diff --git a/app/views/admin/users/_ban_user.html.haml b/app/views/admin/users/_ban_user.html.haml
deleted file mode 100644
index 229c88adb7f..00000000000
--- a/app/views/admin/users/_ban_user.html.haml
+++ /dev/null
@@ -1,9 +0,0 @@
-- 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/_block_user.html.haml b/app/views/admin/users/_block_user.html.haml
deleted file mode 100644
index 29029986345..00000000000
--- a/app/views/admin/users/_block_user.html.haml
+++ /dev/null
@@ -1,8 +0,0 @@
-.card.border-warning
- .card-header.bg-warning.text-white
- = s_('AdminUsers|Block this user')
- .card-body
- = user_block_effects
- %br
- %button.btn.gl-button.btn-warning.js-confirm-modal-button{ data: user_block_data(user, s_('AdminUsers|You can always unblock their account, their data will remain intact.')) }
- = s_('AdminUsers|Block user')
diff --git a/app/views/admin/users/_head.html.haml b/app/views/admin/users/_head.html.haml
index be04e87f8b9..b7b712e078d 100644
--- a/app/views/admin/users/_head.html.haml
+++ b/app/views/admin/users/_head.html.haml
@@ -1,33 +1,38 @@
-%h3.page-title
- = @user.name
- - 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)')
- - if @user.internal?
- %span.cred
- = s_('AdminUsers|(Internal)')
- - if @user.admin
- %span.cred
- = s_('AdminUsers|(Admin)')
- - if @user.deactivated?
- %span.cred
- = s_('AdminUsers|(Deactivated)')
- = render_if_exists 'admin/users/auditor_user_badge'
- = render_if_exists 'admin/users/gma_user_badge'
+.gl-display-flex.gl-flex-wrap.gl-justify-content-space-between.gl-align-items-center.gl-py-3.gl-mb-5.gl-border-b-solid.gl-border-gray-100.gl-border-b-1
+ .gl-my-3
+ %h3.page-title.gl-m-0
+ = @user.name
+ - 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)')
+ - if @user.internal?
+ %span.cred
+ = s_('AdminUsers|(Internal)')
+ - if @user.admin
+ %span.cred
+ = s_('AdminUsers|(Admin)')
+ - if @user.deactivated?
+ %span.cred
+ = s_('AdminUsers|(Deactivated)')
+ = render_if_exists 'admin/users/auditor_user_badge'
+ = render_if_exists 'admin/users/gma_user_badge'
- .float-right
- - if impersonation_enabled? && @user != current_user && @user.can?(:log_in)
- = link_to _('Impersonate'), impersonate_admin_user_path(@user), method: :post, class: "btn btn-info gl-button btn-grouped", data: { qa_selector: 'impersonate_user_link' }
- = link_to edit_admin_user_path(@user), class: "btn btn-default gl-button btn-grouped" do
- = sprite_icon('pencil-square', css_class: 'gl-icon gl-button-icon')
- = _('Edit')
-%hr
+ .gl-my-3.gl-display-flex.gl-flex-wrap.gl-my-n2.gl-mx-n2
+ .gl-p-2
+ #js-admin-user-actions{ data: admin_user_actions_data_attributes(@user) }
+ - if @user != current_user
+ .gl-p-2
+ - if impersonation_enabled? && @user.can?(:log_in)
+ = link_to _('Impersonate'), impersonate_admin_user_path(@user), method: :post, class: "btn btn-default gl-button", data: { qa_selector: 'impersonate_user_link' }
+ - if can_force_email_confirmation?(@user)
+ %button.btn.gl-button.btn-info.js-confirm-modal-button{ data: confirm_user_data(@user) }
+ = _('Confirm user')
%ul.nav-links.nav.nav-tabs
= nav_link(path: 'users#show') do
= link_to _("Account"), admin_user_path(@user)
diff --git a/app/views/admin/users/_reject_pending_user.html.haml b/app/views/admin/users/_reject_pending_user.html.haml
deleted file mode 100644
index 17108427330..00000000000
--- a/app/views/admin/users/_reject_pending_user.html.haml
+++ /dev/null
@@ -1,7 +0,0 @@
-.card.border-danger
- .card-header.bg-danger.gl-text-white
- = s_('AdminUsers|This user has requested access')
- .card-body
- = render partial: 'admin/users/user_reject_effects'
- %br
- = link_to s_('AdminUsers|Reject request'), reject_admin_user_path(user), method: :delete, class: "btn gl-button btn-danger", data: { confirm: s_('AdminUsers|Are you sure?') }
diff --git a/app/views/admin/users/_user_activation_effects.html.haml b/app/views/admin/users/_user_activation_effects.html.haml
deleted file mode 100644
index 244836dac11..00000000000
--- a/app/views/admin/users/_user_activation_effects.html.haml
+++ /dev/null
@@ -1,6 +0,0 @@
-%p
- = s_('AdminUsers|Reactivating a user will:')
-%ul
- %li
- = s_('AdminUsers|Restore user access to the account, including web, Git and API.')
- = render_if_exists 'admin/users/user_activation_effects_on_seats'
diff --git a/app/views/admin/users/_user_approve_effects.html.haml b/app/views/admin/users/_user_approve_effects.html.haml
deleted file mode 100644
index 54e51bf3467..00000000000
--- a/app/views/admin/users/_user_approve_effects.html.haml
+++ /dev/null
@@ -1,11 +0,0 @@
-%p
- = s_('AdminUsers|Approved users can:')
-%ul
- %li
- = s_('AdminUsers|Log in')
- %li
- = s_('AdminUsers|Access Git repositories')
- %li
- = s_('AdminUsers|Access the API')
- %li
- = s_('AdminUsers|Be added to groups and projects')
diff --git a/app/views/admin/users/_user_detail_note.html.haml b/app/views/admin/users/_user_detail_note.html.haml
index 4f2a682c5ca..cc4827327c9 100644
--- a/app/views/admin/users/_user_detail_note.html.haml
+++ b/app/views/admin/users/_user_detail_note.html.haml
@@ -1,7 +1,7 @@
- if @user.note.present?
- text = @user.note
- .card.border-info
- .card-header.bg-info.text-white
+ .card
+ .card-header
= _('Admin Note')
.card-body
%p= text
diff --git a/app/views/admin/users/_user_reject_effects.html.haml b/app/views/admin/users/_user_reject_effects.html.haml
deleted file mode 100644
index 17b6862b0cc..00000000000
--- a/app/views/admin/users/_user_reject_effects.html.haml
+++ /dev/null
@@ -1,10 +0,0 @@
-%p
- = s_('AdminUsers|Rejected users:')
-%ul
- %li
- = s_('AdminUsers|Cannot sign in or access instance information')
- %li
- = s_('AdminUsers|Will be deleted')
-%p
- - link_start = '<a href="%{url}">'.html_safe % { url: help_page_path("user/profile/account/delete_account", anchor: "associated-records") }
- = s_('AdminUsers|For more information, please refer to the %{link_start}user account deletion documentation.%{link_end}').html_safe % { link_start: link_start, link_end: '</a>'.html_safe }
diff --git a/app/views/admin/users/keys.html.haml b/app/views/admin/users/keys.html.haml
index 5f9d11af7c1..28024ae084f 100644
--- a/app/views/admin/users/keys.html.haml
+++ b/app/views/admin/users/keys.html.haml
@@ -3,3 +3,4 @@
- page_title _("SSH Keys"), @user.name, _("Users")
= render 'admin/users/head'
= render 'profiles/keys/key_table', admin: true
+= render partial: 'admin/users/modals'
diff --git a/app/views/admin/users/projects.html.haml b/app/views/admin/users/projects.html.haml
index 3ff726e1945..8c56e888dcc 100644
--- a/app/views/admin/users/projects.html.haml
+++ b/app/views/admin/users/projects.html.haml
@@ -48,3 +48,5 @@
- 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
= sprite_icon('close', size: 16, css_class: 'gl-icon')
+
+= render partial: 'admin/users/modals'
diff --git a/app/views/admin/users/show.html.haml b/app/views/admin/users/show.html.haml
index 08c1e089f21..ad8d9d1f04f 100644
--- a/app/views/admin/users/show.html.haml
+++ b/app/views/admin/users/show.html.haml
@@ -16,8 +16,10 @@
%strong
= link_to user_path(@user) do
= @user.username
- = render 'admin/users/profile', user: @user
-
+ -# Rendered on mobile only so order of cards can be different on desktop vs mobile
+ .gl-md-display-none
+ = render 'admin/users/profile', user: @user
+ = render 'admin/users/user_detail_note'
.card
.card-header
= _('Account:')
@@ -139,123 +141,8 @@
= render 'shared/custom_attributes', custom_attributes: @user.custom_attributes
- .col-md-6
- - unless @user == current_user
- - if can_force_email_confirmation?(@user)
- .gl-card.border-info.gl-mb-5
- .gl-card-header.bg-info.text-white
- = _('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.') % { 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' }
-
- = render 'admin/users/user_detail_note'
-
- - unless @user.internal?
- - if @user.deactivated?
- .gl-card.border-info.gl-mb-5
- .gl-card-header.bg-info.text-white
- = _('Reactivate this user')
- .gl-card-body
- = render partial: 'admin/users/user_activation_effects'
- %br
- %button.btn.gl-button.btn-info.js-confirm-modal-button{ data: user_activation_data(@user) }
- = s_('AdminUsers|Activate user')
- - elsif @user.can_be_deactivated?
- .gl-card.border-warning.gl-mb-5
- .gl-card-header.bg-warning.text-white
- = _('Deactivate this user')
- .gl-card-body
- = user_deactivation_effects
- %br
- %button.btn.gl-button.btn-warning.js-confirm-modal-button{ data: user_deactivation_data(@user, s_('AdminUsers|You can always re-activate their account, their data will remain intact.')) }
- = s_('AdminUsers|Deactivate user')
- - if @user.blocked?
- - 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')
- .gl-card-body
- %p= _('A blocked user cannot:')
- %ul
- %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')
- .card-body
- %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?') }
- - 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:')
- = render 'users/deletion_guidance', user: @user
- %br
- %button.js-delete-user-modal-button.btn.gl-button.btn-danger{ data: { 'gl-modal-action': 'delete',
- delete_user_url: admin_user_path(@user),
- block_user_url: block_admin_user_path(@user),
- username: sanitize_name(@user.name) } }
- = s_('AdminUsers|Delete user')
- - else
- - if @user.solo_owned_groups.present?
- %p
- = _('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.')
- - else
- %p
- = _("You don't have access to delete this user.")
-
- .gl-card.border-danger
- .gl-card-header.bg-danger.text-white
- = s_('AdminUsers|Delete user and contributions')
- .gl-card-body
- - if can?(current_user, :destroy_user, @user)
- %p
- - 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),
- block_user_url: block_admin_user_path(@user),
- username: @user.name } }
- = s_('AdminUsers|Delete user and contributions')
- - else
- %p
- = _("You don't have access to delete this user.")
-
+ -# Rendered on desktop only so order of cards can be different on desktop vs mobile
+ .col-md-6.gl-display-none.gl-md-display-block
+ = render 'admin/users/profile', user: @user
+ = render 'admin/users/user_detail_note'
= render partial: 'admin/users/modals'
diff --git a/app/views/ci/token_access/_index.html.haml b/app/views/ci/token_access/_index.html.haml
new file mode 100644
index 00000000000..e6f21fc4ea4
--- /dev/null
+++ b/app/views/ci/token_access/_index.html.haml
@@ -0,0 +1 @@
+#js-ci-token-access-app{ data: { full_path: @project.full_path } }
diff --git a/app/views/ci/variables/_content.html.haml b/app/views/ci/variables/_content.html.haml
index 5eded970bf0..8a2a479486f 100644
--- a/app/views/ci/variables/_content.html.haml
+++ b/app/views/ci/variables/_content.html.haml
@@ -1,5 +1,5 @@
= _('Variables store information, like passwords and secret keys, that you can use in job scripts.')
-= link_to s_('Learn more.'), help_page_path('ci/variables/README'), target: '_blank', rel: 'noopener noreferrer'
+= link_to s_('Learn more.'), help_page_path('ci/variables/index'), target: '_blank', rel: 'noopener noreferrer'
%p
= _('Variables can be:')
%ul
@@ -7,4 +7,4 @@
= html_escape(_('%{code_open}Protected:%{code_close} Only exposed to protected branches or tags.')) % { code_open: '<code>'.html_safe, code_close: '</code>'.html_safe }
%li
= html_escape(_('%{code_open}Masked:%{code_close} Hidden in job logs. Must match masking requirements.')) % { code_open: '<code>'.html_safe, code_close: '</code>'.html_safe }
- = link_to _('Learn more.'), help_page_path('ci/variables/README', anchor: 'mask-a-cicd-variable'), target: '_blank', rel: 'noopener noreferrer'
+ = link_to _('Learn more.'), help_page_path('ci/variables/index', anchor: 'mask-a-cicd-variable'), target: '_blank', rel: 'noopener noreferrer'
diff --git a/app/views/ci/variables/_index.html.haml b/app/views/ci/variables/_index.html.haml
index f5d28adfa66..9db5ee23c3e 100644
--- a/app/views/ci/variables/_index.html.haml
+++ b/app/views/ci/variables/_index.html.haml
@@ -2,7 +2,7 @@
- if ci_variable_protected_by_default?
%p.settings-message.text-center
- - link_start = '<a href="%{url}">'.html_safe % { url: help_page_path('ci/variables/README', anchor: 'protect-a-cicd-variable') }
+ - link_start = '<a href="%{url}">'.html_safe % { url: help_page_path('ci/variables/index', anchor: 'protect-a-cicd-variable') }
= s_('Environment variables are configured by your administrator to be %{link_start}protected%{link_end} by default.').html_safe % { link_start: link_start, link_end: '</a>'.html_safe }
- is_group = !@group.nil?
@@ -16,8 +16,8 @@
aws_tip_deploy_link: help_page_path('ci/cloud_deployment/index.md', anchor: 'deploy-your-application-to-the-aws-elastic-container-service-ecs'),
aws_tip_commands_link: help_page_path('ci/cloud_deployment/index.md', anchor: 'run-aws-commands-from-gitlab-cicd'),
aws_tip_learn_link: help_page_path('ci/cloud_deployment/index.md', anchor: 'aws'),
- protected_environment_variables_link: help_page_path('ci/variables/README', anchor: 'protect-a-cicd-variable'),
- masked_environment_variables_link: help_page_path('ci/variables/README', anchor: 'mask-a-cicd-variable'),
+ protected_environment_variables_link: help_page_path('ci/variables/index', anchor: 'protect-a-cicd-variable'),
+ masked_environment_variables_link: help_page_path('ci/variables/index', anchor: 'mask-a-cicd-variable'),
} }
- if !@group && @project.group
diff --git a/app/views/ci/variables/_variable_row.html.haml b/app/views/ci/variables/_variable_row.html.haml
index 856d03ba258..3a7f7a241ac 100644
--- a/app/views/ci/variables/_variable_row.html.haml
+++ b/app/views/ci/variables/_variable_row.html.haml
@@ -39,7 +39,7 @@
= value
%p.masking-validation-error.gl-field-error.hide
= s_("CiVariables|Cannot use Masked Variable with current value")
- = link_to sprite_icon('question-o'), help_page_path('ci/variables/README', anchor: 'mask-a-cicd-variable'), target: '_blank', rel: 'noopener noreferrer'
+ = link_to sprite_icon('question-o'), help_page_path('ci/variables/index', anchor: 'mask-a-cicd-variable'), target: '_blank', rel: 'noopener noreferrer'
- unless only_key_value
.ci-variable-body-item.ci-variable-protected-item.table-section.section-20.mr-0.border-top-0
.gl-mr-3
diff --git a/app/views/clusters/clusters/_applications.html.haml b/app/views/clusters/clusters/_applications.html.haml
deleted file mode 100644
index f83a414a0aa..00000000000
--- a/app/views/clusters/clusters/_applications.html.haml
+++ /dev/null
@@ -1 +0,0 @@
-.cluster-applications-table#js-cluster-applications
diff --git a/app/views/clusters/clusters/_applications_tab.html.haml b/app/views/clusters/clusters/_applications_tab.html.haml
deleted file mode 100644
index e1455b0f60a..00000000000
--- a/app/views/clusters/clusters/_applications_tab.html.haml
+++ /dev/null
@@ -1,5 +0,0 @@
-- active = params[:tab] == 'apps'
-
-%li.nav-item{ role: 'presentation' }
- %a#cluster-apps-tab.nav-link.qa-applications{ class: active_when(active), href: clusterable.cluster_path(@cluster.id, params: {tab: 'apps'}) }
- %span= _('Applications')
diff --git a/app/views/clusters/clusters/_banner.html.haml b/app/views/clusters/clusters/_banner.html.haml
index 6d902132c73..1ca4f9c670e 100644
--- a/app/views/clusters/clusters/_banner.html.haml
+++ b/app/views/clusters/clusters/_banner.html.haml
@@ -6,17 +6,19 @@
%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' }
- = sprite_icon('warning', css_class: 'gl-icon gl-alert-icon gl-alert-icon-no-title')
- %button.js-close.gl-alert-dismiss{ type: 'button', 'aria-label' => _('Dismiss') }
- = sprite_icon('close', css_class: 'gl-icon')
+= render 'shared/global_alert',
+ variant: :warning,
+ alert_class: 'hidden js-cluster-api-unreachable',
+ is_contained: true,
+ close_button_class: 'js-close' do
.gl-alert-body
= s_('ClusterIntegration|Your cluster API is unreachable. Please ensure your API URL is correct.')
-.hidden.js-cluster-authentication-failure.js-cluster-api-unreachable.gl-alert.gl-alert-warning{ role: 'alert' }
- = sprite_icon('warning', css_class: 'gl-icon gl-alert-icon gl-alert-icon-no-title')
- %button.js-close.gl-alert-dismiss{ type: 'button', 'aria-label' => _('Dismiss') }
- = sprite_icon('close', css_class: 'gl-icon')
+= render 'shared/global_alert',
+ variant: :warning,
+ alert_class: 'hidden js-cluster-authentication-failure js-cluster-api-unreachable',
+ is_contained: true,
+ close_button_class: 'js-close' do
.gl-alert-body
= s_('ClusterIntegration|There was a problem authenticating with your cluster. Please ensure your CA Certificate and Token are valid.')
diff --git a/app/views/clusters/clusters/_multiple_clusters_message.html.haml b/app/views/clusters/clusters/_multiple_clusters_message.html.haml
index da3e128ba32..f235435d907 100644
--- a/app/views/clusters/clusters/_multiple_clusters_message.html.haml
+++ b/app/views/clusters/clusters/_multiple_clusters_message.html.haml
@@ -1,4 +1,4 @@
-- autodevops_help_url = help_page_path('topics/autodevops/index.md', anchor: 'using-multiple-kubernetes-clusters')
+- autodevops_help_url = help_page_path('topics/autodevops/index.md', anchor: 'use-multiple-kubernetes-clusters')
- help_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe
- help_link_end = '</a>'.html_safe
diff --git a/app/views/clusters/clusters/_provider_details_form.html.haml b/app/views/clusters/clusters/_provider_details_form.html.haml
index a936cdc04dd..fe3d1998234 100644
--- a/app/views/clusters/clusters/_provider_details_form.html.haml
+++ b/app/views/clusters/clusters/_provider_details_form.html.haml
@@ -43,13 +43,13 @@
label_class: 'label-bold' }
.form-text.text-muted
= s_('ClusterIntegration|Allow GitLab to manage namespaces and service accounts for this cluster.')
- = link_to _('More information'), help_page_path('user/project/clusters/index.md', anchor: 'gitlab-managed-clusters'), target: '_blank'
+ = link_to _('More information'), help_page_path('user/project/clusters/gitlab_managed_clusters.md'), target: '_blank'
.form-group
= field.check_box :namespace_per_environment, { label: s_('ClusterIntegration|Namespace per environment'), label_class: 'label-bold' }
.form-text.text-muted
= s_('ClusterIntegration|Deploy each environment to its own namespace. Otherwise, environments within a project share a project-wide namespace. Note that anyone who can trigger a deployment of a namespace can read its secrets. If modified, existing environments will use their current namespaces until the cluster cache is cleared.')
- = link_to _('More information'), help_page_path('user/project/clusters/index.md', anchor: 'custom-namespace'), target: '_blank'
+ = link_to _('More information'), help_page_path('user/project/clusters/deploy_to_cluster.md', anchor: 'custom-namespace'), target: '_blank'
- if cluster.allow_user_defined_namespace?
= render('clusters/clusters/namespace', platform_field: platform_field, field: field)
diff --git a/app/views/clusters/clusters/aws/_new.html.haml b/app/views/clusters/clusters/aws/_new.html.haml
index 93e8b1241a8..93db7db06b3 100644
--- a/app/views/clusters/clusters/aws/_new.html.haml
+++ b/app/views/clusters/clusters/aws/_new.html.haml
@@ -3,8 +3,8 @@
anchor: 'additional-requirements-for-self-managed-instances') }
= s_('Amazon authentication is not %{link_start}correctly configured%{link_end}. Ask your GitLab administrator if you want to use this service.').html_safe % { link_start: documentation_link_start, link_end: '<a/>'.html_safe }
- else
- .js-create-eks-cluster-form-container{ data: { 'gitlab-managed-cluster-help-path' => help_page_path('user/project/clusters/index.md', anchor: 'gitlab-managed-clusters'),
- 'namespace-per-environment-help-path' => help_page_path('user/project/clusters/index.md', anchor: 'custom-namespace'),
+ .js-create-eks-cluster-form-container{ data: { 'gitlab-managed-cluster-help-path' => help_page_path('user/project/clusters/gitlab_managed_clusters.md'),
+ 'namespace-per-environment-help-path' => help_page_path('user/project/clusters/deploy_to_cluster.md', anchor: 'custom-namespace'),
'create-role-path' => clusterable.authorize_aws_role_path,
'create-cluster-path' => clusterable.create_aws_clusters_path,
'account-id' => Gitlab::CurrentSettings.eks_account_id,
@@ -12,6 +12,6 @@
'role-arn' => @aws_role.role_arn,
'instance-types' => @instance_types,
'kubernetes-integration-help-path' => help_page_path('user/project/clusters/index'),
- 'account-and-external-ids-help-path' => help_page_path('user/project/clusters/add_eks_clusters.md', anchor: 'new-eks-cluster'),
- 'create-role-arn-help-path' => help_page_path('user/project/clusters/add_eks_clusters.md', anchor: 'new-eks-cluster'),
+ 'account-and-external-ids-help-path' => help_page_path('user/project/clusters/add_eks_clusters.md', anchor: 'create-a-new-certificate-based-eks-cluster'),
+ 'create-role-arn-help-path' => help_page_path('user/project/clusters/add_eks_clusters.md', anchor: 'create-a-new-certificate-based-eks-cluster'),
'external-link-icon' => sprite_icon('external-link') } }
diff --git a/app/views/clusters/clusters/gcp/_form.html.haml b/app/views/clusters/clusters/gcp/_form.html.haml
index 73a09f00fd6..5266fad9278 100644
--- a/app/views/clusters/clusters/gcp/_form.html.haml
+++ b/app/views/clusters/clusters/gcp/_form.html.haml
@@ -74,13 +74,13 @@
label_class: 'label-bold' }
.form-text.text-muted
= s_('ClusterIntegration|Allow GitLab to manage namespaces and service accounts for this cluster.')
- = link_to _('More information'), help_page_path('user/project/clusters/index.md', anchor: 'gitlab-managed-clusters'), target: '_blank'
+ = link_to _('More information'), help_page_path('user/project/clusters/gitlab_managed_clusters.md', anchor: 'gitlab-managed-clusters'), target: '_blank'
.form-group
= field.check_box :namespace_per_environment, { label: s_('ClusterIntegration|Namespace per environment'), label_class: 'label-bold' }
.form-text.text-muted
= s_('ClusterIntegration|Deploy each environment to its own namespace. Otherwise, environments within a project share a project-wide namespace. Note that anyone who can trigger a deployment of a namespace can read its secrets. If modified, existing environments will use their current namespaces until the cluster cache is cleared.')
- = link_to _('More information'), help_page_path('user/project/clusters/index.md', anchor: 'custom-namespace'), target: '_blank'
+ = link_to _('More information'), help_page_path('user/project/clusters/deploy_to_cluster.md', anchor: 'custom-namespace'), target: '_blank'
.form-group.js-gke-cluster-creation-submit-container
= field.submit s_('ClusterIntegration|Create Kubernetes cluster'),
diff --git a/app/views/clusters/clusters/show.html.haml b/app/views/clusters/clusters/show.html.haml
index 7336b9fe86b..0a482f1eb01 100644
--- a/app/views/clusters/clusters/show.html.haml
+++ b/app/views/clusters/clusters/show.html.haml
@@ -2,21 +2,10 @@
- add_to_breadcrumbs _('Kubernetes Clusters'), clusterable.index_path
- breadcrumb_title @cluster.name
- page_title _('Kubernetes Cluster')
-- manage_prometheus_path = edit_project_service_path(@cluster.project, 'prometheus') if @project
- cluster_environments_path = clusterable.environments_cluster_path(@cluster)
- status_path = clusterable.cluster_status_cluster_path(@cluster.id, format: :json) if can?(current_user, :admin_cluster, @cluster)
.edit-cluster-form.js-edit-cluster-form{ data: { status_path: status_path,
- install_helm_path: clusterable.install_applications_cluster_path(@cluster, :helm),
- install_ingress_path: clusterable.install_applications_cluster_path(@cluster, :ingress),
- install_cert_manager_path: clusterable.install_applications_cluster_path(@cluster, :cert_manager),
- install_crossplane_path: clusterable.install_applications_cluster_path(@cluster, :crossplane),
- install_prometheus_path: clusterable.install_applications_cluster_path(@cluster, :prometheus),
- install_runner_path: clusterable.install_applications_cluster_path(@cluster, :runner),
- install_jupyter_path: clusterable.install_applications_cluster_path(@cluster, :jupyter),
- install_knative_path: clusterable.install_applications_cluster_path(@cluster, :knative),
- update_knative_path: clusterable.update_applications_cluster_path(@cluster, :knative),
- install_elastic_stack_path: clusterable.install_applications_cluster_path(@cluster, :elastic_stack),
cluster_environments_path: cluster_environments_path,
toggle_status: @cluster.enabled? ? 'true': 'false',
has_rbac: has_rbac_enabled?(@cluster) ? 'true': 'false',
@@ -24,15 +13,11 @@
cluster_status: @cluster.status_name,
cluster_status_reason: @cluster.status_reason,
provider_type: @cluster.provider_type,
- pre_installed_knative: @cluster.knative_pre_installed? ? 'true': 'false',
help_path: help_page_path('user/project/clusters/index.md'),
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_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')} }
+ cluster_id: @cluster.id } }
.js-cluster-application-notice
.flash-container
diff --git a/app/views/clusters/clusters/user/_form.html.haml b/app/views/clusters/clusters/user/_form.html.haml
index 7d82fe06799..e9b84952c15 100644
--- a/app/views/clusters/clusters/user/_form.html.haml
+++ b/app/views/clusters/clusters/user/_form.html.haml
@@ -47,13 +47,13 @@
label_class: 'label-bold' }
.form-text.text-muted
= s_('ClusterIntegration|Allow GitLab to manage namespaces and service accounts for this cluster.')
- = link_to _('More information'), help_page_path('user/project/clusters/index.md', anchor: 'gitlab-managed-clusters'), target: '_blank'
+ = link_to _('More information'), help_page_path('user/project/clusters/gitlab_managed_clusters.md'), target: '_blank'
.form-group
= field.check_box :namespace_per_environment, { label: s_('ClusterIntegration|Namespace per environment'), label_class: 'label-bold' }
.form-text.text-muted
= s_('ClusterIntegration|Deploy each environment to its own namespace. Otherwise, environments within a project share a project-wide namespace. Note that anyone who can trigger a deployment of a namespace can read its secrets. If modified, existing environments will use their current namespaces until the cluster cache is cleared.')
- = link_to _('More information'), help_page_path('user/project/clusters/index.md', anchor: 'custom-namespace'), target: '_blank'
+ = link_to _('More information'), help_page_path('user/project/clusters/deploy_to_cluster.md', anchor: 'custom-namespace'), target: '_blank'
= field.fields_for :platform_kubernetes, @user_cluster.platform_kubernetes do |platform_kubernetes_field|
- if @user_cluster.allow_user_defined_namespace?
diff --git a/app/views/dashboard/projects/index.html.haml b/app/views/dashboard/projects/index.html.haml
index c24d386c412..4252b60514a 100644
--- a/app/views/dashboard/projects/index.html.haml
+++ b/app/views/dashboard/projects/index.html.haml
@@ -3,15 +3,6 @@
= content_for :meta_tags do
= auto_discovery_link_tag(:atom, dashboard_projects_url(rss_url_options), title: "All activity")
-- if show_customize_homepage_banner?
- = content_for :customize_homepage_banner do
- .gl-display-none.gl-md-display-block{ class: "gl-pt-6! gl-pb-2! #{(container_class unless @no_container)} #{@content_class}" }
- .js-customize-homepage-banner{ data: { svg_path: image_path('illustrations/monitoring/getting_started.svg'),
- preferences_behavior_path: profile_preferences_path(anchor: 'behavior'),
- callouts_path: user_callouts_path,
- callouts_feature_id: UserCalloutsHelper::CUSTOMIZE_HOMEPAGE,
- track_label: 'home_page' } }
-
= render_dashboard_ultimate_trial(current_user)
- page_title _("Projects")
diff --git a/app/views/devise/shared/_signup_box.html.haml b/app/views/devise/shared/_signup_box.html.haml
index 09b7f247450..a313ad7d23c 100644
--- a/app/views/devise/shared/_signup_box.html.haml
+++ b/app/views/devise/shared/_signup_box.html.haml
@@ -61,7 +61,7 @@
- if show_recaptcha_sign_up?
= recaptcha_tags nonce: content_security_policy_nonce
.submit-container
- = f.submit button_text, class: 'btn gl-button btn-confirm', data: { qa_selector: 'new_user_register_button' }
+ = f.submit button_text, class: 'btn gl-button btn-confirm gl-display-block gl-w-full', data: { qa_selector: 'new_user_register_button' }
= 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/groups/_delete_project_button.html.haml b/app/views/groups/_delete_project_button.html.haml
new file mode 100644
index 00000000000..54a99319418
--- /dev/null
+++ b/app/views/groups/_delete_project_button.html.haml
@@ -0,0 +1 @@
+= link_to _('Delete'), project, data: { confirm: remove_project_message(project) }, method: :delete, class: "btn gl-button btn-danger"
diff --git a/app/views/groups/_home_panel.html.haml b/app/views/groups/_home_panel.html.haml
index 624d0a21b81..b7c2b4d86b2 100644
--- a/app/views/groups/_home_panel.html.haml
+++ b/app/views/groups/_home_panel.html.haml
@@ -23,6 +23,10 @@
.home-panel-buttons.col-md-12.col-lg-6
- if current_user
.gl-display-flex.gl-flex-wrap.gl-lg-justify-content-end.gl-mx-n2{ data: { testid: 'group-buttons' } }
+ - if current_user.admin?
+ = link_to [:admin, @group], class: 'btn btn-default gl-button btn-icon gl-mt-3 gl-mr-2', title: s_('View group in admin area'),
+ data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do
+ = sprite_icon('admin')
- if @notification_setting
.js-vue-notification-dropdown{ data: { 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'), group_id: @group.id, container_class: 'gl-mx-2 gl-mt-3 gl-vertical-align-top' } }
- if can_create_subgroups
diff --git a/app/views/groups/_import_group_from_file_panel.html.haml b/app/views/groups/_import_group_from_file_panel.html.haml
index c70cc2c4936..3bc2146b313 100644
--- a/app/views/groups/_import_group_from_file_panel.html.haml
+++ b/app/views/groups/_import_group_from_file_panel.html.haml
@@ -33,8 +33,7 @@
title: _('Please choose a group URL with no special characters.'),
"data-bind-in" => "#{'create_chat_team' if Gitlab.config.mattermost.enabled}"
%p.validation-error.gl-field-error.field-validation.hide
- = _('Group path is already taken. Suggestions: ')
- %span.gl-path-suggestions
+ = _("Group path is already taken. We've suggested one that is available.")
%p.validation-success.gl-field-success.field-validation.hide= _('Group path is available.')
%p.validation-pending.gl-field-error-ignore.field-validation.hide= _('Checking group path availability...')
.form-group
diff --git a/app/views/groups/_invite_members_modal.html.haml b/app/views/groups/_invite_members_modal.html.haml
index f4f3c8ce8f7..3be1a142ca6 100644
--- a/app/views/groups/_invite_members_modal.html.haml
+++ b/app/views/groups/_invite_members_modal.html.haml
@@ -1,7 +1,8 @@
-- if can?(current_user, :admin_group_member, group)
- .js-invite-members-modal{ data: { id: group.id,
- name: group.name,
- is_project: 'false',
- access_levels: GroupMember.access_level_roles.to_json,
- default_access_level: Gitlab::Access::GUEST,
- help_link: help_page_url('user/permissions') }.merge(group_select_data(group)) }
+- return unless can_manage_members?(group)
+
+.js-invite-members-modal{ data: { id: group.id,
+ name: group.name,
+ is_project: 'false',
+ access_levels: GroupMember.access_level_roles.to_json,
+ default_access_level: Gitlab::Access::GUEST,
+ help_link: help_page_url('user/permissions') }.merge(group_select_data(group)) }
diff --git a/app/views/groups/_project_badges.html.haml b/app/views/groups/_project_badges.html.haml
new file mode 100644
index 00000000000..1f7895e216c
--- /dev/null
+++ b/app/views/groups/_project_badges.html.haml
@@ -0,0 +1,2 @@
+- if project.archived
+ %span.badge.badge-warning.badge-pill.gl-badge.md= _('archived')
diff --git a/app/views/groups/merge_requests.html.haml b/app/views/groups/merge_requests.html.haml
index 33f836c2de0..ad916e3aeec 100644
--- a/app/views/groups/merge_requests.html.haml
+++ b/app/views/groups/merge_requests.html.haml
@@ -2,7 +2,7 @@
- page_title _("Merge requests")
-- if @merge_requests&.size == 0
+- if issuables_count_for_state(:merge_requests, :all) == 0
= render 'shared/empty_states/merge_requests', project_select_button: true
- else
.top-area
diff --git a/app/views/groups/milestones/_form.html.haml b/app/views/groups/milestones/_form.html.haml
index 259e96901fd..a6302569187 100644
--- a/app/views/groups/milestones/_form.html.haml
+++ b/app/views/groups/milestones/_form.html.haml
@@ -1,25 +1,23 @@
= form_for [@group, @milestone], html: { class: 'milestone-form common-note-form js-quick-submit js-requires-input' } do |f|
= form_errors(@milestone)
- .row
- .col-md-6
- .form-group.row
- .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
- .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: group_preview_markdown_path } do
- = 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
+ .form-group.row
+ .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
+ = render "shared/milestones/form_dates", f: f
+ .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: group_preview_markdown_path } do
+ = 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
.form-actions
- if @milestone.new_record?
diff --git a/app/views/groups/projects.html.haml b/app/views/groups/projects.html.haml
index 9d595d19779..9dbf60b119c 100644
--- a/app/views/groups/projects.html.haml
+++ b/app/views/groups/projects.html.haml
@@ -15,13 +15,12 @@
.controls
= link_to _('Members'), project_project_members_path(project), id: "edit_#{dom_id(project)}", class: "btn gl-button"
= link_to _('Edit'), edit_project_path(project), id: "edit_#{dom_id(project)}", class: "btn gl-button"
- = link_to _('Delete'), project, data: { confirm: remove_project_message(project)}, method: :delete, class: "btn gl-button btn-danger"
+ = render 'delete_project_button', project: project
.stats
%span.badge.badge-pill
= storage_counter(project.statistics&.storage_size)
- - if project.archived
- %span.badge.badge-warning archived
+ = render 'project_badges', project: project
.title
= link_to(project_path(project)) do
diff --git a/app/views/groups/runners/_group_runners.html.haml b/app/views/groups/runners/_group_runners.html.haml
index 823d908c5e2..49e297ee13d 100644
--- a/app/views/groups/runners/_group_runners.html.haml
+++ b/app/views/groups/runners/_group_runners.html.haml
@@ -9,19 +9,24 @@
-# Proper policies should be implemented per
-# https://gitlab.com/gitlab-org/gitlab-foss/issues/45894
-- if can?(current_user, :admin_pipeline, @group)
- = render partial: 'ci/runner/how_to_setup_runner_automatically',
- locals: { type: 'group',
- clusters_path: group_clusters_path(@group) }
- - if params[:ci_runner_templates]
+.bs-callout.help-callout
+ - if can?(current_user, :admin_pipeline, @group) && valid_runner_registrars.include?('group')
+ = render partial: 'ci/runner/how_to_setup_runner_automatically',
+ locals: { type: 'group',
+ clusters_path: group_clusters_path(@group) }
+ - if params[:ci_runner_templates]
+ %hr
+ = render partial: 'ci/runner/setup_runner_in_aws',
+ locals: { registration_token: @group.runners_token }
%hr
- = render partial: 'ci/runner/setup_runner_in_aws',
- locals: { registration_token: @group.runners_token }
- %hr
- = render partial: 'ci/runner/how_to_setup_runner',
- locals: { registration_token: @group.runners_token,
- type: 'group',
- reset_token_url: reset_registration_token_group_settings_ci_cd_path,
- project_path: '',
- group_path: @group.full_path }
- %br
+ = render partial: 'ci/runner/how_to_setup_runner',
+ locals: { registration_token: @group.runners_token,
+ type: 'group',
+ reset_token_url: reset_registration_token_group_settings_ci_cd_path,
+ project_path: '',
+ group_path: @group.full_path }
+ %br
+ - else
+ = _('Please contact an admin to register runners.')
+ = link_to _('Learn more.'), help_page_path('user/admin_area/settings/continuous_integration', anchor: 'runner-registration'), target: '_blank', rel: 'noopener noreferrer'
+
diff --git a/app/views/groups/runners/_runner.html.haml b/app/views/groups/runners/_runner.html.haml
index 89e32c0999c..13da2292985 100644
--- a/app/views/groups/runners/_runner.html.haml
+++ b/app/views/groups/runners/_runner.html.haml
@@ -7,16 +7,16 @@
.table-mobile-content
- if runner.group_type?
%span.badge.badge-pill.gl-badge.sm.badge-success
- = _('group')
+ = s_('Runners|group')
- else
%span.badge.badge-pill.gl-badge.sm.badge-info
- = _('specific')
+ = s_('Runners|specific')
- if runner.locked?
%span.badge.badge-pill.gl-badge.sm.badge-warning
- = _('locked')
+ = s_('Runners|locked')
- unless runner.active?
%span.badge.badge-pill.gl-badge.sm.badge-danger
- = _('paused')
+ = s_('Runners|paused')
.table-section.section-30
.table-mobile-header{ role: 'rowheader' }= s_('Runners|Runner')
diff --git a/app/views/groups/runners/_index.html.haml b/app/views/groups/runners/_settings.html.haml
index 187588f5f11..187588f5f11 100644
--- a/app/views/groups/runners/_index.html.haml
+++ b/app/views/groups/runners/_settings.html.haml
diff --git a/app/views/groups/settings/_advanced.html.haml b/app/views/groups/settings/_advanced.html.haml
index d7a145924de..fea0736ffc8 100644
--- a/app/views/groups/settings/_advanced.html.haml
+++ b/app/views/groups/settings/_advanced.html.haml
@@ -24,21 +24,6 @@
"data-bind-in" => "#{'create_chat_team' if Gitlab.config.mattermost.enabled}"
= f.submit s_('GroupSettings|Change group URL'), class: 'btn gl-button btn-warning'
-.sub-section
- %h4.warning-title= s_('GroupSettings|Transfer group')
- = form_for @group, url: transfer_group_path(@group), method: :put, html: { class: 'js-group-transfer-form' } do |f|
- .form-group
- = dropdown_tag('Select parent group', options: { toggle_class: 'js-groups-dropdown', title: 'Parent Group', filter: true, dropdown_class: 'dropdown-open-top dropdown-group-transfer', placeholder: 'Search groups', data: { data: parent_group_options(@group), qa_selector: 'select_group_dropdown' } })
- = hidden_field_tag 'new_parent_group_id'
-
- %ul
- - side_effects_link_start = '<a href="https://docs.gitlab.com/ee/user/project/index.html#redirects-when-changing-repository-paths" target="_blank">'.html_safe
- - warning_text = s_("GroupSettings|Be careful. Changing a group's parent can have unintended %{side_effects_link_start}side effects%{side_effects_link_end}.") % { side_effects_link_start: side_effects_link_start, side_effects_link_end: '</a>'.html_safe }
- %li= warning_text.html_safe
- %li= s_('GroupSettings|You can only transfer the group to a group you manage.')
- %li= s_('GroupSettings|You will need to update your local repositories to point to the new location.')
- %li= s_("GroupSettings|If the parent group's visibility is lower than the group current visibility, visibility levels for subgroups and projects will be changed to match the new parent group's visibility.")
- = f.submit s_('GroupSettings|Transfer group'), class: 'btn gl-button btn-warning', data: { qa_selector: "transfer_group_button" }
-
+= render 'groups/settings/transfer', group: @group
= render 'groups/settings/remove', group: @group
= render_if_exists 'groups/settings/restore', group: @group
diff --git a/app/views/groups/settings/_pages_settings.html.haml b/app/views/groups/settings/_pages_settings.html.haml
index a7b1813e4f1..456e0b0f1d0 100644
--- a/app/views/groups/settings/_pages_settings.html.haml
+++ b/app/views/groups/settings/_pages_settings.html.haml
@@ -2,4 +2,4 @@
= render_if_exists 'shared/pages/max_pages_size_input', form: f
.gl-mt-3
- = f.submit s_('GitLabPages|Save'), class: 'btn gl-button btn-confirm'
+ = f.submit s_('GitLabPages|Save changes'), class: 'btn gl-button btn-confirm'
diff --git a/app/views/groups/settings/_transfer.html.haml b/app/views/groups/settings/_transfer.html.haml
new file mode 100644
index 00000000000..1472ae42152
--- /dev/null
+++ b/app/views/groups/settings/_transfer.html.haml
@@ -0,0 +1,22 @@
+.sub-section
+ %h4.warning-title= s_('GroupSettings|Transfer group')
+ = form_for group, url: transfer_group_path(group), method: :put, html: { class: 'js-group-transfer-form' } do |f|
+ .form-group
+ = dropdown_tag('Select parent group', options: { toggle_class: 'js-groups-dropdown', title: 'Parent Group', filter: true, dropdown_class: 'dropdown-open-top dropdown-group-transfer', placeholder: 'Search groups', disabled: group.paid?, data: { data: parent_group_options(group), qa_selector: 'select_group_dropdown' } })
+ = hidden_field_tag 'new_parent_group_id'
+
+ %ul
+ - side_effects_link_start = '<a href="https://docs.gitlab.com/ee/user/project/index.html#redirects-when-changing-repository-paths" target="_blank">'.html_safe
+ - warning_text = s_("GroupSettings|Be careful. Changing a group's parent can have unintended %{side_effects_link_start}side effects%{side_effects_link_end}.") % { side_effects_link_start: side_effects_link_start, side_effects_link_end: '</a>'.html_safe }
+ %li= warning_text.html_safe
+ %li= s_('GroupSettings|You can only transfer the group to a group you manage.')
+ %li= s_('GroupSettings|You will need to update your local repositories to point to the new location.')
+ %li= s_("GroupSettings|If the parent group's visibility is lower than the group current visibility, visibility levels for subgroups and projects will be changed to match the new parent group's visibility.")
+
+ - if group.paid?
+ .gl-alert.gl-alert-info.gl-mb-5{ data: { testid: 'group-to-transfer-has-linked-subscription-alert' } }
+ = sprite_icon('information-o', size: 16, css_class: 'gl-icon gl-alert-icon gl-alert-icon-no-title')
+ .gl-alert-body
+ = html_escape(_("This group can't be transfered because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group.")) % { linkStart: "<a href=\"#{help_page_path('subscriptions/index', anchor: 'change-the-linked-namespace')}\">".html_safe, linkEnd: '</a>'.html_safe }
+
+ = f.submit s_('GroupSettings|Transfer group'), class: 'btn gl-button btn-warning', data: { qa_selector: "transfer_group_button" }
diff --git a/app/views/groups/settings/ci_cd/show.html.haml b/app/views/groups/settings/ci_cd/show.html.haml
index 3c6514b95b8..018dd4c424d 100644
--- a/app/views/groups/settings/ci_cd/show.html.haml
+++ b/app/views/groups/settings/ci_cd/show.html.haml
@@ -32,9 +32,9 @@
= expanded ? _('Collapse') : _('Expand')
%p
= _("Runners are processes that pick up and execute CI/CD jobs for GitLab.")
- = link_to s_('How do I configure runners?'), help_page_path('ci/runners/README'), target: '_blank', rel: 'noopener noreferrer'
+ = link_to s_('How do I configure runners?'), help_page_path('ci/runners/index'), target: '_blank', rel: 'noopener noreferrer'
.settings-content
- = render 'groups/runners/index'
+ = render 'groups/runners/settings'
%section.settings#auto-devops-settings.no-animate{ class: ('expanded' if expanded) }
.settings-header
diff --git a/app/views/groups/settings/integrations/index.html.haml b/app/views/groups/settings/integrations/index.html.haml
index 7a81d53c085..1db8edb040b 100644
--- a/app/views/groups/settings/integrations/index.html.haml
+++ b/app/views/groups/settings/integrations/index.html.haml
@@ -1,9 +1,9 @@
-- breadcrumb_title _('Integrations')
-- page_title _('Integrations')
+- breadcrumb_title s_('Integrations|Group-level integration management')
+- page_title s_('Integrations|Group-level integration management')
- @content_class = 'limit-container-width' unless fluid_layout
-%h3= s_('Integrations|Project integration management')
+%h3= s_('Integrations|Group-level integration management')
- integrations_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: integrations_help_page_path }
-%p= s_("Integrations|GitLab administrators can set up integrations that all projects inherit and use by default. These integrations apply to all projects that don't already use custom settings. You can override custom settings for a group or project if the settings are necessary at that level. Learn more about %{integrations_link_start}project integration management%{link_end}.").html_safe % { integrations_link_start: integrations_link_start, link_end: "</a>".html_safe }
+%p= s_("Integrations|GitLab administrators can set up integrations that all projects in a group inherit and use by default. These integrations apply to all projects that don't already use custom settings. You can override custom settings for a project if the settings are necessary at that level. Learn more about %{integrations_link_start}group-level integration management%{link_end}.").html_safe % { integrations_link_start: integrations_link_start, link_end: "</a>".html_safe }
= render 'shared/integrations/index', integrations: @integrations
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 23ac7d51e4f..5299c38576d 100644
--- a/app/views/groups/settings/repository/_initial_branch_name.html.haml
+++ b/app/views/groups/settings/repository/_initial_branch_name.html.haml
@@ -5,7 +5,7 @@
%button.gl-button.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.')
+ = s_('GroupSettings|The default name for the initial branch of new repositories created in the group.')
.settings-content
= form_for @group, url: group_path(@group, anchor: 'js-default-branch-name'), html: { class: 'fieldset-form' } do |f|
= form_errors(@group)
@@ -16,7 +16,7 @@
= 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: 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
+ = (s_("GroupSettings|If not specified at the group or instance level, the default is %{default_initial_branch_name}. Does not affect existing repositories.") % { default_initial_branch_name: fallback_branch_name }).html_safe
= f.hidden_field :redirect_target, value: "repository_settings"
= f.submit _('Save changes'), class: 'btn gl-button btn-confirm'
diff --git a/app/views/groups/show.html.haml b/app/views/groups/show.html.haml
index 628425bf463..76850f0a884 100644
--- a/app/views/groups/show.html.haml
+++ b/app/views/groups/show.html.haml
@@ -6,6 +6,8 @@
- if show_thanks_for_purchase_banner?
= render_if_exists 'shared/thanks_for_purchase_banner', plan_title: plan_title, quantity: params[:purchased_quantity].to_i
+= render_if_exists 'shared/qrtly_reconciliation_alert', group: @group
+
- if show_invite_banner?(@group)
= content_for :group_invite_members_banner do
.container-fluid.container-limited{ class: "gl-pb-2! gl-pt-6! #{@content_class}" }
diff --git a/app/views/help/index.html.haml b/app/views/help/index.html.haml
index a56eaaf685f..95888963947 100644
--- a/app/views/help/index.html.haml
+++ b/app/views/help/index.html.haml
@@ -38,7 +38,7 @@
.card-header
= _('Quick help')
%ul.content-list
- %li= link_to _('See our website for getting help'), support_url
+ %li= link_to _('See our website for help'), support_url
%li
%button.btn-blank.btn-link.js-trigger-search-bar{ type: 'button' }
= _('Use the search bar on the top of this page')
diff --git a/app/views/import/gitlab_projects/new.html.haml b/app/views/import/gitlab_projects/new.html.haml
index 8daddbb0042..028268482cd 100644
--- a/app/views/import/gitlab_projects/new.html.haml
+++ b/app/views/import/gitlab_projects/new.html.haml
@@ -21,5 +21,5 @@
= file_field_tag :file, class: ''
.row
.form-actions.col-sm-12
- = submit_tag _('Import project'), class: 'gl-button btn btn-confirm'
+ = submit_tag _('Import project'), class: 'gl-button btn btn-confirm', data: { qa_selector: 'import_project_button' }
= link_to _('Cancel'), new_project_path, class: 'gl-button btn btn-default btn-cancel'
diff --git a/app/views/import/shared/_new_project_form.html.haml b/app/views/import/shared/_new_project_form.html.haml
index 7de8b0ee10f..16526382f42 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 gl-form-input 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 }, data: { qa_selector: 'project_name_field' }
.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 gl-form-input", 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 }, data: { qa_selector: 'project_slug_field' }
diff --git a/app/views/layouts/_flash.html.haml b/app/views/layouts/_flash.html.haml
index 433337602f1..a302fa605e7 100644
--- a/app/views/layouts/_flash.html.haml
+++ b/app/views/layouts/_flash.html.haml
@@ -4,6 +4,8 @@
- flash.each do |key, value|
- if key == 'toast' && value
.js-toast-message{ data: { message: value } }
+ - elsif value == I18n.t('devise.failure.unconfirmed')
+ = render 'shared/confirm_your_email_alert'
- elsif value
%div{ class: "flash-#{key} mb-2" }
= sprite_icon(icons[key], css_class: 'align-middle mr-1') unless icons[key].nil?
diff --git a/app/views/layouts/_loading_hints.html.haml b/app/views/layouts/_loading_hints.html.haml
index cd1a236b6be..c431f05c217 100644
--- a/app/views/layouts/_loading_hints.html.haml
+++ b/app/views/layouts/_loading_hints.html.haml
@@ -7,5 +7,5 @@
- 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
+ - if Gitlab::Tracking.enabled? && Gitlab::CurrentSettings.snowplow_collector_hostname
%link{ rel: 'preconnect', href: Gitlab::CurrentSettings.snowplow_collector_hostname, crossorigin: '' }
diff --git a/app/views/layouts/_page.html.haml b/app/views/layouts/_page.html.haml
index 2b63e2c647c..6c959f5e60c 100644
--- a/app/views/layouts/_page.html.haml
+++ b/app/views/layouts/_page.html.haml
@@ -14,11 +14,12 @@
= render "layouts/header/service_templates_deprecation_callout"
= render "layouts/nav/classification_level_banner"
= yield :flash_message
- = render "shared/ping_consent"
+ = render "shared/service_ping_consent"
= render_account_recovery_regular_check
= render_if_exists "layouts/header/ee_subscribable_banner"
= render_if_exists "shared/namespace_storage_limit_alert"
= render_if_exists "shared/new_user_signups_cap_reached_alert"
+ = yield :page_level_alert
= yield :customize_homepage_banner
- unless @hide_breadcrumbs
= render "layouts/nav/breadcrumbs"
@@ -27,5 +28,6 @@
= render "layouts/flash", extra_flash_class: 'limit-container-width'
= yield :before_content
= yield
+ = yield :after_content
= render "layouts/nav/top_nav_responsive", class: 'layout-page content-wrapper-margin'
diff --git a/app/views/layouts/_search.html.haml b/app/views/layouts/_search.html.haml
index e617b4358e3..5ce275d4a43 100644
--- a/app/views/layouts/_search.html.haml
+++ b/app/views/layouts/_search.html.haml
@@ -3,14 +3,14 @@
.search-input-container
.search-input-wrap
.dropdown{ data: { url: search_autocomplete_path } }
- = search_field_tag 'search', nil, placeholder: _('Search or jump to…'),
+ = search_field_tag 'search', nil, placeholder: _('Search GitLab'),
class: 'search-input dropdown-menu-toggle no-outline js-search-dashboard-options',
spellcheck: false,
autocomplete: 'off',
data: { issues_path: issues_dashboard_path,
mr_path: merge_requests_dashboard_path,
qa_selector: 'search_term_field' },
- aria: { label: _('Search or jump to…') }
+ aria: { label: _('Search GitLab') }
%button.hidden.js-dropdown-search-toggle{ type: 'button', data: { toggle: 'dropdown' } }
.dropdown-menu.dropdown-select{ data: { testid: 'dashboard-search-options' } }
= dropdown_content do
diff --git a/app/views/layouts/_snowplow.html.haml b/app/views/layouts/_snowplow.html.haml
index bdce4eac755..9c0384e5faa 100644
--- a/app/views/layouts/_snowplow.html.haml
+++ b/app/views/layouts/_snowplow.html.haml
@@ -1,4 +1,4 @@
-- return unless Gitlab::CurrentSettings.snowplow_enabled?
+- return unless Gitlab::Tracking.enabled?
= javascript_tag do
:plain
diff --git a/app/views/layouts/application.html.haml b/app/views/layouts/application.html.haml
index 47c092e199a..899bf65de48 100644
--- a/app/views/layouts/application.html.haml
+++ b/app/views/layouts/application.html.haml
@@ -1,7 +1,6 @@
- page_classes = page_class << @html_class
- page_classes = page_classes.flatten.compact
- body_classes = [user_application_theme, user_tab_width, @body_class, client_class_list]
-- body_classes << 'sidebar-refactoring' if sidebar_refactor_enabled?
!!! 5
%html{ lang: I18n.locale, class: page_classes }
diff --git a/app/views/layouts/devise.html.haml b/app/views/layouts/devise.html.haml
index ae7c160c060..5c9c6a06ac1 100644
--- a/app/views/layouts/devise.html.haml
+++ b/app/views/layouts/devise.html.haml
@@ -14,28 +14,29 @@
.row.mt-3
.col-sm-12
%h1.mb-3.font-weight-normal
- = current_appearance&.title.presence || "GitLab"
+ = current_appearance&.title.presence || _('GitLab')
.row.mb-3
.col-sm-7.order-12.order-sm-1.brand-holder
- = brand_image
- - if current_appearance&.description?
- = brand_text
- - else
- %h3.mt-sm-0
- = _('A complete DevOps platform')
+ - unless recently_confirmed_com?
+ = brand_image
+ - if current_appearance&.description?
+ = brand_text
+ - else
+ %h3.gl-sm-mt-0
+ = _('A complete DevOps platform')
- %p
- = _('GitLab is a single application for the entire software development lifecycle. From project planning and source code management to CI/CD, monitoring, and security.')
+ %p
+ = _('GitLab is a single application for the entire software development lifecycle. From project planning and source code management to CI/CD, monitoring, and security.')
- %p
- = _('This is a self-managed instance of GitLab.')
+ %p
+ = _('This is a self-managed instance of GitLab.')
- if Gitlab::CurrentSettings.sign_in_text.present?
= markdown_field(Gitlab::CurrentSettings.current_application_settings, :sign_in_text)
= render_if_exists 'layouts/devise_help_text'
- .col-sm-5.order-1.order-sm-12.new-session-forms-container
+ .col-sm-5.order-1.new-session-forms-container{ class: recently_confirmed_com? ? 'order-sm-first' : 'order-sm-12' }
= yield
= render 'devise/shared/footer', footer_message: footer_message
diff --git a/app/views/layouts/header/_new_dropdown.html.haml b/app/views/layouts/header/_new_dropdown.html.haml
index c5f43fb2c16..0be87ad963c 100644
--- a/app/views/layouts/header/_new_dropdown.html.haml
+++ b/app/views/layouts/header/_new_dropdown.html.haml
@@ -6,7 +6,7 @@
- return if menu_sections.empty?
-%li.header-new.dropdown{ class: top_class, data: { track_label: "new_dropdown", track_event: "click_dropdown", track_experiment: "new_repo" } }
+%li.header-new.dropdown{ class: top_class, data: { track_label: "new_dropdown", track_event: "click_dropdown" } }
= link_to new_project_path, class: "header-new-dropdown-toggle has-tooltip", id: "js-onboarding-new-project-link", title: title, ref: 'tooltip', aria: { label: title }, data: { toggle: 'dropdown', placement: 'bottom', container: 'body', display: 'static', qa_selector: 'new_menu_toggle' } do
= sprite_icon('plus-square')
= sprite_icon('chevron-down', css_class: 'caret-down')
diff --git a/app/views/layouts/header/_registration_enabled_callout.html.haml b/app/views/layouts/header/_registration_enabled_callout.html.haml
index 9266702e44e..25a7f7ba9d7 100644
--- a/app/views/layouts/header/_registration_enabled_callout.html.haml
+++ b/app/views/layouts/header/_registration_enabled_callout.html.haml
@@ -7,8 +7,8 @@
alert_data: { feature_id: UserCalloutsHelper::REGISTRATION_ENABLED_CALLOUT, dismiss_endpoint: user_callouts_path },
close_button_data: { testid: 'close-registration-enabled-callout' } do
.gl-alert-body
- = html_escape(_('%{anchorOpen}Learn more%{anchorClose} about how you can customize / disable registration on your instance.')) % { anchorOpen: "<a href=\"#{help_page_path('user/admin_area/settings/sign_up_restrictions')}\">".html_safe, anchorClose: '</a>'.html_safe }
+ = html_escape(_('%{anchorOpen}Learn more%{anchorClose} about how you can customize / disable registration on your instance.')) % { anchorOpen: "<a href=\"#{help_page_path('user/admin_area/settings/sign_up_restrictions')}\" class=\"gl-link\">".html_safe, anchorClose: '</a>'.html_safe }
.gl-alert-actions
- = link_to general_admin_application_settings_path(anchor: 'js-signup-settings'), class: 'btn gl-alert-action btn-info btn-md gl-button' do
+ = link_to general_admin_application_settings_path(anchor: 'js-signup-settings'), class: 'btn gl-alert-action btn-confirm btn-md gl-button' do
%span.gl-button-text
= _('View setting')
diff --git a/app/views/layouts/minimal.html.haml b/app/views/layouts/minimal.html.haml
new file mode 100644
index 00000000000..b5cb8f2af37
--- /dev/null
+++ b/app/views/layouts/minimal.html.haml
@@ -0,0 +1,18 @@
+- page_classes = page_class.push(@html_class).flatten.compact
+
+!!! 5
+%html{ lang: I18n.locale, class: page_classes }
+ = render "layouts/head"
+ %body{ data: body_data }
+ = header_message
+ = render 'peek/bar'
+ = render "layouts/header/empty"
+ .layout-page
+ .content-wrapper.content-wrapper-margin.gl-pt-6{ class: 'gl-md-pt-11!' }
+ .alert-wrapper.gl-force-block-formatting-context
+ = render "layouts/broadcast"
+ .limit-container-width{ class: container_class }
+ %main#content-body.content
+ = render "layouts/flash" unless @hide_flash
+ = yield
+ = footer_message
diff --git a/app/views/layouts/nav/_dashboard.html.haml b/app/views/layouts/nav/_dashboard.html.haml
index 117382d87b5..e4cdb4e1b08 100644
--- a/app/views/layouts/nav/_dashboard.html.haml
+++ b/app/views/layouts/nav/_dashboard.html.haml
@@ -4,7 +4,7 @@
-# [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", data: { track_label: "projects_dropdown", track_event: "click_dropdown", track_experiment: "new_repo" } }) do
+ = nav_link(path: ['root#index', 'projects#trending', 'projects#starred', 'dashboard/projects#index'], html_options: { id: 'nav-projects-dropdown', class: "home dropdown header-projects", data: { track_label: "projects_dropdown", track_event: "click_dropdown" } }) do
%button{ type: 'button', data: { toggle: "dropdown" } }
= _('Projects')
= sprite_icon('chevron-down', css_class: 'caret-down')
diff --git a/app/views/layouts/nav/projects_dropdown/_show.html.haml b/app/views/layouts/nav/projects_dropdown/_show.html.haml
index 46070975566..f16aab92a95 100644
--- a/app/views/layouts/nav/projects_dropdown/_show.html.haml
+++ b/app/views/layouts/nav/projects_dropdown/_show.html.haml
@@ -15,21 +15,12 @@
= nav_link(path: 'projects#trending') do
= link_to explore_root_path, data: { track_label: "projects_dropdown_explore_projects", track_event: "click_link" } do
= _('Explore projects')
- - experiment(:new_repo, user: current_user) do |e|
- - e.use do
- = nav_link(path: 'projects/new#blank_project', html_options: { class: 'gl-border-0 gl-border-t-1 gl-border-solid gl-border-gray-100' }) do
- = link_to new_project_path(anchor: 'blank_project'), data: { track_label: "projects_dropdown_blank_project", track_event: "click_link", track_experiment: "new_repo", qa_selector: "create_project_link" } do
- = _('Create blank project')
- = nav_link(path: 'projects/new#import_project') do
- = link_to new_project_path(anchor: 'import_project'), data: { track_label: "projects_dropdown_import_project", track_event: "click_link", track_experiment: "new_repo", qa_selector: "import_project_link" } do
- = _('Import project')
- - e.try do
- = nav_link(path: 'projects/new#blank_project', html_options: { class: 'gl-border-0 gl-border-t-1 gl-border-solid gl-border-gray-100' }) do
- = link_to new_project_path(anchor: 'blank_project'), data: { track_label: "projects_dropdown_blank_project", track_event: "click_link", track_experiment: "new_repo" } do
- = _('Create blank project/repository')
- = nav_link(path: 'projects/new#import_project') do
- = link_to new_project_path(anchor: 'import_project'), data: { track_label: "projects_dropdown_import_project", track_event: "click_link", track_experiment: "new_repo" } do
- = _('Import project/repository')
+ = nav_link(path: 'projects/new#blank_project', html_options: { class: 'gl-border-0 gl-border-t-1 gl-border-solid gl-border-gray-100' }) do
+ = link_to new_project_path(anchor: 'blank_project'), data: { track_label: "projects_dropdown_blank_project", track_event: "click_link", qa_selector: "create_project_link" } do
+ = _('Create blank project')
+ = nav_link(path: 'projects/new#import_project') do
+ = link_to new_project_path(anchor: 'import_project'), data: { track_label: "projects_dropdown_import_project", track_event: "click_link", qa_selector: "import_project_link" } do
+ = _('Import project')
= nav_link(path: 'projects/new#create_from_template') do
= link_to new_project_path(anchor: 'create_from_template'), data: { track_label: "projects_dropdown_create_from_template", track_event: "click_link" } do
= _('Create from template')
diff --git a/app/views/layouts/nav/sidebar/_admin.html.haml b/app/views/layouts/nav/sidebar/_admin.html.haml
index 21c3d7cb7e2..d0b73a3364a 100644
--- a/app/views/layouts/nav/sidebar/_admin.html.haml
+++ b/app/views/layouts/nav/sidebar/_admin.html.haml
@@ -1,12 +1,9 @@
-- avatar_size = sidebar_refactor_disabled? ? 24 : 18
-- avatar_size_class = sidebar_refactor_disabled? ? 's40' : 's32'
-
%aside.nav-sidebar.qa-admin-sidebar{ class: ("sidebar-collapsed-desktop" if collapsed_sidebar?), 'aria-label': _('Admin navigation') }
.nav-sidebar-inner-scroll
.context-header
= link_to admin_root_path, title: _('Admin Overview') do
- %span{ class: ['avatar-container', 'settings-avatar', 'rect-avatar', avatar_size_class] }
- = sprite_icon('admin', size: avatar_size)
+ %span{ class: ['avatar-container', 'settings-avatar', 'rect-avatar', 's32'] }
+ = sprite_icon('admin', size: 18)
%span.sidebar-context-title
= _('Admin Area')
%ul.sidebar-top-level-items{ data: { qa_selector: 'admin_sidebar_overview_submenu_content' } }
@@ -209,19 +206,6 @@
= render_if_exists 'layouts/nav/sidebar/credentials_link'
- - 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
.nav-icon-container
diff --git a/app/views/layouts/nav/sidebar/_analytics_links.html.haml b/app/views/layouts/nav/sidebar/_analytics_links.html.haml
index 58989d6afc4..92a7b97203f 100644
--- a/app/views/layouts/nav/sidebar/_analytics_links.html.haml
+++ b/app/views/layouts/nav/sidebar/_analytics_links.html.haml
@@ -1,6 +1,6 @@
- navbar_links = links.sort_by(&:title)
- all_paths = navbar_links.map(&:path)
-- analytics_link = navbar_links.find { |link| link.title == _('Value Stream') } || navbar_links.first
+- analytics_link = navbar_links.find { |link| link.title == _('Value stream') } || navbar_links.first
- if navbar_links.any?
= nav_link(path: all_paths) do
diff --git a/app/views/layouts/nav/sidebar/_context_menu_body.html.haml b/app/views/layouts/nav/sidebar/_context_menu_body.html.haml
deleted file mode 100644
index 321bcda5702..00000000000
--- a/app/views/layouts/nav/sidebar/_context_menu_body.html.haml
+++ /dev/null
@@ -1,9 +0,0 @@
-- avatar_size_class = sidebar_refactor_disabled? ? 's40' : 's32'
-- avatar_classes = ['avatar-container', 'rect-avatar', 'group-avatar']
-- avatar_classes << avatar_size_class
-
-= link_to group_path(@group), title: @group.name, data: { qa_selector: 'group_scope_link' } do
- %span{ class: avatar_classes }
- = group_icon(@group, class: ['avatar', 'avatar-tile', avatar_size_class])
- %span.sidebar-context-title
- = @group.name
diff --git a/app/views/layouts/nav/sidebar/_group.html.haml b/app/views/layouts/nav/sidebar/_group.html.haml
index 0ce1d48a2de..980730bc3be 100644
--- a/app/views/layouts/nav/sidebar/_group.html.haml
+++ b/app/views/layouts/nav/sidebar/_group.html.haml
@@ -1,207 +1,3 @@
-- issues_count = cached_issuables_count(@group, type: :issues)
-- merge_requests_count = cached_issuables_count(@group, type: :merge_requests)
-- aside_title = @group.subgroup? ? _('Subgroup navigation') : _('Group navigation')
-
-%aside.nav-sidebar{ class: ("sidebar-collapsed-desktop" if collapsed_sidebar?), **sidebar_tracking_attributes_by_object(@group), 'aria-label': aside_title }
- .nav-sidebar-inner-scroll
- - if sidebar_refactor_disabled?
- .context-header
- = render 'layouts/nav/sidebar/context_menu_body'
-
- %ul.sidebar-top-level-items.qa-group-sidebar
- - if sidebar_refactor_enabled?
- = nav_link(path: ['groups#show', 'groups#details'], html_options: { class: 'context-header' }) do
- = render 'layouts/nav/sidebar/context_menu_body'
-
- = render_if_exists 'layouts/nav/sidebar/group_trial_status_widget', group: @group
-
- - if group_sidebar_link?(:overview)
- - paths = group_overview_nav_link_paths
- = nav_link(path: paths, unless: -> { current_path?('groups/contribution_analytics#show') }, html_options: { class: 'home' }) do
- - information_link = sidebar_refactor_enabled? ? activity_group_path(@group) : group_path(@group)
- = link_to information_link, class: 'has-sub-items', data: { qa_selector: 'group_information_link' } do
- .nav-icon-container
- - sprite = sidebar_refactor_enabled? ? 'group' : 'home'
- = sprite_icon(sprite)
- %span.nav-item-name
- = group_information_title(@group)
-
- %ul.sidebar-sub-level-items{ data: { qa_selector: 'group_information_submenu'} }
- = nav_link(path: paths, html_options: { class: "fly-out-top-item" } ) do
- = link_to information_link do
- %strong.fly-out-top-item-name
- = group_information_title(@group)
- %li.divider.fly-out-top-item
-
- - if sidebar_refactor_disabled?
- = 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
- = link_to activity_group_path(@group), title: _('Activity') do
- %span
- = _('Activity')
-
- - if group_sidebar_link?(:labels) && sidebar_refactor_enabled?
- = nav_link(path: 'labels#index') do
- = link_to group_labels_path(@group), title: _('Labels') do
- %span
- = _('Labels')
-
- - if sidebar_refactor_enabled?
- - 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)
- = nav_link(path: group_issues_sub_menu_items, unless: -> { current_path?('issues_analytics#show') }) do
- = link_to issues_group_path(@group), data: { qa_selector: 'group_issues_item' }, class: 'has-sub-items' do
- .nav-icon-container
- = sprite_icon('issues')
- %span.nav-item-name
- = _('Issues')
- %span.badge.badge-pill.count= issues_count
-
- %ul.sidebar-sub-level-items{ data: { qa_selector: 'group_issues_sidebar_submenu'} }
- = 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')
- %span.badge.badge-pill.count.issue_counter.fly-out-badge= issues_count
-
- %li.divider.fly-out-top-item
- = nav_link(path: 'groups#issues', html_options: { class: 'home' }) do
- = link_to issues_group_path(@group), title: _('List') do
- %span
- = _('List')
-
- - if group_sidebar_link?(:boards)
- = nav_link(path: ['boards#index', 'boards#show']) do
- = link_to group_boards_path(@group), title: boards_link_text, data: { qa_selector: 'group_issue_boards_link' } do
- %span
- = boards_link_text
-
- - if group_sidebar_link?(:labels) && sidebar_refactor_disabled?
- = nav_link(path: 'labels#index') do
- = link_to group_labels_path(@group), title: _('Labels') do
- %span
- = _('Labels')
-
- - if group_sidebar_link?(:milestones)
- = nav_link(path: 'milestones#index') do
- = link_to group_milestones_path(@group), title: _('Milestones'), data: { qa_selector: 'group_milestones_link' } do
- %span
- = _('Milestones')
-
- = render_if_exists 'layouts/nav/sidebar/group_iterations_link'
-
- - if group_sidebar_link?(:merge_requests)
- = nav_link(path: 'groups#merge_requests') do
- = link_to merge_requests_group_path(@group) do
- .nav-icon-container
- = sprite_icon('git-merge')
- %span.nav-item-name
- = _('Merge requests')
- %span.badge.badge-pill.count= merge_requests_count
- %ul.sidebar-sub-level-items.is-fly-out-only
- = nav_link(path: 'groups#merge_requests', html_options: { class: "fly-out-top-item" } ) do
- = link_to merge_requests_group_path(@group) do
- %strong.fly-out-top-item-name
- = _('Merge requests')
- %span.badge.badge-pill.count.merge_counter.js-merge-counter.fly-out-badge= merge_requests_count
-
- = render_if_exists "layouts/nav/ee/security_link" # EE-specific
-
- = render_if_exists "layouts/nav/ee/push_rules_link" # EE-specific
-
- - if group_sidebar_link?(:kubernetes)
- = nav_link(controller: [:clusters]) do
- = link_to group_clusters_path(@group) do
- .nav-icon-container
- = sprite_icon('cloud-gear')
- %span.nav-item-name
- = _('Kubernetes')
- %ul.sidebar-sub-level-items.is-fly-out-only
- = nav_link(controller: [:clusters], html_options: { class: "fly-out-top-item" } ) do
- = link_to group_clusters_path(@group), title: _('Kubernetes'), class: 'shortcuts-kubernetes' do
- %strong.fly-out-top-item-name
- = _('Kubernetes')
-
- = render 'groups/sidebar/packages'
-
- = render 'layouts/nav/sidebar/analytics_links', links: group_analytics_navbar_links(@group, current_user)
-
- - if group_sidebar_link?(:wiki)
- = render 'layouts/nav/sidebar/wiki_link', wiki_url: @group.wiki.web_url
-
- - if sidebar_refactor_disabled?
- - 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), class: 'has-sub-items' do
- .nav-icon-container
- = sprite_icon('settings')
- %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
- = link_to edit_group_path(@group) do
- %strong.fly-out-top-item-name
- = _('Settings')
- %li.divider.fly-out-top-item
- = nav_link(path: 'groups#edit') do
- = link_to edit_group_path(@group), title: _('General'), data: { qa_selector: 'general_settings_link' } do
- %span
- = _('General')
-
- = nav_link(controller: :integrations) do
- = link_to group_settings_integrations_path(@group), title: _('Integrations') do
- %span
- = _('Integrations')
-
- = nav_link(path: 'groups#projects') do
- = link_to projects_group_path(@group), title: _('Projects') do
- %span
- = _('Projects')
-
- = nav_link(controller: :repository) do
- = link_to group_settings_repository_path(@group), title: _('Repository') do
- %span
- = _('Repository')
-
- = nav_link(controller: [:ci_cd, 'groups/runners']) do
- = link_to group_settings_ci_cd_path(@group), title: _('CI/CD') do
- %span
- = _('CI/CD')
-
- = nav_link(controller: :applications) do
- = link_to group_settings_applications_path(@group), title: _('Applications') do
- %span
- = _('Applications')
-
- = render 'groups/sidebar/packages_settings'
-
- = render_if_exists "groups/ee/settings_nav"
-
- = render_if_exists "groups/ee/administration_nav"
-
- = render 'shared/sidebar_toggle_button'
+-# We're migration the group 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/_group_menus.html.haml.
+= render partial: 'shared/nav/sidebar', object: Sidebars::Groups::Panel.new(group_sidebar_context(@group, current_user))
diff --git a/app/views/layouts/nav/sidebar/_group_menus.html.haml b/app/views/layouts/nav/sidebar/_group_menus.html.haml
new file mode 100644
index 00000000000..5738c8becd5
--- /dev/null
+++ b/app/views/layouts/nav/sidebar/_group_menus.html.haml
@@ -0,0 +1,166 @@
+- issues_count = cached_issuables_count(@group, type: :issues)
+- merge_requests_count = cached_issuables_count(@group, type: :merge_requests)
+
+= render_if_exists 'layouts/nav/sidebar/group_trial_status_widget', group: @group
+
+- if group_sidebar_link?(:overview)
+ - paths = group_overview_nav_link_paths
+ = nav_link(path: paths, unless: -> { current_path?('groups/contribution_analytics#show') }, html_options: { class: 'home' }) do
+ = link_to activity_group_path(@group), class: 'has-sub-items', data: { qa_selector: 'group_information_link' } do
+ .nav-icon-container
+ = sprite_icon('group')
+ %span.nav-item-name
+ = group_information_title(@group)
+
+ %ul.sidebar-sub-level-items{ data: { qa_selector: 'group_information_submenu'} }
+ = nav_link(path: paths, html_options: { class: "fly-out-top-item" } ) do
+ = link_to activity_group_path(@group) do
+ %strong.fly-out-top-item-name
+ = group_information_title(@group)
+ %li.divider.fly-out-top-item
+
+ - if group_sidebar_link?(:activity)
+ = nav_link(path: 'groups#activity') do
+ = link_to activity_group_path(@group), title: _('Activity') do
+ %span
+ = _('Activity')
+
+ - if group_sidebar_link?(:labels)
+ = nav_link(path: 'labels#index') do
+ = link_to group_labels_path(@group), title: _('Labels') do
+ %span
+ = _('Labels')
+
+ - 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)
+ = nav_link(path: group_issues_sub_menu_items, unless: -> { current_path?('issues_analytics#show') }) do
+ = link_to issues_group_path(@group), data: { qa_selector: 'group_issues_item' }, class: 'has-sub-items' do
+ .nav-icon-container
+ = sprite_icon('issues')
+ %span.nav-item-name
+ = _('Issues')
+ %span.badge.badge-pill.count= issues_count
+
+ %ul.sidebar-sub-level-items{ data: { qa_selector: 'group_issues_sidebar_submenu'} }
+ = 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')
+ %span.badge.badge-pill.count.issue_counter.fly-out-badge= issues_count
+
+ %li.divider.fly-out-top-item
+ = nav_link(path: 'groups#issues', html_options: { class: 'home' }) do
+ = link_to issues_group_path(@group), title: _('List') do
+ %span
+ = _('List')
+
+ - if group_sidebar_link?(:boards)
+ = nav_link(path: ['boards#index', 'boards#show']) do
+ = link_to group_boards_path(@group), title: boards_link_text, data: { qa_selector: 'group_issue_boards_link' } do
+ %span
+ = boards_link_text
+
+ - if group_sidebar_link?(:milestones)
+ = nav_link(path: 'milestones#index') do
+ = link_to group_milestones_path(@group), title: _('Milestones'), data: { qa_selector: 'group_milestones_link' } do
+ %span
+ = _('Milestones')
+
+ = render_if_exists 'layouts/nav/sidebar/group_iterations_link'
+
+- if group_sidebar_link?(:merge_requests)
+ = nav_link(path: 'groups#merge_requests') do
+ = link_to merge_requests_group_path(@group) do
+ .nav-icon-container
+ = sprite_icon('git-merge')
+ %span.nav-item-name
+ = _('Merge requests')
+ %span.badge.badge-pill.count= merge_requests_count
+ %ul.sidebar-sub-level-items.is-fly-out-only
+ = nav_link(path: 'groups#merge_requests', html_options: { class: "fly-out-top-item" } ) do
+ = link_to merge_requests_group_path(@group) do
+ %strong.fly-out-top-item-name
+ = _('Merge requests')
+ %span.badge.badge-pill.count.merge_counter.js-merge-counter.fly-out-badge= merge_requests_count
+
+= render_if_exists "layouts/nav/ee/security_link" # EE-specific
+
+= render_if_exists "layouts/nav/ee/push_rules_link" # EE-specific
+
+- if group_sidebar_link?(:kubernetes)
+ = nav_link(controller: [:clusters]) do
+ = link_to group_clusters_path(@group) do
+ .nav-icon-container
+ = sprite_icon('cloud-gear')
+ %span.nav-item-name
+ = _('Kubernetes')
+ %ul.sidebar-sub-level-items.is-fly-out-only
+ = nav_link(controller: [:clusters], html_options: { class: "fly-out-top-item" } ) do
+ = link_to group_clusters_path(@group), title: _('Kubernetes'), class: 'shortcuts-kubernetes' do
+ %strong.fly-out-top-item-name
+ = _('Kubernetes')
+
+= render 'groups/sidebar/packages'
+
+= render 'layouts/nav/sidebar/analytics_links', links: group_analytics_navbar_links(@group, current_user)
+
+- if group_sidebar_link?(:wiki)
+ = render 'layouts/nav/sidebar/wiki_link', wiki_url: @group.wiki.web_url
+
+- if group_sidebar_link?(:settings)
+ = nav_link(path: group_settings_nav_link_paths) do
+ = link_to edit_group_path(@group), class: 'has-sub-items' do
+ .nav-icon-container
+ = sprite_icon('settings')
+ %span.nav-item-name{ data: { qa_selector: 'group_settings' } }
+ = _('Settings')
+ %ul.sidebar-sub-level-items{ data: { testid: 'group-settings-menu', qa_selector: 'group_sidebar_submenu' } }
+ = nav_link(path: %w[groups#projects groups#edit badges#index ci_cd#show groups/applications#index], html_options: { class: "fly-out-top-item" } ) do
+ = link_to edit_group_path(@group) do
+ %strong.fly-out-top-item-name
+ = _('Settings')
+ %li.divider.fly-out-top-item
+ = nav_link(path: 'groups#edit') do
+ = link_to edit_group_path(@group), title: _('General'), data: { qa_selector: 'general_settings_link' } do
+ %span
+ = _('General')
+
+ = nav_link(controller: :integrations) do
+ = link_to group_settings_integrations_path(@group), title: _('Integrations') do
+ %span
+ = _('Integrations')
+
+ = nav_link(path: 'groups#projects') do
+ = link_to projects_group_path(@group), title: _('Projects') do
+ %span
+ = _('Projects')
+
+ = nav_link(controller: :repository) do
+ = link_to group_settings_repository_path(@group), title: _('Repository') do
+ %span
+ = _('Repository')
+
+ = nav_link(controller: [:ci_cd, 'groups/runners']) do
+ = link_to group_settings_ci_cd_path(@group), title: _('CI/CD') do
+ %span
+ = _('CI/CD')
+
+ = nav_link(controller: :applications) do
+ = link_to group_settings_applications_path(@group), title: _('Applications') do
+ %span
+ = _('Applications')
+
+ = render 'groups/sidebar/packages_settings'
+
+ = render_if_exists "groups/ee/settings_nav"
+
+= render_if_exists "groups/ee/administration_nav"
+
+= render 'shared/sidebar_toggle_button'
diff --git a/app/views/layouts/nav/sidebar/_profile.html.haml b/app/views/layouts/nav/sidebar/_profile.html.haml
index daafabdb799..4db1e532ba5 100644
--- a/app/views/layouts/nav/sidebar/_profile.html.haml
+++ b/app/views/layouts/nav/sidebar/_profile.html.haml
@@ -1,12 +1,9 @@
-- avatar_size = sidebar_refactor_disabled? ? 40 : 32
-- avatar_size_class = sidebar_refactor_disabled? ? 's40' : 's32'
-
%aside.nav-sidebar{ class: ("sidebar-collapsed-desktop" if collapsed_sidebar?), **sidebar_tracking_attributes_by_object(current_user), 'aria-label': _('User settings') }
.nav-sidebar-inner-scroll
.context-header
= link_to profile_path, title: _('Profile Settings') do
- %span{ class: ['avatar-container', 'settings-avatar', avatar_size_class] }
- = image_tag avatar_icon_for_user(current_user, avatar_size), class: ['avatar', 'avatar-tile', 'js-sidebar-user-avatar', avatar_size_class], alt: current_user.name, data: { testid: 'sidebar-user-avatar' }
+ %span{ class: ['avatar-container', 'settings-avatar', 's32'] }
+ = image_tag avatar_icon_for_user(current_user, 32), class: ['avatar', 'avatar-tile', 'js-sidebar-user-avatar', 's32'], alt: current_user.name, data: { testid: 'sidebar-user-avatar' }
%span.sidebar-context-title= _('User Settings')
%ul.sidebar-top-level-items
= nav_link(path: 'profiles#show', html_options: {class: 'home'}) do
diff --git a/app/views/layouts/welcome.html.haml b/app/views/layouts/welcome.html.haml
deleted file mode 100644
index 944f524d692..00000000000
--- a/app/views/layouts/welcome.html.haml
+++ /dev/null
@@ -1,8 +0,0 @@
-!!! 5
-%html.subscriptions-layout-html{ lang: 'en' }
- = render 'layouts/head'
- %body.ui-indigo.gl-display-flex.vh-100
- = render "layouts/header/logo_with_title"
- = render "layouts/broadcast"
- .container.gl-display-flex.gl-flex-grow-1
- = yield
diff --git a/app/views/notify/access_token_about_to_expire_email.html.haml b/app/views/notify/access_token_about_to_expire_email.html.haml
index ea27f72764f..fc318de4c42 100644
--- a/app/views/notify/access_token_about_to_expire_email.html.haml
+++ b/app/views/notify/access_token_about_to_expire_email.html.haml
@@ -8,4 +8,4 @@
%li= token
%p
- pat_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: @target_url }
- = html_escape(_('You can create a new one or check them in your %{pat_link_start}personal access tokens%{pat_link_end} settings')) % { pat_link_start: pat_link_start, pat_link_end: '</a>'.html_safe }
+ = html_escape(_('You can create a new one or check them in your %{pat_link_start}personal access tokens%{pat_link_end} settings.')) % { pat_link_start: pat_link_start, pat_link_end: '</a>'.html_safe }
diff --git a/app/views/notify/access_token_about_to_expire_email.text.erb b/app/views/notify/access_token_about_to_expire_email.text.erb
index dc9b1379e47..39608f0d6bd 100644
--- a/app/views/notify/access_token_about_to_expire_email.text.erb
+++ b/app/views/notify/access_token_about_to_expire_email.text.erb
@@ -6,4 +6,4 @@
- <%= token %>
<% end %>
-<%= _('You can create a new one or check them in your personal access tokens settings %{pat_link}') % { pat_link: @target_url } %>
+<%= _('You can create a new one or check them in your personal access tokens settings %{pat_link}.') % { pat_link: @target_url } %>
diff --git a/app/views/notify/access_token_expired_email.html.haml b/app/views/notify/access_token_expired_email.html.haml
index b26431cce91..1e7c07c2282 100644
--- a/app/views/notify/access_token_expired_email.html.haml
+++ b/app/views/notify/access_token_expired_email.html.haml
@@ -4,4 +4,4 @@
= _('One or more of your personal access tokens has expired.')
%p
- pat_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: @target_url }
- = html_escape(_('You can create a new one or check them in your %{pat_link_start}personal access tokens%{pat_link_end} settings')) % { pat_link_start: pat_link_start, pat_link_end: '</a>'.html_safe }
+ = html_escape(_('You can create a new one or check them in your %{pat_link_start}personal access tokens%{pat_link_end} settings.')) % { pat_link_start: pat_link_start, pat_link_end: '</a>'.html_safe }
diff --git a/app/views/notify/access_token_expired_email.text.erb b/app/views/notify/access_token_expired_email.text.erb
index d44f993d094..4dc67e85dc2 100644
--- a/app/views/notify/access_token_expired_email.text.erb
+++ b/app/views/notify/access_token_expired_email.text.erb
@@ -2,4 +2,4 @@
<%= _('One or more of your personal access tokens has expired.') %>
-<%= _('You can create a new one or check them in your personal access tokens settings %{pat_link}') % { pat_link: @target_url } %>
+<%= _('You can create a new one or check them in your personal access tokens settings %{pat_link}.') % { pat_link: @target_url } %>
diff --git a/app/views/notify/in_product_marketing_email.html.haml b/app/views/notify/in_product_marketing_email.html.haml
index 45b002757e3..6382718480f 100644
--- a/app/views/notify/in_product_marketing_email.html.haml
+++ b/app/views/notify/in_product_marketing_email.html.haml
@@ -3,7 +3,7 @@
%head
%meta{ content: "text/html; charset=utf-8", "http-equiv" => "Content-Type" }
%meta{ content: "width=device-width, initial-scale=1", name: "viewport" }
- %link{ href: "https://fonts.googleapis.com/css?family=Source+Sans+Pro:400,600", rel: "stylesheet", type: "text/css" }
+ %link{ href: "https://fonts.googleapis.com/css?family=Source+Sans+Pro:400,600", rel: "stylesheet", type: "text/css", data: { premailer: 'ignore' } }
%title= message.subject
:css
/* CLIENT-SPECIFIC STYLES */
diff --git a/app/views/notify/send_admin_notification.html.haml b/app/views/notify/send_admin_notification.html.haml
new file mode 100644
index 00000000000..f7f1528f332
--- /dev/null
+++ b/app/views/notify/send_admin_notification.html.haml
@@ -0,0 +1,7 @@
+= simple_format @body
+
+\----
+
+%p
+ Don't want to receive updates from GitLab administrators?
+ = link_to 'Unsubscribe', @unsubscribe_url
diff --git a/app/views/notify/send_admin_notification.text.haml b/app/views/notify/send_admin_notification.text.haml
new file mode 100644
index 00000000000..bfacbd3dcb2
--- /dev/null
+++ b/app/views/notify/send_admin_notification.text.haml
@@ -0,0 +1,6 @@
+= h @body
+
+\-----
+
+Don't want to receive updates from GitLab administrators?
+Unsubscribe here: #{@unsubscribe_url}
diff --git a/app/views/notify/send_unsubscribed_notification.html.haml b/app/views/notify/send_unsubscribed_notification.html.haml
new file mode 100644
index 00000000000..9f68feeaa31
--- /dev/null
+++ b/app/views/notify/send_unsubscribed_notification.html.haml
@@ -0,0 +1,2 @@
+%p
+ You have been unsubscribed from receiving GitLab administrator notifications.
diff --git a/app/views/notify/send_unsubscribed_notification.text.haml b/app/views/notify/send_unsubscribed_notification.text.haml
new file mode 100644
index 00000000000..5edc1ddcdae
--- /dev/null
+++ b/app/views/notify/send_unsubscribed_notification.text.haml
@@ -0,0 +1 @@
+You have been unsubscribed from receiving GitLab administrator notifications.
diff --git a/app/views/notify/user_deactivated_email.html.haml b/app/views/notify/user_deactivated_email.html.haml
new file mode 100644
index 00000000000..a9262cab219
--- /dev/null
+++ b/app/views/notify/user_deactivated_email.html.haml
@@ -0,0 +1,17 @@
+= email_default_heading(_('Hello %{name},') % { name: @name })
+%p
+ = _('Your account has been deactivated. You will not be able to: ')
+%ul
+ %li
+ = _('Access Git repositories or the API.')
+ %li
+ = _('Receive any notifications from GitLab.')
+ %li
+ = _('Use slash commands.')
+%p
+ - gitlab_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: root_url }
+ - link_end = '</a>'.html_safe
+ = _('To reactivate your account, %{gitlab_link_start}sign in to GitLab.%{link_end}').html_safe % { gitlab_link_start: gitlab_link_start, link_end: link_end}
+
+%p
+ = _('Please contact your GitLab administrator if you think this is an error.')
diff --git a/app/views/notify/user_deactivated_email.text.erb b/app/views/notify/user_deactivated_email.text.erb
new file mode 100644
index 00000000000..9e7d00f4ad1
--- /dev/null
+++ b/app/views/notify/user_deactivated_email.text.erb
@@ -0,0 +1,10 @@
+<%= _('Hello %{name},') % { name: @name } %>
+
+<%= _('Your account has been deactivated. You will not be able to: ') %>
+ - <%= _('Access Git repositories or the API.') %>
+ - <%= _('Receive any notifications from GitLab.') %>
+ - <%= _('Use slash commands.') %>
+
+<%= _('To reactivate your account, sign in to GitLab at %{gitlab_url}.') % { gitlab_url: root_url } %>
+
+<%= _('Please contact your GitLab administrator if you think this is an error.') %>
diff --git a/app/views/profiles/accounts/show.html.haml b/app/views/profiles/accounts/show.html.haml
index c4de47f276c..809dc3320ff 100644
--- a/app/views/profiles/accounts/show.html.haml
+++ b/app/views/profiles/accounts/show.html.haml
@@ -2,16 +2,20 @@
- @content_class = "limit-container-width" unless fluid_layout
- if current_user.ldap_user?
- .gl-alert.gl-alert-info.gl-my-5
- = sprite_icon('information-o', size: 16, css_class: 'gl-icon gl-alert-icon gl-alert-icon-no-title')
+ = render 'shared/global_alert',
+ variant: :info,
+ alert_class: 'gl-my-5',
+ is_contained: true,
+ dismissible: false do
.gl-alert-body
= s_('Profiles|Some options are unavailable for LDAP accounts')
- if params[:two_factor_auth_enabled_successfully]
- .gl-alert.gl-alert-success.gl-my-5{ role: 'alert' }
- = sprite_icon('check-circle', size: 16, css_class: 'gl-alert-icon gl-alert-icon-no-title')
- %button.gl-alert-dismiss.js-close-2fa-enabled-success-alert{ type: 'button', aria: { label: _('Close') } }
- = sprite_icon('close', size: 16)
+ = render 'shared/global_alert',
+ variant: :success,
+ alert_class: 'gl-my-5',
+ is_contained: true,
+ close_button_class: 'js-close-2fa-enabled-success-alert' do
.gl-alert-body
= html_escape(_('You have set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}.')) % { anchorOpen: '<a href="%{href}">'.html_safe % { href: help_page_path('user/profile/account/two_factor_authentication', anchor: 'generate-new-recovery-codes-using-ssh') }, anchorClose: '</a>'.html_safe }
diff --git a/app/views/profiles/keys/index.html.haml b/app/views/profiles/keys/index.html.haml
index 69b8d2ddafe..584bd44e386 100644
--- a/app/views/profiles/keys/index.html.haml
+++ b/app/views/profiles/keys/index.html.haml
@@ -11,8 +11,8 @@
%h5.gl-mt-0
= _('Add an SSH key')
%p.profile-settings-content
- - generate_link_url = help_page_path("ssh/README", anchor: 'generate-an-ssh-key-pair')
- - existing_link_url = help_page_path("ssh/README", anchor: 'see-if-you-have-an-existing-ssh-key-pair')
+ - generate_link_url = help_page_path("ssh/index", anchor: 'generate-an-ssh-key-pair')
+ - existing_link_url = help_page_path("ssh/index", anchor: 'see-if-you-have-an-existing-ssh-key-pair')
- generate_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: generate_link_url }
- existing_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: existing_link_url }
= _('To add an SSH key you need to %{generate_link_start}generate one%{link_end} or use an %{existing_link_start}existing key%{link_end}.').html_safe % { generate_link_start: generate_link_start, existing_link_start: existing_link_start, link_end: '</a>'.html_safe }
diff --git a/app/views/profiles/personal_access_tokens/index.html.haml b/app/views/profiles/personal_access_tokens/index.html.haml
index 3661b93e33c..7c1f28345fd 100644
--- a/app/views/profiles/personal_access_tokens/index.html.haml
+++ b/app/views/profiles/personal_access_tokens/index.html.haml
@@ -24,7 +24,8 @@
type: type,
path: profile_personal_access_tokens_path,
token: @personal_access_token,
- scopes: @scopes
+ scopes: @scopes,
+ help_path: help_page_path('user/profile/personal_access_tokens.md', anchor: 'personal-access-token-scopes')
= render 'shared/access_tokens/table',
type: type,
diff --git a/app/views/profiles/preferences/show.html.haml b/app/views/profiles/preferences/show.html.haml
index 0adad6b64a0..e52a345bd86 100644
--- a/app/views/profiles/preferences/show.html.haml
+++ b/app/views/profiles/preferences/show.html.haml
@@ -128,29 +128,27 @@
= f.label :first_day_of_week, class: 'label-bold' do
= _('First day of the week')
= f.select :first_day_of_week, first_day_of_week_choices_with_default, {}, class: 'select2'
- - if Feature.enabled?(:user_time_settings)
- .col-sm-12
- %hr
- .col-lg-4.profile-settings-sidebar
- %h4.gl-mt-0= s_('Preferences|Time preferences')
- %p= s_('Preferences|These settings will update how dates and times are displayed for you.')
- .col-lg-8
- .form-group
- %h5= s_('Preferences|Time format')
- .checkbox-icon-inline-wrapper
- - time_format_label = capture do
- = s_('Preferences|Display time in 24-hour format')
- = f.check_box :time_format_in_24h
- = f.label :time_format_in_24h do
- = time_format_label
- %h5= s_('Preferences|Time display')
- .checkbox-icon-inline-wrapper
- - time_display_label = capture do
- = s_('Preferences|Use relative times')
- = f.check_box :time_display_relative
- = f.label :time_display_relative do
- = time_display_label
- .form-text.text-muted
- = s_('Preferences|For example: 30 mins ago.')
+ .col-sm-12
+ %hr
+ .row.js-preferences-form.js-search-settings-section
+ .col-lg-4.profile-settings-sidebar#time-preferences
+ %h4.gl-mt-0
+ = s_('Preferences|Time preferences')
+ %p
+ = s_('Preferences|Configure how dates and times display for you.')
+ = succeed '.' do
+ = link_to _('Learn more'), help_page_path('user/profile/preferences', anchor: 'time-preferences'), target: '_blank'
+ .col-lg-8
+ .form-group.form-check
+ = f.check_box :time_display_relative, class: 'form-check-input'
+ = f.label :time_display_relative, class: 'form-check-label' do
+ = s_('Preferences|Use relative times')
+ .form-text.text-muted
+ = s_('Preferences|For example: 30 minutes ago.')
+ - if Feature.enabled?(:user_time_settings)
+ .form-group.form-check
+ = f.check_box :time_format_in_24h, class: 'form-check-input'
+ = f.label :time_format_in_24h, class: 'form-check-label' do
+ = s_('Preferences|Display time in 24-hour format')
#js-profile-preferences-app{ data: data_attributes }
diff --git a/app/views/profiles/show.html.haml b/app/views/profiles/show.html.haml
index 411954aed6a..0328fa5c282 100644
--- a/app/views/profiles/show.html.haml
+++ b/app/views/profiles/show.html.haml
@@ -72,9 +72,8 @@
.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
+ .col-lg-12
+ %hr
.row.user-time-preferences.js-search-settings-section
.col-lg-4.profile-settings-sidebar
%h4.gl-mt-0= s_("Profiles|Time settings")
diff --git a/app/views/profiles/two_factor_auths/show.html.haml b/app/views/profiles/two_factor_auths/show.html.haml
index 3cd571c23d3..927b6d4edef 100644
--- a/app/views/profiles/two_factor_auths/show.html.haml
+++ b/app/views/profiles/two_factor_auths/show.html.haml
@@ -1,5 +1,6 @@
+- breadcrumb_title _('Two-Factor Authentication')
- page_title _('Two-Factor Authentication'), _('Account')
-- add_to_breadcrumbs(_('Two-Factor Authentication'), profile_account_path)
+- add_to_breadcrumbs _('Account'), profile_account_path
- @content_class = "limit-container-width" unless fluid_layout
- webauthn_enabled = Feature.enabled?(:webauthn)
diff --git a/app/views/projects/_flash_messages.html.haml b/app/views/projects/_flash_messages.html.haml
index f9222387e97..7395495b537 100644
--- a/app/views/projects/_flash_messages.html.haml
+++ b/app/views/projects/_flash_messages.html.haml
@@ -9,3 +9,4 @@
= render 'shared/auto_devops_implicitly_enabled_banner', project: project
= render_if_exists 'projects/above_size_limit_warning', project: project
= render_if_exists 'shared/shared_runners_minutes_limit', project: project, classes: [container_class, ("limit-container-width" unless fluid_layout)]
+ = render_if_exists 'projects/terraform_banner', project: project
diff --git a/app/views/projects/_home_panel.html.haml b/app/views/projects/_home_panel.html.haml
index 26291c0358e..86172499118 100644
--- a/app/views/projects/_home_panel.html.haml
+++ b/app/views/projects/_home_panel.html.haml
@@ -47,6 +47,10 @@
= 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
+ - if current_user.admin?
+ = link_to [:admin, @project], class: 'btn gl-button btn-icon gl-align-self-start gl-py-2! gl-mr-3', title: s_('View project in admin area'),
+ data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do
+ = sprite_icon('admin')
.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 } }
diff --git a/app/views/projects/_import_project_pane.html.haml b/app/views/projects/_import_project_pane.html.haml
index e6ded3ad912..2055f1c7f60 100644
--- a/app/views/projects/_import_project_pane.html.haml
+++ b/app/views/projects/_import_project_pane.html.haml
@@ -7,7 +7,7 @@
= _("Import project from")
.import-buttons
- if gitlab_project_import_enabled?
- .import_gitlab_project.has-tooltip{ data: { container: 'body' } }
+ .import_gitlab_project.has-tooltip{ data: { container: 'body', qa_selector: 'gitlab_import_button' } }
= link_to new_import_gitlab_project_path, class: 'gl-button btn-default btn btn_import_gitlab_project', **tracking_attrs(track_label, 'click_button', 'gitlab_export') do
.gl-button-icon
= sprite_icon('tanuki')
diff --git a/app/views/projects/_invite_members.html.haml b/app/views/projects/_invite_members_empty_project.html.haml
index ab630d34501..ee2215b0fbb 100644
--- a/app/views/projects/_invite_members.html.haml
+++ b/app/views/projects/_invite_members_empty_project.html.haml
@@ -6,7 +6,8 @@
.js-invite-members-trigger{ data: { variant: 'confirm',
classes: 'gl-mb-8 gl-xs-w-full',
display_text: s_('InviteMember|Invite members'),
+ trigger_source: 'project-empty-page',
event: 'click_button',
label: 'invite_members_empty_project' } }
-= render 'shared/issuable/invite_members_trigger', project: @project
+= render 'projects/invite_members_modal', project: @project
diff --git a/app/views/projects/_invite_members_modal.html.haml b/app/views/projects/_invite_members_modal.html.haml
index 00f823b9016..5dd6ec0addf 100644
--- a/app/views/projects/_invite_members_modal.html.haml
+++ b/app/views/projects/_invite_members_modal.html.haml
@@ -1,7 +1,8 @@
-- if can_invite_members_for_project?(project)
- .js-invite-members-modal{ data: { id: project.id,
- name: project.name,
- is_project: 'true',
- access_levels: ProjectMember.access_level_roles.to_json,
- default_access_level: Gitlab::Access::GUEST,
- help_link: help_page_url('user/permissions') } }
+- return unless can_import_members?
+
+.js-invite-members-modal{ data: { id: project.id,
+ name: project.name,
+ is_project: 'true',
+ access_levels: ProjectMember.access_level_roles.to_json,
+ default_access_level: Gitlab::Access::GUEST,
+ help_link: help_page_url('user/permissions') } }
diff --git a/app/views/projects/_merge_request_merge_checks_settings.html.haml b/app/views/projects/_merge_request_merge_checks_settings.html.haml
index 694d192d079..fbc58283cbf 100644
--- a/app/views/projects/_merge_request_merge_checks_settings.html.haml
+++ b/app/views/projects/_merge_request_merge_checks_settings.html.haml
@@ -8,7 +8,7 @@
= form.label :only_allow_merge_if_pipeline_succeeds, class: 'form-check-label' do
= s_('ProjectSettings|Pipelines must succeed')
.text-secondary
- - configuring_pipelines_for_merge_requests_help_link_url = help_page_path('ci/merge_request_pipelines/index.md', anchor: 'configuring-pipelines-for-merge-requests')
+ - configuring_pipelines_for_merge_requests_help_link_url = help_page_path('ci/pipelines/merge_request_pipelines.md', anchor: 'configure-pipelines-for-merge-requests')
- configuring_pipelines_for_merge_requests_help_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: configuring_pipelines_for_merge_requests_help_link_url }
= s_('ProjectSettings|To enable this feature, configure pipelines. %{link_start}How to configure pipelines for merge requests?%{link_end}').html_safe % { link_start: configuring_pipelines_for_merge_requests_help_link_start, link_end: '</a>'.html_safe }
.form-check.mb-2
diff --git a/app/views/projects/_new_project_fields.html.haml b/app/views/projects/_new_project_fields.html.haml
index 66fc313213a..55696337bc1 100644
--- a/app/views/projects/_new_project_fields.html.haml
+++ b/app/views/projects/_new_project_fields.html.haml
@@ -23,7 +23,7 @@
display_path: true,
extra_group: namespace_id),
{},
- { class: 'select2 js-select-namespace qa-project-namespace-select block-truncated', data: { track_label: "#{track_label}", track_event: "activate_form_input", track_property: "project_path", track_value: "" }})
+ { class: 'select2 js-select-namespace qa-project-namespace-select block-truncated', data: { track_label: "#{track_label}", track_event: "activate_form_input", track_property: "project_path", track_value: "", qa_selector: "select_namespace_dropdown" }})
- else
.input-group-prepend.static-namespace.flex-shrink-0.has-tooltip{ title: user_url(current_user.username) + '/' }
diff --git a/app/views/projects/_remove.html.haml b/app/views/projects/_remove.html.haml
index e991a9b0ec7..cb0ec9f19c8 100644
--- a/app/views/projects/_remove.html.haml
+++ b/app/views/projects/_remove.html.haml
@@ -3,7 +3,7 @@
.sub-section
%h4.danger-title= _('Delete project')
%p
- %strong= _('Deleting the project will delete its repository and all related resources including issues, merge requests, etc.')
+ %strong= _('Deleting the project will delete its repository and all related resources, including issues and merge requests.')
= link_to _('Learn more.'), help_page_path('user/project/settings/index', anchor: 'removing-a-fork-relationship'), target: '_blank', rel: 'noopener noreferrer'
%p
%strong= _('Deleted projects cannot be restored!')
diff --git a/app/views/projects/_terraform_banner.html.haml b/app/views/projects/_terraform_banner.html.haml
new file mode 100644
index 00000000000..a30c4a2d624
--- /dev/null
+++ b/app/views/projects/_terraform_banner.html.haml
@@ -0,0 +1,5 @@
+- @content_class = "container-limited limit-container-width" unless fluid_layout
+
+- if show_terraform_banner?(project)
+ .container-fluid{ class: @content_class }
+ .js-terraform-notification{ data: { project_id: project.id } }
diff --git a/app/views/projects/blame/show.html.haml b/app/views/projects/blame/show.html.haml
index cba63d5e6d6..8fe9c9e5c52 100644
--- a/app/views/projects/blame/show.html.haml
+++ b/app/views/projects/blame/show.html.haml
@@ -1,5 +1,4 @@
- page_title _("Blame"), @blob.path, @ref
-- link_icon = sprite_icon("link", size: 12)
#blob-content-holder.tree-holder
= render "projects/blob/breadcrumb", blob: @blob, blame: true
@@ -48,8 +47,8 @@
%td.line-numbers
- (current_line...(current_line + line_count)).each do |i|
%a.diff-line-num.gl-justify-content-end{ href: "#L#{i}", id: "L#{i}", 'data-line-number' => i, class: "gl-display-flex!" }
- = link_icon
- = i
+ .file-line-num
+ = i
\
%td.lines
diff --git a/app/views/projects/blob/_pipeline_tour_success.html.haml b/app/views/projects/blob/_pipeline_tour_success.html.haml
index ef1fe25ba1b..8f1c2f93162 100644
--- a/app/views/projects/blob/_pipeline_tour_success.html.haml
+++ b/app/views/projects/blob/_pipeline_tour_success.html.haml
@@ -1,6 +1,6 @@
.js-success-pipeline-modal{ data: { 'commit-cookie': suggest_pipeline_commit_cookie_name,
'go-to-pipelines-path': project_pipelines_path(@project),
'project-merge-requests-path': project_merge_requests_path(@project),
- 'example-link': help_page_path('ci/examples/README.md', anchor: 'gitlab-cicd-examples'),
+ 'example-link': help_page_path('ci/examples/index.md', anchor: 'gitlab-cicd-examples'),
'code-quality-link': help_page_path('user/project/merge_requests/code_quality'),
'human-access': @project.team.human_max_access(current_user&.id) } }
diff --git a/app/views/projects/blob/viewers/_csv.html.haml b/app/views/projects/blob/viewers/_csv.html.haml
new file mode 100644
index 00000000000..3a58bc9902c
--- /dev/null
+++ b/app/views/projects/blob/viewers/_csv.html.haml
@@ -0,0 +1 @@
+.file-content#js-csv-viewer{ data: { data: viewer.blob.data } }
diff --git a/app/views/projects/branches/new.html.haml b/app/views/projects/branches/new.html.haml
index 6cb2c435a30..6de50d48721 100644
--- a/app/views/projects/branches/new.html.haml
+++ b/app/views/projects/branches/new.html.haml
@@ -2,10 +2,10 @@
- default_ref = params[:ref] || @project.default_branch
- if @error
- .gl-alert.gl-alert-danger
- = sprite_icon('error', size: 16, css_class: 'gl-icon gl-alert-icon gl-alert-icon-no-title')
- %button.js-close.gl-alert-dismiss{ type: 'button', 'aria-label' => _('Dismiss') }
- = sprite_icon('close', size: 16, css_class: 'gl-icon')
+ = render 'shared/global_alert',
+ variant: :danger,
+ close_button_class: 'js-close',
+ is_contained: true do
.gl-alert-body
= @error
%h3.page-title
diff --git a/app/views/projects/cycle_analytics/show.html.haml b/app/views/projects/cycle_analytics/show.html.haml
index c1f6cfc40c3..3c9762e200a 100644
--- a/app/views/projects/cycle_analytics/show.html.haml
+++ b/app/views/projects/cycle_analytics/show.html.haml
@@ -1,6 +1,6 @@
- page_title _("Value Stream Analytics")
- add_page_specific_style 'page_bundles/cycle_analytics'
- svgs = { empty_state_svg_path: image_path("illustrations/analytics/cycle-analytics-empty-chart.svg"), no_data_svg_path: image_path("illustrations/analytics/cycle-analytics-empty-chart.svg"), no_access_svg_path: image_path("illustrations/analytics/no-access.svg") }
-- initial_data = { request_path: project_cycle_analytics_path(@project), full_path: @project.full_path }.merge!(svgs)
+- initial_data = { project_id: @project.id, group_path: @project.group&.path, request_path: project_cycle_analytics_path(@project), full_path: @project.full_path }.merge!(svgs)
#js-cycle-analytics{ data: initial_data }
diff --git a/app/views/projects/default_branch/_show.html.haml b/app/views/projects/default_branch/_show.html.haml
index 9e9fc08dac0..68ca318e88c 100644
--- a/app/views/projects/default_branch/_show.html.haml
+++ b/app/views/projects/default_branch/_show.html.haml
@@ -17,7 +17,7 @@
- else
.form-group
= f.label :default_branch, "Default branch", class: 'label-bold'
- = f.select(:default_branch, @project.repository.branch_names, {}, {class: 'select2 select-wide'})
+ = f.select(:default_branch, @project.repository.branch_names, {}, {class: 'select2 select-wide', data: { qa_selector: 'default_branch_dropdown' }})
.form-group
.form-check
@@ -28,4 +28,4 @@
= _("When merge requests and commits in the default branch close, any issues they reference also close.")
= link_to sprite_icon('question-o'), help_page_path('user/project/issues/managing_issues.md', anchor: 'disabling-automatic-issue-closing'), target: '_blank'
- = f.submit _('Save changes'), class: "gl-button btn btn-confirm"
+ = f.submit _('Save changes'), class: "gl-button btn btn-confirm", data: { qa_selector: 'save_changes_button' }
diff --git a/app/views/projects/diffs/_warning.html.haml b/app/views/projects/diffs/_warning.html.haml
index 30b0631b465..1d9b1b13d5c 100644
--- a/app/views/projects/diffs/_warning.html.haml
+++ b/app/views/projects/diffs/_warning.html.haml
@@ -1,9 +1,8 @@
-.gl-alert.gl-alert-warning.gl-mb-5
- %button.js-close.gl-alert-dismiss{ type: 'button', 'aria-label' => _('Dismiss') }
- = sprite_icon('close', size: 16, css_class: 'gl-icon')
- = sprite_icon('warning', size: 16, css_class: 'gl-icon gl-alert-icon')
- %h4.gl-alert-title
- = _("Too many changes to show.")
+= render 'shared/global_alert',
+ title: _('Too many changes to show.'),
+ variant: :warning,
+ is_contained: true,
+ alert_class: 'gl-mb-5' do
.gl-alert-body
= html_escape(_("To preserve performance only %{strong_open}%{display_size} of %{real_size}%{strong_close} files are displayed.")) % { display_size: diff_files.size, real_size: diff_files.real_size, strong_open: '<strong>'.html_safe, strong_close: '</strong>'.html_safe }
.gl-alert-actions
diff --git a/app/views/projects/empty.html.haml b/app/views/projects/empty.html.haml
index 027b81d6c68..0fda74a3be5 100644
--- a/app/views/projects/empty.html.haml
+++ b/app/views/projects/empty.html.haml
@@ -7,7 +7,7 @@
= render "home_panel"
= render "archived_notice", project: @project
-= render "invite_members" if can_import_members?
+= render 'invite_members_empty_project' if can_import_members?
%h4.gl-mt-0.gl-mb-3
= _('The repository for this project is empty')
diff --git a/app/views/projects/feature_flags/edit.html.haml b/app/views/projects/feature_flags/edit.html.haml
index 1549f5cf6d6..f71c97c2a8f 100644
--- a/app/views/projects/feature_flags/edit.html.haml
+++ b/app/views/projects/feature_flags/edit.html.haml
@@ -8,9 +8,6 @@
project_id: @project.id,
feature_flags_path: project_feature_flags_path(@project),
environments_endpoint: search_project_environments_path(@project, format: :json),
- user_callouts_path: user_callouts_path,
- 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/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/forks/error.html.haml b/app/views/projects/forks/error.html.haml
index 0c15796b667..30e2e9f19d9 100644
--- a/app/views/projects/forks/error.html.haml
+++ b/app/views/projects/forks/error.html.haml
@@ -1,10 +1,11 @@
- page_title _("Fork project")
- if @forked_project && !@forked_project.saved?
- .gl-alert.gl-alert-danger.gl-mt-5
- = sprite_icon('error', size: 16, css_class: 'gl-icon gl-alert-icon')
- %h4.gl-alert-title
- = sprite_icon('fork')
- = _("Fork Error!")
+ = render 'shared/global_alert',
+ title: _('Fork Error!'),
+ variant: :danger,
+ alert_class: 'gl-mt-5',
+ is_contained: true,
+ dismissible: false do
.gl-alert-body
%p
= _("You tried to fork %{link_to_the_project} but it failed for the following reason:").html_safe % { link_to_the_project: link_to_project(@project) }
@@ -14,9 +15,9 @@
&ndash;
- error = @forked_project.errors.full_messages.first
- if error.include?("already been taken")
- = _("Name has already been taken")
+ = _('Name has already been taken')
- else
= error
.gl-alert-actions
- = link_to _("Try to fork again"), new_project_fork_path(@project), title: _("Fork"), class: "btn gl-alert-action btn-info btn-md gl-button"
+ = link_to _('Try to fork again'), new_project_fork_path(@project), title: _("Fork"), class: "btn gl-alert-action btn-info btn-md gl-button"
diff --git a/app/views/projects/forks/new.html.haml b/app/views/projects/forks/new.html.haml
index 0716eda79a8..8848fbae9cb 100644
--- a/app/views/projects/forks/new.html.haml
+++ b/app/views/projects/forks/new.html.haml
@@ -1,6 +1,6 @@
- page_title s_("ForkProject|Fork project")
-- if Feature.enabled?(:fork_project_form)
+- if Feature.enabled?(:fork_project_form, @project, default_enabled: :yaml)
#fork-groups-mount-element{ data: { fork_illustration: image_path('illustrations/project-create-new-sm.svg'),
endpoint: new_project_fork_path(@project, format: :json),
new_group_path: new_group_path,
diff --git a/app/views/projects/import/jira/show.html.haml b/app/views/projects/import/jira/show.html.haml
index 3c0664e4d5f..29296ce23c9 100644
--- a/app/views/projects/import/jira/show.html.haml
+++ b/app/views/projects/import/jira/show.html.haml
@@ -1,7 +1,7 @@
.js-jira-import-root{ data: { project_path: @project.full_path,
issues_path: project_issues_path(@project),
jira_integration_path: edit_project_service_path(@project, :jira),
- is_jira_configured: @project.jira_service&.active? && @project.jira_service&.valid_connection?.to_s,
+ is_jira_configured: @project.jira_integration&.configured?.to_s,
in_progress_illustration: image_path('illustrations/export-import.svg'),
project_id: @project.id,
setup_illustration: image_path('illustrations/manual_action.svg') } }
diff --git a/app/views/projects/issues/_alert_moved_from_service_desk.html.haml b/app/views/projects/issues/_alert_moved_from_service_desk.html.haml
index 9b142b08574..662270fb8e1 100644
--- a/app/views/projects/issues/_alert_moved_from_service_desk.html.haml
+++ b/app/views/projects/issues/_alert_moved_from_service_desk.html.haml
@@ -2,9 +2,10 @@
- service_desk_link_url = help_page_path('user/project/service_desk')
- service_desk_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: service_desk_link_url }
-.hide.gl-alert.gl-alert-warning.js-alert-moved-from-service-desk-warning.gl-mt-5{ role: 'alert' }
- = sprite_icon('warning', css_class: 'gl-icon gl-alert-icon gl-alert-icon-no-title')
- %button.js-close.gl-alert-dismiss{ type: 'button', 'aria-label' => _('Dismiss') }
- = sprite_icon('close', css_class: 'gl-icon')
+= render 'shared/global_alert',
+ variant: :warning,
+ is_contained: true,
+ close_button_class: 'js-close',
+ alert_class: 'hide js-alert-moved-from-service-desk-warning gl-mt-5' do
.gl-alert-body.gl-mr-3
= s_('This project does not have %{service_desk_link_start}Service Desk%{service_desk_link_end} enabled, so the user who created the issue will no longer receive email notifications about new activity.').html_safe % { service_desk_link_start: service_desk_link_start, service_desk_link_end: '</a>'.html_safe }
diff --git a/app/views/projects/issues/index.html.haml b/app/views/projects/issues/index.html.haml
index 3e8442eee86..ecf10cd4821 100644
--- a/app/views/projects/issues/index.html.haml
+++ b/app/views/projects/issues/index.html.haml
@@ -9,7 +9,7 @@
= auto_discovery_link_tag(:atom, safe_params.merge(rss_url_options).to_h, title: "#{@project.name} issues")
.js-jira-issues-import-status{ data: { can_edit: can?(current_user, :admin_project, @project).to_s,
- is_jira_configured: @project.jira_service.present?.to_s,
+ is_jira_configured: @project.jira_integration.present?.to_s,
issues_path: project_issues_path(@project),
project_path: @project.full_path } }
diff --git a/app/views/projects/issues/show.html.haml b/app/views/projects/issues/show.html.haml
index a465f59c559..6c6f98e0b20 100644
--- a/app/views/projects/issues/show.html.haml
+++ b/app/views/projects/issues/show.html.haml
@@ -4,4 +4,4 @@
- page_title "#{@issue.title} (#{@issue.to_reference})", _("Issues")
= render 'projects/issuable/show', issuable: @issue, api_awards_path: award_emoji_issue_api_path(@issue)
-= render 'shared/issuable/invite_members_trigger', project: @project
+= render 'projects/invite_members_modal', project: @project
diff --git a/app/views/projects/mattermosts/_no_teams.html.haml b/app/views/projects/mattermosts/_no_teams.html.haml
index f375222e311..adef11f315a 100644
--- a/app/views/projects/mattermosts/_no_teams.html.haml
+++ b/app/views/projects/mattermosts/_no_teams.html.haml
@@ -15,4 +15,4 @@
and try again.
%hr
.clearfix
- = link_to 'Go back', edit_project_service_path(@project, @service), class: 'gl-button btn btn-lg float-right'
+ = link_to 'Go back', edit_project_service_path(@project, @integration), class: 'gl-button btn btn-lg float-right'
diff --git a/app/views/projects/mattermosts/_team_selection.html.haml b/app/views/projects/mattermosts/_team_selection.html.haml
index ea04a55a77c..4109fdfc13b 100644
--- a/app/views/projects/mattermosts/_team_selection.html.haml
+++ b/app/views/projects/mattermosts/_team_selection.html.haml
@@ -2,7 +2,7 @@
This service will be installed on the Mattermost instance at
%strong= link_to Gitlab.config.mattermost.host, Gitlab.config.mattermost.host
%hr
-= form_for(:mattermost, method: :post, url: project_mattermost_path(@project), html: { class: 'js-requires-input'} ) do |f|
+= form_for(:mattermost, method: :post, url: project_mattermost_path(@project), html: { class: 'js-requires-input' }) do |f|
%h4 Team
%p
= @teams.one? ? 'The team' : 'Select the team'
@@ -42,5 +42,5 @@
%hr
.clearfix
.float-right
- = link_to 'Cancel', edit_project_service_path(@project, @service), class: 'gl-button btn btn-lg'
+ = link_to 'Cancel', edit_project_service_path(@project, @integration), class: 'gl-button btn btn-lg'
= f.submit 'Install', class: 'gl-button btn btn-success btn-lg'
diff --git a/app/views/projects/merge_requests/show.html.haml b/app/views/projects/merge_requests/show.html.haml
index 691ce8dc5fc..c4ee522bfa7 100644
--- a/app/views/projects/merge_requests/show.html.haml
+++ b/app/views/projects/merge_requests/show.html.haml
@@ -96,5 +96,5 @@
#js-review-bar
-= render 'shared/issuable/invite_members_trigger', project: @project
+= render 'projects/invite_members_modal', project: @project
diff --git a/app/views/projects/milestones/_form.html.haml b/app/views/projects/milestones/_form.html.haml
index dfb9defb91c..5f2057df4aa 100644
--- a/app/views/projects/milestones/_form.html.haml
+++ b/app/views/projects/milestones/_form.html.haml
@@ -1,27 +1,25 @@
= form_for [@project, @milestone],
html: { class: 'milestone-form common-note-form js-quick-submit js-requires-input' } do |f|
= form_errors(@milestone)
- .row
- .col-md-6
- .form-group.row
- .col-form-label.col-sm-2
- = f.label :title, _('Title')
- .col-sm-10
- = 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',
- supports_autocomplete: true,
- placeholder: _('Write milestone description...')
- = render 'shared/notes/hints'
- .clearfix
- .error-alert
- = render 'shared/milestones/form_dates', f: f
+ .form-group.row
+ .col-form-label.col-sm-2
+ = f.label :title, _('Title')
+ .col-sm-10
+ = f.text_field :title, maxlength: 255, class: 'form-control gl-form-input', data: { qa_selector: 'milestone_title_field' }, required: true, autofocus: true
+ = render 'shared/milestones/form_dates', f: f
+ .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',
+ supports_autocomplete: true,
+ placeholder: _('Write milestone description...')
+ = render 'shared/notes/hints'
+ .clearfix
+ .error-alert
.form-actions
- if @milestone.new_record?
diff --git a/app/views/projects/milestones/show.html.haml b/app/views/projects/milestones/show.html.haml
index 99fe64723d9..dbde3346b81 100644
--- a/app/views/projects/milestones/show.html.haml
+++ b/app/views/projects/milestones/show.html.haml
@@ -12,19 +12,17 @@
= render_if_exists 'shared/milestones/burndown', milestone: @milestone, project: @project
- if can?(current_user, :read_issue, @project) && @milestone.total_issues_count == 0
- .gl-alert.gl-alert-info.gl-mt-3.gl-mb-5{ data: { testid: 'no-issues-alert' } }
- .gl-alert-container
- = sprite_icon('information-o', size: 16, css_class: 'gl-icon gl-alert-icon gl-alert-icon-no-title')
- .gl-alert-content
- .gl-alert-body
- %span= _('Assign some issues to this milestone.')
-- elsif @milestone.complete? && @milestone.active?
- .gl-alert.gl-alert-success.gl-mt-3.gl-mb-5{ data: { testid: 'all-issues-closed-alert' } }
- .gl-alert-container
- = sprite_icon('check-circle', size: 16, css_class: 'gl-icon gl-alert-icon gl-alert-icon-no-title')
- .gl-alert-content
- .gl-alert-body
- %span= _('All issues for this milestone are closed. You may close this milestone now.')
+ = render 'shared/global_alert',
+ variant: :info,
+ dismissible: false,
+ is_contained: true,
+ alert_data: { testid: 'no-issues-alert' },
+ alert_class: 'gl-mt-3 gl-mb-5' do
+ .gl-alert-body
+ = _('Assign some issues to this milestone.')
+- else
+ = render 'shared/milestones/milestone_complete_alert', milestone: @milestone do
+ = _('All issues for this milestone are closed. You may close this milestone now.')
= render 'shared/milestones/tabs', milestone: @milestone
= render 'shared/milestones/sidebar', milestone: @milestone, project: @project, affix_offset: 153
diff --git a/app/views/projects/packages/packages/show.html.haml b/app/views/projects/packages/packages/show.html.haml
index aeca3f5b3e3..76eb22109a4 100644
--- a/app/views/projects/packages/packages/show.html.haml
+++ b/app/views/projects/packages/packages/show.html.haml
@@ -6,23 +6,7 @@
.row
.col-12
- #js-vue-packages-detail{ data: { package: package_from_presenter(@package),
- can_delete: can?(current_user, :destroy_package, @project).to_s,
- svg_path: image_path('illustrations/no-packages.svg'),
- npm_path: package_registry_instance_url(:npm),
- npm_help_path: help_page_path('user/packages/npm_registry/index'),
- maven_path: package_registry_project_url(@project.id, :maven),
- maven_help_path: help_page_path('user/packages/maven_repository/index'),
- conan_path: package_registry_project_url(@project.id, :conan),
- conan_help_path: help_page_path('user/packages/conan_repository/index'),
- nuget_path: nuget_package_registry_url(@project.id),
- nuget_help_path: help_page_path('user/packages/nuget_repository/index'),
- pypi_path: pypi_registry_url(@project.id),
- pypi_setup_path: package_registry_project_url(@project.id, :pypi),
- pypi_help_path: help_page_path('user/packages/pypi_repository/index'),
- composer_path: composer_registry_url(@project&.group&.id),
- composer_help_path: help_page_path('user/packages/composer_repository/index'),
- project_name: @project.name,
- project_list_url: project_packages_path(@project),
- group_list_url: @project.group ? group_packages_path(@project.group) : '',
- composer_config_repository_name: composer_config_repository_name(@project.group&.id)} }
+ - if Feature.enabled?(:package_details_apollo)
+ #js-vue-packages-detail-new{ data: package_details_data(@project) }
+ - else
+ #js-vue-packages-detail{ data: package_details_data(@project, @package) }
diff --git a/app/views/projects/pages/_pages_settings.html.haml b/app/views/projects/pages/_pages_settings.html.haml
index 483f192109b..2db44528d51 100644
--- a/app/views/projects/pages/_pages_settings.html.haml
+++ b/app/views/projects/pages/_pages_settings.html.haml
@@ -1,5 +1,8 @@
= form_for @project, url: project_pages_path(@project), html: { class: 'inline', title: pages_https_only_title } do |f|
- = render_if_exists 'shared/pages/max_pages_size_input', form: f
+ - if can?(current_user, :update_max_pages_size)
+ = render_if_exists 'shared/pages/max_pages_size_input', form: f
+ .gl-mt-3
+ = f.submit s_('GitLabPages|Save changes'), class: 'btn btn-confirm gl-button'
- if Gitlab.config.pages.external_http || Gitlab.config.pages.external_https
@@ -15,4 +18,4 @@
= s_("GitLabPages|When enabled, all attempts to visit your website through HTTP are automatically redirected to HTTPS using a response with status code 301. Requires a valid certificate for all domains. %{docs_link_start}Learn more.%{link_end}").html_safe % { docs_link_start: docs_link_start, link_end: link_end }
.gl-mt-3
- = f.submit s_('GitLabPages|Save'), class: 'btn btn-confirm gl-button'
+ = f.submit s_('GitLabPages|Save changes'), class: 'btn btn-confirm gl-button'
diff --git a/app/views/projects/pipelines/_with_tabs.html.haml b/app/views/projects/pipelines/_with_tabs.html.haml
index e56a240c487..c1d48992500 100644
--- a/app/views/projects/pipelines/_with_tabs.html.haml
+++ b/app/views/projects/pipelines/_with_tabs.html.haml
@@ -78,7 +78,7 @@
= build_summary(build)
#js-tab-dag.tab-pane
- #js-pipeline-dag-vue{ data: { pipeline_project_path: @project.full_path, pipeline_iid: @pipeline.iid, empty_svg_path: image_path('illustrations/empty-state/empty-dag-md.svg'), about_dag_doc_path: help_page_path('ci/directed_acyclic_graph/index.md'), dag_doc_path: help_page_path('ci/yaml/README.md', anchor: 'needs')} }
+ #js-pipeline-dag-vue{ data: { pipeline_project_path: @project.full_path, pipeline_iid: @pipeline.iid, empty_svg_path: image_path('illustrations/empty-state/empty-dag-md.svg'), about_dag_doc_path: help_page_path('ci/directed_acyclic_graph/index.md'), dag_doc_path: help_page_path('ci/yaml/index.md', anchor: 'needs')} }
#js-tab-tests.tab-pane
#js-pipeline-tests-detail{ data: { summary_endpoint: summary_project_pipeline_tests_path(@project, @pipeline, format: :json),
diff --git a/app/views/projects/pipelines/index.html.haml b/app/views/projects/pipelines/index.html.haml
index 9669b2e72dc..ae76d4905e0 100644
--- a/app/views/projects/pipelines/index.html.haml
+++ b/app/views/projects/pipelines/index.html.haml
@@ -22,7 +22,7 @@
"ci-lint-path" => can?(current_user, :create_pipeline, @project) && project_ci_lint_path(@project),
"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,
+ "pipeline-editor-path" => can?(current_user, :create_pipeline, @project) && project_ci_pipeline_editor_path(@project),
+ "suggested-ci-templates" => suggested_ci_templates.to_json,
"code-quality-page-path" => @project.present(current_user: current_user).add_code_quality_ci_yml_path,
"ci-runner-settings-path" => project_settings_ci_cd_path(@project, ci_runner_templates: true, anchor: 'js-runners-settings') } }
diff --git a/app/views/projects/prometheus/metrics/edit.html.haml b/app/views/projects/prometheus/metrics/edit.html.haml
index 15a9c922ca6..d308824571e 100644
--- a/app/views/projects/prometheus/metrics/edit.html.haml
+++ b/app/views/projects/prometheus/metrics/edit.html.haml
@@ -1,6 +1,6 @@
- add_to_breadcrumbs _("Settings"), edit_project_path(@project)
- add_to_breadcrumbs _("Integrations"), project_settings_integrations_path(@project)
-- add_to_breadcrumbs "Prometheus", edit_project_service_path(@project, PrometheusService)
+- add_to_breadcrumbs "Prometheus", edit_project_service_path(@project, ::Integrations::Prometheus)
- breadcrumb_title s_('Metrics|Edit metric')
- page_title @metric.title, s_('Metrics|Edit metric')
= render 'form', project: @project, metric: @metric
diff --git a/app/views/projects/prometheus/metrics/new.html.haml b/app/views/projects/prometheus/metrics/new.html.haml
index fa925d090cb..8415ec9ee41 100644
--- a/app/views/projects/prometheus/metrics/new.html.haml
+++ b/app/views/projects/prometheus/metrics/new.html.haml
@@ -1,6 +1,6 @@
- add_to_breadcrumbs _("Settings"), edit_project_path(@project)
- add_to_breadcrumbs _("Integrations"), project_settings_integrations_path(@project)
-- add_to_breadcrumbs "Prometheus", edit_project_service_path(@project, PrometheusService)
+- add_to_breadcrumbs "Prometheus", edit_project_service_path(@project, ::Integrations::Prometheus)
- breadcrumb_title s_('Metrics|New metric')
- page_title s_('Metrics|New metric')
= render 'form', project: @project, metric: @metric
diff --git a/app/views/projects/protected_branches/shared/_create_protected_branch.html.haml b/app/views/projects/protected_branches/shared/_create_protected_branch.html.haml
index ad131b22924..57fc9a16c0a 100644
--- a/app/views/projects/protected_branches/shared/_create_protected_branch.html.haml
+++ b/app/views/projects/protected_branches/shared/_create_protected_branch.html.haml
@@ -10,7 +10,7 @@
.col-md-10
= render partial: "projects/protected_branches/shared/dropdown", locals: { f: f }
.form-text.text-muted
- - wildcards_url = help_page_url('user/project/protected_branches', anchor: 'wildcard-protected-branches')
+ - wildcards_url = help_page_url('user/project/protected_branches', anchor: 'configure-multiple-protected-branches-by-using-a-wildcard')
- wildcards_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: wildcards_url }
= (s_("ProtectedBranch|%{wildcards_link_start}Wildcards%{wildcards_link_end} such as %{code_tag_start}*-stable%{code_tag_end} or %{code_tag_start}production/*%{code_tag_end} are supported.") % { wildcards_link_start: wildcards_link_start, wildcards_link_end: '</a>', code_tag_start: '<code>', code_tag_end: '</code>' }).html_safe
.form-group.row
diff --git a/app/views/projects/protected_branches/shared/_index.html.haml b/app/views/projects/protected_branches/shared/_index.html.haml
index 08246a173d8..2e9a9357fb0 100644
--- a/app/views/projects/protected_branches/shared/_index.html.haml
+++ b/app/views/projects/protected_branches/shared/_index.html.haml
@@ -3,19 +3,16 @@
%section.settings.no-animate#js-protected-branches-settings{ class: ('expanded' if expanded), data: { qa_selector: 'protected_branches_settings_content' } }
.settings-header
%h4.settings-title.js-settings-toggle.js-settings-toggle-trigger-only
- Protected branches
+ = s_("ProtectedBranch|Protected branches")
%button.btn.gl-button.btn-default.js-settings-toggle.qa-expand-protected-branches{ type: 'button' }
= expanded ? 'Collapse' : 'Expand'
%p
- Keep stable branches secure, and force developers to use merge requests. #{link_to "What are protected branches?", help_page_path("user/project/protected_branches")}
+ = s_("ProtectedBranch|Keep stable branches secure and force developers to use merge requests.")
+ = link_to s_("ProtectedBranch|What are protected branches?"), help_page_path("user/project/protected_branches")
.settings-content
%p
- By default, protected branches protect your code and:
- %ul
- %li Allow only users with Maintainer #{link_to "permissions", help_page_path("user/permissions")} to create new protected branches.
- %li Allow only users with Maintainer permissions to push code.
- %li Prevent <strong>anyone</strong> from #{link_to "force-pushing", help_page_path('topics/git/git_rebase', anchor: 'force-push')} to the branch.
- %li Prevent <strong>anyone</strong> from deleting the branch.
+ = s_("ProtectedBranch|By default, protected branches restrict who can modify the branch.")
+ = link_to s_("ProtectedBranch|Learn more."), help_page_path("user/project/protected_branches", anchor: "who-can-modify-a-protected-branch")
- if can? current_user, :admin_project, @project
= content_for :create_protected_branch
diff --git a/app/views/projects/protected_tags/shared/_index.html.haml b/app/views/projects/protected_tags/shared/_index.html.haml
index aab4d366605..fe63f921780 100644
--- a/app/views/projects/protected_tags/shared/_index.html.haml
+++ b/app/views/projects/protected_tags/shared/_index.html.haml
@@ -3,18 +3,16 @@
%section.settings.no-animate#js-protected-tags-settings{ class: ('expanded' if expanded), data: { qa_selector: 'protected_tag_settings_content' } }
.settings-header
%h4.settings-title.js-settings-toggle.js-settings-toggle-trigger-only
- Protected tags
+ = s_("ProtectedTag|Protected tags")
%button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' }
= expanded ? 'Collapse' : 'Expand'
%p
- Limit access to creating and updating tags. #{link_to "What are protected tags?", help_page_path("user/project/protected_tags")}
+ = s_("ProtectedTag|Limit access to creating and updating tags.")
+ = link_to s_("ProtectedTag|What are protected tags?"), help_page_path("user/project/protected_tags")
.settings-content
%p
- By default, protected tags protect your code and:
- %ul
- %li Allow only users with Maintainer #{link_to "permissions", help_page_path("user/permissions")} to create tags.
- %li Prevent <strong>anyone</strong> from updating tags.
- %li Prevent <strong>anyone</strong> from deleting tags.
+ = s_("ProtectedTag|By default, protected branches restrict who can modify the tag.")
+ = link_to s_("ProtectedTag|Learn more."), help_page_path("user/project/protected_tags", anchor: "who-can-modify-a-protected-tag")
- if can? current_user, :admin_project, @project
= yield :create_protected_tag
diff --git a/app/views/projects/registry/settings/_index.haml b/app/views/projects/registry/settings/_index.haml
deleted file mode 100644
index a4d4a1bb2dd..00000000000
--- a/app/views/projects/registry/settings/_index.haml
+++ /dev/null
@@ -1,9 +0,0 @@
-#js-registry-settings{ data: { project_id: @project.id,
- project_path: @project.full_path,
- cadence_options: cadence_options.to_json,
- keep_n_options: keep_n_options.to_json,
- older_than_options: older_than_options.to_json,
- is_admin: current_user&.admin.to_s,
- admin_settings_path: ci_cd_admin_application_settings_path(anchor: 'js-registry-settings'),
- enable_historic_entries: container_expiration_policies_historic_entry_enabled?(@project).to_s,
- tags_regex_help_page_path: help_page_path('user/packages/container_registry/index', anchor: 'regex-pattern-examples') } }
diff --git a/app/views/projects/releases/index.html.haml b/app/views/projects/releases/index.html.haml
index 4d5b8cc80f7..9ddf2201fad 100644
--- a/app/views/projects/releases/index.html.haml
+++ b/app/views/projects/releases/index.html.haml
@@ -1,3 +1,5 @@
- page_title _('Releases')
+- if use_startup_query_for_index_page?
+ - add_page_startup_graphql_call('releases/all_releases', index_page_startup_query_variables)
#js-releases-page{ data: data_for_releases_page }
diff --git a/app/views/projects/runners/_index.html.haml b/app/views/projects/runners/_settings.html.haml
index a02bdac442b..a02bdac442b 100644
--- a/app/views/projects/runners/_index.html.haml
+++ b/app/views/projects/runners/_settings.html.haml
diff --git a/app/views/projects/runners/_specific_runners.html.haml b/app/views/projects/runners/_specific_runners.html.haml
index 210cc414007..eb376ff7960 100644
--- a/app/views/projects/runners/_specific_runners.html.haml
+++ b/app/views/projects/runners/_specific_runners.html.haml
@@ -2,22 +2,26 @@
= _('Specific runners')
.bs-callout.help-callout
- = _('These runners are specific to this project.')
- %hr
- = render partial: 'ci/runner/how_to_setup_runner_automatically',
- locals: { type: 'specific',
- clusters_path: project_clusters_path(@project) }
- - if params[:ci_runner_templates]
+ - if valid_runner_registrars.include?('project')
+ = _('These runners are specific to this project.')
%hr
- = render partial: 'ci/runner/setup_runner_in_aws',
- locals: { registration_token: @project.runners_token }
- %hr
- = render partial: 'ci/runner/how_to_setup_runner',
- locals: { registration_token: @project.runners_token,
- type: 'specific',
- reset_token_url: reset_registration_token_namespace_project_settings_ci_cd_path,
- project_path: @project.path_with_namespace,
- group_path: '' }
+ = render partial: 'ci/runner/how_to_setup_runner_automatically',
+ locals: { type: s_('Runners|specific'),
+ clusters_path: project_clusters_path(@project) }
+ - if params[:ci_runner_templates]
+ %hr
+ = render partial: 'ci/runner/setup_runner_in_aws',
+ locals: { registration_token: @project.runners_token }
+ %hr
+ = render partial: 'ci/runner/how_to_setup_runner',
+ locals: { registration_token: @project.runners_token,
+ type: s_('Runners|specific'),
+ reset_token_url: reset_registration_token_namespace_project_settings_ci_cd_path,
+ project_path: @project.path_with_namespace,
+ group_path: '' }
+ - else
+ = _('Please contact an admin to register runners.')
+ = link_to _('Learn more.'), help_page_path('user/admin_area/settings/continuous_integration', anchor: 'runner-registration'), target: '_blank', rel: 'noopener noreferrer'
%hr
diff --git a/app/views/projects/security/configuration/show.html.haml b/app/views/projects/security/configuration/show.html.haml
index 4d6feb9de6d..d4a85893fa4 100644
--- a/app/views/projects/security/configuration/show.html.haml
+++ b/app/views/projects/security/configuration/show.html.haml
@@ -1,4 +1,6 @@
- breadcrumb_title _("Security Configuration")
- page_title _("Security Configuration")
+- redesign_enabled = ::Feature.enabled?(:security_configuration_redesign, @project, default_enabled: :yaml)
+- @content_class = "limit-container-width" unless fluid_layout || !redesign_enabled
#js-security-configuration-static{ data: { project_path: @project.full_path, upgrade_path: security_upgrade_path } }
diff --git a/app/views/projects/settings/access_tokens/index.html.haml b/app/views/projects/settings/access_tokens/index.html.haml
index 1bf252b6282..52ef2e7d1ee 100644
--- a/app/views/projects/settings/access_tokens/index.html.haml
+++ b/app/views/projects/settings/access_tokens/index.html.haml
@@ -33,12 +33,17 @@
= render 'shared/access_tokens/form',
type: type,
path: project_settings_access_tokens_path(@project),
+ project: @project,
token: @project_access_token,
scopes: @scopes,
- prefix: :project_access_token
+ access_levels: ProjectMember.access_level_roles,
+ default_access_level: Gitlab::Access::MAINTAINER,
+ prefix: :project_access_token,
+ help_path: help_page_path('user/project/settings/project_access_tokens', anchor: 'limiting-scopes-of-a-project-access-token')
= render 'shared/access_tokens/table',
active_tokens: @active_project_access_tokens,
+ project: @project,
type: type,
type_plural: type_plural,
revoke_route_helper: ->(token) { revoke_namespace_project_settings_access_token_path(id: token) },
diff --git a/app/views/projects/settings/ci_cd/_autodevops_form.html.haml b/app/views/projects/settings/ci_cd/_autodevops_form.html.haml
index 68e4bed8b9a..8563f28eb33 100644
--- a/app/views/projects/settings/ci_cd/_autodevops_form.html.haml
+++ b/app/views/projects/settings/ci_cd/_autodevops_form.html.haml
@@ -6,7 +6,7 @@
- kubernetes_cluster_path = help_page_path('user/project/clusters/index')
- kubernetes_cluster_link_start = link_start % { url: kubernetes_cluster_path }
-- base_domain_path = help_page_path('user/project/clusters/index', anchor: 'base-domain')
+- base_domain_path = help_page_path('user/project/clusters/gitlab_managed_clusters', anchor: 'base-domain')
- base_domain_link_start = link_start % { url: base_domain_path }
.row
diff --git a/app/views/projects/settings/ci_cd/_form.html.haml b/app/views/projects/settings/ci_cd/_form.html.haml
index c89c9879f4b..a91c12d01ad 100644
--- a/app/views/projects/settings/ci_cd/_form.html.haml
+++ b/app/views/projects/settings/ci_cd/_form.html.haml
@@ -10,7 +10,7 @@
%strong= _("Public pipelines")
.form-text.text-muted
= _("Allow public access to pipelines and job details, including output logs and artifacts.")
- = link_to sprite_icon('question-o'), help_page_path('ci/pipelines/settings', anchor: 'visibility-of-pipelines'), target: '_blank'
+ = link_to sprite_icon('question-o'), help_page_path('ci/pipelines/settings', anchor: 'change-which-users-can-view-your-pipelines'), target: '_blank'
.form-group
.form-check
@@ -36,7 +36,7 @@
= f.text_field :ci_config_path, class: 'form-control', placeholder: '.gitlab-ci.yml'
%p.form-text.text-muted
= html_escape(_("The name of the CI/CD configuration file. A path relative to the root directory is optional (for example %{code_open}my/path/.myfile.yml%{code_close}).")) % { code_open: '<code>'.html_safe, code_close: '</code>'.html_safe }
- = link_to sprite_icon('question-o'), help_page_path('ci/pipelines/settings', anchor: 'custom-cicd-configuration-file'), target: '_blank'
+ = link_to sprite_icon('question-o'), help_page_path('ci/pipelines/settings', anchor: 'specify-a-custom-cicd-configuration-file'), target: '_blank'
%hr
.form-group
@@ -44,7 +44,7 @@
= _("Git strategy")
%p
= _("Choose which Git strategy to use when fetching the project.")
- = link_to sprite_icon('question-o'), help_page_path('ci/pipelines/settings', anchor: 'git-strategy'), target: '_blank'
+ = link_to sprite_icon('question-o'), help_page_path('ci/pipelines/settings', anchor: 'choose-the-default-git-strategy'), target: '_blank'
.form-check
= f.radio_button :build_allow_git_fetch, 'false', { class: 'form-check-input' }
= f.label :build_allow_git_fetch_false, class: 'form-check-label' do
@@ -66,7 +66,7 @@
= form.number_field :default_git_depth, { class: 'form-control gl-form-input', min: 0, max: 1000 }
%p.form-text.text-muted
= html_escape(_('The number of changes to fetch from GitLab when cloning a repository. Lower values can speed up pipeline execution. Set to %{code_open}0%{code_close} or blank to fetch all branches and tags for each job')) % { code_open: '<code>'.html_safe, code_close: '</code>'.html_safe }
- = link_to sprite_icon('question-o'), help_page_path('ci/pipelines/settings', anchor: 'git-shallow-clone'), target: '_blank'
+ = link_to sprite_icon('question-o'), help_page_path('ci/pipelines/settings', anchor: 'limit-the-number-of-changes-fetched-during-clone'), target: '_blank'
%hr
.form-group
@@ -74,7 +74,7 @@
= f.text_field :build_timeout_human_readable, class: 'form-control gl-form-input'
%p.form-text.text-muted
= html_escape(_('Jobs fail if they run longer than the timeout time. Input value is in seconds by default. Human readable input is also accepted, for example %{code_open}1 hour%{code_close}.')) % { code_open: '<code>'.html_safe, code_close: '</code>'.html_safe }
- = link_to sprite_icon('question-o'), help_page_path('ci/pipelines/settings', anchor: 'timeout'), target: '_blank'
+ = link_to sprite_icon('question-o'), help_page_path('ci/pipelines/settings', anchor: 'set-a-limit-for-how-long-jobs-can-run'), target: '_blank'
- if can?(current_user, :update_max_artifacts_size, @project)
.form-group
@@ -94,7 +94,7 @@
.input-group-text /
%p.form-text.text-muted
= html_escape(_('The regular expression used to find test coverage output in the job log. For example, use %{regex} for Simplecov (Ruby). Leave blank to disable.')) % { regex: '<code>\(\d+.\d+%\)</code>'.html_safe }
- = link_to sprite_icon('question-o'), help_page_path('ci/pipelines/settings', anchor: 'test-coverage-parsing'), target: '_blank'
+ = link_to sprite_icon('question-o'), help_page_path('ci/pipelines/settings', anchor: 'add-test-coverage-results-to-a-merge-request'), target: '_blank'
= f.submit _('Save changes'), class: "btn gl-button btn-confirm", data: { qa_selector: 'save_general_pipelines_changes_button' }
diff --git a/app/views/projects/settings/ci_cd/show.html.haml b/app/views/projects/settings/ci_cd/show.html.haml
index ade3d40a8df..70626636ac0 100644
--- a/app/views/projects/settings/ci_cd/show.html.haml
+++ b/app/views/projects/settings/ci_cd/show.html.haml
@@ -41,9 +41,9 @@
= expanded ? _('Collapse') : _('Expand')
%p
= _("Runners are processes that pick up and execute CI/CD jobs for GitLab.")
- = link_to s_('How do I configure runners?'), help_page_path('ci/runners/README'), target: '_blank', rel: 'noopener noreferrer'
+ = link_to s_('How do I configure runners?'), help_page_path('ci/runners/index'), target: '_blank', rel: 'noopener noreferrer'
.settings-content
- = render 'projects/runners/index'
+ = render 'projects/runners/settings'
- if Gitlab::CurrentSettings.current_application_settings.keep_latest_artifact?
%section.settings.no-animate#js-artifacts-settings{ class: ('expanded' if expanded) }
@@ -71,13 +71,10 @@
= expanded ? _('Collapse') : _('Expand')
%p
= _("Trigger a pipeline for a branch or tag by generating a trigger token and using it with an API call. The token impersonates a user's project access and permissions.")
- = link_to _('Learn more.'), help_page_path('ci/triggers/README'), target: '_blank', rel: 'noopener noreferrer'
+ = link_to _('Learn more.'), help_page_path('ci/triggers/index'), target: '_blank', rel: 'noopener noreferrer'
.settings-content
= render 'projects/triggers/index'
-- if settings_container_registry_expiration_policy_available?(@project)
- = render 'projects/registry/settings/index'
-
= render_if_exists 'projects/settings/ci_cd/auto_rollback', expanded: expanded
- if can?(current_user, :create_freeze_period, @project)
@@ -98,3 +95,16 @@
.settings-content
= render 'ci/deploy_freeze/index'
+
+- if Feature.enabled?(:ci_scoped_job_token, @project, default_enabled: :yaml)
+ %section.settings.no-animate#js-token-access{ class: ('expanded' if expanded) }
+ .settings-header
+ %h4.settings-title.js-settings-toggle.js-settings-toggle-trigger-only
+ = _("Token Access")
+ %button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' }
+ = expanded ? _('Collapse') : _('Expand')
+ %p
+ = _("Control which projects can be accessed by API requests authenticated with this project's CI_JOB_TOKEN CI/CD variable. It is a security risk to disable this feature, because unauthorized projects might attempt to retrieve an active token and access the API.")
+ = link_to _('Learn more'), help_page_path('api/index', anchor: 'limit-gitlab-cicd-job-token-access'), target: '_blank', rel: 'noopener noreferrer'
+ .settings-content
+ = render 'ci/token_access/index'
diff --git a/app/views/projects/settings/operations/show.html.haml b/app/views/projects/settings/operations/show.html.haml
index e2c1a00a587..215448be3d6 100644
--- a/app/views/projects/settings/operations/show.html.haml
+++ b/app/views/projects/settings/operations/show.html.haml
@@ -1,7 +1,6 @@
- @content_class = 'limit-container-width' unless fluid_layout
-- title = Feature.enabled?(:sidebar_refactor, current_user, default_enabled: :yaml) ? _('Monitor Settings') : _('Operations Settings')
-- page_title title
-- breadcrumb_title title
+- page_title _('Monitor Settings')
+- breadcrumb_title _('Monitor Settings')
= render 'projects/settings/operations/metrics_dashboard'
= render 'projects/settings/operations/tracing'
@@ -10,4 +9,4 @@
= render 'projects/settings/operations/incidents'
= render 'projects/settings/operations/grafana_integration'
= render_if_exists 'projects/settings/operations/status_page'
-= render 'projects/settings/operations/prometheus', service: prometheus_service if Feature.enabled?(:settings_operations_prometheus_service)
+= render 'projects/settings/operations/prometheus', service: prometheus_integration if Feature.enabled?(:settings_operations_prometheus_service)
diff --git a/app/views/registrations/experience_levels/show.html.haml b/app/views/registrations/experience_levels/show.html.haml
index f878245a48c..16e59757147 100644
--- a/app/views/registrations/experience_levels/show.html.haml
+++ b/app/views/registrations/experience_levels/show.html.haml
@@ -1,4 +1,5 @@
- page_title _('What’s your experience level?')
+- @hide_flash = true
.gl-display-flex.gl-flex-direction-column.gl-align-items-center
= image_tag 'learn-gitlab-avatar.jpg', width: '90'
diff --git a/app/views/registrations/invites/new.html.haml b/app/views/registrations/invites/new.html.haml
deleted file mode 100644
index 0feae9b17e9..00000000000
--- a/app/views/registrations/invites/new.html.haml
+++ /dev/null
@@ -1,17 +0,0 @@
-- 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
- = 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 e85ce1ba6ac..9356b6ad49c 100644
--- a/app/views/registrations/welcome/show.html.haml
+++ b/app/views/registrations/welcome/show.html.haml
@@ -1,10 +1,11 @@
+- @html_class = "subscriptions-layout-html"
- page_title _('Your profile')
- add_page_specific_style 'page_bundles/signup'
- gitlab_experience_text = _('To personalize your GitLab experience, we\'d like to know a bit more about you')
.row.gl-flex-grow-1
- .d-flex.gl-flex-direction-column.gl-align-items-center.gl-w-full.gl-p-5
- .edit-profile.login-page.d-flex.flex-column.gl-align-items-center.pt-lg-3
+ .d-flex.gl-flex-direction-column.gl-align-items-center.gl-w-full.gl-px-5.gl-pb-5
+ .edit-profile.login-page.d-flex.flex-column.gl-align-items-center
= render_if_exists "registrations/welcome/progress_bar"
%h2.gl-text-center= html_escape(_('Welcome to GitLab,%{br_tag}%{name}!')) % { name: html_escape(current_user.first_name), br_tag: '<br/>'.html_safe }
- if Gitlab.com?
diff --git a/app/views/root/index.html.haml b/app/views/root/index.html.haml
new file mode 100644
index 00000000000..97dd8e133f5
--- /dev/null
+++ b/app/views/root/index.html.haml
@@ -0,0 +1,10 @@
+- if show_customize_homepage_banner?
+ = content_for :customize_homepage_banner do
+ .gl-display-none.gl-md-display-block{ class: "gl-pt-6! gl-pb-2! #{(container_class unless @no_container)} #{@content_class}" }
+ .js-customize-homepage-banner{ data: { svg_path: image_path('illustrations/monitoring/getting_started.svg'),
+ preferences_behavior_path: profile_preferences_path(anchor: 'behavior'),
+ callouts_path: user_callouts_path,
+ callouts_feature_id: UserCalloutsHelper::CUSTOMIZE_HOMEPAGE,
+ track_label: 'home_page' } }
+
+= render template: 'dashboard/projects/index'
diff --git a/app/views/search/_results.html.haml b/app/views/search/_results.html.haml
index 4ba906dd02f..d5d3cd753f3 100644
--- a/app/views/search/_results.html.haml
+++ b/app/views/search/_results.html.haml
@@ -1,20 +1,16 @@
- search_bar_classes = 'search-sidebar gl-display-flex gl-flex-direction-column gl-mr-4'
+= render_if_exists 'shared/promotions/promote_advanced_search'
+= render partial: 'search/results_status', locals: { search_service: @search_service } unless @search_objects.to_a.empty?
-- if @search_objects.to_a.empty?
- .gl-md-display-flex
- - if %w(issues merge_requests).include?(@scope)
- #js-search-sidebar{ class: search_bar_classes }
- .gl-w-full.gl-flex-grow-1.gl-overflow-x-hidden
+.results.gl-md-display-flex.gl-mt-3
+ - if %w(issues merge_requests).include?(@scope)
+ #js-search-sidebar{ class: search_bar_classes }
+ .gl-w-full.gl-flex-grow-1.gl-overflow-x-hidden
+ - if @timeout
+ = render partial: "search/results/timeout"
+ - elsif @search_objects.to_a.empty?
= render partial: "search/results/empty"
- = render_if_exists 'shared/promotions/promote_advanced_search'
-- else
- = render partial: 'search/results_status', locals: { search_service: @search_service }
- = render_if_exists 'shared/promotions/promote_advanced_search'
-
- .results.gl-md-display-flex.gl-mt-3
- - if %w(issues merge_requests).include?(@scope)
- #js-search-sidebar{ class: search_bar_classes }
- .gl-w-full.gl-flex-grow-1.gl-overflow-x-hidden
+ - else
- if @scope == 'commits'
%ul.content-list.commit-list
= render partial: "search/results/commit", collection: @search_objects
diff --git a/app/views/search/results/_blob_data.html.haml b/app/views/search/results/_blob_data.html.haml
index 16d640273b0..fb2825ad15e 100644
--- a/app/views/search/results/_blob_data.html.haml
+++ b/app/views/search/results/_blob_data.html.haml
@@ -5,6 +5,7 @@
= sprite_icon('document')
%strong
= search_blob_title(project, path)
+ = copy_file_path_button(path)
- if blob.data
.file-content.code.term{ data: { qa_selector: 'file_text_content' } }
= render 'shared/file_highlight', blob: blob, first_line_number: blob.startline, blob_link: blob_link, highlight_line: blob.highlight_line
diff --git a/app/views/search/results/_issuable.html.haml b/app/views/search/results/_issuable.html.haml
index da0adba88db..551f5c048bc 100644
--- a/app/views/search/results/_issuable.html.haml
+++ b/app/views/search/results/_issuable.html.haml
@@ -1,14 +1,19 @@
-%div{ class: 'search-result-row gl-pb-3! gl-mt-5 gl-mb-0!' }
- %span.gl-display-flex.gl-align-items-center
- %span.badge.badge-pill.gl-badge.sm{ class: "badge-#{issuable_state_to_badge_class(issuable)}" }= issuable_state_text(issuable)
- = sprite_icon('eye-slash', css_class: 'gl-text-gray-500 gl-ml-2') if issuable.respond_to?(:confidential?) && issuable.confidential?
- = link_to issuable_path(issuable), data: { track_event: 'click_text', track_label: "#{issuable.class.name.downcase}_title", track_property: 'search_result' }, class: 'gl-w-full' do
- %span.term.str-truncated.gl-font-weight-bold.gl-ml-2= issuable.title
- .gl-text-gray-500.gl-my-3
- = issuable_project_reference(issuable)
- &middot;
- = sprintf(s_('created %{issuable_created} by %{author}'), { issuable_created: time_ago_with_tooltip(issuable.created_at, placement: 'bottom'), author: link_to_member(@project, issuable.author, avatar: false) }).html_safe
- &middot;
- = sprintf(s_('updated %{time_ago}'), { time_ago: time_ago_with_tooltip(issuable.updated_at, placement: 'bottom') }).html_safe
- .description.term.col-sm-10.gl-px-0
- = highlight_and_truncate_issuable(issuable, @search_term, @search_highlight)
+%div{ class: 'search-result-row gl-display-flex gl-sm-flex-direction-row gl-flex-direction-column gl-align-items-center gl-pb-3! gl-mt-5 gl-mb-0!' }
+ .col-sm-9
+ %span.gl-display-flex.gl-align-items-center
+ %span.badge.badge-pill.gl-badge.sm{ class: "badge-#{issuable_state_to_badge_class(issuable)}" }= issuable_state_text(issuable)
+ = sprite_icon('eye-slash', css_class: 'gl-text-gray-500 gl-ml-2') if issuable.respond_to?(:confidential?) && issuable.confidential?
+ = link_to issuable_path(issuable), data: { track_event: 'click_text', track_label: "#{issuable.class.name.downcase}_title", track_property: 'search_result' }, class: 'gl-w-full' do
+ %span.term.str-truncated.gl-font-weight-bold.gl-ml-2= issuable.title
+ .gl-text-gray-500.gl-my-3
+ = issuable_project_reference(issuable)
+ &middot;
+ = sprintf(s_('created %{issuable_created} by %{author}'), { issuable_created: time_ago_with_tooltip(issuable.created_at, placement: 'bottom'), author: link_to_member(@project, issuable.author, avatar: false) }).html_safe
+ .description.term.gl-px-0
+ = highlight_and_truncate_issuable(issuable, @search_term, @search_highlight)
+ .col-sm-3.gl-mt-3.gl-sm-mt-0.gl-text-right
+ - if Feature.enabled?(:search_sort_issues_by_popularity) && issuable.respond_to?(:upvotes_count) && issuable.upvotes_count > 0
+ %li.issuable-upvotes.gl-list-style-none.has-tooltip{ title: _('Upvotes') }
+ = sprite_icon('thumb-up', css_class: "gl-vertical-align-middle")
+ = issuable.upvotes_count
+ %span.gl-text-gray-500= sprintf(s_('updated %{time_ago}'), { time_ago: time_ago_with_tooltip(issuable.updated_at, placement: 'bottom') }).html_safe
diff --git a/app/views/search/results/_timeout.html.haml b/app/views/search/results/_timeout.html.haml
new file mode 100644
index 00000000000..740e2bedd54
--- /dev/null
+++ b/app/views/search/results/_timeout.html.haml
@@ -0,0 +1,10 @@
+.gl-display-flex.gl-flex-direction-column.gl-align-items-center
+ %div
+ .svg-content.svg-150
+ = image_tag 'illustrations/search-timeout-md.svg'
+ %div
+ %h4.gl-text-center.gl-font-weight-bold= _('Your search timed out')
+ %p.gl-text-center= _('To resolve this, try to:')
+ %ul
+ %li= html_escape(_('Refine your search criteria (select a %{strong_open}group%{strong_close} and %{strong_open}project%{strong_close} when possible)')) % { strong_open: '<strong>'.html_safe, strong_close: '</strong>'.html_safe }
+ %li= html_escape(_('Use double quotes for multiple keywords, such as %{code_open}"your search"%{code_close}')) % { code_open: '<code>'.html_safe, code_close: '</code>'.html_safe }
diff --git a/app/views/shared/_auto_devops_implicitly_enabled_banner.html.haml b/app/views/shared/_auto_devops_implicitly_enabled_banner.html.haml
index f788bf53a4c..35a3835a522 100644
--- a/app/views/shared/_auto_devops_implicitly_enabled_banner.html.haml
+++ b/app/views/shared/_auto_devops_implicitly_enabled_banner.html.haml
@@ -10,5 +10,5 @@
%div
= _('Container registry is not enabled on this GitLab instance. Ask an administrator to enable it in order for Auto DevOps to work.')
.gl-alert-actions
- = link_to _('Settings'), project_settings_ci_cd_path(project), class: 'alert-link btn gl-button btn-info'
- = link_to _('More information'), help_page_path('topics/autodevops/index.md'), target: '_blank', class: 'alert-link btn gl-button btn-default gl-ml-2'
+ = link_to _('Settings'), project_settings_ci_cd_path(project), class: 'alert-link btn gl-button btn-confirm'
+ = link_to _('More information'), help_page_path('topics/autodevops/index.md'), target: '_blank', class: 'alert-link btn gl-button btn-default gl-ml-3'
diff --git a/app/views/shared/_confirm_your_email_alert.html.haml b/app/views/shared/_confirm_your_email_alert.html.haml
new file mode 100644
index 00000000000..b9906a89ce4
--- /dev/null
+++ b/app/views/shared/_confirm_your_email_alert.html.haml
@@ -0,0 +1,7 @@
+.js-vue-alert{ 'v-cloak': true,
+ data: { dismissible: 'true',
+ title: _('Please confirm your email address'),
+ primary_button_text: _('Resend confirmation email'),
+ primary_button_link: new_user_confirmation_path,
+ variant: 'warning'} }
+ = (_("To continue, you need to select the link in the confirmation email we sent to verify your email address. If you didn't get our email, select %{strongStart}Resend confirmation email.%{strongEnd}") % { strongStart: '<strong>', strongEnd: '</strong>' }).html_safe
diff --git a/app/views/shared/_global_alert.html.haml b/app/views/shared/_global_alert.html.haml
index bebc72fe428..ea83f5c1656 100644
--- a/app/views/shared/_global_alert.html.haml
+++ b/app/views/shared/_global_alert.html.haml
@@ -2,19 +2,23 @@
- title = local_assigns.fetch(:title, nil)
- variant = local_assigns.fetch(:variant, :info)
+- dismissible = local_assigns.fetch(:dismissible, true)
- alert_class = local_assigns.fetch(:alert_class, nil)
- alert_data = local_assigns.fetch(:alert_data, nil)
- close_button_class = local_assigns.fetch(:close_button_class, nil)
- close_button_data = local_assigns.fetch(:close_button_data, nil)
- icon = icons[variant]
+- alert_root_class = 'gl-alert-layout-limited' if fluid_layout
+- alert_container_class = [container_class, @content_class] unless fluid_layout || local_assigns.fetch(:is_contained, false)
-%div{ role: 'alert', class: ["gl-alert-#{variant}", alert_class], data: alert_data }
- %div{ class: [container_class, @content_class, 'gl-px-0!'] }
- .gl-alert
- = sprite_icon(icon, size: 16, css_class: "gl-alert-icon#{' gl-alert-icon-no-title' if title.nil?}")
- %button.gl-alert-dismiss.js-close{ type: 'button', aria: { label: _('Close') }, class: close_button_class, data: close_button_data }
+%div{ role: 'alert', class: [alert_root_class, 'gl-alert-max-content', 'gl-alert', "gl-alert-#{variant}", alert_class], data: alert_data }
+ .gl-alert-container{ class: alert_container_class }
+ = sprite_icon(icon, size: 16, css_class: "gl-alert-icon#{' gl-alert-icon-no-title' if title.nil?}")
+ - if dismissible
+ %button.btn.gl-dismiss-btn.btn-default.btn-sm.gl-button.btn-default-tertiary.btn-icon.js-close{ type: 'button', aria: { label: _('Dismiss') }, class: close_button_class, data: close_button_data }
= sprite_icon('close', size: 16)
+ .gl-alert-content{ role: 'alert' }
- if title
- .gl-alert-title
+ %h4.gl-alert-title
= title
= yield
diff --git a/app/views/shared/_group_form.html.haml b/app/views/shared/_group_form.html.haml
index 7055dc8142a..e96372a29db 100644
--- a/app/views/shared/_group_form.html.haml
+++ b/app/views/shared/_group_form.html.haml
@@ -28,8 +28,7 @@
title: _('Please choose a group URL with no special characters.'),
"data-bind-in" => "#{'create_chat_team' if Gitlab.config.mattermost.enabled}"
%p.validation-error.gl-field-error.field-validation.hide
- = _('Group path is already taken. Suggestions: ')
- %span.gl-path-suggestions
+ = _("Group path is already taken. We've suggested one that is available.")
%p.validation-success.gl-field-success.field-validation.hide= _('Group path is available.')
%p.validation-pending.gl-field-error-ignore.field-validation.hide= _('Checking group URL availability...')
diff --git a/app/views/shared/_import_form.html.haml b/app/views/shared/_import_form.html.haml
index 65e02341936..f03314563cb 100644
--- a/app/views/shared/_import_form.html.haml
+++ b/app/views/shared/_import_form.html.haml
@@ -8,7 +8,18 @@
= _('Git repository URL')
= 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
+ = render 'shared/global_alert',
+ variant: :warning,
+ alert_class: 'gl-mt-3 js-import-url-warning hide',
+ dismissible: false,
+ close_button_class: 'js-close-2fa-enabled-success-alert' do
+ .gl-alert-body
+ = s_('Import|A repository URL usually ends in a .git suffix, although this is not required. Double check to make sure your repository URL is correct.')
+ .gl-alert.gl-alert-not-dismissible.gl-alert-warning.gl-mt-3.hide#project_import_url_warning
+ .gl-alert-container
+ = sprite_icon('warning-solid', css_class: 'gl-icon s16 gl-alert-icon gl-alert-icon-no-title')
+ .gl-alert-content{ role: 'alert' }
.row
.form-group.col-md-6
= f.label :import_url_user, class: 'label-bold' do
diff --git a/app/views/shared/_new_project_item_select.html.haml b/app/views/shared/_new_project_item_select.html.haml
index 3817ff8a56d..d5f4add2796 100644
--- a/app/views/shared/_new_project_item_select.html.haml
+++ b/app/views/shared/_new_project_item_select.html.haml
@@ -1,5 +1,5 @@
- if any_projects?(@projects)
- .project-item-select-holder.btn-group.gl-ml-auto.gl-mr-auto.gl-py-3.gl-relative.gl-display-flex.gl-overflow-hidden
+ .project-item-select-holder.btn-group.gl-ml-auto.gl-mr-auto.gl-relative.gl-overflow-hidden{ class: 'gl-display-flex!' }
%a.btn.gl-button.btn-confirm.new-project-item-link.block-truncated.qa-new-project-item-link{ href: '', data: { label: local_assigns[:label], type: local_assigns[:type] }, class: "gl-m-0!" }
= loading_icon(color: 'light')
= project_select_tag :project_path, class: "project-item-select gl-absolute! gl-visibility-hidden", data: { include_groups: local_assigns[:include_groups], order_by: 'last_activity_at', relative_path: local_assigns[:path], with_shared: local_assigns[:with_shared], include_projects_in_subgroups: local_assigns[:include_projects_in_subgroups] }, with_feature_enabled: local_assigns[:with_feature_enabled]
diff --git a/app/views/shared/_project_limit.html.haml b/app/views/shared/_project_limit.html.haml
index 9110f5a7f31..90612ba623f 100644
--- a/app/views/shared/_project_limit.html.haml
+++ b/app/views/shared/_project_limit.html.haml
@@ -1,8 +1,10 @@
- if cookies[:hide_project_limit_message].blank? && !current_user.hide_project_limit && !current_user.can_create_project? && current_user.projects_limit > 0
- .project-limit-message.gl-alert.gl-alert-warning.gl-display-none.gl-sm-display-block
- = _("You won't be able to create new projects because you have reached your project limit.")
-
- .float-right
- = link_to _("Don't show again"), profile_path(user: {hide_project_limit: true}), method: :put, class: 'alert-link'
- |
- = link_to _('Remind later'), '#', class: 'hide-project-limit-message alert-link'
+ = render 'shared/global_alert',
+ variant: :warning,
+ dismissible: false,
+ alert_class: 'project-limit-message' do
+ .gl-alert-body
+ = _("You won't be able to create new projects because you have reached your project limit.")
+ .gl-alert-actions
+ = link_to _('Remind later'), '#', class: 'alert-link hide-project-limit-message btn gl-button btn-confirm'
+ = link_to _("Don't show again"), profile_path(user: {hide_project_limit: true}), method: :put, class: 'alert-link btn gl-button btn-default gl-ml-3'
diff --git a/app/views/shared/_ping_consent.html.haml b/app/views/shared/_service_ping_consent.html.haml
index d0f1e4d7221..77597124e5c 100644
--- a/app/views/shared/_ping_consent.html.haml
+++ b/app/views/shared/_service_ping_consent.html.haml
@@ -1,5 +1,5 @@
- if session[:ask_for_usage_stats_consent]
- .ping-consent-message.gl-alert.gl-alert-info
+ .service-ping-consent-message.gl-alert.gl-alert-info
= sprite_icon('information-o', css_class: 'gl-icon gl-alert-icon gl-alert-icon-no-title')
%button.js-close.gl-alert-dismiss{ type: 'button', 'aria-label' => _('Dismiss') }
= sprite_icon('close', css_class: 'gl-icon')
@@ -8,7 +8,7 @@
- settings_link = link_to _('your settings'), metrics_and_profiling_admin_application_settings_path(anchor: 'js-usage-settings'), class: 'gl-link'
= s_('To help improve GitLab, we would like to periodically %{docs_link}. This can be changed at any time in %{settings_link}.').html_safe % { docs_link: docs_link, settings_link: settings_link }
.gl-alert-actions.gl-mt-3
- - send_usage_data_path = admin_application_settings_path(application_setting: { version_check_enabled: 1, usage_ping_enabled: 1 })
+ - send_service_data_path = admin_application_settings_path(application_setting: { version_check_enabled: 1, usage_ping_enabled: 1 })
- not_now_path = admin_application_settings_path(application_setting: { version_check_enabled: 0, usage_ping_enabled: 0 })
- = link_to _("Send usage data"), send_usage_data_path, 'data-url' => admin_application_settings_path, method: :put, 'data-check-enabled': true, 'data-ping-enabled': true, class: 'js-usage-consent-action alert-link btn gl-button btn-info'
- = link_to _("Don't send usage data"), not_now_path, 'data-url' => admin_application_settings_path, method: :put, 'data-check-enabled': false, 'data-ping-enabled': false, class: 'js-usage-consent-action alert-link btn gl-button btn-default gl-ml-2'
+ = link_to _("Send service data"), send_service_data_path, 'data-url' => admin_application_settings_path, method: :put, 'data-check-enabled': true, 'data-service-ping-enabled': true, class: 'js-service-ping-consent-action alert-link btn gl-button btn-info'
+ = link_to _("Don't send service data"), not_now_path, 'data-url' => admin_application_settings_path, method: :put, 'data-check-enabled': false, 'data-service-ping-enabled': false, class: 'js-service-ping-consent-action alert-link btn gl-button btn-default gl-ml-2'
diff --git a/app/views/shared/_sidebar_toggle_button.html.haml b/app/views/shared/_sidebar_toggle_button.html.haml
index a5a411db8a0..b3d6c4c327b 100644
--- a/app/views/shared/_sidebar_toggle_button.html.haml
+++ b/app/views/shared/_sidebar_toggle_button.html.haml
@@ -1,7 +1,5 @@
%a.toggle-sidebar-button.js-toggle-sidebar.qa-toggle-sidebar.rspec-toggle-sidebar{ role: "button", type: "button", title: "Toggle sidebar" }
= sprite_icon('chevron-double-lg-left', css_class: 'icon-chevron-double-lg-left')
- - if sidebar_refactor_disabled?
- = sprite_icon('chevron-double-lg-right', css_class: 'icon-chevron-double-lg-right')
%span.collapse-text.gl-ml-3= _("Collapse sidebar")
= button_tag class: 'close-nav-button', type: 'button' do
diff --git a/app/views/shared/access_tokens/_form.html.haml b/app/views/shared/access_tokens/_form.html.haml
index 88c24a27497..6435475a9a3 100644
--- a/app/views/shared/access_tokens/_form.html.haml
+++ b/app/views/shared/access_tokens/_form.html.haml
@@ -1,5 +1,9 @@
- title = local_assigns.fetch(:title, _('Add a %{type}') % { type: type })
- prefix = local_assigns.fetch(:prefix, :personal_access_token)
+- help_path = local_assigns.fetch(:help_path)
+- project = local_assigns.fetch(:project, false)
+- access_levels = local_assigns.fetch(:access_levels, false)
+- default_access_level = local_assigns.fetch(:default_access_level, false)
%h5.gl-mt-0
= title
@@ -11,13 +15,16 @@
= form_errors(token)
.row
- .form-group.col-md-6
- = f.label :name, _('Name'), class: 'label-bold'
- = f.text_field :name, class: 'form-control gl-form-input', required: true, data: { qa_selector: 'access_token_name_field' }
+ .form-group.col
+ .row
+ = f.label :name, _('Token name'), class: 'label-bold col-md-12'
+ .col-md-6
+ = f.text_field :name, class: 'form-control gl-form-input', required: true, data: { qa_selector: 'access_token_name_field' }, :'aria-describedby' => 'access_token_help_text'
+ %span.form-text.text-muted.col-md-12#access_token_help_text= _('For example, the application using the token or the purpose of the token.')
.row
.form-group.col-md-6
- = f.label :expires_at, _('Expires at'), class: 'label-bold'
+ = f.label :expires_at, _('Expiration date'), class: 'label-bold'
.input-icon-wrapper
= render_if_exists 'personal_access_tokens/callout_max_personal_access_token_lifetime'
@@ -25,8 +32,20 @@
.js-access-tokens-expires-at
= f.text_field :expires_at, class: 'datepicker gl-datepicker-input form-control gl-form-input', placeholder: 'YYYY-MM-DD', autocomplete: 'off', data: { js_name: 'expiresAt' }
+ - if project
+ .row
+ .form-group.col-md-6
+ = label_tag :access_level, _("Select a role"), class: "label-bold"
+ .select-wrapper
+ = select_tag :"#{prefix}[access_level]", options_for_select(access_levels, default_access_level), class: "form-control project-access-select select-control", data: { qa_selector: 'access_token_access_level' }
+ = sprite_icon('chevron-down', css_class: "gl-icon gl-absolute gl-top-3 gl-right-3 gl-text-gray-200")
+
.form-group
- = f.label :scopes, _('Scopes'), class: 'label-bold'
+ %b{ :'aria-describedby' => 'select_scope_help_text' }
+ = s_('Tokens|Select scopes')
+ %p.text-secondary#select_scope_help_text
+ = s_('Tokens|Scopes set the permission levels granted to the token.')
+ = link_to "Learn more.", help_path, target: '_blank'
= render 'shared/tokens/scopes_form', prefix: prefix, token: token, scopes: scopes
- if prefix == :personal_access_token && Feature.enabled?(:personal_access_tokens_scoped_to_projects, current_user)
diff --git a/app/views/shared/access_tokens/_table.html.haml b/app/views/shared/access_tokens/_table.html.haml
index 9c59d5ae1fa..1f08bff9858 100644
--- a/app/views/shared/access_tokens/_table.html.haml
+++ b/app/views/shared/access_tokens/_table.html.haml
@@ -1,10 +1,15 @@
- no_active_tokens_message = local_assigns.fetch(:no_active_tokens_message, _('This user has no active %{type}.') % { type: type_plural })
- impersonation = local_assigns.fetch(:impersonation, false)
+- project = local_assigns.fetch(:project, false)
+- personal = !impersonation && !project
%hr
%h5
= _('Active %{type} (%{token_length})') % { type: type_plural, token_length: active_tokens.length }
+- if personal && !personal_access_token_expiration_enforced?
+ %p.profile-settings-content
+ = _("Personal access tokens are not revoked upon expiration.")
- if impersonation
%p.profile-settings-content
= _("To see all the user's personal access tokens you must impersonate them first.")
@@ -14,18 +19,21 @@
%table.table.active-tokens
%thead
%tr
- %th= _('Name')
+ %th= _('Token name')
+ %th= _('Scopes')
%th= s_('AccessTokens|Created')
%th
= _('Last Used')
= 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')
+ - if project
+ %th= _('Role')
%th
%tbody
- active_tokens.each do |token|
%tr
%td= token.name
+ %td= token.scopes.present? ? token.scopes.join(', ') : _('no scopes selected')
%td= token.created_at.to_date.to_s(:medium)
%td
- if token.last_used_at?
@@ -42,8 +50,9 @@
= _('In %{time_to_now}') % { time_to_now: distance_of_time_in_words_to_now(token.expires_at) }
- else
%span.token-never-expires-label= _('Never')
- %td= token.scopes.present? ? token.scopes.join(', ') : _('no scopes selected')
- %td= link_to _('Revoke'), revoke_route_helper.call(token), method: :put, class: 'gl-button btn btn-danger btn-sm float-right qa-revoke-button', data: { confirm: _('Are you sure you want to revoke this %{type}? This action cannot be undone.') % { type: type } }
+ - if project
+ %td= project.project_member(token.user).human_access
+ %td= link_to _('Revoke'), revoke_route_helper.call(token), method: :put, class: "gl-button btn btn-danger btn-sm float-right qa-revoke-button #{'btn-danger-secondary' unless token.expires?}", data: { confirm: _('Are you sure you want to revoke this %{type}? This action cannot be undone.') % { type: type } }
- else
.settings-message.text-center
= no_active_tokens_message
diff --git a/app/views/shared/boards/_show.html.haml b/app/views/shared/boards/_show.html.haml
index c1a50cfe718..9ccd5655fb0 100644
--- a/app/views/shared/boards/_show.html.haml
+++ b/app/views/shared/boards/_show.html.haml
@@ -2,6 +2,7 @@
- group = local_assigns.fetch(:group, false)
- @no_breadcrumb_container = true
- @no_container = true
+- @content_wrapper_class = "#{@content_wrapper_class} gl-relative"
- @content_class = "issue-boards-content js-focus-mode-board"
- if board.to_type == "EpicBoard"
- breadcrumb_title _("Epic Boards")
@@ -9,6 +10,9 @@
- breadcrumb_title _("Issue Boards")
= render 'shared/alerts/positioning_disabled'
+= content_for :after_content do
+ #js-right-sidebar-portal
+
- page_title("#{board.name}", _("Boards"))
- add_page_specific_style 'page_bundles/boards'
diff --git a/app/views/shared/deploy_keys/_form.html.haml b/app/views/shared/deploy_keys/_form.html.haml
index 452e54f9cd4..bf2514f8b0d 100644
--- a/app/views/shared/deploy_keys/_form.html.haml
+++ b/app/views/shared/deploy_keys/_form.html.haml
@@ -13,7 +13,7 @@
= form.label :key, class: 'col-form-label col-sm-2'
.col-sm-10
%p.light
- - link_start = "<a href='#{help_page_path('ssh/README')}' target='_blank' rel='noreferrer noopener'>".html_safe
+ - link_start = "<a href='#{help_page_path('ssh/index')}' 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, data: { qa_selector: 'deploy_key_field' }
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 0c671b4a1c0..8da48a7936a 100644
--- a/app/views/shared/deploy_keys/_project_group_form.html.haml
+++ b/app/views/shared/deploy_keys/_project_group_form.html.haml
@@ -9,7 +9,7 @@
.form-group.row
%p.light.gl-mb-0
= _('Paste a public key here.')
- = link_to _('How do I generate it?'), help_page_path("ssh/README")
+ = link_to _('How do I generate it?'), help_page_path("ssh/index")
= f.fields_for :deploy_keys_projects do |deploy_keys_project_form|
.form-group.row
diff --git a/app/views/shared/deploy_tokens/_form.html.haml b/app/views/shared/deploy_tokens/_form.html.haml
index 976776ccc62..5d351bd11fd 100644
--- a/app/views/shared/deploy_tokens/_form.html.haml
+++ b/app/views/shared/deploy_tokens/_form.html.haml
@@ -38,7 +38,7 @@
- if packages_registry_enabled?(group_or_project)
%fieldset.form-group.form-check
- = f.check_box :read_package_registry, class: 'form-check-input'
+ = f.check_box :read_package_registry, class: 'form-check-input', data: { qa_selector: 'deploy_token_read_package_registry_checkbox' }
= f.label :read_package_registry, 'read_package_registry', class: 'label-bold form-check-label'
.text-secondary= s_('DeployTokens|Allows read access to the package registry.')
diff --git a/app/views/shared/empty_states/_issues.html.haml b/app/views/shared/empty_states/_issues.html.haml
index 13d9d71d58e..9842457a2eb 100644
--- a/app/views/shared/empty_states/_issues.html.haml
+++ b/app/views/shared/empty_states/_issues.html.haml
@@ -47,7 +47,7 @@
= link_to _('New issue'), button_path, class: 'gl-button btn btn-confirm', id: 'new_issue_link'
- if show_import_button
- .js-csv-import-export-buttons{ data: { show_import_button: show_import_button.to_s, issuable_type: issuable_type, import_csv_issues_path: import_csv_namespace_project_issues_path, can_edit: can_edit.to_s, project_import_jira_path: project_import_jira_path(@project), max_attachment_size: number_to_human_size(Gitlab::CurrentSettings.max_attachment_size.megabytes), container_class: 'gl-display-inline-flex gl-vertical-align-middle', show_label: 'true' } }
+ .js-csv-import-export-buttons{ data: { show_import_button: 'true', issuable_type: issuable_type, import_csv_issues_path: import_csv_namespace_project_issues_path, can_edit: can_edit.to_s, project_import_jira_path: project_import_jira_path(@project), max_attachment_size: number_to_human_size(Gitlab::CurrentSettings.max_attachment_size.megabytes), container_class: 'gl-display-inline-flex gl-vertical-align-middle', show_label: 'true' } }
%hr
%p.gl-text-center.gl-mb-0
%strong
diff --git a/app/views/shared/issuable/_bulk_update_sidebar.html.haml b/app/views/shared/issuable/_bulk_update_sidebar.html.haml
index bbbb728d048..3a526a9f306 100644
--- a/app/views/shared/issuable/_bulk_update_sidebar.html.haml
+++ b/app/views/shared/issuable/_bulk_update_sidebar.html.haml
@@ -6,21 +6,13 @@
= form_tag [:bulk_update, @project, type], method: :post, class: "bulk-update" do
.block.issuable-sidebar-header
.filter-item.inline.update-issues-btn.float-left
- = button_tag _('Update all'), class: "gl-button btn update-selected-issues btn-confirm", disabled: true
+ = button_tag _('Update all'), class: "gl-button btn js-update-selected-issues btn-confirm", disabled: true
= button_tag _('Cancel'), class: "gl-button btn btn-default js-bulk-update-menu-hide float-right"
- if params[:state] != 'merged'
.block
.title
= _('Status')
- .filter-item
- = dropdown_tag(_("Select status"), options: { toggle_class: "js-issue-status", title: _("Change status"), dropdown_class: "dropdown-menu-status dropdown-menu-selectable", data: { field_name: "update[state_event]", default_label: _("Status") } } ) do
- %ul
- %li
- %a{ href: "#", data: { id: "reopen" } }
- = _('Open')
- %li
- %a{ href: "#", data: { id: "close" } }
- = _('Closed')
+ .js-issue-status
.block
.title
= _('Assignee')
diff --git a/app/views/shared/issuable/_form.html.haml b/app/views/shared/issuable/_form.html.haml
index e79719d41b0..6aa80e6808d 100644
--- a/app/views/shared/issuable/_form.html.haml
+++ b/app/views/shared/issuable/_form.html.haml
@@ -6,11 +6,16 @@
= form_errors(issuable)
- if @conflict
- .gl-alert.gl-alert-danger.gl-mb-5
- Someone edited the #{issuable.class.model_name.human.downcase} the same time you did.
- Please check out
- = link_to "the #{issuable.class.model_name.human.downcase}", polymorphic_path([@project, issuable]), target: "_blank", rel: 'noopener noreferrer'
- and make sure your changes will not unintentionally remove theirs
+ = render 'shared/global_alert',
+ variant: :danger,
+ dismissible: false,
+ is_contained: true,
+ alert_class: 'gl-mb-5' do
+ .gl-alert-body
+ Someone edited the #{issuable.class.model_name.human.downcase} the same time you did.
+ Please check out
+ = link_to "the #{issuable.class.model_name.human.downcase}", polymorphic_path([@project, issuable]), target: "_blank", rel: 'noopener noreferrer'
+ and make sure your changes will not unintentionally remove theirs
= render 'shared/issuable/form/branch_chooser', issuable: issuable, form: form
diff --git a/app/views/shared/issuable/_invite_members_trigger.html.haml b/app/views/shared/issuable/_invite_members_trigger.html.haml
deleted file mode 100644
index 5dd6ec0addf..00000000000
--- a/app/views/shared/issuable/_invite_members_trigger.html.haml
+++ /dev/null
@@ -1,8 +0,0 @@
-- return unless can_import_members?
-
-.js-invite-members-modal{ data: { id: project.id,
- name: project.name,
- is_project: 'true',
- access_levels: ProjectMember.access_level_roles.to_json,
- default_access_level: Gitlab::Access::GUEST,
- help_link: help_page_url('user/permissions') } }
diff --git a/app/views/shared/issuable/_search_bar.html.haml b/app/views/shared/issuable/_search_bar.html.haml
index c03697a4076..737a0ff8c5b 100644
--- a/app/views/shared/issuable/_search_bar.html.haml
+++ b/app/views/shared/issuable/_search_bar.html.haml
@@ -25,6 +25,8 @@
= check_box_tag checkbox_id, nil, false, class: "check-all-issues left"
- if is_epic_board
#js-board-filtered-search{ data: { full_path: @group&.full_path } }
+ - elsif Feature.enabled?(:issue_boards_filtered_search, board&.resource_parent) && board
+ #js-issue-board-filtered-search
- 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.html.haml b/app/views/shared/issuable/_sidebar.html.haml
index 416c788603a..c76aa176696 100644
--- a/app/views/shared/issuable/_sidebar.html.haml
+++ b/app/views/shared/issuable/_sidebar.html.haml
@@ -10,19 +10,13 @@
%aside.right-sidebar.js-right-sidebar.js-issuable-sidebar{ data: { signed: { in: signed_in }, issuable_type: issuable_type }, class: sidebar_gutter_collapsed_class, 'aria-live' => 'polite', 'aria-label': issuable_type }
.issuable-sidebar
- .block.issuable-sidebar-header
- - if signed_in
- %span.issuable-header-text.hide-collapsed.float-left
- = _('To Do')
+ .issuable-sidebar-header.gl-py-3
%a.gutter-toggle.float-right.js-sidebar-toggle.has-tooltip{ role: "button", href: "#", "aria-label" => _('Toggle sidebar'), title: sidebar_gutter_tooltip_text, data: { container: 'body', placement: 'left', boundary: 'viewport' } }
= sidebar_gutter_toggle_icon
- if signed_in
- = render "shared/issuable/sidebar_todo", issuable_sidebar: issuable_sidebar
+ .js-issuable-todo{ data: { project_path: issuable_sidebar[:project_full_path], iid: issuable_sidebar[:iid], id: issuable_sidebar[:id] } }
= form_for issuable_type, url: issuable_sidebar[:issuable_json_path], remote: true, html: { class: 'issuable-context-form inline-update js-issuable-update' } do |f|
- - if signed_in
- .block.todo.hide-expanded
- = render "shared/issuable/sidebar_todo", issuable_sidebar: issuable_sidebar, is_collapsed: true
.block.assignee.qa-assignee-block
= render "shared/issuable/sidebar_assignees", issuable_sidebar: issuable_sidebar, assignees: assignees, signed_in: signed_in
@@ -34,34 +28,11 @@
= render_if_exists 'shared/issuable/sidebar_item_epic', issuable_sidebar: issuable_sidebar, group_path: @project.group.full_path, project_path: issuable_sidebar[:project_full_path], issue_iid: issuable_sidebar[:iid], issuable_type: issuable_type
- if issuable_sidebar[:supports_milestone]
- - milestone = issuable_sidebar[:milestone] || {}
.block.milestone{ :class => ("gl-border-b-0!" if issuable_sidebar[:supports_iterations]), data: { qa_selector: 'milestone_block' } }
- .sidebar-collapsed-icon.has-tooltip{ title: sidebar_milestone_tooltip_label(milestone), data: { container: 'body', html: 'true', placement: 'left', boundary: 'viewport' } }
- = sprite_icon('clock')
- %span.milestone-title.collapse-truncated-title
- - if milestone.present?
- = milestone[:title]
- - else
- = _('None')
- .hide-collapsed.gl-line-height-20.gl-mb-2.gl-text-gray-900{ data: { testid: "milestone_title" } }
- = _('Milestone')
- = loading_icon(css_class: 'gl-vertical-align-text-bottom hidden block-loading')
- - if can_edit_issuable
- = link_to _('Edit'), '#', class: 'js-sidebar-dropdown-toggle edit-link float-right', data: { qa_selector: "edit_milestone_link", track_label: "right_sidebar", track_property: "milestone", track_event: "click_edit_button", track_value: "" }
- .value.hide-collapsed
- - if milestone.present?
- - milestone_title = milestone[:expired] ? _("%{milestone_name} (Past due)").html_safe % { milestone_name: milestone[:title] } : milestone[:title]
- = link_to milestone_title, milestone[:web_url], class: "bold has-tooltip", title: sidebar_milestone_remaining_days(milestone), data: { container: "body", html: 'true', boundary: 'viewport', qa_selector: 'milestone_link', qa_title: milestone[:title] }
- - else
- %span.no-value
- = _('None')
-
- .selectbox.hide-collapsed
- = f.hidden_field 'milestone_id', value: milestone[:id], id: nil
- = dropdown_tag('Milestone', options: { title: _('Assign milestone'), toggle_class: 'js-milestone-select js-extra-options', filter: true, dropdown_class: 'dropdown-menu-selectable', placeholder: _('Search milestones'), data: { show_no: true, field_name: "#{issuable_type}[milestone_id]", project_id: issuable_sidebar[:project_id], issuable_id: issuable_sidebar[:id], ability_name: issuable_type, issue_update: issuable_sidebar[:issuable_json_path], use_id: true, default_no: true, selected: milestone[:title], null_default: true, display: 'static' }})
+ .js-milestone-select{ data: { can_edit: can_edit_issuable.to_s, project_path: issuable_sidebar[:project_full_path], issue_iid: issuable_sidebar[:iid] } }
- if @project.group.present? && issuable_sidebar[:supports_iterations]
- .block{ class: 'gl-pt-0!' }
+ .block{ class: 'gl-pt-0!', data: { qa_selector: 'iteration_container' } }
= render_if_exists 'shared/issuable/iteration_select', can_edit: can_edit_issuable.to_s, group_path: @project.group.full_path, project_path: issuable_sidebar[:project_full_path], issue_iid: issuable_sidebar[:iid], issuable_type: issuable_type
- if issuable_sidebar[:supports_time_tracking]
@@ -75,13 +46,13 @@
.js-sidebar-labels{ data: sidebar_labels_data(issuable_sidebar, @project) }
- = render_if_exists 'shared/issuable/sidebar_weight', issuable_sidebar: issuable_sidebar
+ = render_if_exists 'shared/issuable/sidebar_weight', issuable_sidebar: issuable_sidebar, can_edit: can_edit_issuable.to_s, project_path: issuable_sidebar[:project_full_path], issue_iid: issuable_sidebar[:iid]
- if issuable_sidebar[:supports_severity]
#js-severity
- if issuable_sidebar.dig(:features_available, :health_status)
- .js-sidebar-status-entry-point
+ .js-sidebar-status-entry-point{ data: sidebar_status_data(issuable_sidebar, @project) }
- if issuable_sidebar.has_key?(:confidential)
%script#js-confidential-issue-data{ type: "application/json" }= { is_confidential: issuable_sidebar[:confidential], is_editable: can_edit_issuable }.to_json.html_safe
diff --git a/app/views/shared/issuable/_sidebar_todo.html.haml b/app/views/shared/issuable/_sidebar_todo.html.haml
deleted file mode 100644
index a867421298b..00000000000
--- a/app/views/shared/issuable/_sidebar_todo.html.haml
+++ /dev/null
@@ -1,15 +0,0 @@
-- is_collapsed = local_assigns.fetch(:is_collapsed, false)
-- has_todo = !!issuable_sidebar.dig(:current_user, :todo, :id)
-
-- todo_button_data = issuable_todo_button_data(issuable_sidebar, is_collapsed)
-- button_title = has_todo ? todo_button_data[:mark_text] : todo_button_data[:todo_text]
-- button_icon = has_todo ? todo_button_data[:mark_icon] : todo_button_data[:todo_icon]
-
-%button.issuable-todo-btn.js-issuable-todo{ type: 'button',
- class: (is_collapsed ? 'btn-blank sidebar-collapsed-icon dont-change-state has-tooltip' : 'gl-button btn btn-default issuable-header-btn float-right'),
- title: button_title,
- 'aria-label' => button_title,
- data: todo_button_data }
- %span.issuable-todo-inner.js-issuable-todo-inner<
- = is_collapsed ? button_icon : button_title
- = loading_icon(css_class: is_collapsed ? '' : 'gl-ml-3')
diff --git a/app/views/shared/issuable/_sort_dropdown.html.haml b/app/views/shared/issuable/_sort_dropdown.html.haml
index 9e3caf62d77..caf271e9ee9 100644
--- a/app/views/shared/issuable/_sort_dropdown.html.haml
+++ b/app/views/shared/issuable/_sort_dropdown.html.haml
@@ -1,6 +1,7 @@
- sort_value = @sort
- sort_title = issuable_sort_option_title(sort_value)
- viewing_issues = controller.controller_name == 'issues' || controller.action_name == 'issues'
+- viewing_merge_requests = controller.controller_name == 'merge_requests'
.dropdown.inline.gl-ml-3.issue-sort-dropdown
.btn-group{ role: 'group' }
@@ -17,6 +18,7 @@
= sortable_item(sort_title_due_date, page_filter_path(sort: sort_value_due_date), sort_title) if viewing_issues
= sortable_item(sort_title_popularity, page_filter_path(sort: sort_value_popularity), sort_title)
= sortable_item(sort_title_label_priority, page_filter_path(sort: sort_value_label_priority), sort_title)
+ = sortable_item(sort_title_merged_date, page_filter_path(sort: sort_value_merged_date), sort_title) if viewing_merge_requests
= sortable_item(sort_title_relative_position, page_filter_path(sort: sort_value_relative_position), sort_title) if viewing_issues
= render_if_exists('shared/ee/issuable/sort_dropdown', viewing_issues: viewing_issues, sort_title: sort_title)
= issuable_sort_direction_button(sort_value)
diff --git a/app/views/shared/issue_type/_details_content.html.haml b/app/views/shared/issue_type/_details_content.html.haml
index ceedb5e5c59..0bf002fbbc5 100644
--- a/app/views/shared/issue_type/_details_content.html.haml
+++ b/app/views/shared/issue_type/_details_content.html.haml
@@ -20,6 +20,9 @@
#js-related-merge-requests{ data: { endpoint: expose_path(api_v4_projects_issues_related_merge_requests_path(id: @project.id, issue_iid: issuable.iid)), project_namespace: @project.namespace.path, project_path: @project.path } }
+ - if can?(current_user, :admin_feature_flags_issue_links, @project)
+ = render_if_exists 'projects/issues/related_feature_flags'
+
- if can?(current_user, :download_code, @project)
- add_page_startup_api_call related_branches_path
#related-branches{ data: { url: related_branches_path } }
diff --git a/app/views/shared/members/_group.html.haml b/app/views/shared/members/_group.html.haml
deleted file mode 100644
index 2aac3a94c49..00000000000
--- a/app/views/shared/members/_group.html.haml
+++ /dev/null
@@ -1,50 +0,0 @@
-- group_link = local_assigns[:group_link]
-- group = group_link.shared_with_group
-- can_admin_member = local_assigns[:can_admin_member]
-- group_link_path = local_assigns[:group_link_path]
-- dom_id = "group_member_#{group_link.id}"
-
--# Note this is just for groups. For individual members please see shared/members/_member
-
-%li.member.js-member.group_member.py-2.px-3.d-flex.flex-column.flex-md-row{ id: dom_id, data: { qa_selector: 'group_row' } }
- %span.list-item-name.mb-2.m-md-0
- = group_icon(group, class: "avatar s40 flex-shrink-0 flex-grow-0", alt: '')
- .user-info
- = link_to group.full_name, group_path(group), class: 'member'
- .cgray
- Given access #{time_ago_with_tooltip(group_link.created_at)}
- %span.js-expires-in{ class: ('gl-display-none' unless group_link.expires?) }
- &middot;
- %span.js-expires-in-text{ class: ('text-warning' if group_link.expires_soon?) }
- - if group_link.expires?
- = _("Expires in %{expires_at}").html_safe % { expires_at: distance_of_time_in_words_to_now(group_link.expires_at) }
- .controls.member-controls.align-items-center
- = form_tag group_link_path, method: :put, remote: true, class: 'js-edit-member-form form-group d-sm-flex' do
- = hidden_field_tag "group_link[group_access]", group_link.group_access
- .member-form-control.dropdown.mr-sm-2.d-sm-inline-block
- %button.dropdown-menu-toggle.js-member-permissions-dropdown{ type: "button",
- disabled: !can_admin_member,
- data: { toggle: "dropdown", field_name: "group_link[group_access]" } }
- %span.dropdown-toggle-text
- = group_link.human_access
- = sprite_icon("chevron-down", css_class: "dropdown-menu-toggle-icon gl-top-3")
- .dropdown-menu.dropdown-select.dropdown-menu-right.dropdown-menu-selectable
- = dropdown_title(_("Change role"))
- .dropdown-content
- %ul
- - Gitlab::Access.options_with_owner.each do |role, role_id|
- %li
- = link_to role, '#',
- class: ("is-active" if group_link.group_access == role_id),
- data: { id: role_id, el_id: dom_id }
- .clearable-input.member-form-control.d-sm-inline-block
- = text_field_tag 'group_link[expires_at]', group_link.expires_at, class: 'form-control js-access-expiration-date js-member-update-control', placeholder: _('Expiration date'), id: "member_expires_at_#{group.id}", disabled: !can_admin_member
- = sprite_icon('close', size: 16, css_class: 'clear-icon js-clear-input gl-text-gray-200')
- - if can_admin_member
- = link_to group_link_path,
- method: :delete,
- data: { confirm: _("Are you sure you want to remove %{group_name}?") % { group_name: group.name }, qa_selector: 'delete_group_access_link' },
- class: 'gl-button btn btn-danger m-0 ml-sm-2 align-self-center' do
- %span.d-block.d-sm-none
- = _("Delete")
- = sprite_icon('remove', css_class: 'd-none d-sm-block')
diff --git a/app/views/shared/members/_manage_access_button.html.haml b/app/views/shared/members/_manage_access_button.html.haml
new file mode 100644
index 00000000000..13509a7480a
--- /dev/null
+++ b/app/views/shared/members/_manage_access_button.html.haml
@@ -0,0 +1,7 @@
+- path = local_assigns.fetch(:path, nil)
+
+.gl-float-right
+ = link_to path, class: 'btn btn-default btn-sm gl-button' do
+ = sprite_icon('pencil-square', css_class: 'gl-icon gl-button-icon')
+ %span.gl-button-text
+ = _('Manage access')
diff --git a/app/views/shared/members/_member.html.haml b/app/views/shared/members/_member.html.haml
index 8f334be0427..ba0e5e492f4 100644
--- a/app/views/shared/members/_member.html.haml
+++ b/app/views/shared/members/_member.html.haml
@@ -1,5 +1,4 @@
- show_roles = local_assigns.fetch(:show_roles, true)
-- show_controls = local_assigns.fetch(:show_controls, true)
- force_mobile_view = local_assigns.fetch(:force_mobile_view, false)
- member = local_assigns.fetch(:member)
- current_user_is_group_owner = local_assigns.fetch(:current_user_is_group_owner, false)
@@ -7,11 +6,10 @@
- group = local_assigns.fetch(:group)
- user = local_assigns.fetch(:user, member.user)
- source = member.source
-- override = member.try(:override)
-# Note this is just for individual members. For groups please see shared/members/_group
-%li.member.js-member.py-2.px-3.d-flex.flex-column{ class: [dom_class(member), ("is-overridden" if override), ("flex-md-row" unless force_mobile_view)], id: dom_id(member), data: { qa_selector: 'member_row' } }
+%li.member.js-member.py-2.px-3.d-flex.flex-column{ class: [dom_class(member), ("flex-md-row" unless force_mobile_view)], id: dom_id(member), data: { qa_selector: 'member_row' } }
%span.list-item-name.mb-2.m-md-0
- if user
= image_tag avatar_icon_for_user(user, 40), class: "avatar s40 flex-shrink-0 flex-grow-0", alt: ''
@@ -62,70 +60,4 @@
- if show_roles
.controls.member-controls.align-items-center
= render_if_exists 'shared/members/ee/ldap_tag', can_override: member.can_override?
- - if show_controls && member.source == membership_source
-
- - if member.can_resend_invite?
- = link_to sprite_icon('paper-airplane'), polymorphic_path([:resend_invite, member]),
- method: :post,
- class: 'gl-button btn btn-default align-self-center mr-sm-2',
- title: _('Resend invite')
-
- - if user != current_user && member.can_update?
- = form_for member, remote: true, html: { class: "js-edit-member-form form-group #{'d-sm-flex' unless force_mobile_view}" } do |f|
- = f.hidden_field :access_level
- .member-form-control.dropdown{ class: [("mr-sm-2 d-sm-inline-block" unless force_mobile_view)] }
- %button.dropdown-menu-toggle.js-member-permissions-dropdown{ type: "button",
- disabled: member.can_override? && !override,
- data: { toggle: "dropdown", field_name: "#{f.object_name}[access_level]", qa_selector: "access_level_dropdown" } }
- %span.dropdown-toggle-text
- = member.human_access
- = sprite_icon("chevron-down", css_class: "dropdown-menu-toggle-icon gl-top-3")
- .dropdown-menu.dropdown-select.dropdown-menu-right.dropdown-menu-selectable
- = dropdown_title(_("Change role"))
- .dropdown-content
- %ul
- - member.valid_level_roles.each do |role, role_id|
- %li
- = link_to role, '#',
- class: ("is-active" if member.access_level == role_id),
- data: { id: role_id, el_id: dom_id(member), qa_selector: "#{role.downcase}_access_level_link" }
- = render_if_exists 'shared/members/ee/revert_ldap_group_sync_option',
- group: group,
- member: member,
- can_override: member.can_override?
- .clearable-input.member-form-control{ class: [("d-sm-inline-block" unless force_mobile_view)] }
- = f.text_field :expires_at,
- disabled: member.can_override? && !override,
- class: 'form-control js-access-expiration-date js-member-update-control',
- placeholder: _('Expiration date'),
- id: "member_expires_at_#{member.id}",
- data: { el_id: dom_id(member) }
- = sprite_icon('close', size: 16, css_class: 'clear-icon js-clear-input gl-text-gray-200')
- - else
- %span.member-access-text.user-access-role= member.human_access
-
- - if member.can_approve?
- = link_to polymorphic_path([:approve_access_request, member]),
- method: :post,
- class: "btn btn-confirm btn-icon gl-button align-self-center m-0 mb-2 #{'mb-sm-0 ml-sm-2' unless force_mobile_view}",
- title: _('Grant access') do
- %span{ class: ('d-block d-sm-none' unless force_mobile_view) }
- = _('Grant access')
- - unless force_mobile_view
- = sprite_icon('check', css_class: 'd-none d-sm-block')
-
- - if member.can_remove?
- - if current_user == user
- = link_to polymorphic_path([:leave, member.source, :members]), method: :delete, data: { confirm: leave_confirmation_message(member.source) }, class: "btn gl-button btn-svg btn-danger align-self-center m-0 #{'ml-sm-2' unless force_mobile_view}" do
- = sprite_icon('leave', css_class: 'gl-icon')
- = _('Leave')
- - else
- %button{ data: { member_path: member_path(member.member), member_type: member.type, message: remove_member_message(member), is_access_request: member.request?.to_s, qa_selector: 'delete_member_button' },
- class: "js-remove-member-button btn gl-button btn-danger align-self-center m-0 #{'ml-sm-2 btn-icon' unless force_mobile_view}",
- title: remove_member_title(member) }
- %span{ class: ('d-block d-sm-none' unless force_mobile_view) }
- = _("Delete")
- - unless force_mobile_view
- = sprite_icon('remove', css_class: 'd-none d-sm-block gl-icon')
- - else
- %span.member-access-text.user-access-role= member.human_access
+ %span.member-access-text.user-access-role= member.human_access
diff --git a/app/views/shared/members/_requests.html.haml b/app/views/shared/members/_requests.html.haml
index 3aa43ed1922..8b0a85656dc 100644
--- a/app/views/shared/members/_requests.html.haml
+++ b/app/views/shared/members/_requests.html.haml
@@ -1,20 +1,19 @@
- membership_source = local_assigns.fetch(:membership_source)
- requesters = local_assigns.fetch(:requesters)
-- force_mobile_view = local_assigns.fetch(:force_mobile_view, false)
- group = local_assigns.fetch(:group)
- current_user_is_group_owner = group && group.has_owner?(current_user)
- return if requesters.empty?
-.card.gl-mt-3{ class: ('card-mobile' if force_mobile_view ) }
+.card.gl-mt-3{ data: { testid: 'access-requests' } }
.card-header
= _("Users requesting access to")
%strong= membership_source.name
%span.badge.badge-pill= requesters.size
+ = render 'shared/members/manage_access_button', path: membership_source.is_a?(Project) ? project_project_members_path(@project, tab: 'access_requests') : group_group_members_path(@group, tab: 'access_requests')
%ul.content-list.members-list
= render partial: 'shared/members/member',
collection: requesters, as: :member,
locals: { membership_source: membership_source,
group: group,
- force_mobile_view: force_mobile_view,
current_user_is_group_owner: current_user_is_group_owner }
diff --git a/app/views/shared/members/_search_field.html.haml b/app/views/shared/members/_search_field.html.haml
deleted file mode 100644
index b1e3134f7aa..00000000000
--- a/app/views/shared/members/_search_field.html.haml
+++ /dev/null
@@ -1,6 +0,0 @@
-- name = local_assigns.fetch(:name, :search)
-
-.search-control-wrap.gl-relative
- = search_field_tag name, params[name], { placeholder: _('Search'), class: 'form-control', spellcheck: false }
- %button.user-search-btn.border-left.gl-display-flex.gl-align-items-center.gl-justify-content-center{ type: 'submit', 'aria': { label: _('Submit search') }, data: { testid: 'user-search-submit' } }
- = sprite_icon('search')
diff --git a/app/views/shared/members/_sort_dropdown.html.haml b/app/views/shared/members/_sort_dropdown.html.haml
deleted file mode 100644
index 682e3a0433b..00000000000
--- a/app/views/shared/members/_sort_dropdown.html.haml
+++ /dev/null
@@ -1,19 +0,0 @@
-.dropdown.inline.qa-user-sort-dropdown{ data: { testid: 'user-sort-dropdown' } }
- = dropdown_toggle(member_sort_options_hash[@sort], { toggle: 'dropdown', testid: 'dropdown-toggle' })
- %ul.dropdown-menu.dropdown-menu-right.dropdown-menu-selectable
- %li.dropdown-header
- = _("Sort by")
- - member_sort_options_hash.each do |value, title|
- %li
- = link_to filter_group_project_member_path(sort: value), class: ("is-active" if @sort == value) do
- = title
- %li.divider
- %li{ data: { testid: 'filter-members-with-inherited-permissions' } }
- = link_to filter_group_project_member_path(with_inherited_permissions: nil), class: ("is-active" unless params[:with_inherited_permissions].present?) do
- = _("Show all members")
- %li{ data: { testid: 'filter-members-with-inherited-permissions' } }
- = link_to filter_group_project_member_path(with_inherited_permissions: 'exclude'), class: ("is-active" if params[:with_inherited_permissions] == 'exclude') do
- = _("Show only direct members")
- %li{ data: { testid: 'filter-members-with-inherited-permissions' } }
- = link_to filter_group_project_member_path(with_inherited_permissions: 'only'), class: ("is-active" if params[:with_inherited_permissions] == 'only') do
- = _("Show only inherited members")
diff --git a/app/views/shared/milestones/_form_dates.html.haml b/app/views/shared/milestones/_form_dates.html.haml
index e0664c1feba..7a41e381a96 100644
--- a/app/views/shared/milestones/_form_dates.html.haml
+++ b/app/views/shared/milestones/_form_dates.html.haml
@@ -1,13 +1,11 @@
-.col-md-6
- .form-group.row
- .col-form-label.col-sm-2
- = f.label :start_date, _('Start Date')
- .col-sm-10
- = 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 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')
+.form-group.row
+ .col-form-label.col-sm-2
+ = f.label :start_date, _('Start Date')
+ .col-sm-4
+ = 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')
+ .col-form-label.col-sm-2
+ = f.label :due_date, _('Due Date')
+ .col-sm-4
+ = 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/_issuable.html.haml b/app/views/shared/milestones/_issuable.html.haml
index 184904dd7ab..12380d4c34e 100644
--- a/app/views/shared/milestones/_issuable.html.haml
+++ b/app/views/shared/milestones/_issuable.html.haml
@@ -25,3 +25,5 @@
= link_to polymorphic_path(issuable_type_args, { milestone_title: @milestone.title, assignee_id: assignee.id, state: 'all' }),
class: 'has-tooltip', title: _("Assigned to %{assignee_name}") % { assignee_name: assignee.name }, data: { container: 'body' } do
- image_tag(avatar_icon_for_user(assignee, 16), class: "avatar s16", alt: '')
+
+ = render_if_exists "shared/milestones/issuable_weight", issuable: issuable
diff --git a/app/views/shared/milestones/_issuables.html.haml b/app/views/shared/milestones/_issuables.html.haml
index 9147e1c50e3..460ddd0897c 100644
--- a/app/views/shared/milestones/_issuables.html.haml
+++ b/app/views/shared/milestones/_issuables.html.haml
@@ -4,11 +4,15 @@
.card
.card-header{ class: panel_class }
- .title
- = title
- - if show_counter
- .counter
- = number_with_delimiter(issuables.length)
+ .header.gl-mb-2
+ .title
+ = title
+ .issuable-count-weight.gl-ml-3
+ - if show_counter
+ %span.counter
+ = sprite_icon('issues', css_class: 'gl-vertical-align-text-bottom')
+ = number_with_delimiter(issuables.length)
+ = render_if_exists "shared/milestones/issuables_weight", issuables: issuables
- class_prefix = dom_class(issuables).pluralize
%ul{ class: "content-list milestone-#{class_prefix}-list", id: "#{class_prefix}-list-#{id}" }
diff --git a/app/views/shared/milestones/_milestone_complete_alert.html.haml b/app/views/shared/milestones/_milestone_complete_alert.html.haml
new file mode 100644
index 00000000000..1c25fae747e
--- /dev/null
+++ b/app/views/shared/milestones/_milestone_complete_alert.html.haml
@@ -0,0 +1,10 @@
+- milestone = local_assigns[:milestone]
+
+- if milestone.complete? && milestone.active?
+ = render 'shared/global_alert',
+ variant: :success,
+ is_contained: true,
+ alert_data: { testid: 'all-issues-closed-alert' },
+ dismissible: false do
+ .gl-alert-body
+ = yield
diff --git a/app/views/shared/milestones/_top.html.haml b/app/views/shared/milestones/_top.html.haml
index c37fdf0c98f..2709a39c475 100644
--- a/app/views/shared/milestones/_top.html.haml
+++ b/app/views/shared/milestones/_top.html.haml
@@ -5,11 +5,8 @@
= render 'shared/milestones/header', milestone: milestone
= render 'shared/milestones/description', milestone: milestone
-
-- if milestone.complete? && milestone.active?
- .gl-alert.gl-alert-success.gl-mt-3
- %span
- = _('All issues for this milestone are closed.')
- = group ? _('You may close the milestone now.') : _('Navigate to the project to close the milestone.')
+= render 'shared/milestones/milestone_complete_alert', milestone: milestone do
+ = _('All issues for this milestone are closed.')
+ = group ? _('You may close the milestone now.') : _('Navigate to the project to close the milestone.')
= render_if_exists 'shared/milestones/burndown', milestone: milestone, project: @project
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 ab4d8816ec9..cfa87351689 100644
--- a/app/views/shared/namespaces/cascading_settings/_enforcement_checkbox.html.haml
+++ b/app/views/shared/namespaces/cascading_settings/_enforcement_checkbox.html.haml
@@ -1,9 +1,10 @@
- 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 unless attribute && group && form
- return if setting_locked
- lock_attribute = "lock_#{attribute}"
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
index d27b3641637..83d602aba21 100644
--- a/app/views/shared/namespaces/cascading_settings/_setting_label_checkbox.html.haml
+++ b/app/views/shared/namespaces/cascading_settings/_setting_label_checkbox.html.haml
@@ -1,10 +1,11 @@
- attribute = local_assigns.fetch(:attribute, nil)
+- group = local_assigns.fetch(:group, 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
+- return unless attribute && group && 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
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
index 4a2ec9f30fd..66c760b466c 100644
--- a/app/views/shared/namespaces/cascading_settings/_setting_label_fieldset.html.haml
+++ b/app/views/shared/namespaces/cascading_settings/_setting_label_fieldset.html.haml
@@ -1,9 +1,10 @@
- attribute = local_assigns.fetch(:attribute, nil)
+- group = local_assigns.fetch(:group, 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
+- return unless attribute && group && settings_path_helper
%legend.h5.gl-border-none.gl-m-0
= render 'shared/namespaces/cascading_settings/setting_label_container' do
diff --git a/app/views/shared/nav/_scope_menu.html.haml b/app/views/shared/nav/_scope_menu.html.haml
index cbee0e0429c..1a7089fb570 100644
--- a/app/views/shared/nav/_scope_menu.html.haml
+++ b/app/views/shared/nav/_scope_menu.html.haml
@@ -1,6 +1,6 @@
-- if sidebar_refactor_enabled?
- = nav_link(**scope_menu.active_routes, html_options: scope_menu.nav_link_html_options) do
- = render 'shared/nav/scope_menu_body', scope_menu: scope_menu
-- else
- .context-header
- = render 'shared/nav/scope_menu_body', scope_menu: scope_menu
+= nav_link(**scope_menu.active_routes, html_options: scope_menu.nav_link_html_options) do
+ = link_to scope_menu.link, **scope_menu.container_html_options, data: { qa_selector: 'sidebar_menu_link', qa_menu_item: scope_qa_menu_item(scope_menu.container) } do
+ %span{ class: scope_avatar_classes(scope_menu.container) }
+ = source_icon(scope_menu.container, alt: scope_menu.title, class: ['avatar', 'avatar-tile', 's32'], width: 32, height: 32)
+ %span.sidebar-context-title
+ = scope_menu.title
diff --git a/app/views/shared/nav/_scope_menu_body.html.haml b/app/views/shared/nav/_scope_menu_body.html.haml
deleted file mode 100644
index a94c681e2d3..00000000000
--- a/app/views/shared/nav/_scope_menu_body.html.haml
+++ /dev/null
@@ -1,8 +0,0 @@
-- avatar_size = sidebar_refactor_disabled? ? 40 : 32
-- avatar_size_class = sidebar_refactor_disabled? ? 's40' : 's32'
-
-= link_to scope_menu.link, **scope_menu.container_html_options, data: { qa_selector: 'project_scope_link' } do
- %span{ class: ['avatar-container', 'rect-avatar', 'project-avatar', avatar_size_class] }
- = source_icon(scope_menu.container, alt: scope_menu.title, class: ['avatar', 'avatar-tile', avatar_size_class], width: avatar_size, height: avatar_size)
- %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 54c3b8a281d..915352996d9 100644
--- a/app/views/shared/nav/_sidebar.html.haml
+++ b/app/views/shared/nav/_sidebar.html.haml
@@ -1,15 +1,14 @@
%aside.nav-sidebar{ class: ('sidebar-collapsed-desktop' if collapsed_sidebar?), **sidebar_tracking_attributes_by_object(sidebar.container), 'aria-label': sidebar.aria_label }
.nav-sidebar-inner-scroll
- - if sidebar.scope_menu && sidebar_refactor_disabled?
- = render partial: 'shared/nav/scope_menu', object: sidebar.scope_menu
- - elsif sidebar.render_raw_scope_menu_partial
- = render sidebar.render_raw_scope_menu_partial
-
- %ul.sidebar-top-level-items.qa-project-sidebar
- - if sidebar.scope_menu && sidebar_refactor_enabled?
+ %ul.sidebar-top-level-items{ data: { qa_selector: sidebar_qa_selector(sidebar.container) } }
+ - if sidebar.render_raw_scope_menu_partial
+ = render sidebar.render_raw_scope_menu_partial
+ - elsif sidebar.scope_menu
= render partial: 'shared/nav/scope_menu', object: sidebar.scope_menu
+
- if sidebar.renderable_menus.any?
= render partial: 'shared/nav/sidebar_menu', collection: sidebar.renderable_menus
+
- if sidebar.render_raw_menus_partial
= render sidebar.render_raw_menus_partial
diff --git a/app/views/shared/nav/_sidebar_menu.html.haml b/app/views/shared/nav/_sidebar_menu.html.haml
index b80bd515a32..9a04139d2f2 100644
--- a/app/views/shared/nav/_sidebar_menu.html.haml
+++ b/app/views/shared/nav/_sidebar_menu.html.haml
@@ -15,12 +15,12 @@
%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
- - if sidebar_refactor_disabled?
- = link_to sidebar_menu.link, class: "'has-sub-items' if sidebar_menu.has_renderable_items?", **sidebar_menu.collapsed_container_html_options do
- = render 'shared/nav/sidebar_menu_collapsed', sidebar_menu: sidebar_menu
- - else
- %span.fly-out-top-item-container
- = render 'shared/nav/sidebar_menu_collapsed', sidebar_menu: sidebar_menu
+ %span.fly-out-top-item-container
+ %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?
%li.divider.fly-out-top-item
diff --git a/app/views/shared/nav/_sidebar_menu_collapsed.html.haml b/app/views/shared/nav/_sidebar_menu_collapsed.html.haml
deleted file mode 100644
index 78567a991df..00000000000
--- a/app/views/shared/nav/_sidebar_menu_collapsed.html.haml
+++ /dev/null
@@ -1,5 +0,0 @@
-%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)
diff --git a/app/views/shared/snippets/_embed.html.haml b/app/views/shared/snippets/_embed.html.haml
index f698e1a301b..b5abd00b8fd 100644
--- a/app/views/shared/snippets/_embed.html.haml
+++ b/app/views/shared/snippets/_embed.html.haml
@@ -4,12 +4,12 @@
= external_snippet_icon('doc-text')
%strong.file-title-name
- %a.gitlab-embedded-snippets-title{ href: url_for(only_path: false, overwrite_params: nil) }
+ %a.gitlab-embedded-snippets-title{ href: url_for(only_path: false, overwrite_params: nil), target: '_blank', rel: 'noopener noreferrer' }
= blob.name
%small
= number_to_human_size(blob.size)
- %a.gitlab-logo-wrapper{ href: url_for(only_path: false, overwrite_params: nil), title: 'view on gitlab' }
+ %a.gitlab-logo-wrapper{ href: url_for(only_path: false, overwrite_params: nil), title: 'View on GitLab', target: '_blank', rel: 'noopener noreferrer' }
%img.gitlab-logo{ src: image_url('ext_snippet_icons/logo.svg'), alt: "GitLab logo" }
.file-actions.d-none.d-sm-block
diff --git a/app/views/shared/wikis/edit.html.haml b/app/views/shared/wikis/edit.html.haml
index 729646c2731..15710f0df49 100644
--- a/app/views/shared/wikis/edit.html.haml
+++ b/app/views/shared/wikis/edit.html.haml
@@ -18,7 +18,7 @@
.nav-controls.pb-md-3.pb-lg-0
- if @page.persisted?
- - if can?(current_user, :admin_wiki, @wiki.container)
+ - if can?(current_user, :create_wiki, @wiki.container)
#delete-wiki-modal-wrapper{ data: { delete_wiki_url: wiki_page_path(@wiki, @page), page_title: @page.human_title } }
= render 'shared/wikis/form', uploads_path: wiki_attachment_upload_url
diff --git a/app/views/users/unsubscribes/show.html.haml b/app/views/users/unsubscribes/show.html.haml
new file mode 100644
index 00000000000..8b3dc69f3a7
--- /dev/null
+++ b/app/views/users/unsubscribes/show.html.haml
@@ -0,0 +1,11 @@
+- page_title _("Unsubscribe"), _("Admin Notifications")
+%h3.page-title Unsubscribe from Admin notifications
+
+%hr
+= form_tag unsubscribe_path(Base64.urlsafe_encode64(@email)) do
+ %p
+ Yes, I want to unsubscribe
+ %strong= @email
+ from any further admin emails.
+ .form-actions
+ = submit_tag 'Unsubscribe', class: 'gl-button btn btn-confirm'