summaryrefslogtreecommitdiff
path: root/app/views
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2021-08-19 09:08:42 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2021-08-19 09:08:42 +0000
commitb76ae638462ab0f673e5915986070518dd3f9ad3 (patch)
treebdab0533383b52873be0ec0eb4d3c66598ff8b91 /app/views
parent434373eabe7b4be9593d18a585fb763f1e5f1a6f (diff)
downloadgitlab-ce-b76ae638462ab0f673e5915986070518dd3f9ad3.tar.gz
Add latest changes from gitlab-org/gitlab@14-2-stable-eev14.2.0-rc42
Diffstat (limited to 'app/views')
-rw-r--r--app/views/admin/application_settings/_ci_cd.html.haml28
-rw-r--r--app/views/admin/application_settings/_email.html.haml10
-rw-r--r--app/views/admin/application_settings/_grafana.html.haml8
-rw-r--r--app/views/admin/application_settings/_help_page.html.haml12
-rw-r--r--app/views/admin/application_settings/_kroki.html.haml11
-rw-r--r--app/views/admin/application_settings/_package_registry.html.haml2
-rw-r--r--app/views/admin/application_settings/_pages.html.haml54
-rw-r--r--app/views/admin/application_settings/_performance_bar.html.haml4
-rw-r--r--app/views/admin/application_settings/_plantuml.html.haml7
-rw-r--r--app/views/admin/application_settings/_prometheus.html.haml15
-rw-r--r--app/views/admin/application_settings/_realtime.html.haml3
-rw-r--r--app/views/admin/application_settings/_repository_static_objects.html.haml4
-rw-r--r--app/views/admin/application_settings/_signin.html.haml47
-rw-r--r--app/views/admin/application_settings/_signup.html.haml3
-rw-r--r--app/views/admin/application_settings/_terms.html.haml6
-rw-r--r--app/views/admin/application_settings/_visibility_and_access.html.haml1
-rw-r--r--app/views/admin/application_settings/appearances/_form.html.haml2
-rw-r--r--app/views/admin/application_settings/general.html.haml6
-rw-r--r--app/views/admin/application_settings/metrics_and_profiling.html.haml10
-rw-r--r--app/views/admin/application_settings/network.html.haml3
-rw-r--r--app/views/admin/application_settings/preferences.html.haml7
-rw-r--r--app/views/admin/application_settings/repository.html.haml5
-rw-r--r--app/views/admin/applications/_form.html.haml4
-rw-r--r--app/views/admin/applications/new.html.haml7
-rw-r--r--app/views/admin/applications/show.html.haml48
-rw-r--r--app/views/admin/dashboard/index.html.haml5
-rw-r--r--app/views/admin/dev_ops_report/_callout.html.haml13
-rw-r--r--app/views/admin/dev_ops_report/_report.html.haml5
-rw-r--r--app/views/admin/groups/_form.html.haml2
-rw-r--r--app/views/admin/groups/show.html.haml1
-rw-r--r--app/views/admin/projects/show.html.haml1
-rw-r--r--app/views/admin/runners/_runner.html.haml80
-rw-r--r--app/views/admin/runners/index.html.haml138
-rw-r--r--app/views/admin/services/_form.html.haml9
-rw-r--r--app/views/admin/services/_service_templates_deprecated_alert.html.haml10
-rw-r--r--app/views/admin/services/edit.html.haml6
-rw-r--r--app/views/admin/services/index.html.haml43
-rw-r--r--app/views/ci/runner/_how_to_setup_runner.html.haml3
-rw-r--r--app/views/ci/runner/_how_to_setup_runner_automatically.html.haml21
-rw-r--r--app/views/ci/variables/_index.html.haml1
-rw-r--r--app/views/clusters/clusters/_integrations.html.haml26
-rw-r--r--app/views/clusters/clusters/_multiple_clusters_message.html.haml2
-rw-r--r--app/views/dashboard/_projects_head.html.haml2
-rw-r--r--app/views/devise/shared/_email_opted_in.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.haml8
-rw-r--r--app/views/groups/dependency_proxies/_url.html.haml6
-rw-r--r--app/views/groups/dependency_proxies/show.html.haml2
-rw-r--r--app/views/groups/group_members/index.html.haml13
-rw-r--r--app/views/groups/runners/_group_runners.html.haml11
-rw-r--r--app/views/groups/runners/_settings.html.haml3
-rw-r--r--app/views/groups/runners/_sort_dropdown.html.haml (renamed from app/views/admin/runners/_sort_dropdown.html.haml)3
-rw-r--r--app/views/groups/runners/index.html.haml6
-rw-r--r--app/views/groups/settings/_advanced.html.haml4
-rw-r--r--app/views/groups/settings/_lfs.html.haml9
-rw-r--r--app/views/groups/settings/_permissions.html.haml40
-rw-r--r--app/views/groups/settings/_project_access_token_creation.html.haml13
-rw-r--r--app/views/groups/settings/_two_factor_auth.html.haml14
-rw-r--r--app/views/groups/sidebar/_packages.html.haml27
-rw-r--r--app/views/groups/sidebar/_packages_settings.html.haml5
-rw-r--r--app/views/help/instance_configuration.html.haml2
-rw-r--r--app/views/help/instance_configuration/_package_registry.html.haml48
-rw-r--r--app/views/help/instance_configuration/_rate_limit_row.html.haml7
-rw-r--r--app/views/help/instance_configuration/_rate_limits.html.haml36
-rw-r--r--app/views/import/bulk_imports/status.html.haml5
-rw-r--r--app/views/jira_connect/branches/new.html.haml5
-rw-r--r--app/views/jira_connect/subscriptions/index.html.haml7
-rw-r--r--app/views/layouts/_head.html.haml2
-rw-r--r--app/views/layouts/_loading_hints.html.haml10
-rw-r--r--app/views/layouts/_mailer.html.haml1
-rw-r--r--app/views/layouts/_page.html.haml3
-rw-r--r--app/views/layouts/_recaptcha_verification.html.haml10
-rw-r--r--app/views/layouts/header/_default.html.haml28
-rw-r--r--app/views/layouts/header/_service_templates_deprecation_callout.html.haml21
-rw-r--r--app/views/layouts/nav/_dashboard.html.haml90
-rw-r--r--app/views/layouts/nav/_explore.html.haml19
-rw-r--r--app/views/layouts/nav/_top_nav_responsive.html.haml2
-rw-r--r--app/views/layouts/nav/groups_dropdown/_show.html.haml23
-rw-r--r--app/views/layouts/nav/projects_dropdown/_show.html.haml28
-rw-r--r--app/views/layouts/nav/sidebar/_analytics_links.html.haml22
-rw-r--r--app/views/layouts/nav/sidebar/_group_menus.html.haml163
-rw-r--r--app/views/layouts/nav/sidebar/_wiki_link.html.haml11
-rw-r--r--app/views/notify/member_invited_email.html.haml126
-rw-r--r--app/views/profiles/show.html.haml14
-rw-r--r--app/views/projects/_home_panel.html.haml38
-rw-r--r--app/views/projects/_invite_members_modal.html.haml9
-rw-r--r--app/views/projects/_last_push.html.haml30
-rw-r--r--app/views/projects/_new_project_fields.html.haml3
-rw-r--r--app/views/projects/_terraform_banner.html.haml2
-rw-r--r--app/views/projects/blame/show.html.haml2
-rw-r--r--app/views/projects/blob/_editor.html.haml2
-rw-r--r--app/views/projects/blob/viewers/_gitlab_ci_yml.html.haml2
-rw-r--r--app/views/projects/blob/viewers/_gitlab_ci_yml_loading.html.haml2
-rw-r--r--app/views/projects/blob/viewers/_route_map.html.haml2
-rw-r--r--app/views/projects/blob/viewers/_route_map_loading.html.haml2
-rw-r--r--app/views/projects/branches/_branch.html.haml2
-rw-r--r--app/views/projects/ci/builds/_build.html.haml16
-rw-r--r--app/views/projects/commit/_commit_box.html.haml2
-rw-r--r--app/views/projects/commit/show.html.haml2
-rw-r--r--app/views/projects/commits/show.html.haml2
-rw-r--r--app/views/projects/deployments/_confirm_rollback_modal.html.haml23
-rw-r--r--app/views/projects/deployments/_rollback.haml3
-rw-r--r--app/views/projects/diffs/_file.html.haml2
-rw-r--r--app/views/projects/edit.html.haml4
-rw-r--r--app/views/projects/empty.html.haml2
-rw-r--r--app/views/projects/environments/_external_url.html.haml4
-rw-r--r--app/views/projects/environments/_form.html.haml21
-rw-r--r--app/views/projects/environments/_metrics_button.html.haml7
-rw-r--r--app/views/projects/environments/_pin_button.html.haml3
-rw-r--r--app/views/projects/environments/_terminal_button.html.haml3
-rw-r--r--app/views/projects/environments/edit.html.haml7
-rw-r--r--app/views/projects/environments/new.html.haml5
-rw-r--r--app/views/projects/environments/show.html.haml54
-rw-r--r--app/views/projects/feature_flags/edit.html.haml2
-rw-r--r--app/views/projects/feature_flags/new.html.haml2
-rw-r--r--app/views/projects/issues/_issue.html.haml5
-rw-r--r--app/views/projects/issues/captcha_check.html.haml7
-rw-r--r--app/views/projects/issues/verify.html.haml3
-rw-r--r--app/views/projects/jobs/_table.html.haml2
-rw-r--r--app/views/projects/merge_requests/_merge_request.html.haml2
-rw-r--r--app/views/projects/merge_requests/creations/_new_submit.html.haml2
-rw-r--r--app/views/projects/merge_requests/show.html.haml3
-rw-r--r--app/views/projects/mirrors/_mirror_repos.html.haml6
-rw-r--r--app/views/projects/mirrors/_mirror_repos_push.html.haml4
-rw-r--r--app/views/projects/packages/packages/show.html.haml6
-rw-r--r--app/views/projects/pipelines/show.html.haml4
-rw-r--r--app/views/projects/project_members/index.html.haml43
-rw-r--r--app/views/projects/runners/_specific_runners.html.haml4
-rw-r--r--app/views/projects/security/configuration/show.html.haml3
-rw-r--r--app/views/projects/settings/_general.html.haml2
-rw-r--r--app/views/projects/show.html.haml1
-rw-r--r--app/views/projects/snippets/show.html.haml2
-rw-r--r--app/views/search/results/_blob_data.html.haml15
-rw-r--r--app/views/search/results/_issuable.html.haml2
-rw-r--r--app/views/search/show.html.haml8
-rw-r--r--app/views/shared/_allow_request_access.html.haml8
-rw-r--r--app/views/shared/_captcha_check.html.haml37
-rw-r--r--app/views/shared/_check_recovery_settings.html.haml15
-rw-r--r--app/views/shared/_group_form.html.haml3
-rw-r--r--app/views/shared/_recaptcha_form.html.haml23
-rw-r--r--app/views/shared/_service_ping_consent.html.haml10
-rw-r--r--app/views/shared/access_tokens/_table.html.haml6
-rw-r--r--app/views/shared/blob/_markdown_buttons.html.haml2
-rw-r--r--app/views/shared/boards/_show.html.haml6
-rw-r--r--app/views/shared/deploy_tokens/_form.html.haml23
-rw-r--r--app/views/shared/deploy_tokens/_index.html.haml2
-rw-r--r--app/views/shared/doorkeeper/applications/_show.html.haml15
-rw-r--r--app/views/shared/groups/_empty_state.html.haml5
-rw-r--r--app/views/shared/icons/_dev_ops_report_overview.svg64
-rw-r--r--app/views/shared/integrations/_form.html.haml3
-rw-r--r--app/views/shared/integrations/_tabs.html.haml18
-rw-r--r--app/views/shared/integrations/edit.html.haml6
-rw-r--r--app/views/shared/integrations/overrides.html.haml10
-rw-r--r--app/views/shared/issuable/_form.html.haml2
-rw-r--r--app/views/shared/issuable/_sidebar_assignees.html.haml2
-rw-r--r--app/views/shared/issuable/_sidebar_user_dropdown.html.haml2
-rw-r--r--app/views/shared/issuable/_sort_dropdown.html.haml1
-rw-r--r--app/views/shared/issuable/form/_metadata_issuable_reviewer.html.haml3
-rw-r--r--app/views/shared/issuable/form/_type_selector.html.haml6
-rw-r--r--app/views/shared/nav/_sidebar_menu.html.haml49
-rw-r--r--app/views/shared/notes/_comment_button.html.haml2
-rw-r--r--app/views/shared/notes/_form.html.haml2
-rw-r--r--app/views/shared/projects/_project.html.haml4
-rw-r--r--app/views/shared/projects/_topics.html.haml32
-rw-r--r--app/views/snippets/show.html.haml2
-rw-r--r--app/views/users/show.html.haml8
166 files changed, 781 insertions, 1503 deletions
diff --git a/app/views/admin/application_settings/_ci_cd.html.haml b/app/views/admin/application_settings/_ci_cd.html.haml
index fb530e18b03..ee97a678aaa 100644
--- a/app/views/admin/application_settings/_ci_cd.html.haml
+++ b/app/views/admin/application_settings/_ci_cd.html.haml
@@ -6,20 +6,24 @@
.form-check
= f.check_box :auto_devops_enabled, class: 'form-check-input'
= f.label :auto_devops_enabled, class: 'form-check-label' do
- %strong= s_('CICD|Default to Auto DevOps pipeline for all projects')
+ = s_('CICD|Default to Auto DevOps pipeline for all projects')
.form-text.text-muted
= s_('CICD|The Auto DevOps pipeline runs by default in all projects with no CI/CD configuration file.')
= link_to _('What is Auto DevOps?'), help_page_path('topics/autodevops/index.md'), target: '_blank'
.form-group
= f.label :auto_devops_domain, s_('AdminSettings|Auto DevOps domain'), class: 'label-bold'
- = f.text_field :auto_devops_domain, class: 'form-control gl-form-input', placeholder: 'domain.com'
+ = f.text_field :auto_devops_domain, class: 'form-control gl-form-input', placeholder: 'example.com'
.form-text.text-muted
- = s_("AdminSettings|Specify a domain to use by default for every project's Auto Review Apps and Auto Deploy stages.")
+ = s_("AdminSettings|The default domain to use for Auto Review Apps and Auto Deploy stages in all projects.")
+ = link_to _('Learn more.'), help_page_path('topics/autodevops/stages.md', anchor: 'auto-review-apps'), target: '_blank'
+
.form-group
.form-check
= f.check_box :shared_runners_enabled, class: 'form-check-input'
= f.label :shared_runners_enabled, class: 'form-check-label' do
= s_("AdminSettings|Enable shared runners for new projects")
+ .form-text.text-muted
+ = s_("AdminSettings|All new projects can use the instance's shared runners by default.")
= render_if_exists 'admin/application_settings/shared_runners_minutes_setting', form: f
@@ -31,32 +35,32 @@
= f.label :max_artifacts_size, _('Maximum artifacts size (MB)'), class: 'label-bold'
= f.number_field :max_artifacts_size, class: 'form-control gl-form-input'
.form-text.text-muted
- = _("Set the maximum file size for each job's artifacts")
- = link_to sprite_icon('question-o'), help_page_path('user/admin_area/settings/continuous_integration', anchor: 'maximum-artifacts-size')
+ = _("The maximum file size for job artifacts.")
+ = link_to _('Learn more.'), help_page_path('user/admin_area/settings/continuous_integration', anchor: 'maximum-artifacts-size')
.form-group
= f.label :default_artifacts_expire_in, _('Default artifacts expiration'), class: 'label-bold'
= f.text_field :default_artifacts_expire_in, class: 'form-control gl-form-input'
.form-text.text-muted
- = html_escape(_("Set the default expiration time for each job's artifacts. 0 for unlimited. The default unit is in seconds, but you can define an alternative. For example: %{code_open}4 mins 2 sec%{code_close}, %{code_open}2h42min%{code_close}.")) % { code_open: '<code>'.html_safe, code_close: '</code>'.html_safe }
- = link_to sprite_icon('question-o'), help_page_path('user/admin_area/settings/continuous_integration', anchor: 'default-artifacts-expiration')
+ = html_escape(_("The default expiration time for job artifacts. 0 for unlimited. The default unit is in seconds, but you can use other units, for example %{code_open}4 mins 2 sec%{code_close}, %{code_open}2h42min%{code_close}.")) % { code_open: '<code>'.html_safe, code_close: '</code>'.html_safe }
+ = link_to _('Learn more.'), help_page_path('user/admin_area/settings/continuous_integration', anchor: 'default-artifacts-expiration')
.form-group
.form-check
= f.check_box :keep_latest_artifact, class: 'form-check-input'
= f.label :keep_latest_artifact, class: 'form-check-label' do
- %strong
- = s_('AdminSettings|Keep the latest artifacts for all jobs in the latest successful pipelines')
+ = s_('AdminSettings|Keep the latest artifacts for all jobs in the latest successful pipelines')
.form-text.text-muted
= s_('AdminSettings|The latest artifacts for all jobs in the most recent successful pipelines in each project are stored and do not expire.')
.form-group
= f.label :archive_builds_in_human_readable, _('Archive jobs'), class: 'label-bold'
- = f.text_field :archive_builds_in_human_readable, class: 'form-control gl-form-input', placeholder: 'never'
+ = f.text_field :archive_builds_in_human_readable, class: 'form-control gl-form-input'
.form-text.text-muted
- = html_escape(_("Set the duration for which the jobs will be considered as old and expired. Once that time passes, the jobs will be archived and no longer able to be retried. Make it empty to never expire jobs. It has to be no less than 1 day, for example: %{code_open}15 days%{code_close}, %{code_open}1 month%{code_close}, %{code_open}2 years%{code_close}.")) % { code_open: '<code>'.html_safe, code_close: '</code>'.html_safe }
+ = html_escape(_("Jobs older than the configured time are considered expired and are archived. Archived jobs can no longer be retried. Leave empty to never archive jobs automatically. The default unit is in days, but you can use other units, for example %{code_open}15 days%{code_close}, %{code_open}1 month%{code_close}, %{code_open}2 years%{code_close}. Minimum value is 1 day.")) % { code_open: '<code>'.html_safe, code_close: '</code>'.html_safe }
+ = link_to _('Learn more.'), help_page_path('user/admin_area/settings/continuous_integration', anchor: 'archive-jobs')
.form-group
.form-check
= f.check_box :protected_ci_variables, class: 'form-check-input'
= f.label :protected_ci_variables, class: 'form-check-label' do
- %strong= s_('AdminSettings|Protect CI/CD variables by default')
+ = s_('AdminSettings|Protect CI/CD variables by default')
.form-text.text-muted
= s_('AdminSettings|New CI/CD variables in projects and groups default to protected.')
.form-group
diff --git a/app/views/admin/application_settings/_email.html.haml b/app/views/admin/application_settings/_email.html.haml
index b22aaabe41a..1c35250644d 100644
--- a/app/views/admin/application_settings/_email.html.haml
+++ b/app/views/admin/application_settings/_email.html.haml
@@ -8,20 +8,20 @@
= f.label :email_author_in_body, class: 'form-check-label' do
= _('Include author name in notification email body')
.form-text.text-muted
- = _('Some email servers do not support overriding the email sender name. Enable this option to include the name of the author of the issue, merge request or comment in the email body instead.')
+ = _("Include the name of the author of the issue, merge request or comment in the email body. By default, GitLab overrides the email sender's name. Some email servers don't support that option.")
.form-group
.form-check
= f.check_box :html_emails_enabled, class: 'form-check-input'
= f.label :html_emails_enabled, class: 'form-check-label' do
- = _('Enable HTML emails')
+ = _('Enable multipart emails')
.form-text.text-muted
- = _('By default GitLab sends emails in HTML and plain text formats so mail clients can choose what format to use. Disable this option if you only want to send emails in plain text format.')
+ = _('Send email in multipart format (HTML and plain text). Uncheck to send email messages in plain text only.')
.form-group
= f.label :commit_email_hostname, _('Custom hostname (for private commit emails)'), class: 'label-bold'
= f.text_field :commit_email_hostname, class: 'form-control gl-form-input'
.form-text.text-muted
- commit_email_hostname_docs_link = link_to _('Learn more'), help_page_path('user/admin_area/settings/email.md', anchor: 'custom-hostname-for-private-commit-emails'), target: '_blank'
- = _("This setting will update the hostname that is used to generate private commit emails. %{learn_more}").html_safe % { learn_more: commit_email_hostname_docs_link }
+ = _("Hostname used in private commit emails. %{learn_more}").html_safe % { learn_more: commit_email_hostname_docs_link }
= render_if_exists 'admin/application_settings/email_additional_text_setting', form: f
@@ -31,6 +31,6 @@
= f.label :in_product_marketing_emails_enabled, class: 'form-check-label' do
= _('Enable in-product marketing emails')
.form-text.text-muted
- = _('By default, GitLab sends emails to help guide users through the onboarding process.')
+ = _('Send emails to help guide new users through the onboarding process.')
= f.submit _('Save changes'), class: "gl-button btn btn-confirm", data: { qa_selector: 'save_changes_button' }
diff --git a/app/views/admin/application_settings/_grafana.html.haml b/app/views/admin/application_settings/_grafana.html.haml
index fd9e7ee50c4..70c1e3ce3c1 100644
--- a/app/views/admin/application_settings/_grafana.html.haml
+++ b/app/views/admin/application_settings/_grafana.html.haml
@@ -2,16 +2,16 @@
= form_errors(@application_setting)
%fieldset
- %p
- = _("Add a Grafana button in the admin sidebar, monitoring section, to access a variety of statistics on the health and performance of GitLab.")
- = link_to sprite_icon('question-o'), help_page_path('administration/monitoring/performance/grafana_configuration.md')
.form-group
.form-check
= f.check_box :grafana_enabled, class: 'form-check-input'
= f.label :grafana_enabled, class: 'form-check-label' do
- = _('Enable access to Grafana')
+ = _("Add a link to Grafana")
+ .form-text.text-muted
+ = _("A Metrics Dashboard menu item appears in the Monitoring section of the Admin Area.")
.form-group
= f.label :grafana_url, _('Grafana URL'), class: 'label-bold'
= f.text_field :grafana_url, class: 'form-control gl-form-input', placeholder: '/-/grafana'
+ %span.form-text.text-muted#support_help_block= _('URL of the Grafana instance to link to from the Metrics Dashboard menu item.')
= 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 b71e8ca831e..ecf3203df9a 100644
--- a/app/views/admin/application_settings/_help_page.html.haml
+++ b/app/views/admin/application_settings/_help_page.html.haml
@@ -7,20 +7,22 @@
.form-group
= 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-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 the Help page.')
+ = _('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')
+ = f.text_field :help_page_support_url, class: 'form-control gl-form-input', placeholder: 'https://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.')
- if show_documentation_base_url_field?
.form-group
= f.label :help_page_documentation_base_url, _('Documentation pages URL'), class: 'label-bold'
= f.text_field :help_page_documentation_base_url, class: 'form-control gl-form-input', placeholder: 'https://docs.gitlab.com'
-
+ - docs_link_url = help_page_path('user/admin_area/settings/help_page', anchor: 'destination-requirements')
+ - docs_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: docs_link_url }
+ %span.form-text.text-muted#support_help_block= html_escape(_('Requests for pages at %{code_start}%{help_text_url}%{code_end} redirect to the URL. The destination must meet certain requirements. %{docs_link_start}Learn more.%{docs_link_end}')) % { code_start: '<code>'.html_safe, help_text_url: help_url, code_end: '</code>'.html_safe, docs_link_start: docs_link_start, docs_link_end: '</a>'.html_safe }
= f.submit _('Save changes'), class: "gl-button btn btn-confirm"
diff --git a/app/views/admin/application_settings/_kroki.html.haml b/app/views/admin/application_settings/_kroki.html.haml
index b9da2047453..b22eef83876 100644
--- a/app/views/admin/application_settings/_kroki.html.haml
+++ b/app/views/admin/application_settings/_kroki.html.haml
@@ -6,7 +6,8 @@
%button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' }
= expanded ? _('Collapse') : _('Expand')
%p
- = _('Allow rendering of diagrams in AsciiDoc and Markdown documents using %{link}.').html_safe % { link: link_to('Kroki', 'https://kroki.io', target: '_blank') }
+ = _('Users can render diagrams in AsciiDoc, Markdown, reStructuredText, and Textile documents using Kroki.')
+ = link_to _('Learn more.'), help_page_path('administration/integration/kroki.md'), target: '_blank', rel: 'noopener noreferrer'
.settings-content
= form_for @application_setting, url: general_admin_application_settings_path(anchor: 'js-kroki-settings'), html: { class: 'fieldset-form', id: 'kroki-settings' } do |f|
= form_errors(@application_setting) if expanded
@@ -20,11 +21,15 @@
= f.label :kroki_url, 'Kroki URL', class: 'label-bold'
= f.text_field :kroki_url, class: 'form-control gl-form-input', placeholder: 'http://your-kroki-instance:8000'
.form-text.text-muted
- = (_('When Kroki is enabled, GitLab sends diagrams to an instance of Kroki to display them as images. You can use the free public cloud instance %{kroki_public_url} or you can %{install_link} on your own infrastructure. Once you\'ve installed Kroki, make sure to update the server URL to point to your instance.') % { kroki_public_url: '<code>https://kroki.io</code>', install_link: link_to('install Kroki', 'https://docs.kroki.io/kroki/setup/install/', target: '_blank') }).html_safe
+ - install_link_url = 'https://docs.kroki.io/kroki/setup/install/'
+ - install_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: install_link_url }
+ = html_escape(_('Use the public cloud instance URL (%{kroki_public_url}) or %{install_link_start}install Kroki%{install_link_end} on your own infrastructure and use your own instance URL.')) % { kroki_public_url: '<code>https://kroki.io</code>'.html_safe, install_link_start: install_link_start, install_link_end: '</a>'.html_safe }
.form-group
= f.label :kroki_formats, 'Additional diagram formats', class: 'label-bold'
.form-text.text-muted
- = (_('Using additional formats requires starting the companion containers. Make sure that all %{kroki_images} are running.') % { kroki_images: link_to('required containers', 'https://docs.kroki.io/kroki/setup/install/#_images', target: '_blank') }).html_safe
+ - container_link_url = 'https://docs.kroki.io/kroki/setup/install/#images'
+ - container_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: container_link_url }
+ = html_escape(_('To use the additional formats, you must start the required %{container_link_start}companion containers%{container_link_end}.')) % { container_link_start: container_link_start, container_link_end: '</a>'.html_safe }
- kroki_available_formats.each do |format|
.form-check
= f.check_box format[:name], class: 'form-check-input'
diff --git a/app/views/admin/application_settings/_package_registry.html.haml b/app/views/admin/application_settings/_package_registry.html.haml
index 8de65f267d2..7cdadaaf37b 100644
--- a/app/views/admin/application_settings/_package_registry.html.haml
+++ b/app/views/admin/application_settings/_package_registry.html.haml
@@ -6,7 +6,7 @@
%button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' }
= expanded_by_default? ? _('Collapse') : _('Expand')
%p
- = _("Settings related to the use and experience of using GitLab's Package Registry.")
+ = _("Control how the GitLab Package Registry functions.")
= render_if_exists 'admin/application_settings/ee_package_registry'
diff --git a/app/views/admin/application_settings/_pages.html.haml b/app/views/admin/application_settings/_pages.html.haml
index 5d6443825b7..d14c8cffcc7 100644
--- a/app/views/admin/application_settings/_pages.html.haml
+++ b/app/views/admin/application_settings/_pages.html.haml
@@ -3,42 +3,48 @@
%fieldset
.form-group
- = f.label :max_pages_size, _('Maximum size of pages (MB)'), class: 'label-bold'
- = f.number_field :max_pages_size, class: 'form-control gl-form-input'
- .form-text.text-muted
- = _("0 for unlimited")
- .form-group
.form-check
= f.check_box :pages_domain_verification_enabled, class: 'form-check-input'
= f.label :pages_domain_verification_enabled, class: 'form-check-label' do
- = _("Require users to prove ownership of custom domains")
+ = s_("AdminSettings|Require users to prove ownership of custom domains")
.form-text.text-muted
- = _("Domain verification is an essential security measure for public GitLab sites. Users are required to demonstrate they control a domain before it is enabled")
- = link_to sprite_icon('question-o'), help_page_path('user/project/pages/custom_domains_ssl_tls_certification/index.md', anchor: '4-verify-the-domains-ownership')
+ - pages_link_url = help_page_path('administration/pages/index', anchor: 'custom-domain-verification')
+ - pages_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: pages_link_url }
+ = s_('AdminSettings|Domain verification is an essential security measure for public GitLab sites. Users are required to demonstrate they control a domain before it is enabled. %{link_start}Learn more.%{link_end}').html_safe % { link_start: pages_link_start, link_end: '</a>'.html_safe }
- if Gitlab.config.pages.access_control
.form-group
.form-check
= f.check_box :force_pages_access_control, class: 'form-check-input'
= f.label :force_pages_access_control, class: 'form-check-label' do
- = _("Disable public access to Pages sites")
+ = s_("AdminSettings|Disable public access to Pages sites")
.form-text.text-muted
- = _("Access to Pages websites are controlled based on the user's membership to a given project. By checking this box, users will be required to be logged in to have access to all Pages websites in your instance.")
- = link_to sprite_icon('question-o'), help_page_path('administration/pages/index.md', anchor: 'disabling-public-access-to-all-pages-websites')
+ - pages_link_url = help_page_path('administration/pages/index', anchor: 'disable-public-access-to-all-pages-sites')
+ - pages_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: pages_link_url }
+ = s_("AdminSettings|Select to disable public access for Pages sites, which requires users to sign in for access to the Pages sites in your instance. %{link_start}Learn more.%{link_end}").html_safe % { link_start: pages_link_start, link_end: '</a>'.html_safe }
+ .form-group
+ = f.label :max_pages_size, _('Maximum size of pages (MB)'), class: 'label-bold'
+ = f.number_field :max_pages_size, class: 'form-control gl-form-input'
+ .form-text.text-muted
+ - pages_link_url = help_page_path('administration/pages/index', anchor: 'set-global-maximum-pages-size-per-project')
+ - pages_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: pages_link_url }
+ = s_('AdminSettings|Set the maximum size of GitLab Pages per project (0 for unlimited). %{link_start}Learn more.%{link_end}').html_safe % { link_start: pages_link_start, link_end: '</a>'.html_safe }
%h5
- = _("Configure Let's Encrypt")
+ = s_("AdminSettings|Configure Let's Encrypt")
%p
- lets_encrypt_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: "https://letsencrypt.org/" }
- = _("%{lets_encrypt_link_start}Let's Encrypt%{lets_encrypt_link_end} is a free, automated, and open certificate authority (CA), that give digital certificates in order to enable HTTPS (SSL/TLS) for websites.").html_safe % { lets_encrypt_link_start: lets_encrypt_link_start, lets_encrypt_link_end: '</a>'.html_safe }
- .form-group
- = f.label :lets_encrypt_notification_email, _("Email"), class: 'label-bold'
- = f.text_field :lets_encrypt_notification_email, class: 'form-control gl-form-input'
- .form-text.text-muted
- = _("A Let's Encrypt account will be configured for this GitLab installation using your email address. You will receive emails to warn of expiring certificates.")
- .form-group
- .form-check
- = f.check_box :lets_encrypt_terms_of_service_accepted, class: 'form-check-input'
- = f.label :lets_encrypt_terms_of_service_accepted, class: 'form-check-label' do
- - terms_of_service_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: lets_encrypt_terms_of_service_admin_application_settings_path }
- = _("I have read and agree to the Let's Encrypt %{link_start}Terms of Service%{link_end} (PDF)").html_safe % { link_start: terms_of_service_link_start, link_end: '</a>'.html_safe }
+ = _("%{lets_encrypt_link_start}Let's Encrypt%{lets_encrypt_link_end} is a free, automated, and open certificate authority (CA) that issues digital certificates to enable HTTPS (SSL/TLS) for sites.").html_safe % { lets_encrypt_link_start: lets_encrypt_link_start, lets_encrypt_link_end: '</a>'.html_safe }
+ .form-group
+ = f.label :lets_encrypt_notification_email, s_("AdminSettings|Let's Encrypt email"), class: 'label-bold'
+ = f.text_field :lets_encrypt_notification_email, class: 'form-control gl-form-input'
+ .form-text.text-muted
+ - pages_link_url = help_page_path('administration/pages/index', anchor: 'lets-encrypt-integration')
+ - pages_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: pages_link_url }
+ = s_("AdminSettings|A Let's Encrypt account will be configured for this GitLab instance using this email address. You will receive emails to warn of expiring certificates. %{link_start}Learn more.%{link_end}").html_safe % { link_start: pages_link_start, link_end: '</a>'.html_safe }
+ .form-group
+ .form-check
+ = f.check_box :lets_encrypt_terms_of_service_accepted, class: 'form-check-input'
+ = f.label :lets_encrypt_terms_of_service_accepted, class: 'form-check-label' do
+ - terms_of_service_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: lets_encrypt_terms_of_service_admin_application_settings_path }
+ = s_("AdminSettings|I have read and agree to the Let's Encrypt %{link_start}Terms of Service%{link_end} (PDF).").html_safe % { link_start: terms_of_service_link_start, link_end: '</a>'.html_safe }
= f.submit _('Save changes'), class: "gl-button btn btn-confirm"
diff --git a/app/views/admin/application_settings/_performance_bar.html.haml b/app/views/admin/application_settings/_performance_bar.html.haml
index f603dcab407..ba7d747fa04 100644
--- a/app/views/admin/application_settings/_performance_bar.html.haml
+++ b/app/views/admin/application_settings/_performance_bar.html.haml
@@ -6,9 +6,9 @@
.form-check
= f.check_box :performance_bar_enabled, class: 'form-check-input', data: { qa_selector: 'enable_performance_bar_checkbox'}
= f.label :performance_bar_enabled, class: 'form-check-label' do
- = _("Enable access to the Performance Bar")
+ = _("Allow non-administrators to access to the performance bar")
.form-group
- = f.label :performance_bar_allowed_group_path, _('Allowed group'), class: 'label-bold'
+ = f.label :performance_bar_allowed_group_path, _('Allow access to members of the following group'), class: 'label-bold'
= f.text_field :performance_bar_allowed_group_path, class: 'form-control gl-form-input', placeholder: 'my-org/my-group', value: @application_setting.performance_bar_allowed_group&.full_path
= f.submit _('Save changes'), class: 'gl-button btn btn-confirm qa-save-changes-button'
diff --git a/app/views/admin/application_settings/_plantuml.html.haml b/app/views/admin/application_settings/_plantuml.html.haml
index 632aeec6ce3..39de15dc38d 100644
--- a/app/views/admin/application_settings/_plantuml.html.haml
+++ b/app/views/admin/application_settings/_plantuml.html.haml
@@ -6,7 +6,8 @@
%button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' }
= expanded ? _('Collapse') : _('Expand')
%p
- = _('Allow rendering of PlantUML diagrams in Asciidoc documents.')
+ = _('Render diagrams in your documents using PlantUML.')
+ = link_to _('Learn more.'), help_page_path('administration/integration/plantuml.md'), target: '_blank', rel: 'noopener noreferrer'
.settings-content
= form_for @application_setting, url: general_admin_application_settings_path(anchor: 'js-plantuml-settings'), html: { class: 'fieldset-form', id: 'plantuml-settings' } do |f|
= form_errors(@application_setting) if expanded
@@ -20,8 +21,6 @@
= f.label :plantuml_url, _('PlantUML URL'), class: 'label-bold'
= f.text_field :plantuml_url, class: 'form-control gl-form-input', placeholder: 'http://your-plantuml-instance:8080'
.form-text.text-muted
- Allow rendering of
- = link_to "PlantUML", "http://plantuml.com"
- diagrams in Asciidoc documents using an external PlantUML service.
+ = _('The hostname of your PlantUML server.')
= f.submit _('Save changes'), class: "gl-button btn btn-confirm"
diff --git a/app/views/admin/application_settings/_prometheus.html.haml b/app/views/admin/application_settings/_prometheus.html.haml
index f102b3d580b..59690fdee8b 100644
--- a/app/views/admin/application_settings/_prometheus.html.haml
+++ b/app/views/admin/application_settings/_prometheus.html.haml
@@ -2,26 +2,23 @@
= form_errors(@application_setting)
%fieldset
- %p
- - link_to_restart = link_to(_('restart'), help_page_path('administration/restart_gitlab'))
- = _('Enable a Prometheus metrics endpoint at %{metrics_path} to expose a variety of statistics on the health and performance of GitLab. Additional information on authenticating and connecting to the metrics endpoint is available %{link}.').html_safe % { metrics_path: "<code>#{metrics_path}</code>".html_safe, link: link_to(_('here'), admin_health_check_path) }
- = _('This setting requires a %{link_to_restart} to take effect.').html_safe % { link_to_restart: link_to_restart }
- = link_to sprite_icon('question-o'), help_page_path('administration/monitoring/prometheus/index')
.form-group
.form-check
= f.check_box :prometheus_metrics_enabled, class: 'form-check-input'
= f.label :prometheus_metrics_enabled, class: 'form-check-label' do
- = _("Enable Prometheus Metrics")
+ = _("Enable health and performance metrics endpoint")
+ .form-text.text-muted
+ = _('Enable a Prometheus endpoint that exposes health and performance statistics. The Health Check menu item appears in the Monitoring section of the Admin Area. Restart required.')
+ = link_to _('Learn More.'), help_page_path('administration/monitoring/prometheus/gitlab_metrics.md'), target: '_blank'
- unless Gitlab::Metrics.metrics_folder_present?
.form-text.text-muted
%strong.cred= _("WARNING:")
= _("Environment variable %{code_start}%{environment_variable}%{code_end} does not exist or is not pointing to a valid directory.").html_safe % { environment_variable: prometheus_multiproc_dir, code_start: '<code>'.html_safe, code_end: '</code>'.html_safe }
= link_to sprite_icon('question-o'), help_page_path('administration/monitoring/prometheus/gitlab_metrics', anchor: 'metrics-shared-directory')
.form-group
- = f.label :metrics_method_call_threshold, _('Method Call Threshold (ms)'), class: 'label-bold'
+ = f.label :metrics_method_call_threshold, _('Method call threshold (ms)'), class: 'label-bold'
= f.number_field :metrics_method_call_threshold, class: 'form-control gl-form-input'
.form-text.text-muted
- A method call is only tracked when it takes longer to complete than
- the given amount of milliseconds.
+ Only track method calls that take longer to complete than the given duration.
= f.submit _('Save changes'), class: "gl-button btn btn-confirm"
diff --git a/app/views/admin/application_settings/_realtime.html.haml b/app/views/admin/application_settings/_realtime.html.haml
index 545c27d2a7e..6a7ec05d206 100644
--- a/app/views/admin/application_settings/_realtime.html.haml
+++ b/app/views/admin/application_settings/_realtime.html.haml
@@ -6,7 +6,6 @@
= f.label :polling_interval_multiplier, _('Polling interval multiplier'), class: 'label-bold'
= f.text_field :polling_interval_multiplier, class: 'form-control gl-form-input'
.form-text.text-muted
- = _("Change this value to influence how frequently the GitLab UI polls for updates. If you set the value to 2 all polling intervals are multiplied by 2, which means that polling happens half as frequently. The multiplier can also have a decimal value. The default value (1) is a reasonable choice for the majority of GitLab installations. Set to 0 to completely disable polling.")
- = link_to sprite_icon('question-o'), help_page_path('administration/polling')
+ = _('Multiplier to apply to polling intervals. Decimal values are supported. Defaults to 1.')
= f.submit _('Save changes'), class: "gl-button btn btn-confirm"
diff --git a/app/views/admin/application_settings/_repository_static_objects.html.haml b/app/views/admin/application_settings/_repository_static_objects.html.haml
index f8ec04003fa..d962d050ebc 100644
--- a/app/views/admin/application_settings/_repository_static_objects.html.haml
+++ b/app/views/admin/application_settings/_repository_static_objects.html.haml
@@ -7,12 +7,12 @@
= _('External storage URL')
= f.text_field :static_objects_external_storage_url, class: 'form-control gl-form-input'
%span.form-text.text-muted#static_objects_external_storage_url_help_block
- = _('URL of the external storage that will serve the repository static objects (e.g. archives, blobs, ...).')
+ = _('URL of the external storage to serve the repository static objects.')
.form-group
= f.label :static_objects_external_storage_auth_token, class: 'label-bold' do
= _('External storage authentication token')
= f.text_field :static_objects_external_storage_auth_token, class: 'form-control gl-form-input'
%span.form-text.text-muted#static_objects_external_storage_auth_token_help_block
- = _('A secure token that identifies an external storage request.')
+ = _('Secure token that identifies an external storage request.')
= f.submit _('Save changes'), class: "gl-button btn btn-confirm"
diff --git a/app/views/admin/application_settings/_signin.html.haml b/app/views/admin/application_settings/_signin.html.haml
index 12a9f949750..156e7d3fb76 100644
--- a/app/views/admin/application_settings/_signin.html.haml
+++ b/app/views/admin/application_settings/_signin.html.haml
@@ -6,22 +6,22 @@
.form-check
= f.check_box :password_authentication_enabled_for_web, class: 'form-check-input'
= f.label :password_authentication_enabled_for_web, class: 'form-check-label' do
- = _('Password authentication enabled for web interface')
+ = _('Allow password authentication for the web interface')
.form-text.text-muted
- = _('When disabled, an external authentication provider must be used.')
+ = _('When inactive, an external authentication provider must be used.')
.form-group
.form-check
= f.check_box :password_authentication_enabled_for_git, class: 'form-check-input'
= f.label :password_authentication_enabled_for_git, class: 'form-check-label' do
- = _('Password authentication enabled for Git over HTTP(S)')
+ = _('Allow password authentication for Git over HTTP(S)')
.form-text.text-muted
- When disabled, a Personal Access Token
+ When inactive, a Personal Access Token
- if Gitlab::Auth::Ldap::Config.enabled?
or LDAP password
must be used to authenticate.
- if omniauth_enabled? && button_based_providers.any?
%fieldset.form-group
- %legend.gl-font-base.gl-mb-3.gl-border-none.gl-font-weight-bold= _('Enabled OAuth sign-in sources')
+ %legend.gl-font-base.gl-mb-3.gl-border-none.gl-font-weight-bold= _('Enabled OAuth authentication sources')
= hidden_field_tag 'application_setting[enabled_oauth_sign_in_sources][]'
- oauth_providers_checkboxes.each do |source|
= source
@@ -30,39 +30,44 @@
.form-check
= f.check_box :require_two_factor_authentication, class: 'form-check-input'
= f.label :require_two_factor_authentication, class: 'form-check-label' do
- = _('Require all users to set up two-factor authentication')
+ = _('Enforce two-factor authentication')
+ %p.form-text.text-muted
+ = _('Enforce two-factor authentication for all user sign-ins.')
+ = link_to _('Learn more.'), help_page_path('security/two_factor_authentication.md'), target: '_blank', rel: 'noopener noreferrer'
+ .form-group
+ = f.label :two_factor_authentication, _('Two-factor grace period'), class: 'label-bold'
+ = f.number_field :two_factor_grace_period, min: 0, class: 'form-control gl-form-input', placeholder: '0'
+ .form-text.text-muted
+ = _('Maximum time that users are allowed to skip the setup of two-factor authentication (in hours). Set to 0 (zero) to enforce at next sign in.')
.form-group
= f.label :admin_mode, _('Admin Mode'), class: 'label-bold'
= sprite_icon('lock', css_class: 'gl-icon')
.form-check
= f.check_box :admin_mode, class: 'form-check-input'
= f.label :admin_mode, class: 'form-check-label' do
- = _('Require additional authentication for administrative tasks')
- .form-text.text-muted
- = link_to _('Learn more.'), help_page_path('user/admin_area/settings/sign_in_restrictions', anchor: 'admin-mode')
+ = _('Enable admin mode')
+ %p.form-text.text-muted
+ = _('Require additional authentication for administrative tasks.')
+ = link_to _('Learn more.'), help_page_path('user/admin_area/settings/sign_in_restrictions', anchor: 'admin-mode'), target: '_blank', rel: 'noopener noreferrer'
.form-group
= f.label :unknown_sign_in, _('Email notification for unknown sign-ins'), class: 'label-bold'
.form-check
= f.check_box :notify_on_unknown_sign_in, class: 'form-check-input'
= f.label :notify_on_unknown_sign_in, class: 'form-check-label' do
- = _('Notify users by email when sign-in location is not recognized')
- = link_to sprite_icon('question-o'),
- 'https://docs.gitlab.com/ee/user/profile/unknown_sign_in_notification.html',
- target: '_blank'
- .form-group
- = f.label :two_factor_authentication, _('Two-factor grace period (hours)'), class: 'label-bold'
- = f.number_field :two_factor_grace_period, min: 0, class: 'form-control gl-form-input', placeholder: '0'
- .form-text.text-muted= _('Amount of time (in hours) that users are allowed to skip forced configuration of two-factor authentication')
+ = _('Enable email notification')
+ %p.form-text.text-muted
+ = _('Notify users by email when sign-in location is not recognized.')
+ = link_to _('Learn more.'), help_page_path('user/profile/unknown_sign_in_notification.md'), target: '_blank', rel: 'noopener noreferrer'
.form-group
= f.label :home_page_url, _('Home page URL'), class: 'label-bold'
= f.text_field :home_page_url, class: 'form-control gl-form-input', placeholder: 'http://company.example.com', :'aria-describedby' => 'home_help_block'
- %span.form-text.text-muted#home_help_block= _("We will redirect non-logged in users to this page")
+ %span.form-text.text-muted#home_help_block= _("Direct non-authenticated users to this page.")
.form-group
- = f.label :after_sign_out_path, _('After sign-out path'), class: 'label-bold'
+ = f.label :after_sign_out_path, _('Sign-out page URL'), class: 'label-bold'
= f.text_field :after_sign_out_path, class: 'form-control gl-form-input', placeholder: 'http://company.example.com', :'aria-describedby' => 'after_sign_out_path_help_block'
- %span.form-text.text-muted#after_sign_out_path_help_block= _("We will redirect users to this page after they sign out")
+ %span.form-text.text-muted#home_help_block= _("Direct users to this page after they sign out.")
.form-group
= f.label :sign_in_text, _('Sign-in text'), class: 'label-bold'
= f.text_area :sign_in_text, class: 'form-control gl-form-input', rows: 4
- .form-text.text-muted Markdown enabled
+ %span.form-text.text-muted#home_help_block= _("Add text to the sign-in page. Markdown enabled.")
= f.submit _('Save changes'), class: "gl-button btn btn-confirm"
diff --git a/app/views/admin/application_settings/_signup.html.haml b/app/views/admin/application_settings/_signup.html.haml
index a5b47159239..a658ba63939 100644
--- a/app/views/admin/application_settings/_signup.html.haml
+++ b/app/views/admin/application_settings/_signup.html.haml
@@ -17,4 +17,5 @@
email_restrictions_enabled: @application_setting[:email_restrictions_enabled].to_s,
supported_syntax_link_url: 'https://github.com/google/re2/wiki/Syntax',
email_restrictions: @application_setting.email_restrictions,
- after_sign_up_text: @application_setting[:after_sign_up_text] } }
+ after_sign_up_text: @application_setting[:after_sign_up_text],
+ pending_user_count: pending_user_count } }
diff --git a/app/views/admin/application_settings/_terms.html.haml b/app/views/admin/application_settings/_terms.html.haml
index fe260812ad9..fdf79004c45 100644
--- a/app/views/admin/application_settings/_terms.html.haml
+++ b/app/views/admin/application_settings/_terms.html.haml
@@ -6,13 +6,13 @@
.form-check
= f.check_box :enforce_terms, class: 'form-check-input'
= f.label :enforce_terms, class: 'form-check-label' do
- = _("Require all users to accept Terms of Service and Privacy Policy when they access GitLab.")
+ = _("All users must accept the Terms of Service and Privacy Policy to access GitLab")
.form-text.text-muted
- = _("When enabled, users cannot use GitLab until the terms have been accepted.")
.form-group
= f.label :terms do
= _("Terms of Service Agreement and Privacy Policy")
= f.text_area :terms, class: 'form-control gl-form-input', rows: 8
.form-text.text-muted
- = _("Markdown enabled")
+ = _("Markdown supported.")
+ = link_to _('What is Markdown?'), help_page_path('user/markdown.md'), target: '_blank', rel: 'noopener noreferrer'
= f.submit _("Save changes"), class: "gl-button btn btn-confirm"
diff --git a/app/views/admin/application_settings/_visibility_and_access.html.haml b/app/views/admin/application_settings/_visibility_and_access.html.haml
index 4bf47c3d60d..b6266c3ea34 100644
--- a/app/views/admin/application_settings/_visibility_and_access.html.haml
+++ b/app/views/admin/application_settings/_visibility_and_access.html.haml
@@ -9,6 +9,7 @@
= f.label s_('ProjectCreationLevel|Default project creation protection'), class: 'label-bold'
= f.select :default_project_creation, options_for_select(Gitlab::Access.project_creation_options, @application_setting.default_project_creation), {}, class: 'form-control'
= render_if_exists 'admin/application_settings/default_project_deletion_protection_setting', form: f
+ = render_if_exists 'admin/application_settings/default_delayed_project_deletion_setting', form: f
= render_if_exists 'admin/application_settings/default_project_deletion_adjourned_period_setting', form: f
.form-group.visibility-level-setting
= f.label :default_project_visibility, class: 'label-bold'
diff --git a/app/views/admin/application_settings/appearances/_form.html.haml b/app/views/admin/application_settings/appearances/_form.html.haml
index a48b57bffd9..3bd16e4c344 100644
--- a/app/views/admin/application_settings/appearances/_form.html.haml
+++ b/app/views/admin/application_settings/appearances/_form.html.haml
@@ -40,7 +40,7 @@
= f.hidden_field :favicon_cache
= f.file_field :favicon, class: '', accept: 'image/*'
.hint
- = _("Maximum file size is 1MB. Image size must be 32x32px. Allowed image formats are %{favicon_extension_whitelist}.") % { favicon_extension_whitelist: favicon_extension_whitelist }
+ = _("Maximum file size is 1 MB. Image size must be 32 x 32 pixels. Allowed image formats are %{favicon_extension_whitelist}.") % { favicon_extension_whitelist: favicon_extension_whitelist }
%br
= _("Images with incorrect dimensions are not resized automatically, and may result in unexpected behavior.")
diff --git a/app/views/admin/application_settings/general.html.haml b/app/views/admin/application_settings/general.html.haml
index 53bdbcd7137..9102769cc6e 100644
--- a/app/views/admin/application_settings/general.html.haml
+++ b/app/views/admin/application_settings/general.html.haml
@@ -53,7 +53,8 @@
%button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' }
= expanded_by_default? ? _('Collapse') : _('Expand')
%p
- = _('Set requirements for a user to sign-in. Enable mandatory two-factor authentication.')
+ = _('Set sign-in restrictions for all users.')
+ = link_to _('Learn more.'), help_page_path('user/admin_area/settings/sign_in_restrictions.md'), target: '_blank', rel: 'noopener noreferrer'
.settings-content
= render 'signin'
@@ -64,7 +65,8 @@
%button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' }
= expanded_by_default? ? _('Collapse') : _('Expand')
%p
- = _('Include a Terms of Service agreement and Privacy Policy that all users must accept.')
+ = _('Add a Terms of Service agreement and Privacy Policy for users of this GitLab instance.')
+ = link_to _('Learn more.'), help_page_path('user/admin_area/settings/terms.md'), target: '_blank', rel: 'noopener noreferrer'
.settings-content
= render 'terms'
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 14483e4e55e..f1e37c76130 100644
--- a/app/views/admin/application_settings/metrics_and_profiling.html.haml
+++ b/app/views/admin/application_settings/metrics_and_profiling.html.haml
@@ -11,7 +11,7 @@
%button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' }
= expanded_by_default? ? _('Collapse') : _('Expand')
%p
- = _('Enable and configure Prometheus metrics.')
+ = _('Monitor the health and performance of GitLab with Prometheus.')
.settings-content
= render 'prometheus'
@@ -22,7 +22,9 @@
%button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' }
= expanded_by_default? ? _('Collapse') : _('Expand')
%p
- = _('Enable and configure Grafana.')
+ = _('Link to your Grafana instance.')
+ = link_to s_('Learn more.'), help_page_path('administration/monitoring/performance/grafana_configuration.md'), target: '_blank', rel: 'noopener noreferrer'
+
.settings-content
= render 'grafana'
@@ -33,8 +35,8 @@
%button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' }
= expanded_by_default? ? _('Collapse') : _('Expand')
%p
- = _('Enable access to the Performance Bar for a given group.')
- = link_to sprite_icon('question-o'), help_page_path('administration/monitoring/performance/performance_bar')
+ = _('Enable access to the performance bar for non-administrators in a given group.')
+ = link_to s_('Learn more.'), help_page_path('administration/monitoring/performance/performance_bar.md', anchor: 'enable-the-performance-bar-for-non-administrators'), target: '_blank', rel: 'noopener noreferrer'
.settings-content
= render 'performance_bar'
diff --git a/app/views/admin/application_settings/network.html.haml b/app/views/admin/application_settings/network.html.haml
index 72a27e4523f..0e9dcb23dcb 100644
--- a/app/views/admin/application_settings/network.html.haml
+++ b/app/views/admin/application_settings/network.html.haml
@@ -68,7 +68,8 @@
%button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' }
= expanded_by_default? ? _('Collapse') : _('Expand')
%p
- = _('Configure limit for issues created per minute by web and API requests.')
+ = _('Limit the number of issues and epics per minute a user can create through web and API requests.')
+ = link_to _('Learn more.'), help_page_path('user/admin_area/settings/rate_limit_on_issues_creation.md'), target: '_blank', rel: 'noopener noreferrer'
.settings-content
= render 'issue_limits'
diff --git a/app/views/admin/application_settings/preferences.html.haml b/app/views/admin/application_settings/preferences.html.haml
index 0dfc3d7a60d..9711c335802 100644
--- a/app/views/admin/application_settings/preferences.html.haml
+++ b/app/views/admin/application_settings/preferences.html.haml
@@ -43,18 +43,19 @@
%button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' }
= expanded_by_default? ? _('Collapse') : _('Expand')
%p
- = _('Size and domain settings for static websites')
+ = s_('AdminSettings|Size and domain settings for Pages static sites.')
.settings-content
= render 'pages'
%section.settings.as-realtime.no-animate#js-realtime-settings{ class: ('expanded' if expanded_by_default?) }
.settings-header
%h4
- = _('Real-time features')
+ = _('Polling interval multiplier')
%button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' }
= expanded_by_default? ? _('Collapse') : _('Expand')
%p
- = _('Change this value to influence how frequently the GitLab UI polls for updates.')
+ = _('Adjust how frequently the GitLab UI polls for updates.')
+ = link_to _('Learn more.'), help_page_path('administration/polling.md'), target: '_blank', rel: 'noopener noreferrer'
.settings-content
= render 'realtime'
diff --git a/app/views/admin/application_settings/repository.html.haml b/app/views/admin/application_settings/repository.html.haml
index 2a9fba1aef6..ac200002cd2 100644
--- a/app/views/admin/application_settings/repository.html.haml
+++ b/app/views/admin/application_settings/repository.html.haml
@@ -55,10 +55,11 @@
%section.settings.as-repository-static-objects.no-animate#js-repository-static-objects-settings{ class: ('expanded' if expanded_by_default?) }
.settings-header
%h4
- = _('Repository static objects')
+ = _('External storage for repository static objects')
%button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' }
= expanded_by_default? ? _('Collapse') : _('Expand')
%p
- = _('Serve repository static objects (e.g. archives, blobs, ...) from an external storage (e.g. a CDN).')
+ = _('Serve repository static objects (for example, archives and blobs) from external storage.')
+ = link_to s_('Learn more.'), help_page_path('administration/static_objects_external_storage.md'), target: '_blank', rel: 'noopener noreferrer'
.settings-content
= render 'repository_static_objects'
diff --git a/app/views/admin/applications/_form.html.haml b/app/views/admin/applications/_form.html.haml
index e7e17502da2..74eda21d5bd 100644
--- a/app/views/admin/applications/_form.html.haml
+++ b/app/views/admin/applications/_form.html.haml
@@ -40,5 +40,5 @@
= render 'shared/tokens/scopes_form', prefix: 'doorkeeper_application', token: application, scopes: @scopes
.form-actions
- = f.submit 'Submit', class: "gl-button btn btn-confirm wide"
- = link_to "Cancel", admin_applications_path, class: "gl-button btn btn-default btn-cancel"
+ = f.submit _('Save application'), class: "gl-button btn btn-confirm wide"
+ = link_to _('Cancel'), admin_applications_path, class: "gl-button btn btn-default btn-cancel"
diff --git a/app/views/admin/applications/new.html.haml b/app/views/admin/applications/new.html.haml
index 4d4b6b0c994..731cb51e2e4 100644
--- a/app/views/admin/applications/new.html.haml
+++ b/app/views/admin/applications/new.html.haml
@@ -1,6 +1,7 @@
-- breadcrumb_title _("Applications")
-- page_title _("New Application")
+- breadcrumb_title _("Add new application")
+- page_title _("Add new application")
-%h3.page-title New application
+%h3.page-title
+ = _("Add new application")
- @url = admin_applications_path
= render 'form', application: @application
diff --git a/app/views/admin/applications/show.html.haml b/app/views/admin/applications/show.html.haml
index 8d643a7a4bc..8dcd5f81c23 100644
--- a/app/views/admin/applications/show.html.haml
+++ b/app/views/admin/applications/show.html.haml
@@ -3,47 +3,7 @@
%h3.page-title
Application: #{@application.name}
-.table-holder.oauth-application-show
- %table.table
- %tr
- %td
- = _('Application ID')
- %td
- .clipboard-group
- .input-group
- %input.label.label-monospace.monospace{ id: "application_id", type: "text", autocomplete: 'off', value: @application.uid, readonly: true }
- .input-group-append
- = clipboard_button(target: '#application_id', title: _("Copy ID"), class: "gl-button btn btn-default")
- %tr
- %td
- = _('Secret')
- %td
- .clipboard-group
- .input-group
- %input.label.label-monospace.monospace{ id: "secret", type: "text", autocomplete: 'off', value: @application.secret, readonly: true }
- .input-group-append
- = clipboard_button(target: '#secret', title: _("Copy secret"), class: "gl-button btn btn-default")
- %tr
- %td
- = _('Callback URL')
- %td
- - @application.redirect_uri.split.each do |uri|
- %div
- %span.monospace= uri
- %tr
- %td
- Trusted
- %td
- = @application.trusted? ? 'Y' : 'N'
-
- %tr
- %td
- Confidential
- %td
- = @application.confidential? ? 'Y' : 'N'
-
- = render "shared/tokens/scopes_list", token: @application
-
-.form-actions
- = link_to 'Edit', edit_admin_application_path(@application), class: 'gl-button btn btn-confirm wide float-left'
- = render 'delete_form', application: @application, submit_btn_css: 'gl-button btn btn-danger gl-ml-3'
+= render 'shared/doorkeeper/applications/show',
+ edit_path: edit_admin_application_path(@application),
+ delete_path: admin_application_path(@application),
+ show_trusted_row: true
diff --git a/app/views/admin/dashboard/index.html.haml b/app/views/admin/dashboard/index.html.haml
index ec3daf6c494..97b3a757a3f 100644
--- a/app/views/admin/dashboard/index.html.haml
+++ b/app/views/admin/dashboard/index.html.haml
@@ -118,6 +118,7 @@
- if Gitlab::CurrentSettings.version_check_enabled
.float-right
= version_status_badge
+ = link_to(sprite_icon('question'), "https://gitlab.com/gitlab-org/gitlab/-/blob/master/CHANGELOG.md", class: 'gl-ml-2', target: '_blank', rel: 'noopener noreferrer')
%p
= link_to _('GitLab'), general_admin_application_settings_path
%span.float-right
@@ -151,9 +152,9 @@
%span.float-right
#{Rails::VERSION::STRING}
%p
- = Gitlab::Database.human_adapter_name
+ = Gitlab::Database.main.human_adapter_name
%span.float-right
- = Gitlab::Database.version
+ = Gitlab::Database.main.version
%p
= _('Redis')
%span.float-right
diff --git a/app/views/admin/dev_ops_report/_callout.html.haml b/app/views/admin/dev_ops_report/_callout.html.haml
deleted file mode 100644
index 2b4c258a00c..00000000000
--- a/app/views/admin/dev_ops_report/_callout.html.haml
+++ /dev/null
@@ -1,13 +0,0 @@
-.gl-mt-3
-.user-callout{ data: { uid: 'dev_ops_report_intro_callout_dismissed' } }
- .bordered-box.landing.content-block
- %button.gl-button.btn.btn-default-tertiary.close.js-close-callout{ type: 'button',
- 'aria-label' => _('Dismiss DevOps Report introduction') }
- = sprite_icon('close', size: 16, css_class: 'dismiss-icon')
- .user-callout-copy
- %h4
- = _('Introducing Your DevOps Report')
- %p
- = _('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 0b26548d6e6..208afefc73b 100644
--- a/app/views/admin/dev_ops_report/_report.html.haml
+++ b/app/views/admin/dev_ops_report/_report.html.haml
@@ -1,9 +1,6 @@
- service_ping_enabled = Gitlab::CurrentSettings.usage_ping_enabled
-- if service_ping_enabled && show_callout?('dev_ops_report_intro_callout_dismissed')
- = render 'callout'
-
- 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') } }
+ #js-devops-score{ data: { devops_score_metrics: devops_score_metrics(@metric).to_json, no_data_image_path: image_path('dev_ops_report_no_data.svg'), devops_score_intro_image_path: image_path('dev_ops_report_overview.svg') } }
diff --git a/app/views/admin/groups/_form.html.haml b/app/views/admin/groups/_form.html.haml
index e7e0e58f6fb..91a018121c0 100644
--- a/app/views/admin/groups/_form.html.haml
+++ b/app/views/admin/groups/_form.html.haml
@@ -1,4 +1,4 @@
-= form_for [:admin, @group] do |f|
+= gitlab_ui_form_for [:admin, @group] do |f|
= form_errors(@group)
= render 'shared/group_form', f: f
= render 'shared/group_form_description', f: f
diff --git a/app/views/admin/groups/show.html.haml b/app/views/admin/groups/show.html.haml
index 9b42e1b4967..ae809f01592 100644
--- a/app/views/admin/groups/show.html.haml
+++ b/app/views/admin/groups/show.html.haml
@@ -4,7 +4,6 @@
- page_title @group.name, _("Groups")
- current_user_is_group_owner = @group && @group.has_owner?(current_user)
-.js-remove-member-modal
%h3.page-title
= _('Group: %{group_name}') % { group_name: @group.full_name }
diff --git a/app/views/admin/projects/show.html.haml b/app/views/admin/projects/show.html.haml
index 5c92cbf957e..1a87b21351c 100644
--- a/app/views/admin/projects/show.html.haml
+++ b/app/views/admin/projects/show.html.haml
@@ -5,7 +5,6 @@
- @content_class = "admin-projects"
- current_user_is_group_owner = @group && @group.has_owner?(current_user)
-.js-remove-member-modal
%h3.page-title
= _('Project: %{name}') % { name: @project.full_name }
= link_to edit_project_path(@project), class: "btn btn-default gl-button float-right" do
diff --git a/app/views/admin/runners/_runner.html.haml b/app/views/admin/runners/_runner.html.haml
deleted file mode 100644
index ce143a6b155..00000000000
--- a/app/views/admin/runners/_runner.html.haml
+++ /dev/null
@@ -1,80 +0,0 @@
--# Note: This file should stay aligned with:
--# `app/views/groups/runners/_runner.html.haml`
-
-.gl-responsive-table-row{ data: { testid: "runner-row-#{runner.id}" } }
- .table-section.section-10.section-wrap
- .table-mobile-header{ role: 'rowheader' }= _('Type')
- .table-mobile-content
- - if runner.instance_type?
- %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= s_('Runners|group')
- - else
- %span.badge.badge-pill.gl-badge.sm.badge-info= s_('Runners|specific')
- - if runner.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= s_('Runners|paused')
-
- .table-section.section-30
- .table-mobile-header{ role: 'rowheader' }= s_('Runners|Runner')
- .table-mobile-content
- = link_to("##{runner.id} (#{runner.short_sha})", admin_runner_path(runner))
- .gl-text-truncate
- %span{ title: runner.description, data: { toggle: 'tooltip', container: 'body' } }
- = runner.description
-
- .table-section.section-10
- .table-mobile-header{ role: 'rowheader' }= _('Version')
- .table-mobile-content.str-truncated.has-tooltip{ title: runner.version }
- = runner.version
-
- .table-section.section-10
- .table-mobile-header{ role: 'rowheader' }= _('IP Address')
- .table-mobile-content.str-truncated.has-tooltip{ title: runner.ip_address }
- = runner.ip_address
-
- .table-section.section-5
- .table-mobile-header{ role: 'rowheader' }= _('Projects')
- .table-mobile-content
- - if runner.instance_type? || runner.group_type?
- = _('n/a')
- - else
- = runner.projects.count(:all)
-
- .table-section.section-5
- .table-mobile-header{ role: 'rowheader' }= _('Jobs')
- .table-mobile-content
- = limited_counter_with_delimiter(runner.builds)
-
- .table-section.section-10.section-wrap
- .table-mobile-header{ role: 'rowheader' }= _('Tags')
- .table-mobile-content
- - runner.tags.map(&:name).sort.each do |tag|
- %span.badge.badge-primary.str-truncated.has-tooltip{ title: tag }
- = tag
-
- .table-section.section-10
- .table-mobile-header{ role: 'rowheader' }= _('Last contact')
- .table-mobile-content
- - contacted_at = runner_contacted_at(runner)
- - if contacted_at
- = time_ago_with_tooltip contacted_at
- - else
- = _('Never')
-
- .table-section.table-button-footer.section-10
- .btn-group.table-action-buttons
- .btn-group
- = link_to admin_runner_path(runner), class: 'gl-button btn btn-default btn-icon has-tooltip', title: _('Edit'), ref: 'tooltip', aria: { label: _('Edit') }, data: { placement: 'top', container: 'body'} do
- = sprite_icon('pencil', css_class: 'gl-icon')
- .btn-group
- - if runner.active?
- = link_to [:pause, :admin, runner], method: :post, class: 'gl-button btn btn-default btn-icon has-tooltip', title: _('Pause'), ref: 'tooltip', aria: { label: _('Pause') }, data: { placement: 'top', container: 'body', confirm: _('Are you sure?') } do
- = sprite_icon('pause', css_class: 'gl-icon')
- - else
- = link_to [:resume, :admin, runner], method: :post, class: 'gl-button btn btn-default btn-icon has-tooltip gl-px-3', title: _('Resume'), ref: 'tooltip', aria: { label: _('Resume') }, data: { placement: 'top', container: 'body'} do
- = sprite_icon('play', css_class: 'gl-icon')
- .btn-group
- = link_to [:admin, runner], method: :delete, class: 'gl-button btn btn-danger btn-icon has-tooltip', title: _('Remove'), ref: 'tooltip', aria: { label: _('Remove') }, data: { placement: 'top', container: 'body', confirm: _('Are you sure?') } do
- = sprite_icon('close', css_class: 'gl-icon')
diff --git a/app/views/admin/runners/index.html.haml b/app/views/admin/runners/index.html.haml
index f9c52d9316b..f298fce7bcf 100644
--- a/app/views/admin/runners/index.html.haml
+++ b/app/views/admin/runners/index.html.haml
@@ -1,140 +1,4 @@
- breadcrumb_title _('Runners')
- page_title _('Runners')
-- if Feature.enabled?(:runner_list_view_vue_ui, current_user, default_enabled: :yaml)
- #js-runner-list{ data: { registration_token: Gitlab::CurrentSettings.runners_registration_token, runner_install_help_page: 'https://docs.gitlab.com/runner/install/', active_runners_count: @active_runners_count } }
-- else
- .row
- .col-sm-6
- .bs-callout
- %p
- = _("Runners are processes that pick up and execute CI/CD jobs for GitLab.")
- %br
- = _('You can register runners as separate users, on separate servers, and on your local machine. Register as many runners as you want.')
- %br
-
- %div
- %span= _('Runners can be:')
- %ul
- %li
- %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= s_('Runners|group')
- \-
- = _('Runs jobs from all unassigned projects in its group.')
- %li
- %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= s_('Runners|locked')
- \-
- = _('Cannot be assigned to other projects.')
- %li
- %span.badge.badge-pill.gl-badge.sm.badge-danger= s_('Runners|paused')
- \-
- = _('Not available to run jobs.')
-
- .col-sm-6
- .bs-callout
- = render partial: 'ci/runner/how_to_setup_runner',
- locals: { registration_token: Gitlab::CurrentSettings.runners_registration_token,
- type: s_('Runners|shared'),
- reset_token_url: reset_registration_token_admin_application_settings_path,
- project_path: '',
- group_path: '' }
-
- .row
- .col-sm-9
- = form_tag admin_runners_path, id: 'runners-search', method: :get, class: 'filter-form js-filter-form' do
- .filtered-search-wrapper.d-flex
- .filtered-search-box
- = dropdown_tag(_('Recent searches'),
- options: { wrapper_class: 'filtered-search-history-dropdown-wrapper',
- toggle_class: 'gl-button btn btn-default filtered-search-history-dropdown-toggle-button',
- dropdown_class: 'filtered-search-history-dropdown',
- content_class: 'filtered-search-history-dropdown-content' }) do
- .js-filtered-search-history-dropdown{ data: { full_path: admin_runners_path } }
- .filtered-search-box-input-container.droplab-dropdown
- .scroll-container
- %ul.tokens-container.list-unstyled
- %li.input-token
- %input.form-control.filtered-search{ search_filter_input_options('runners') }
- #js-dropdown-hint.filtered-search-input-dropdown-menu.dropdown-menu.hint-dropdown
- %ul.filter-dropdown{ data: { dynamic: true, dropdown: true } }
- %li.filter-dropdown-item{ data: {hint: "#{'{{hint}}'}", tag: "#{'{{tag}}'}", action: "#{'{{hint === \'search\' ? \'submit\' : \'\' }}'}" } }
- = button_tag class: %w[gl-button btn btn-link] do
- -# Encapsulate static class name `{{icon}}` inside #{} to bypass
- -# haml lint's ClassAttributeWithStaticValue
- %svg
- %use{ 'xlink:href': "#{'{{icon}}'}" }
- %span.js-filter-hint
- {{formattedKey}}
- #js-dropdown-operator.filtered-search-input-dropdown-menu.dropdown-menu
- %ul.filter-dropdown{ data: { dropdown: true, dynamic: true } }
- %li.filter-dropdown-item{ data: { value: "{{ title }}" } }
- %button.gl-button.btn.btn-link{ type: 'button' }
- {{ title }}
- %span.btn-helptext
- {{ help }}
- #js-dropdown-admin-runner-status.filtered-search-input-dropdown-menu.dropdown-menu
- %ul{ data: { dropdown: true } }
- - Ci::Runner::AVAILABLE_STATUSES.each do |status|
- %li.filter-dropdown-item{ data: { value: status } }
- = button_tag class: %w[gl-button btn btn-link] do
- = status.titleize
-
- #js-dropdown-admin-runner-type.filtered-search-input-dropdown-menu.dropdown-menu
- %ul{ data: { dropdown: true } }
- - Ci::Runner::AVAILABLE_TYPES.each do |runner_type|
- %li.filter-dropdown-item{ data: { value: runner_type } }
- = button_tag class: %w[gl-button btn btn-link] do
- = runner_type.titleize
-
- #js-dropdown-admin-runner-type.filtered-search-input-dropdown-menu.dropdown-menu
- %ul{ data: { dropdown: true } }
- - Ci::Runner::AVAILABLE_TYPES.each do |runner_type|
- %li.filter-dropdown-item{ data: { value: runner_type } }
- = button_tag class: %w[gl-button btn btn-link] do
- = runner_type.titleize
-
- #js-dropdown-runner-tag.filtered-search-input-dropdown-menu.dropdown-menu
- %ul{ data: { dropdown: true } }
- %li.filter-dropdown-item{ data: { value: 'none' } }
- %button.gl-button.btn.btn-link
- = _('No Tag')
- %li.divider.droplab-item-ignore
- %ul.filter-dropdown{ data: { dynamic: true, dropdown: true } }
- %li.filter-dropdown-item
- %button.gl-button.btn.btn-link.js-data-value
- %span.dropdown-light-content
- {{name}}
-
- = button_tag class: %w[clear-search hidden] do
- = sprite_icon('close', size: 16, css_class: 'clear-search-icon')
- .filter-dropdown-container
- = render 'sort_dropdown'
-
- .col-sm-3.text-right-lg
- = _('Runners currently online: %{active_runners_count}') % { active_runners_count: @active_runners_count }
- - if @runners.any?
- .content-list{ data: { testid: 'runners-table' } }
- .table-holder
- .gl-responsive-table-row.table-row-header{ role: 'row' }
- .table-section.section-10{ role: 'rowheader' }= _('Type/State')
- .table-section.section-30{ role: 'rowheader' }= s_('Runners|Runner')
- .table-section.section-10{ role: 'rowheader' }= _('Version')
- .table-section.section-10{ role: 'rowheader' }= _('IP Address')
- .table-section.section-5{ role: 'rowheader' }= _('Projects')
- .table-section.section-5{ role: 'rowheader' }= _('Jobs')
- .table-section.section-10{ role: 'rowheader' }= _('Tags')
- .table-section.section-10{ role: 'rowheader' }= _('Last contact')
- .table-section.section-10{ role: 'rowheader' }
-
- - @runners.each do |runner|
- = render 'admin/runners/runner', runner: runner
- = paginate @runners, theme: 'gitlab'
- - else
- .nothing-here-block= _('No runners found')
+#js-admin-runners{ data: { registration_token: Gitlab::CurrentSettings.runners_registration_token, runner_install_help_page: 'https://docs.gitlab.com/runner/install/', active_runners_count: @active_runners_count } }
diff --git a/app/views/admin/services/_form.html.haml b/app/views/admin/services/_form.html.haml
deleted file mode 100644
index 4d9fa6d3d57..00000000000
--- a/app/views/admin/services/_form.html.haml
+++ /dev/null
@@ -1,9 +0,0 @@
-= render "service_templates_deprecated_alert"
-
-%h3.page-title
- = @service.title
-
-%p= @service.description
-
-= form_for :service, url: admin_application_settings_service_path, method: :put, html: { class: 'fieldset-form js-integration-settings-form' } do |form|
- = render 'shared/service_settings', form: form, integration: @service
diff --git a/app/views/admin/services/_service_templates_deprecated_alert.html.haml b/app/views/admin/services/_service_templates_deprecated_alert.html.haml
deleted file mode 100644
index eac2f9c7f4e..00000000000
--- a/app/views/admin/services/_service_templates_deprecated_alert.html.haml
+++ /dev/null
@@ -1,10 +0,0 @@
-- doc_link_start = "<a href=\"#{integrations_help_page_path}\" target='_blank' rel='noopener noreferrer'>".html_safe
-- settings_link_start = "<a href=\"#{integrations_admin_application_settings_path}\">".html_safe
-
-.gl-alert.gl-alert-danger.gl-mt-5{ role: 'alert' }
- .gl-alert-container
- = sprite_icon('error', css_class: 'gl-alert-icon gl-alert-icon-no-title')
- .gl-alert-content
- %h4.gl-alert-title= s_('AdminSettings|Service templates are deprecated and will be removed in GitLab 14.0.')
- .gl-alert-body
- = html_escape_once(s_("AdminSettings|You can't add new templates. To migrate or remove a Service template, create a new integration at %{settings_link_start}Settings &gt; Integrations%{link_end}. Learn more about %{doc_link_start}Project integration management%{link_end}.")).html_safe % { settings_link_start: settings_link_start, doc_link_start: doc_link_start, link_end: '</a>'.html_safe }
diff --git a/app/views/admin/services/edit.html.haml b/app/views/admin/services/edit.html.haml
deleted file mode 100644
index d13b5a34dac..00000000000
--- a/app/views/admin/services/edit.html.haml
+++ /dev/null
@@ -1,6 +0,0 @@
-- add_to_breadcrumbs _("Service Templates"), admin_application_settings_services_path
-- page_title @service.title, _("Service Templates")
-- breadcrumb_title @service.title
-- @content_class = 'limit-container-width' unless fluid_layout
-
-= render 'form'
diff --git a/app/views/admin/services/index.html.haml b/app/views/admin/services/index.html.haml
deleted file mode 100644
index 91706452402..00000000000
--- a/app/views/admin/services/index.html.haml
+++ /dev/null
@@ -1,43 +0,0 @@
-- page_title _("Service Templates")
-- @content_class = 'limit-container-width' unless fluid_layout
-
-= render "service_templates_deprecated_alert"
-
-- if @activated_services.any?
- %h3.page-title Service templates
- %p= s_('AdminSettings|Service template allows you to set default values for integrations')
-
- %table.table.b-table.gl-table
- %colgroup
- %col
- %col
- %col
- %col{ width: 135 }
- %thead
- %tr
- %th
- %th= _('Service')
- %th= _('Description')
- %th= _('Last edit')
- - @activated_services.each do |service|
- - if service.type.in?(@existing_instance_types)
- %tr
- %td
- %td
- = link_to edit_admin_application_settings_integration_path(service.to_param), class: 'gl-text-blue-300!' do
- %strong.has-tooltip{ title: s_('AdminSettings|Moved to integrations'), data: { container: 'body' } }
- = service.title
- %td.gl-cursor-default.gl-text-gray-400
- = service.description
- %td
- - else
- %tr
- %td
- = boolean_to_icon service.activated?
- %td
- = link_to edit_admin_application_settings_service_path(service.id) do
- %strong= service.title
- %td
- = service.description
- %td.light
- = time_ago_with_tooltip service.updated_at
diff --git a/app/views/ci/runner/_how_to_setup_runner.html.haml b/app/views/ci/runner/_how_to_setup_runner.html.haml
index cddea17efbf..24048a8b328 100644
--- a/app/views/ci/runner/_how_to_setup_runner.html.haml
+++ b/app/views/ci/runner/_how_to_setup_runner.html.haml
@@ -1,7 +1,6 @@
- link = link_to _("Install GitLab Runner and ensure it's running."), 'https://docs.gitlab.com/runner/install/', target: '_blank'
.gl-mb-3
- %h5= _("Set up a %{type} runner manually") % { type: type }
-
+ %h5= _("Set up a %{type} Runner for a project") % { type: type }
%ol
%li
= link.html_safe
diff --git a/app/views/ci/runner/_how_to_setup_runner_automatically.html.haml b/app/views/ci/runner/_how_to_setup_runner_automatically.html.haml
deleted file mode 100644
index 7140c0f4e7c..00000000000
--- a/app/views/ci/runner/_how_to_setup_runner_automatically.html.haml
+++ /dev/null
@@ -1,21 +0,0 @@
-%h5= _('Set up a %{type} runner automatically') % { type: type }
-
-%p
- - link_to_help_page = link_to(_('Learn more.'),
- help_page_path('user/project/clusters/index'),
- target: '_blank',
- rel: 'noopener noreferrer')
-
- = _('Register a runner on a Kubernetes cluster. %{link_to_help_page}').html_safe % { link_to_help_page: link_to_help_page }
-
-%ol
- %li
- = _('Click the button below.')
- %li
- = _('Select an existing Kubernetes cluster or create a new one.')
- %li
- = _('From the Kubernetes cluster details view, applications list, install GitLab Runner.')
-
-= link_to _('Install GitLab Runner on Kubernetes'),
- clusters_path,
- class: 'gl-button btn btn-info'
diff --git a/app/views/ci/variables/_index.html.haml b/app/views/ci/variables/_index.html.haml
index 9db5ee23c3e..cdfc174ebf1 100644
--- a/app/views/ci/variables/_index.html.haml
+++ b/app/views/ci/variables/_index.html.haml
@@ -16,6 +16,7 @@
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'),
+ contains_variable_reference_link: help_page_path('ci/variables/index', anchor: 'use-variables-or-in-other-variables'),
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'),
} }
diff --git a/app/views/clusters/clusters/_integrations.html.haml b/app/views/clusters/clusters/_integrations.html.haml
index 96219fa9de5..f136091dad5 100644
--- a/app/views/clusters/clusters/_integrations.html.haml
+++ b/app/views/clusters/clusters/_integrations.html.haml
@@ -5,25 +5,23 @@
.settings-content#integrations-settings-section
- if can?(current_user, :admin_cluster, @cluster)
.sub-section.form-group
- = form_for @prometheus_integration, as: :integration, namespace: :prometheus, url: @cluster.integrations_path, method: :post, html: { class: 'js-cluster-integrations-form' } do |prometheus_form|
+ = gitlab_ui_form_for @prometheus_integration, as: :integration, namespace: :prometheus, url: @cluster.integrations_path, method: :post, html: { class: 'js-cluster-integrations-form' } do |prometheus_form|
= prometheus_form.hidden_field :application_type
.form-group.gl-form-group
- .gl-form-checkbox.custom-control.custom-checkbox
- = prometheus_form.check_box :enabled, class: 'custom-control-input'
- = prometheus_form.label :enabled, s_('ClusterIntegration|Enable Prometheus integration'), class: 'custom-control-label'
- .form-text.text-gl-muted
- = s_('ClusterIntegration|Allows GitLab to query a specifically configured in-cluster Prometheus for metrics.')
- = link_to _('More information.'), help_page_path("user/clusters/integrations", anchor: "prometheus-cluster-integration"), target: '_blank'
+ - help_text = s_('ClusterIntegration|Allows GitLab to query a specifically configured in-cluster Prometheus for metrics.')
+ - help_link = link_to(_('More information.'), help_page_path("user/clusters/integrations", anchor: "prometheus-cluster-integration"), target: '_blank', rel: 'noopener noreferrer')
+ = prometheus_form.gitlab_ui_checkbox_component :enabled,
+ s_('ClusterIntegration|Enable Prometheus integration'),
+ help_text: '%{help_text} %{help_link}'.html_safe % { help_text: help_text, help_link: help_link }
= prometheus_form.submit _('Save changes'), class: 'btn gl-button btn-success'
.sub-section.form-group
- = form_for @elastic_stack_integration, as: :integration, namespace: :elastic_stack, url: @cluster.integrations_path, method: :post, html: { class: 'js-cluster-integrations-form' } do |elastic_stack_form|
+ = gitlab_ui_form_for @elastic_stack_integration, as: :integration, namespace: :elastic_stack, url: @cluster.integrations_path, method: :post, html: { class: 'js-cluster-integrations-form' } do |elastic_stack_form|
= elastic_stack_form.hidden_field :application_type
.form-group.gl-form-group
- .gl-form-checkbox.custom-control.custom-checkbox
- = elastic_stack_form.check_box :enabled, class: 'custom-control-input'
- = elastic_stack_form.label :enabled, s_('ClusterIntegration|Enable Elastic Stack integration'), class: 'custom-control-label'
- .form-text.text-gl-muted
- = s_('ClusterIntegration|Allows GitLab to query a specifically configured in-cluster Elasticsearch for pod logs.')
- = link_to _('More information.'), help_page_path("user/clusters/integrations", anchor: "elastic-stack-cluster-integration"), target: '_blank'
+ - help_text = s_('ClusterIntegration|Allows GitLab to query a specifically configured in-cluster Elasticsearch for pod logs.')
+ - help_link = link_to(_('More information.'), help_page_path("user/clusters/integrations", anchor: "elastic-stack-cluster-integration"), target: '_blank', rel: 'noopener noreferrer')
+ = elastic_stack_form.gitlab_ui_checkbox_component :enabled,
+ s_('ClusterIntegration|Enable Elastic Stack integration'),
+ help_text: '%{help_text} %{help_link}'.html_safe % { help_text: help_text, help_link: help_link }
= elastic_stack_form.submit _('Save changes'), class: 'btn gl-button btn-success'
diff --git a/app/views/clusters/clusters/_multiple_clusters_message.html.haml b/app/views/clusters/clusters/_multiple_clusters_message.html.haml
index f235435d907..ed95744c11d 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: 'use-multiple-kubernetes-clusters')
+- autodevops_help_url = help_page_path('topics/autodevops/multiple_clusters_auto_devops.md')
- help_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe
- help_link_end = '</a>'.html_safe
diff --git a/app/views/dashboard/_projects_head.html.haml b/app/views/dashboard/_projects_head.html.haml
index 90a49e4bbe3..fdaf2107686 100644
--- a/app/views/dashboard/_projects_head.html.haml
+++ b/app/views/dashboard/_projects_head.html.haml
@@ -9,7 +9,7 @@
- if current_user.can_create_project?
.page-title-controls
- = link_to _("New project"), new_project_path, class: "gl-button btn btn-confirm"
+ = link_to _("New project"), new_project_path, class: "gl-button btn btn-confirm", data: { qa_selector: 'new_project_button' }
.top-area.scrolling-tabs-container.inner-page-scroll-tabs
.fade-left= sprite_icon('chevron-lg-left', size: 12)
diff --git a/app/views/devise/shared/_email_opted_in.html.haml b/app/views/devise/shared/_email_opted_in.html.haml
index 6896ef21536..3817f9f651d 100644
--- a/app/views/devise/shared/_email_opted_in.html.haml
+++ b/app/views/devise/shared/_email_opted_in.html.haml
@@ -1,6 +1,6 @@
-- is_hidden = local_assigns.fetch(:hidden, Gitlab.dev_env_or_com?)
+- return unless Gitlab.dev_env_or_com?
-.gl-mb-3.js-email-opt-in{ class: is_hidden ? 'hidden' : '' }
+.gl-mb-3.js-email-opt-in.hidden
.gl-font-weight-bold.gl-mb-3
= _('Email updates (optional)')
= f.check_box :email_opted_in
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 3bc2146b313..8d6e043ebf7 100644
--- a/app/views/groups/_import_group_from_file_panel.html.haml
+++ b/app/views/groups/_import_group_from_file_panel.html.haml
@@ -30,7 +30,8 @@
id: 'import_group_path',
required: true,
pattern: Gitlab::PathRegex::NAMESPACE_FORMAT_REGEX_JS,
- title: _('Please choose a group URL with no special characters.'),
+ title: group_url_error_message,
+ maxlength: ::Namespace::URL_MAX_LENGTH,
"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. We've suggested one that is available.")
diff --git a/app/views/groups/_invite_members_modal.html.haml b/app/views/groups/_invite_members_modal.html.haml
index 3be1a142ca6..78f079df158 100644
--- a/app/views/groups/_invite_members_modal.html.haml
+++ b/app/views/groups/_invite_members_modal.html.haml
@@ -1,8 +1,6 @@
-- return unless can_manage_members?(group)
+- return unless can_admin_group_member?(group)
-.js-invite-members-modal{ data: { id: group.id,
- name: group.name,
- is_project: 'false',
+.js-invite-members-modal{ data: { 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)) }
+ help_link: help_page_url('user/permissions') }.merge(group_select_data(group)).merge(common_invite_modal_dataset(group)).merge(users_filter_data(group)) }
diff --git a/app/views/groups/dependency_proxies/_url.html.haml b/app/views/groups/dependency_proxies/_url.html.haml
index 785ad8f94fd..a8034c50ed8 100644
--- a/app/views/groups/dependency_proxies/_url.html.haml
+++ b/app/views/groups/dependency_proxies/_url.html.haml
@@ -1,6 +1,6 @@
-- proxy_url = group_dependency_proxy_url(@group)
+- proxy_url = group_dependency_proxy_image_prefix(@group)
-%h5.prepend-top-20= _('Dependency proxy URL')
+%h5.prepend-top-20= _('Dependency proxy image prefix')
.row
.col-lg-8.col-md-12.input-group
@@ -8,5 +8,5 @@
= clipboard_button(text: "#{proxy_url}", title: _("Copy %{proxy_url}") % { proxy_url: proxy_url })
.row
- .col-12.help-block.gl-mt-3
+ .col-12.help-block.gl-mt-3{ data: { qa_selector: 'dependency_proxy_count' } }
= _('Contains %{count} blobs of images (%{size})') % { count: @blobs_count, size: number_to_human_size(@blobs_total_size) }
diff --git a/app/views/groups/dependency_proxies/show.html.haml b/app/views/groups/dependency_proxies/show.html.haml
index 5cf4ff4bc26..177018af830 100644
--- a/app/views/groups/dependency_proxies/show.html.haml
+++ b/app/views/groups/dependency_proxies/show.html.haml
@@ -13,7 +13,7 @@
.form-group
%h5.prepend-top-20= _('Enable proxy')
.js-dependency-proxy-toggle-area
- = render "shared/buttons/project_feature_toggle", is_checked: @dependency_proxy.enabled?, label: s_("DependencyProxy|Toggle Dependency Proxy") do
+ = render "shared/buttons/project_feature_toggle", is_checked: @dependency_proxy.enabled?, label: s_("DependencyProxy|Toggle Dependency Proxy"), data: { qa_selector: 'dependency_proxy_setting_toggle' } do
= f.hidden_field :enabled, { class: 'js-project-feature-toggle-input'}
- if @dependency_proxy.enabled
diff --git a/app/views/groups/group_members/index.html.haml b/app/views/groups/group_members/index.html.haml
index c5b8c5e25a3..97867e312af 100644
--- a/app/views/groups/group_members/index.html.haml
+++ b/app/views/groups/group_members/index.html.haml
@@ -2,11 +2,10 @@
- page_title _('Group members')
- groups_select_tag_data = group_select_data(@group).merge({ skip_groups: @skip_groups })
-.js-remove-member-modal
.row.gl-mt-3
.col-lg-12
.gl-display-flex.gl-flex-wrap
- - if can_manage_members?
+ - if can_admin_group_member?(@group)
.gl-w-half.gl-xs-w-full
%h4
= _('Group members')
@@ -21,7 +20,7 @@
trigger_source: 'group-members-page',
display_text: _('Invite members') } }
= render 'groups/invite_members_modal', group: @group
- - if can_manage_members? && Feature.disabled?(:invite_members_group_modal, @group)
+ - if can_admin_group_member?(@group) && Feature.disabled?(:invite_members_group_modal, @group)
%hr.gl-mt-4
%ul.nav-links.nav.nav-tabs.gitlab-tabs{ role: 'tablist' }
%li.nav-tab{ role: 'presentation' }
@@ -36,9 +35,9 @@
= render_if_exists 'groups/group_members/ldap_sync'
- .js-group-members-list-app{ data: { members_data: group_members_app_data_json(@group,
- members: @members,
- invited: @invited_members,
- access_requests: @requesters) } }
+ .js-group-members-list-app{ data: { members_data: group_members_app_data(@group,
+ members: @members,
+ invited: @invited_members,
+ access_requests: @requesters).to_json } }
.loading
.gl-spinner.gl-spinner-md
diff --git a/app/views/groups/runners/_group_runners.html.haml b/app/views/groups/runners/_group_runners.html.haml
index 49e297ee13d..1cccce9f59a 100644
--- a/app/views/groups/runners/_group_runners.html.haml
+++ b/app/views/groups/runners/_group_runners.html.haml
@@ -3,17 +3,14 @@
%h4
= _('Group runners')
-%p
- = _('These runners are shared across projects in this group.')
- = _('Group runners can be managed with the %{link}.').html_safe % { link: link }
-
-# Proper policies should be implemented per
-# https://gitlab.com/gitlab-org/gitlab-foss/issues/45894
.bs-callout.help-callout
+ %p
+ = _('These runners are shared across projects in this group.')
+ = _('Group runners can be managed with the %{link}.').html_safe % { link: link }
+
- 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',
diff --git a/app/views/groups/runners/_settings.html.haml b/app/views/groups/runners/_settings.html.haml
index 187588f5f11..55960703f9a 100644
--- a/app/views/groups/runners/_settings.html.haml
+++ b/app/views/groups/runners/_settings.html.haml
@@ -75,7 +75,7 @@
= button_tag class: 'clear-search hidden' do
= sprite_icon('close', size: 16, css_class: 'clear-search-icon')
.filter-dropdown-container
- = render 'admin/runners/sort_dropdown'
+ = render 'groups/runners/sort_dropdown'
.col-sm-3.text-right-lg
= _('Runners currently online: %{active_runners_count}') % { active_runners_count: limited_counter_with_delimiter(@all_group_runners.online) }
@@ -96,6 +96,7 @@
.table-section.section-10{ role: 'rowheader' }
- @group_runners.each do |runner|
+ - runner = runner.present(current_user: current_user)
= render 'groups/runners/runner', runner: runner
= paginate @group_runners, theme: 'gitlab', :params => { :anchor => 'runners-settings' }
- else
diff --git a/app/views/admin/runners/_sort_dropdown.html.haml b/app/views/groups/runners/_sort_dropdown.html.haml
index c6627ae0f27..e914bd00dac 100644
--- a/app/views/admin/runners/_sort_dropdown.html.haml
+++ b/app/views/groups/runners/_sort_dropdown.html.haml
@@ -1,4 +1,4 @@
-- sorted_by = sort_options_hash[@sort]
+- sorted_by = sort_options_hash[@sort] || sort_title_created_date
.dropdown.inline.gl-ml-3
%button.dropdown-menu-toggle{ type: 'button', data: { toggle: 'dropdown', display: 'static' } }
@@ -8,4 +8,3 @@
%li
= sortable_item(sort_title_created_date, page_filter_path(sort: sort_value_created_date), sorted_by)
= sortable_item(sort_title_contacted_date, page_filter_path(sort: sort_value_contacted_date), sorted_by)
-
diff --git a/app/views/groups/runners/index.html.haml b/app/views/groups/runners/index.html.haml
new file mode 100644
index 00000000000..4e7bc99b1f0
--- /dev/null
+++ b/app/views/groups/runners/index.html.haml
@@ -0,0 +1,6 @@
+- page_title s_('Runners|Runners')
+
+%h2.page-title
+ = s_('Runners|Group Runners')
+
+#js-group-runners{ data: { registration_token: @group.runners_token, group_id: @group.id } }
diff --git a/app/views/groups/settings/_advanced.html.haml b/app/views/groups/settings/_advanced.html.haml
index fea0736ffc8..cdff533e3c7 100644
--- a/app/views/groups/settings/_advanced.html.haml
+++ b/app/views/groups/settings/_advanced.html.haml
@@ -20,10 +20,12 @@
= f.text_field :path, placeholder: 'open-source', class: 'form-control',
autofocus: local_assigns[:autofocus] || false, required: true,
pattern: Gitlab::PathRegex::NAMESPACE_FORMAT_REGEX_JS,
- title: s_('GroupSettings|Please choose a group URL with no special characters.'),
+ title: group_url_error_message,
+ maxlength: ::Namespace::URL_MAX_LENGTH,
"data-bind-in" => "#{'create_chat_team' if Gitlab.config.mattermost.enabled}"
= f.submit s_('GroupSettings|Change group URL'), class: 'btn gl-button btn-warning'
= render 'groups/settings/transfer', group: @group
= render 'groups/settings/remove', group: @group
= render_if_exists 'groups/settings/restore', group: @group
+= render_if_exists 'groups/settings/immediately_remove', group: @group
diff --git a/app/views/groups/settings/_lfs.html.haml b/app/views/groups/settings/_lfs.html.haml
index b16c9faafa4..1255a2901ea 100644
--- a/app/views/groups/settings/_lfs.html.haml
+++ b/app/views/groups/settings/_lfs.html.haml
@@ -6,8 +6,7 @@
%p= s_('Check the %{docs_link_start}documentation%{docs_link_end}.').html_safe % { docs_link_start: docs_link_start, docs_link_end: '</a>'.html_safe }
.form-group.gl-mb-3
- .gl-form-checkbox.custom-control.custom-checkbox
- = f.check_box :lfs_enabled, checked: @group.lfs_enabled?, class: 'custom-control-input', data: { qa_selector: 'lfs_checkbox' }
- = f.label :lfs_enabled, class: 'custom-control-label' do
- = _('Allow projects within this group to use Git LFS')
- %p.help-text= _('This setting can be overridden in each project.')
+ = f.gitlab_ui_checkbox_component :lfs_enabled,
+ _('Allow projects within this group to use Git LFS'),
+ help_text: _('This setting can be overridden in each project.'),
+ checkbox_options: { checked: @group.lfs_enabled?, data: { qa_selector: 'lfs_checkbox' } }
diff --git a/app/views/groups/settings/_permissions.html.haml b/app/views/groups/settings/_permissions.html.haml
index d1f356ed665..683e70248b6 100644
--- a/app/views/groups/settings/_permissions.html.haml
+++ b/app/views/groups/settings/_permissions.html.haml
@@ -1,4 +1,4 @@
-= form_for @group, html: { multipart: true, class: 'gl-show-field-errors js-general-permissions-form' }, authenticity_token: true do |f|
+= gitlab_ui_form_for @group, html: { multipart: true, class: 'gl-show-field-errors js-general-permissions-form' }, authenticity_token: true do |f|
%input{ type: 'hidden', name: 'update_section', value: 'js-permissions-settings' }
= form_errors(@group)
@@ -9,34 +9,28 @@
- if @group.root?
.form-group.gl-mb-3
- .gl-form-checkbox.custom-control.custom-checkbox
- = f.check_box :prevent_sharing_groups_outside_hierarchy, disabled: !can_change_prevent_sharing_groups_outside_hierarchy?(@group), class: 'custom-control-input'
- = f.label :prevent_sharing_groups_outside_hierarchy, class: 'custom-control-label' do
- %span
- = s_('GroupSettings|Prevent members from sending invitations to groups outside of %{group} and its subgroups.').html_safe % { group: link_to_group(@group) }
- %p.js-descr.help-text= prevent_sharing_groups_outside_hierarchy_help_text(@group)
+ = f.gitlab_ui_checkbox_component :prevent_sharing_groups_outside_hierarchy,
+ s_('GroupSettings|Prevent members from sending invitations to groups outside of %{group} and its subgroups.').html_safe % { group: link_to_group(@group) },
+ help_text: prevent_sharing_groups_outside_hierarchy_help_text(@group),
+ checkbox_options: { disabled: !can_change_prevent_sharing_groups_outside_hierarchy?(@group) }
.form-group.gl-mb-3
- .gl-form-checkbox.custom-control.custom-checkbox
- = f.check_box :share_with_group_lock, disabled: !can_change_share_with_group_lock?(@group), class: 'custom-control-input'
- = f.label :share_with_group_lock, class: 'custom-control-label' do
- %span
- = s_('GroupSettings|Prevent sharing a project within %{group} with other groups').html_safe % { group: link_to_group(@group) }
- %p.js-descr.help-text= share_with_group_lock_help_text(@group)
+ = f.gitlab_ui_checkbox_component :share_with_group_lock,
+ s_('GroupSettings|Prevent sharing a project within %{group} with other groups').html_safe % { group: link_to_group(@group) },
+ checkbox_options: { disabled: !can_change_share_with_group_lock?(@group) },
+ help_text: share_with_group_lock_help_text(@group)
.form-group.gl-mb-3
- .gl-form-checkbox.custom-control.custom-checkbox
- = f.check_box :emails_disabled, checked: @group.emails_disabled?, disabled: !can_disable_group_emails?(@group), class: 'custom-control-input'
- = f.label :emails_disabled, class: 'custom-control-label' do
- %span= s_('GroupSettings|Disable email notifications')
- %p.help-text= s_('GroupSettings|This setting will override user notification preferences for all members of the group, subgroups, and projects.')
+ = f.gitlab_ui_checkbox_component :emails_disabled,
+ s_('GroupSettings|Disable email notifications'),
+ checkbox_options: { checked: @group.emails_disabled?, disabled: !can_disable_group_emails?(@group) },
+ help_text: s_('GroupSettings|This setting will override user notification preferences for all members of the group, subgroups, and projects.')
.form-group.gl-mb-3
- .gl-form-checkbox.custom-control.custom-checkbox
- = f.check_box :mentions_disabled, checked: @group.mentions_disabled?, class: 'custom-control-input'
- = f.label :mentions_disabled, class: 'custom-control-label' do
- %span= s_('GroupSettings|Disable group mentions')
- %p.help-text= s_('GroupSettings|This setting will prevent group members from being notified if the group is mentioned.')
+ = f.gitlab_ui_checkbox_component :mentions_disabled,
+ s_('GroupSettings|Disable group mentions'),
+ checkbox_options: { checked: @group.mentions_disabled? },
+ help_text: s_('GroupSettings|This setting will prevent group members from being notified if the group is mentioned.')
= render 'groups/settings/project_access_token_creation', f: f, group: @group
= render_if_exists 'groups/settings/delayed_project_removal', f: f, group: @group
diff --git a/app/views/groups/settings/_project_access_token_creation.html.haml b/app/views/groups/settings/_project_access_token_creation.html.haml
index 8be17c6cc30..948b25390ba 100644
--- a/app/views/groups/settings/_project_access_token_creation.html.haml
+++ b/app/views/groups/settings/_project_access_token_creation.html.haml
@@ -1,10 +1,9 @@
- return unless render_setting_to_allow_project_access_token_creation?(group)
.form-group.gl-mb-3
- .gl-form-checkbox.custom-control.custom-checkbox
- = f.check_box :resource_access_token_creation_allowed, checked: group.namespace_settings.resource_access_token_creation_allowed?, class: 'custom-control-input', data: { qa_selector: 'resource_access_token_creation_allowed_checkbox' }
- = f.label :resource_access_token_creation_allowed, class: 'custom-control-label' do
- %span= s_('GroupSettings|Allow project access token creation')
- - project_access_tokens_link = help_page_path('user/project/settings/project_access_tokens')
- - link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: project_access_tokens_link }
- %p.help-text= s_('GroupSettings|Users can create %{link_start}project access tokens%{link_end} for projects in this group.').html_safe % { link_start: link_start, link_end: '</a>'.html_safe }
+ - project_access_tokens_link = help_page_path('user/project/settings/project_access_tokens')
+ - link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: project_access_tokens_link }
+ = f.gitlab_ui_checkbox_component :resource_access_token_creation_allowed,
+ s_('GroupSettings|Allow project access token creation'),
+ checkbox_options: { checked: group.namespace_settings.resource_access_token_creation_allowed?, data: { qa_selector: 'resource_access_token_creation_allowed_checkbox' } },
+ help_text: s_('GroupSettings|Users can create %{link_start}project access tokens%{link_end} for projects in this group.').html_safe % { link_start: link_start, link_end: '</a>'.html_safe }
diff --git a/app/views/groups/settings/_two_factor_auth.html.haml b/app/views/groups/settings/_two_factor_auth.html.haml
index bd3b3283288..9e5eeee2e2a 100644
--- a/app/views/groups/settings/_two_factor_auth.html.haml
+++ b/app/views/groups/settings/_two_factor_auth.html.haml
@@ -7,17 +7,15 @@
%p= s_('Check the %{docs_link_start}documentation%{docs_link_end}.').html_safe % { docs_link_start: docs_link_start, docs_link_end: '</a>'.html_safe }
.form-group
- .gl-form-checkbox.custom-control.custom-checkbox
- = f.check_box :require_two_factor_authentication, class: 'custom-control-input', data: { qa_selector: 'require_2fa_checkbox' }
- = f.label :require_two_factor_authentication, class: 'custom-control-label' do
- = _('Require all users in this group to setup two-factor authentication')
+ = f.gitlab_ui_checkbox_component :require_two_factor_authentication,
+ _('Require all users in this group to setup two-factor authentication'),
+ checkbox_options: { data: { qa_selector: 'require_2fa_checkbox' } }
.form-group
= f.label :two_factor_grace_period, _('Time before enforced'), class: 'label-bold'
= f.text_field :two_factor_grace_period, class: 'form-control form-control-sm w-auto'
.form-text.text-muted= _('Amount of time (in hours) that users are allowed to skip forced configuration of two-factor authentication')
- unless group.has_parent?
.form-group
- .gl-form-checkbox.custom-control.custom-checkbox
- = f.check_box :allow_mfa_for_subgroups, class: 'custom-control-input', checked: group.namespace_settings&.allow_mfa_for_subgroups
- = f.label :allow_mfa_for_subgroups, class: 'custom-control-label' do
- = _('Allow subgroups to set up their own two-factor authentication rules')
+ = f.gitlab_ui_checkbox_component :allow_mfa_for_subgroups,
+ _('Allow subgroups to set up their own two-factor authentication rules'),
+ checkbox_options: { checked: group.namespace_settings&.allow_mfa_for_subgroups }
diff --git a/app/views/groups/sidebar/_packages.html.haml b/app/views/groups/sidebar/_packages.html.haml
deleted file mode 100644
index e0158e4bf22..00000000000
--- a/app/views/groups/sidebar/_packages.html.haml
+++ /dev/null
@@ -1,27 +0,0 @@
-- packages_link = group_packages_list_nav? ? group_packages_path(@group) : group_container_registries_path(@group)
-
-- if group_packages_nav?
- = nav_link(controller: ['groups/packages', 'groups/registry/repositories', 'groups/dependency_proxies']) do
- = link_to packages_link, title: _('Packages'), class: 'has-sub-items' do
- .nav-icon-container
- = sprite_icon('package')
- %span.nav-item-name
- = _('Packages & Registries')
- %ul.sidebar-sub-level-items
- = nav_link(controller: [:packages, :repositories], html_options: { class: "fly-out-top-item" } ) do
- = link_to packages_link, title: _('Packages & Registries') do
- %strong.fly-out-top-item-name
- = _('Packages & Registries')
- %li.divider.fly-out-top-item
- - if group_packages_list_nav?
- = nav_link(controller: 'groups/packages') do
- = link_to group_packages_path(@group), title: _('Packages') do
- %span= _('Package Registry')
- - if group_container_registry_nav?
- = nav_link(controller: 'groups/registry/repositories') do
- = link_to group_container_registries_path(@group), title: _('Container Registry') do
- %span= _('Container Registry')
- - if group_dependency_proxy_nav?
- = nav_link(controller: 'groups/dependency_proxies') do
- = link_to group_dependency_proxy_path(@group), title: _('Dependency Proxy') do
- %span= _('Dependency Proxy')
diff --git a/app/views/groups/sidebar/_packages_settings.html.haml b/app/views/groups/sidebar/_packages_settings.html.haml
deleted file mode 100644
index 78533aba75f..00000000000
--- a/app/views/groups/sidebar/_packages_settings.html.haml
+++ /dev/null
@@ -1,5 +0,0 @@
-- if group_packages_list_nav?
- = nav_link(controller: :packages_and_registries) do
- = link_to group_settings_packages_and_registries_path(@group), title: _('Packages & Registries'), data: { qa_selector: 'group_package_settings_link' } do
- %span
- = _('Packages & Registries')
diff --git a/app/views/help/instance_configuration.html.haml b/app/views/help/instance_configuration.html.haml
index 1cd05dcf65e..88c531535b4 100644
--- a/app/views/help/instance_configuration.html.haml
+++ b/app/views/help/instance_configuration.html.haml
@@ -8,6 +8,8 @@
= render 'help/instance_configuration/ssh_info'
= render 'help/instance_configuration/gitlab_pages'
= render 'help/instance_configuration/gitlab_ci'
+ = render 'help/instance_configuration/package_registry'
+ = render 'help/instance_configuration/rate_limits'
%p
%strong= _("Table of contents")
diff --git a/app/views/help/instance_configuration/_package_registry.html.haml b/app/views/help/instance_configuration/_package_registry.html.haml
new file mode 100644
index 00000000000..38202b8d6e6
--- /dev/null
+++ b/app/views/help/instance_configuration/_package_registry.html.haml
@@ -0,0 +1,48 @@
+- package_file_size_limits = @instance_configuration.settings[:package_file_size_limits]
+- content_for :table_content do
+ - if package_file_size_limits.present?
+ %li= link_to _('Package Registry'), '#package-registry'
+
+- content_for :settings_content do
+ - if package_file_size_limits.present?
+ %h2#package-registry
+ = _('Package Registry')
+
+ %p
+ = _('There are several file size limits in place for the Package Registry.')
+ .table-responsive
+ %table
+ %thead
+ %tr
+ %th= _('Package type')
+ - package_file_size_limits.each_key do |title|
+ %th= title
+ %tbody
+ %tr
+ %td= 'Conan'
+ - package_file_size_limits.each_value do |limits|
+ %td= instance_configuration_human_size_cell(limits[:conan])
+ %tr
+ %td= 'Maven'
+ - package_file_size_limits.each_value do |limits|
+ %td= instance_configuration_human_size_cell(limits[:maven])
+ %tr
+ %td= 'npm'
+ - package_file_size_limits.each_value do |limits|
+ %td= instance_configuration_human_size_cell(limits[:npm])
+ %tr
+ %td= 'NuGet'
+ - package_file_size_limits.each_value do |limits|
+ %td= instance_configuration_human_size_cell(limits[:nuget])
+ %tr
+ %td= 'PyPI'
+ - package_file_size_limits.each_value do |limits|
+ %td= instance_configuration_human_size_cell(limits[:pypi])
+ %tr
+ %td= 'Terraform Module'
+ - package_file_size_limits.each_value do |limits|
+ %td= instance_configuration_human_size_cell(limits[:terraform_module])
+ %tr
+ %td= _('Generic')
+ - package_file_size_limits.each_value do |limits|
+ %td= instance_configuration_human_size_cell(limits[:generic])
diff --git a/app/views/help/instance_configuration/_rate_limit_row.html.haml b/app/views/help/instance_configuration/_rate_limit_row.html.haml
new file mode 100644
index 00000000000..85c165de7d4
--- /dev/null
+++ b/app/views/help/instance_configuration/_rate_limit_row.html.haml
@@ -0,0 +1,7 @@
+- public_visible = local_assigns.fetch(:public_visible, false)
+
+- if rate_limit && (public_visible || user_signed_in?)
+ %tr
+ %td= title
+ %td= instance_configuration_cell_html(rate_limit[:enabled] ? rate_limit[:requests_per_period] : nil)
+ %td= instance_configuration_cell_html(rate_limit[:enabled] ? rate_limit[:period_in_seconds] : nil)
diff --git a/app/views/help/instance_configuration/_rate_limits.html.haml b/app/views/help/instance_configuration/_rate_limits.html.haml
new file mode 100644
index 00000000000..d72bd845c5b
--- /dev/null
+++ b/app/views/help/instance_configuration/_rate_limits.html.haml
@@ -0,0 +1,36 @@
+- rate_limits = @instance_configuration.settings[:rate_limits]
+- content_for :table_content do
+ - if rate_limits
+ %li= link_to _('Rate Limits'), '#rate-limits'
+
+- content_for :settings_content do
+ - if rate_limits
+ %h2#rate-limits
+ = _('Rate Limits')
+
+ %p
+ = _('There are several rate limits in place to protect the system.')
+ .table-responsive
+ %table
+ %thead
+ %tr
+ %th= _('Rate limit')
+ %th= _('Requests per period')
+ %th= _('Period in seconds')
+ %tbody
+ = render 'help/instance_configuration/rate_limit_row', title: _('Unauthenticated requests'), rate_limit: rate_limits[:unauthenticated], public_visible: true
+ = render 'help/instance_configuration/rate_limit_row', title: _('Authenticated API requests'), rate_limit: rate_limits[:authenticated_api]
+ = render 'help/instance_configuration/rate_limit_row', title: _('Authenticated web requests'), rate_limit: rate_limits[:authenticated_web]
+ = render 'help/instance_configuration/rate_limit_row', title: _('Protected Paths: requests'), rate_limit: rate_limits[:protected_paths]
+ = render 'help/instance_configuration/rate_limit_row', title: _('Package Registry: unauthenticated API requests'), rate_limit: rate_limits[:unauthenticated_packages_api], public_visible: true
+ = render 'help/instance_configuration/rate_limit_row', title: _('Package Registry: authenticated API requests'), rate_limit: rate_limits[:authenticated_packages_api]
+ = render 'help/instance_configuration/rate_limit_row', title: _('Issue creation requests'), rate_limit: rate_limits[:issue_creation]
+ = render 'help/instance_configuration/rate_limit_row', title: _('Note creation requests'), rate_limit: rate_limits[:note_creation]
+ = render 'help/instance_configuration/rate_limit_row', title: _('Project export requests'), rate_limit: rate_limits[:project_export]
+ = render 'help/instance_configuration/rate_limit_row', title: _('Project export download requests'), rate_limit: rate_limits[:project_export_download]
+ = render 'help/instance_configuration/rate_limit_row', title: _('Project import requests'), rate_limit: rate_limits[:project_import]
+ = render 'help/instance_configuration/rate_limit_row', title: _('Group export requests'), rate_limit: rate_limits[:group_export]
+ = render 'help/instance_configuration/rate_limit_row', title: _('Group export download requests'), rate_limit: rate_limits[:group_export_download]
+ = render 'help/instance_configuration/rate_limit_row', title: _('Group import requests'), rate_limit: rate_limits[:group_import]
+ = render 'help/instance_configuration/rate_limit_row', title: _('Raw blob requests'), rate_limit: rate_limits[:raw_blob]
+ %br
diff --git a/app/views/import/bulk_imports/status.html.haml b/app/views/import/bulk_imports/status.html.haml
index cd90c76ed10..2aae8811678 100644
--- a/app/views/import/bulk_imports/status.html.haml
+++ b/app/views/import/bulk_imports/status.html.haml
@@ -1,10 +1,11 @@
- add_to_breadcrumbs _('New group'), new_group_path
- add_page_specific_style 'page_bundles/import'
-- breadcrumb_title _('Import groups')
+- page_title _('Import groups')
#import-groups-mount-element{ data: { status_path: status_import_bulk_imports_path(format: :json),
available_namespaces_path: import_available_namespaces_path(format: :json),
create_bulk_import_path: import_bulk_imports_path(format: :json),
jobs_path: realtime_changes_import_bulk_imports_path(format: :json),
source_url: @source_url,
- group_path_regex: Gitlab::PathRegex::NAMESPACE_FORMAT_REGEX_JS } }
+ group_path_regex: Gitlab::PathRegex::NAMESPACE_FORMAT_REGEX_JS,
+ group_url_error_message: group_url_error_message } }
diff --git a/app/views/jira_connect/branches/new.html.haml b/app/views/jira_connect/branches/new.html.haml
new file mode 100644
index 00000000000..f0e34c30018
--- /dev/null
+++ b/app/views/jira_connect/branches/new.html.haml
@@ -0,0 +1,5 @@
+- @hide_breadcrumbs = true
+- @hide_top_links = true
+- page_title _('New branch')
+
+.js-jira-connect-create-branch{ data: @new_branch_data }
diff --git a/app/views/jira_connect/subscriptions/index.html.haml b/app/views/jira_connect/subscriptions/index.html.haml
index 43672551caf..cbe9a860210 100644
--- a/app/views/jira_connect/subscriptions/index.html.haml
+++ b/app/views/jira_connect/subscriptions/index.html.haml
@@ -24,9 +24,10 @@
%p.jira-connect-app-body.gl-px-5.gl-mt-7.gl-font-base.gl-text-center
%strong= s_('Integrations|Browser limitations')
- - firefox_link_url = 'https://www.mozilla.org/en-US/firefox/'
- - firefox_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: firefox_link_url }
- = s_('Integrations|Adding a namespace works only in browsers that allow cross‑site cookies. Use %{firefox_link_start}Firefox%{firefox_link_end}, or enable cross‑site cookies in your browser, when adding a namespace.').html_safe % { firefox_link_start: firefox_link_start, firefox_link_end: '</a>'.html_safe }
+ - browser_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'
+ - firefox_link_start = browser_link_start.html_safe % { url: 'https://www.mozilla.org/en-US/firefox/' }
+ - chrome_link_start = browser_link_start.html_safe % { url: 'https://www.google.com/chrome/' }
+ = s_('Integrations|Adding a namespace works only in browsers that allow cross‑site cookies. Use %{firefox_link_start}Firefox%{link_end}, %{chrome_link_start}Google Chrome%{link_end}, or enable cross‑site cookies in your browser, when adding a namespace.').html_safe % { firefox_link_start: firefox_link_start, chrome_link_start: chrome_link_start, link_end: '</a>'.html_safe }
= link_to _('Learn more'), 'https://gitlab.com/gitlab-org/gitlab/-/issues/284211', target: '_blank', rel: 'noopener noreferrer'
= webpack_bundle_tag 'performance_bar' if performance_bar_enabled?
diff --git a/app/views/layouts/_head.html.haml b/app/views/layouts/_head.html.haml
index 683d3a6ad1b..a89c621a55c 100644
--- a/app/views/layouts/_head.html.haml
+++ b/app/views/layouts/_head.html.haml
@@ -44,7 +44,7 @@
- else
= stylesheet_link_tag_defer "application"
= yield :page_specific_styles
- = stylesheet_link_tag_defer "application_utilities"
+ = stylesheet_link_tag_defer 'application_utilities'
= stylesheet_link_tag "disable_animations", media: "all" if Rails.env.test? || Gitlab.config.gitlab['disable_animations']
= stylesheet_link_tag "test_environment", media: "all" if Rails.env.test?
diff --git a/app/views/layouts/_loading_hints.html.haml b/app/views/layouts/_loading_hints.html.haml
index c431f05c217..e2189009045 100644
--- a/app/views/layouts/_loading_hints.html.haml
+++ b/app/views/layouts/_loading_hints.html.haml
@@ -1,11 +1,15 @@
= cache_if(Feature.enabled?(:cached_loading_hints, current_user), [ActionController::Base.asset_host, user_application_theme, user_color_scheme], expires_in: 1.minute) do
+ - css_crossorigin = ActionController::Base.asset_host ? 'anonymous' : nil
+
- if ActionController::Base.asset_host
%link{ rel: 'dns-prefetch', href: ActionController::Base.asset_host }
%link{ rel: 'preconnect', href: ActionController::Base.asset_host, crossorigin: '' }
- if user_application_theme == 'gl-dark'
- %link{ { rel: 'preload', href: stylesheet_url('application_dark'), as: 'style' }, ActionController::Base.asset_host ? { crossorigin: 'anonymous' } : {} }
+ = preload_link_tag(path_to_stylesheet('application_utilities_dark'), crossorigin: css_crossorigin)
+ = preload_link_tag(path_to_stylesheet('application_dark'), crossorigin: css_crossorigin)
- 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' } : {} }
+ = preload_link_tag(path_to_stylesheet('application_utilities'), crossorigin: css_crossorigin)
+ = preload_link_tag(path_to_stylesheet('application'), crossorigin: css_crossorigin)
+ = preload_link_tag(path_to_stylesheet("highlight/themes/#{user_color_scheme}"), crossorigin: css_crossorigin)
- 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/_mailer.html.haml b/app/views/layouts/_mailer.html.haml
index 74d05be7f95..95ebe09a2e6 100644
--- a/app/views/layouts/_mailer.html.haml
+++ b/app/views/layouts/_mailer.html.haml
@@ -14,6 +14,7 @@
= stylesheet_link_tag 'mailer.css'
%body
+ = yield :preview_text
%table#body{ border: "0", cellpadding: "0", cellspacing: "0" }
%tbody
%tr.line
diff --git a/app/views/layouts/_page.html.haml b/app/views/layouts/_page.html.haml
index 6c959f5e60c..ba2d6aa79eb 100644
--- a/app/views/layouts/_page.html.haml
+++ b/app/views/layouts/_page.html.haml
@@ -11,7 +11,6 @@
= render "layouts/broadcast"
= render "layouts/header/read_only_banner"
= render "layouts/header/registration_enabled_callout"
- = render "layouts/header/service_templates_deprecation_callout"
= render "layouts/nav/classification_level_banner"
= yield :flash_message
= render "shared/service_ping_consent"
@@ -29,5 +28,7 @@
= yield :before_content
= yield
= yield :after_content
+ -# This is needed by [GitLab JH](https://gitlab.com/gitlab-jh/jh-team/gitlab-cn/-/issues/81)
+ = render_if_exists "shared/footer/global_footer"
= render "layouts/nav/top_nav_responsive", class: 'layout-page content-wrapper-margin'
diff --git a/app/views/layouts/_recaptcha_verification.html.haml b/app/views/layouts/_recaptcha_verification.html.haml
deleted file mode 100644
index 3405fb9d5ef..00000000000
--- a/app/views/layouts/_recaptcha_verification.html.haml
+++ /dev/null
@@ -1,10 +0,0 @@
-- humanized_resource_name = spammable.class.model_name.human.downcase
-
-%h3.page-title
- = _('Anti-spam verification')
-%hr
-
-%p
- = _("We detected potential spam in the %{humanized_resource_name}. Please solve the reCAPTCHA to proceed.") % { humanized_resource_name: humanized_resource_name }
-
-= render 'shared/recaptcha_form', spammable: spammable
diff --git a/app/views/layouts/header/_default.html.haml b/app/views/layouts/header/_default.html.haml
index 87580e57e75..2f6287bdfb3 100644
--- a/app/views/layouts/header/_default.html.haml
+++ b/app/views/layouts/header/_default.html.haml
@@ -1,12 +1,11 @@
- has_impersonation_link = header_link?(:admin_impersonation)
- user_status_data = user_status_properties(current_user)
-- use_top_nav_redesign = Feature.enabled?(:combined_menu, current_user, default_enabled: :yaml)
%header.navbar.navbar-gitlab.navbar-expand-sm.js-navbar{ data: { qa_selector: 'navbar' } }
%a.gl-sr-only.gl-accessibility{ href: "#content-body" } Skip to content
.container-fluid
.header-content
- .title-container.hide-when-menu-expanded
+ .title-container.hide-when-top-nav-responsive-open
%h1.title
%span.gl-sr-only GitLab
= link_to root_path, title: _('Dashboard'), id: 'logo', **tracking_attrs('main_navigation', 'click_gitlab_logo_link', 'navigation') do
@@ -20,24 +19,18 @@
%span.gl-badge.gl-bg-green-500.gl-text-white.gl-rounded-pill.gl-font-weight-bold.gl-py-1
= _('Next')
- - if use_top_nav_redesign
- .gl-display-none.gl-sm-display-block
- = render "layouts/nav/top_nav"
- - else
- - if current_user
- = render "layouts/nav/dashboard"
- - else
- = render "layouts/nav/explore"
+ .gl-display-none.gl-sm-display-block
+ = render "layouts/nav/top_nav"
.navbar-collapse.collapse
%ul.nav.navbar-nav
- if current_user
- = render 'layouts/header/new_dropdown', class: ('gl-display-none gl-sm-display-block' if use_top_nav_redesign)
+ = render 'layouts/header/new_dropdown', class: 'gl-display-none gl-sm-display-block'
- if top_nav_show_search
- search_menu_item = top_nav_search_menu_item_attrs
%li.nav-item.d-none.d-lg-block.m-auto
= render 'layouts/search' unless current_controller?(:search)
- %li.nav-item{ class: use_top_nav_redesign ? 'd-none d-sm-inline-block d-lg-none' : 'd-inline-block d-lg-none' }
+ %li.nav-item{ class: 'd-none d-sm-inline-block d-lg-none' }
= link_to search_menu_item.fetch(:href), title: search_menu_item.fetch(:title), aria: { label: search_menu_item.fetch(:title) }, data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do
= sprite_icon(search_menu_item.fetch(:icon))
- if header_link?(:issues)
@@ -118,14 +111,11 @@
- sign_in_text = allow_signup? ? _('Sign in / Register') : _('Sign in')
= link_to sign_in_text, new_session_path(:user, redirect_to_referer: 'yes'), class: 'gl-button btn btn-default btn-sign-in'
- %button.navbar-toggler.d-block.d-sm-none{ type: 'button', class: ('gl-border-none!' if use_top_nav_redesign) }
+ %button.navbar-toggler.d-block.d-sm-none{ type: 'button', class: 'gl-border-none!', data: { testid: 'top-nav-responsive-toggle' } }
%span.sr-only= _('Toggle navigation')
- - if use_top_nav_redesign
- %span.more-icon.gl-px-3.gl-font-sm.gl-font-weight-bold
- %span.gl-pr-2= _('Menu')
- = sprite_icon('hamburger', size: 16)
- - else
- = sprite_icon('ellipsis_h', size: 12, css_class: 'more-icon')
+ %span.more-icon.gl-px-3.gl-font-sm.gl-font-weight-bold
+ %span.gl-pr-2= _('Menu')
+ = sprite_icon('hamburger', size: 16)
= sprite_icon('close', size: 12, css_class: 'close-icon')
- if display_whats_new?
diff --git a/app/views/layouts/header/_service_templates_deprecation_callout.html.haml b/app/views/layouts/header/_service_templates_deprecation_callout.html.haml
deleted file mode 100644
index 056d4426d5a..00000000000
--- a/app/views/layouts/header/_service_templates_deprecation_callout.html.haml
+++ /dev/null
@@ -1,21 +0,0 @@
-- return unless show_service_templates_deprecated_callout?
-
-- doc_link_start = "<a href=\"#{integrations_help_page_path}\" target='_blank' rel='noopener noreferrer'>".html_safe
-- settings_link_start = "<a href=\"#{integrations_admin_application_settings_path}\">".html_safe
-
-%div{ class: [container_class, @content_class, 'gl-pt-5!'] }
- .gl-alert.gl-alert-warning.js-service-templates-deprecated-callout{ role: 'alert', data: { feature_id: UserCalloutsHelper::SERVICE_TEMPLATES_DEPRECATED_CALLOUT, dismiss_endpoint: user_callouts_path } }
- = sprite_icon('warning', size: 16, css_class: 'gl-alert-icon')
- %button.gl-alert-dismiss.js-close{ type: 'button', aria: { label: _('Close') }, data: { testid: 'close-service-templates-deprecated-callout' } }
- = sprite_icon('close', size: 16)
- .gl-alert-title
- = s_('AdminSettings|Service templates are deprecated and will be removed in GitLab 14.0.')
- .gl-alert-body
- = html_escape_once(s_('AdminSettings|You should migrate to %{doc_link_start}Project integration management%{link_end}, available at %{settings_link_start}Settings &gt; Integrations.%{link_end}')).html_safe % { doc_link_start: doc_link_start, settings_link_start: settings_link_start, link_end: '</a>'.html_safe }
- .gl-alert-actions
- = link_to admin_application_settings_services_path, class: 'btn gl-alert-action btn-info btn-md gl-button' do
- %span.gl-button-text
- = s_('AdminSettings|See affected service templates')
- = link_to "https://gitlab.com/gitlab-org/gitlab/-/issues/325905", class: 'btn gl-alert-action btn-default btn-md gl-button', target: '_blank', rel: 'noopener noreferrer' do
- %span.gl-button-text
- = _('Leave feedback')
diff --git a/app/views/layouts/nav/_dashboard.html.haml b/app/views/layouts/nav/_dashboard.html.haml
deleted file mode 100644
index e4cdb4e1b08..00000000000
--- a/app/views/layouts/nav/_dashboard.html.haml
+++ /dev/null
@@ -1,90 +0,0 @@
--# WARNING! This file is slated to be removed along with the `combined_menu`
--# feature flag. The logic here will be migrated to an upcoming `top_nav_helper`.
--# Please see [this MR][1] for more context.
--# [1]: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/56587
-%ul.list-unstyled.navbar-sub-nav
- - if dashboard_nav_link?(:projects)
- = nav_link(path: ['root#index', 'projects#trending', 'projects#starred', 'dashboard/projects#index'], html_options: { id: 'nav-projects-dropdown', class: "home dropdown header-projects", 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')
- .dropdown-menu.frequent-items-dropdown-menu
- = render "layouts/nav/projects_dropdown/show"
-
- - if dashboard_nav_link?(:groups)
- = nav_link(controller: ['dashboard/groups', 'explore/groups'], html_options: { id: 'nav-groups-dropdown', class: "d-none d-md-block home dropdown header-groups", data: { track_label: "groups_dropdown", track_event: "click_dropdown" } }) do
- %button{ type: 'button', data: { toggle: "dropdown" } }
- = _('Groups')
- = sprite_icon('chevron-down', css_class: 'caret-down')
- .dropdown-menu.frequent-items-dropdown-menu
- = render "layouts/nav/groups_dropdown/show"
-
- - if any_dashboard_nav_link?([:groups, :milestones, :activity, :snippets])
- = nav_link(html_options: { id: 'nav-more-dropdown', class: "header-more dropdown", data: { track_label: "more_dropdown", track_event: "click_more_link" } }) do
- %a{ href: "#", data: { toggle: "dropdown" } }
- = _('More')
- = sprite_icon('chevron-down', css_class: 'caret-down')
- .dropdown-menu
- %ul
- - if dashboard_nav_link?(:groups)
- %li.d-md-none
- = link_to dashboard_groups_path, class: 'dashboard-shortcuts-groups' do
- = _('Groups')
- - if dashboard_nav_link?(:activity)
- = nav_link(path: 'dashboard#activity') do
- = link_to activity_dashboard_path, class: 'dashboard-shortcuts-activity' do
- = _('Activity')
-
- - if dashboard_nav_link?(:milestones)
- = nav_link(controller: 'dashboard/milestones') do
- = link_to dashboard_milestones_path, class: 'dashboard-shortcuts-milestones' do
- = _('Milestones')
-
- - if dashboard_nav_link?(:snippets)
- = nav_link(controller: 'dashboard/snippets') do
- = link_to dashboard_snippets_path, class: 'dashboard-shortcuts-snippets' do
- = _('Snippets')
-
- %li.dropdown
- = render_if_exists 'dashboard/nav_link_list'
-
- - if current_user.admin?
- = nav_link(controller: 'admin/dashboard') do
- = link_to admin_root_path, class: 'admin-icon d-xl-none' do
- = _('Admin Area')
- - if Gitlab::CurrentSettings.admin_mode
- - if header_link?(:admin_mode)
- = nav_link(controller: 'admin/sessions') do
- = link_to destroy_admin_session_path, method: :post, class: 'd-lg-none lock-open-icon' do
- = _('Leave Admin Mode')
- - elsif current_user.admin?
- = nav_link(controller: 'admin/sessions') do
- = link_to new_admin_session_path, class: 'd-lg-none lock-icon' do
- = _('Enter Admin Mode')
- - if Gitlab::Sherlock.enabled?
- %li
- = link_to sherlock_transactions_path, class: 'admin-icon' do
- = _('Sherlock Transactions')
-
- - if current_user.admin?
- = nav_link(controller: 'admin/dashboard', html_options: { class: "d-none d-xl-block"}) do
- = link_to admin_root_path, class: 'admin-icon', title: _('Admin Area'), aria: { label: _('Admin Area') }, data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do
- = sprite_icon('admin', size: 18)
-
- - if Gitlab::CurrentSettings.admin_mode
- - if header_link?(:admin_mode)
- = nav_link(controller: 'admin/sessions', html_options: { class: "d-none d-lg-block"}) do
- = link_to destroy_admin_session_path, method: :post, title: _('Leave Admin Mode'), aria: { label: _('Leave Admin Mode') }, data: { toggle: 'tooltip', placement: 'bottom', container: 'body' } do
- = sprite_icon('lock-open', size: 18)
- - elsif current_user.admin?
- = nav_link(controller: 'admin/sessions', html_options: { class: "d-none d-lg-block"}) do
- = link_to new_admin_session_path, title: _('Enter Admin Mode'), aria: { label: _('Enter Admin Mode') }, data: { toggle: 'tooltip', placement: 'bottom', container: 'body' } do
- = sprite_icon('lock', size: 18)
-
- -# Shortcut to Dashboard > Projects
- - if dashboard_nav_link?(:projects)
- %li.hidden
- = link_to dashboard_projects_path, class: 'dashboard-shortcuts-projects' do
- = _('Projects')
-
- = render_if_exists 'layouts/nav/geo_primary_node_url'
diff --git a/app/views/layouts/nav/_explore.html.haml b/app/views/layouts/nav/_explore.html.haml
deleted file mode 100644
index 5b47eb27b04..00000000000
--- a/app/views/layouts/nav/_explore.html.haml
+++ /dev/null
@@ -1,19 +0,0 @@
--# WARNING! This file is slated to be removed along with the `combined_menu`
--# feature flag. The logic here will be migrated to an upcoming `top_nav_helper`.
--# Please see [this MR][1] for more context.
--# [1]: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/56587
-%ul.list-unstyled.navbar-sub-nav
- - if explore_nav_link?(:projects)
- = nav_link(path: ['dashboard#show', 'root#show', 'projects#trending', 'projects#starred', 'projects#index'], html_options: {class: 'home'}) do
- = link_to explore_root_path, title: _('Projects'), class: 'dashboard-shortcuts-projects' do
- = _('Projects')
- - if explore_nav_link?(:groups)
- = nav_link(controller: [:groups, 'groups/milestones', 'groups/group_members']) do
- = link_to explore_groups_path, title: _('Groups'), class: 'dashboard-shortcuts-groups' do
- = _('Groups')
- - if explore_nav_link?(:snippets)
- = nav_link(controller: :snippets) do
- = link_to explore_snippets_path, title: _('Snippets'), class: 'dashboard-shortcuts-snippets' do
- = _('Snippets')
- %li
- = link_to _("Help"), help_path, title: _('About GitLab CE')
diff --git a/app/views/layouts/nav/_top_nav_responsive.html.haml b/app/views/layouts/nav/_top_nav_responsive.html.haml
index 0d122f1adff..86fd8b6d80c 100644
--- a/app/views/layouts/nav/_top_nav_responsive.html.haml
+++ b/app/views/layouts/nav/_top_nav_responsive.html.haml
@@ -1,5 +1,3 @@
-- return unless Feature.enabled?(:combined_menu, current_user, default_enabled: :yaml)
-
- top_class = local_assigns.fetch(:class, nil)
- view_model = top_nav_responsive_view_model(project: @project, group: @group)
diff --git a/app/views/layouts/nav/groups_dropdown/_show.html.haml b/app/views/layouts/nav/groups_dropdown/_show.html.haml
deleted file mode 100644
index d7b0c7150d4..00000000000
--- a/app/views/layouts/nav/groups_dropdown/_show.html.haml
+++ /dev/null
@@ -1,23 +0,0 @@
--# WARNING! This file is slated to be removed along with the `combined_menu`
--# feature flag. The logic here will be migrated to an upcoming `top_nav_helper`.
--# Please see [this MR][1] for more context.
--# [1]: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/56587
-- group_meta = { id: @group.id, name: @group.name, namespace: @group.full_name, web_url: group_path(@group), avatar_url: @group.avatar_url } if @group&.persisted?
-.frequent-items-dropdown-container.with-deprecated-styles
- .frequent-items-dropdown-sidebar
- %ul
- = nav_link(path: 'dashboard/groups#index') do
- = link_to dashboard_groups_path, data: { track_label: "groups_dropdown_your_groups", track_event: "click_link" } do
- = _('Your groups')
- = nav_link(path: 'groups#explore') do
- = link_to explore_groups_path, data: { track_label: "groups_dropdown_explore_groups", track_event: "click_link" } do
- = _('Explore groups')
- - if current_user.can_create_group?
- = nav_link(path: 'groups/new#create-group-pane', html_options: { class: 'gl-border-0 gl-border-t-1 gl-border-solid gl-border-gray-100' }) do
- = link_to new_group_path(anchor: 'create-group-pane'), data: { track_label: "groups_dropdown_create_group", track_event: "click_link" } do
- = _('Create group')
- = nav_link(path: 'groups/new#import-group-pane') do
- = link_to new_group_path(anchor: 'import-group-pane'), data: { track_label: "groups_dropdown_import_group", track_event: "click_link" } do
- = _('Import group')
- .frequent-items-dropdown-content
- #js-groups-dropdown{ data: { user_name: current_user.username, group: group_meta } }
diff --git a/app/views/layouts/nav/projects_dropdown/_show.html.haml b/app/views/layouts/nav/projects_dropdown/_show.html.haml
deleted file mode 100644
index f16aab92a95..00000000000
--- a/app/views/layouts/nav/projects_dropdown/_show.html.haml
+++ /dev/null
@@ -1,28 +0,0 @@
--# WARNING! This file is slated to be removed along with the `combined_menu`
--# feature flag. The logic here will be migrated to an upcoming `top_nav_helper`.
--# Please see [this MR][1] for more context.
--# [1]: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/56587
-- project_meta = { id: @project.id, name: @project.name, namespace: @project.full_name, web_url: project_path(@project), avatar_url: @project.avatar_url } if @project&.persisted?
-.frequent-items-dropdown-container.with-deprecated-styles
- .frequent-items-dropdown-sidebar
- %ul
- = nav_link(path: 'dashboard/projects#index') do
- = link_to dashboard_projects_path, data: { track_label: "projects_dropdown_your_projects", track_event: "click_link" } do
- = _('Your projects')
- = nav_link(path: 'projects#starred') do
- = link_to starred_dashboard_projects_path, data: { track_label: "projects_dropdown_starred_projects", track_event: "click_link" } do
- = _('Starred projects')
- = 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')
- = 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')
- .frequent-items-dropdown-content
- #js-projects-dropdown{ data: { user_name: current_user.username, project: project_meta } }
diff --git a/app/views/layouts/nav/sidebar/_analytics_links.html.haml b/app/views/layouts/nav/sidebar/_analytics_links.html.haml
deleted file mode 100644
index 92a7b97203f..00000000000
--- a/app/views/layouts/nav/sidebar/_analytics_links.html.haml
+++ /dev/null
@@ -1,22 +0,0 @@
-- 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
-
-- if navbar_links.any?
- = nav_link(path: all_paths) do
- = link_to analytics_link.link, {class: 'shortcuts-analytics has-sub-items', data: { qa_selector: 'analytics_anchor' } } do
- .nav-icon-container
- = sprite_icon('chart')
- %span.nav-item-name{ data: { qa_selector: 'analytics_link' } }
- = _('Analytics')
-
- %ul.sidebar-sub-level-items{ data: { qa_selector: 'analytics_sidebar_submenu' } }
- = nav_link(path: analytics_link.path, html_options: { class: "fly-out-top-item" } ) do
- = link_to analytics_link.link do
- %strong.fly-out-top-item-name
- = _('Analytics')
- %li.divider.fly-out-top-item
- - navbar_links.each do |menu_item|
- = nav_link(path: menu_item.path) do
- = link_to(menu_item.link, menu_item.link_to_options) do
- %span= menu_item.title
diff --git a/app/views/layouts/nav/sidebar/_group_menus.html.haml b/app/views/layouts/nav/sidebar/_group_menus.html.haml
index 5738c8becd5..25b6c264d92 100644
--- a/app/views/layouts/nav/sidebar/_group_menus.html.haml
+++ b/app/views/layouts/nav/sidebar/_group_menus.html.haml
@@ -1,166 +1,3 @@
-- 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/_wiki_link.html.haml b/app/views/layouts/nav/sidebar/_wiki_link.html.haml
deleted file mode 100644
index b6b63b75fcc..00000000000
--- a/app/views/layouts/nav/sidebar/_wiki_link.html.haml
+++ /dev/null
@@ -1,11 +0,0 @@
-= nav_link(controller: :wikis) do
- = link_to wiki_url, class: 'shortcuts-wiki', data: { qa_selector: 'wiki_link' } do
- .nav-icon-container
- = sprite_icon('book')
- %span.nav-item-name
- = _('Wiki')
- %ul.sidebar-sub-level-items.is-fly-out-only
- = nav_link(controller: :wikis, html_options: { class: "fly-out-top-item" } ) do
- = link_to wiki_url do
- %strong.fly-out-top-item-name
- = _('Wiki')
diff --git a/app/views/notify/member_invited_email.html.haml b/app/views/notify/member_invited_email.html.haml
index a4ea63e3d53..843a820bd1b 100644
--- a/app/views/notify/member_invited_email.html.haml
+++ b/app/views/notify/member_invited_email.html.haml
@@ -1,60 +1,68 @@
-- placeholders = { strong_start: '<strong>'.html_safe, strong_end: '</strong>'.html_safe, project_or_group_name: member_source.human_name, project_or_group: member_source.model_name.singular, br_tag: '<br/>'.html_safe, role: member.human_access.downcase }
+- placeholders = { strong_start: '<strong>'.html_safe,
+ strong_end: '</strong>'.html_safe,
+ project_or_group_name: member_source.human_name,
+ project_or_group: member_source.model_name.singular,
+ br_tag: '<br/>'.html_safe,
+ role: member.human_access.downcase }
+- join_text = s_('InviteEmail|Join now')
+- join_url = invite_url(@token, invite_type: Emails::Members::INITIAL_INVITE, experiment_name: 'invite_email_preview_text')
+- inviter_name = member.created_by.name if member.created_by
-- experiment('members/invite_email', actor: member) do |experiment_instance|
- - experiment_instance.use do
- %tr
- %td.text-content
- %h2.invite-header
- = s_('InviteEmail|You are invited!')
- %p
- - if member.created_by
- = html_escape(s_("InviteEmail|%{inviter} invited you to join the %{strong_start}%{project_or_group_name}%{strong_end}%{br_tag}%{project_or_group} as a %{role}")) % placeholders.merge({ inviter: (link_to member.created_by.name, user_url(member.created_by)).html_safe })
- - else
- = html_escape(s_("InviteEmail|You are invited to join the %{strong_start}%{project_or_group_name}%{strong_end}%{br_tag}%{project_or_group} as a %{role}")) % placeholders
- %p.invite-actions
- = link_to s_('InviteEmail|Join now'), invite_url(@token, invite_type: Members::InviteEmailExperiment::INVITE_TYPE), class: 'invite-btn-join'
- - experiment_instance.try(:activity) do
- %tr
- %td.text-content{ colspan: 2 }
- %img.mail-avatar{ height: "60", src: avatar_icon_for_user(member.created_by, 60, only_path: false), width: "60", alt: "" }
- %p
- = html_escape(s_("InviteEmail|%{inviter} invited you to join the %{strong_start}%{project_or_group_name}%{strong_end}%{br_tag}%{project_or_group} as a %{role}")) % placeholders.merge({ inviter: (link_to member.created_by.name, user_url(member.created_by)).html_safe })
- %p.invite-actions
- = link_to s_('InviteEmail|Join now'), invite_url(@token, invite_type: Members::InviteEmailExperiment::INVITE_TYPE), class: 'invite-btn-join'
- %tr.border-top
- %td.text-content.mailer-align-left.half-width
- %h4
- = s_('InviteEmail|%{project_or_group} details') % { project_or_group: member_source.model_name.singular.capitalize }
- %ul
- %li
- %div
- %img.mailer-icon{ alt: '', src: image_url("mailers/members/users.png") }
- %span
- - member_count = member_source.members.size
- = n_('%{bold_start}%{count}%{bold_end} member', '%{bold_start}%{count}%{bold_end} members',
- member_count).html_safe % { count: number_with_delimiter(member_count),
- bold_start: '<b>'.html_safe,
- bold_end: '</b>'.html_safe }
- %li
- %div
- %img.mailer-icon{ alt: '', src: image_url("mailers/members/issues.png") }
- %span
- - issue_count = member_source.open_issues_count(member.created_by)
- = n_('%{bold_start}%{count}%{bold_end} issue', '%{bold_start}%{count}%{bold_end} issues',
- issue_count).html_safe % { count: number_with_delimiter(issue_count),
- bold_start: '<b>'.html_safe,
- bold_end: '</b>'.html_safe }
- %li
- %div
- %img.mailer-icon{ alt: '', src: image_url("mailers/members/merge-request-open.png") }
- %span
- - mr_count = member_source.open_merge_requests_count(member.created_by)
- = n_('%{bold_start}%{count}%{bold_end} opened merge request', '%{bold_start}%{count}%{bold_end} opened merge requests',
- mr_count).html_safe % { count: number_with_delimiter(mr_count),
- bold_start: '<b>'.html_safe,
- bold_end: '</b>'.html_safe }
- %td.text-content.mailer-align-left.half-width
- %h4
- = s_("InviteEmail|What's it about?")
- %p
- = invited_to_description(member_source)
+- experiment(:invite_email_preview_text, actor: member) do |experiment_instance|
+ - experiment_instance.use {}
+ - experiment_instance.candidate do
+ = content_for :preview_text do
+ %div{ style: "display:none;font-size:1px;line-height:1px;max-height:0px;max-width:0px;opacity:0;overflow:hidden;" }
+ - if member.created_by
+ = s_('InviteEmail|Join your team on GitLab! %{inviter} invited you to %{project_or_group_name}') % { inviter: inviter_name, project_or_group_name: placeholders[:project_or_group_name] }
+ - else
+ = s_('InviteEmail|Join your team on GitLab! You are invited to %{project_or_group_name}') % { project_or_group_name: placeholders[:project_or_group_name] }
+ = gmail_goto_action(join_text, join_url)
+
+%tr
+ %td.text-content{ colspan: 2 }
+ %img.mail-avatar{ height: "60", src: avatar_icon_for_user(member.created_by, 60, only_path: false), width: "60", alt: "" }
+ %p
+ - if member.created_by
+ = html_escape(s_("InviteEmail|%{inviter} invited you to join the %{strong_start}%{project_or_group_name}%{strong_end}%{br_tag}%{project_or_group} as a %{role}")) % placeholders.merge({ inviter: (link_to inviter_name, user_url(member.created_by)).html_safe })
+ - else
+ = html_escape(s_("InviteEmail|You are invited to join the %{strong_start}%{project_or_group_name}%{strong_end}%{br_tag}%{project_or_group} as a %{role}")) % placeholders
+ %p.invite-actions
+ = link_to join_text, join_url, class: 'invite-btn-join'
+%tr.border-top
+ %td.text-content.mailer-align-left.half-width
+ %h4
+ = s_('InviteEmail|%{project_or_group} details') % { project_or_group: member_source.model_name.singular.capitalize }
+ %ul
+ %li
+ %div
+ %img.mailer-icon{ alt: '', src: image_url("mailers/members/users.png") }
+ %span
+ - member_count = member_source.members.size
+ = n_('%{bold_start}%{count}%{bold_end} member', '%{bold_start}%{count}%{bold_end} members',
+ member_count).html_safe % { count: number_with_delimiter(member_count),
+ bold_start: '<b>'.html_safe,
+ bold_end: '</b>'.html_safe }
+ %li
+ %div
+ %img.mailer-icon{ alt: '', src: image_url("mailers/members/issues.png") }
+ %span
+ - issue_count = member_source.open_issues_count(member.created_by)
+ = n_('%{bold_start}%{count}%{bold_end} issue', '%{bold_start}%{count}%{bold_end} issues',
+ issue_count).html_safe % { count: number_with_delimiter(issue_count),
+ bold_start: '<b>'.html_safe,
+ bold_end: '</b>'.html_safe }
+ %li
+ %div
+ %img.mailer-icon{ alt: '', src: image_url("mailers/members/merge-request-open.png") }
+ %span
+ - mr_count = member_source.open_merge_requests_count(member.created_by)
+ = n_('%{bold_start}%{count}%{bold_end} opened merge request', '%{bold_start}%{count}%{bold_end} opened merge requests',
+ mr_count).html_safe % { count: number_with_delimiter(mr_count),
+ bold_start: '<b>'.html_safe,
+ bold_end: '</b>'.html_safe }
+ %td.text-content.mailer-align-left.half-width
+ %h4
+ = s_("InviteEmail|What's it about?")
+ %p
+ = invited_to_description(member_source)
diff --git a/app/views/profiles/show.html.haml b/app/views/profiles/show.html.haml
index 0328fa5c282..6eba0309a4f 100644
--- a/app/views/profiles/show.html.haml
+++ b/app/views/profiles/show.html.haml
@@ -77,12 +77,10 @@
.row.user-time-preferences.js-search-settings-section
.col-lg-4.profile-settings-sidebar
%h4.gl-mt-0= s_("Profiles|Time settings")
- %p= s_("Profiles|You can set your current timezone here")
+ %p= s_("Profiles|Set your local time zone")
.col-lg-8
- -# TODO: might need an entry in user/profile.md to describe some of these settings
- -# https://gitlab.com/gitlab-org/gitlab-foss/issues/60070
%h5= _("Time zone")
- = dropdown_tag(_("Select a timezone"), options: { toggle_class: 'gl-button btn js-timezone-dropdown input-lg', title: _("Select a timezone"), filter: true, placeholder: s_("OfSearchInADropdown|Filter"), data: { data: timezone_data } } )
+ = dropdown_tag(_("Select a time zone"), options: { toggle_class: 'gl-button btn js-timezone-dropdown input-lg', title: _("Select a time zone"), filter: true, placeholder: s_("OfSearchInADropdown|Filter"), data: { data: timezone_data } } )
%input.hidden{ :type => 'hidden', :id => 'user_timezone', :name => 'user[timezone]', value: @user.timezone }
.col-lg-12
%hr
@@ -100,6 +98,7 @@
= f.text_field :id, class: 'gl-form-input', readonly: true, label: s_('Profiles|User ID'), wrapper: { class: 'col-md-3' }
= f.text_field :pronouns, class: 'input-md gl-form-input', help: s_("Profiles|Enter your pronouns to let people know how to refer to you")
+ = f.text_field :pronunciation, class: 'input-md gl-form-input', help: s_("Profiles|Enter how your name is pronounced to help people address you correctly")
= render_if_exists 'profiles/email_settings', form: f
= f.text_field :skype, class: 'input-md gl-form-input', placeholder: s_("Profiles|username")
= f.text_field :linkedin, class: 'input-md gl-form-input', help: s_("Profiles|Your LinkedIn profile name from linkedin.com/in/profilename")
@@ -123,10 +122,9 @@
= f.check_box :include_private_contributions, label: s_('Profiles|Include private contributions on my profile'), wrapper_class: 'mb-2', inline: true
.help-block
= s_("Profiles|Choose to show contributions of private projects on your public profile without any project, repository or organization information")
- .row.gl-justify-content-end.gl-mt-5
- .col-lg-8.gl-display-flex
- = f.submit s_("Profiles|Update profile settings"), class: 'gl-button btn btn-confirm gl-mr-3'
- = link_to _("Cancel"), user_path(current_user), class: 'gl-button btn btn-default btn-cancel'
+ %hr
+ = f.submit s_("Profiles|Update profile settings"), class: 'gl-button btn btn-confirm gl-mr-3'
+ = link_to _("Cancel"), user_path(current_user), class: 'gl-button btn btn-default btn-cancel'
.modal.modal-profile-crop{ data: { cropper_css_path: ActionController::Base.helpers.stylesheet_path('lazy_bundles/cropper.css') } }
.modal-dialog
diff --git a/app/views/projects/_home_panel.html.haml b/app/views/projects/_home_panel.html.haml
index 86172499118..8909536a1ec 100644
--- a/app/views/projects/_home_panel.html.haml
+++ b/app/views/projects/_home_panel.html.haml
@@ -1,6 +1,5 @@
- empty_repo = @project.empty_repo?
- show_auto_devops_callout = show_auto_devops_callout?(@project)
-- max_project_topic_length = 15
- emails_disabled = @project.emails_disabled?
- cache_enabled = Feature.enabled?(:cache_home_panel, @project, type: :development, default_enabled: :yaml)
@@ -25,24 +24,8 @@
%span.access-request-links.gl-ml-3
= render 'shared/members/access_request_links', source: @project
- - if @project.topic_list.present?
- = cache_if(cache_enabled, [@project, :topic_list], expires_in: 1.day) do
- %span.home-panel-topic-list.mt-2.w-100.d-inline-flex.gl-font-base.gl-font-weight-normal.gl-align-items-center
- = sprite_icon('tag', css_class: 'icon gl-relative gl-mr-2')
-
- - @project.topics_to_show.each do |topic|
- - project_topics_classes = "badge badge-pill badge-secondary gl-mr-2"
- - explore_project_topic_path = explore_projects_path(topic: topic)
- - if topic.length > max_project_topic_length
- %a{ class: "#{ project_topics_classes } str-truncated-30 has-tooltip", data: { container: "body" }, title: topic, href: explore_project_topic_path, itemprop: 'keywords' }
- = topic.titleize
- - else
- %a{ class: project_topics_classes, href: explore_project_topic_path, itemprop: 'keywords' }
- = topic.titleize
-
- - if @project.has_extra_topics?
- .text-nowrap.has-tooltip{ data: { container: 'body' }, title: @project.has_extra_topics? ? @project.topics_not_shown.join(', ') : nil }
- = _("+ %{count} more") % { count: @project.count_of_extra_topics_not_shown }
+ .gl-mt-3.gl-pl-3.gl-w-full
+ = render "shared/projects/topics", project: @project, cache_enabled: cache_enabled
= 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
@@ -88,12 +71,11 @@
= render_if_exists "projects/home_mirror"
- if @project.badges.present?
- = cache_if(cache_enabled, [@project, :badges], expires_in: 1.day) do
- .project-badges.mb-2
- - @project.badges.each do |badge|
- %a.gl-mr-3{ href: badge.rendered_link_url(@project),
- target: '_blank',
- rel: 'noopener noreferrer' }>
- %img.project-badge{ src: badge.rendered_image_url(@project),
- 'aria-hidden': true,
- alt: 'Project badge' }>
+ .project-badges.mb-2
+ - @project.badges.each do |badge|
+ %a.gl-mr-3{ href: badge.rendered_link_url(@project),
+ target: '_blank',
+ rel: 'noopener noreferrer' }>
+ %img.project-badge{ src: badge.rendered_image_url(@project),
+ 'aria-hidden': true,
+ alt: 'Project badge' }>
diff --git a/app/views/projects/_invite_members_modal.html.haml b/app/views/projects/_invite_members_modal.html.haml
index 5dd6ec0addf..6375a56bf5d 100644
--- a/app/views/projects/_invite_members_modal.html.haml
+++ b/app/views/projects/_invite_members_modal.html.haml
@@ -1,8 +1,5 @@
-- return unless can_import_members?
+- return unless can_admin_project_member?(project)
-.js-invite-members-modal{ data: { id: project.id,
- name: project.name,
- is_project: 'true',
+.js-invite-members-modal{ data: { is_project: 'true',
access_levels: ProjectMember.access_level_roles.to_json,
- default_access_level: Gitlab::Access::GUEST,
- help_link: help_page_url('user/permissions') } }
+ help_link: help_page_url('user/permissions') }.merge(common_invite_modal_dataset(project)).merge(users_filter_data(project.group)) }
diff --git a/app/views/projects/_last_push.html.haml b/app/views/projects/_last_push.html.haml
index afe42b334ba..9ba7d25b662 100644
--- a/app/views/projects/_last_push.html.haml
+++ b/app/views/projects/_last_push.html.haml
@@ -1,19 +1,21 @@
- event = last_push_event
- if event && show_last_push_widget?(event)
- .row-content-block.top-block.d-none.d-sm-block.white
- .event-last-push
- .event-last-push-text
- %span= s_("LastPushEvent|You pushed to")
- %strong
- = link_to event.ref_name, project_commits_path(event.project, event.ref_name), class: 'ref-name'
+ .gl-alert.gl-alert-success.mt-2{ role: 'alert' }
+ = sprite_icon('check-circle', size: 16, css_class: 'gl-icon gl-alert-icon gl-alert-icon-no-title')
+ %button.js-close-banner.gl-alert-dismiss{ type: 'button', 'aria-label' => _('Dismiss') }
+ = sprite_icon('close', size: 16, css_class: 'gl-icon')
+ .gl-alert-body
+ %span= s_("LastPushEvent|You pushed to")
+ %strong.gl-display-inline-flex.gl-max-w-50p{ data: { toggle: 'tooltip' }, title: event.ref_name }
+ = link_to event.ref_name, project_commits_path(event.project, event.ref_name), class: 'ref-name gl-text-truncate'
- - if event.project != @project
- %span= s_("LastPushEvent|at")
- %strong= link_to_project event.project
+ - if event.project != @project
+ %span= s_("LastPushEvent|at")
+ %strong= link_to_project event.project
- #{time_ago_with_tooltip(event.created_at)}
+ #{time_ago_with_tooltip(event.created_at)}
- - if can?(current_user, :create_merge_request_in, event.project.default_merge_request_target)
- .flex-right
- = link_to new_mr_path_from_push_event(event), title: _("New merge request"), class: "btn gl-button btn-info btn-sm qa-create-merge-request" do
- #{ _('Create merge request') }
+ - if can?(current_user, :create_merge_request_in, event.project.default_merge_request_target)
+ .gl-alert-actions
+ = link_to new_mr_path_from_push_event(event), title: _("New merge request"), class: "btn gl-button btn-confirm qa-create-merge-request" do
+ #{ _('Create merge request') }
diff --git a/app/views/projects/_new_project_fields.html.haml b/app/views/projects/_new_project_fields.html.haml
index 55696337bc1..026c7a0d79d 100644
--- a/app/views/projects/_new_project_fields.html.haml
+++ b/app/views/projects/_new_project_fields.html.haml
@@ -54,8 +54,7 @@
.form-group.row.initialize-with-readme-setting
%div{ :class => "col-sm-12" }
.form-check
- - experiment(:new_project_readme, actor: current_user) do |e|
- = check_box_tag 'project[initialize_with_readme]', '1', e.run, class: 'form-check-input', data: { qa_selector: "initialize_with_readme_checkbox", track_label: "#{track_label}", track_event: "activate_form_input", track_property: "init_with_readme", track_value: "" }
+ = check_box_tag 'project[initialize_with_readme]', '1', true, class: 'form-check-input', data: { qa_selector: "initialize_with_readme_checkbox", track_label: "#{track_label}", track_event: "activate_form_input", track_property: "init_with_readme", track_value: "" }
= label_tag 'project[initialize_with_readme]', class: 'form-check-label' do
.option-title
%strong= s_('ProjectsNew|Initialize repository with a README')
diff --git a/app/views/projects/_terraform_banner.html.haml b/app/views/projects/_terraform_banner.html.haml
index a30c4a2d624..881e4ccd9df 100644
--- a/app/views/projects/_terraform_banner.html.haml
+++ b/app/views/projects/_terraform_banner.html.haml
@@ -2,4 +2,4 @@
- if show_terraform_banner?(project)
.container-fluid{ class: @content_class }
- .js-terraform-notification{ data: { project_id: project.id } }
+ .js-terraform-notification{ data: { terraform_image_path: image_path('illustrations/third-party-logos/ci_cd-template-logos/terraform.svg') } }
diff --git a/app/views/projects/blame/show.html.haml b/app/views/projects/blame/show.html.haml
index 8fe9c9e5c52..30c052e054f 100644
--- a/app/views/projects/blame/show.html.haml
+++ b/app/views/projects/blame/show.html.haml
@@ -51,7 +51,7 @@
= i
\
- %td.lines
+ %td.lines.gl-w-full
%pre.code.highlight
%code
- blame_group[:lines].each do |line|
diff --git a/app/views/projects/blob/_editor.html.haml b/app/views/projects/blob/_editor.html.haml
index f2f753b4e86..41333c416de 100644
--- a/app/views/projects/blob/_editor.html.haml
+++ b/app/views/projects/blob/_editor.html.haml
@@ -5,7 +5,7 @@
.file-holder-bottom-radius.file-holder.file.gl-mb-3
.js-file-title.file-title.gl-display-flex.gl-align-items-center.clearfix{ data: { current_action: action } }
.editor-ref.block-truncated.has-tooltip{ title: ref }
- = sprite_icon('fork', size: 12)
+ = sprite_icon('branch', size: 12)
= ref
- if current_action?(:edit) || current_action?(:update)
%span.float-left.gl-mr-3
diff --git a/app/views/projects/blob/viewers/_gitlab_ci_yml.html.haml b/app/views/projects/blob/viewers/_gitlab_ci_yml.html.haml
index d8d27c3330b..afde59aa37d 100644
--- a/app/views/projects/blob/viewers/_gitlab_ci_yml.html.haml
+++ b/app/views/projects/blob/viewers/_gitlab_ci_yml.html.haml
@@ -6,4 +6,4 @@
= s_('Pipelines|This GitLab CI configuration is invalid:')
= viewer.validation_message(project: @project, sha: @commit.sha, user: @current_user)
-= link_to _('Learn more'), help_page_path('ci/yaml/README')
+= link_to _('Learn more'), help_page_path('ci/yaml/index')
diff --git a/app/views/projects/blob/viewers/_gitlab_ci_yml_loading.html.haml b/app/views/projects/blob/viewers/_gitlab_ci_yml_loading.html.haml
index b1c8e110493..cf57f1b531d 100644
--- a/app/views/projects/blob/viewers/_gitlab_ci_yml_loading.html.haml
+++ b/app/views/projects/blob/viewers/_gitlab_ci_yml_loading.html.haml
@@ -1,4 +1,4 @@
= loading_icon(css_class: "gl-vertical-align-text-bottom mr-1")
= s_('Pipelines|Validating GitLab CI configuration…')
-= link_to _('Learn more'), help_page_path('ci/yaml/README')
+= link_to _('Learn more'), help_page_path('ci/yaml/index')
diff --git a/app/views/projects/blob/viewers/_route_map.html.haml b/app/views/projects/blob/viewers/_route_map.html.haml
index 068cf400cd5..30182c100d5 100644
--- a/app/views/projects/blob/viewers/_route_map.html.haml
+++ b/app/views/projects/blob/viewers/_route_map.html.haml
@@ -6,4 +6,4 @@
This Route Map is invalid:
= viewer.validation_message
-= link_to 'Learn more', help_page_path('ci/environments/index.md', anchor: 'going-from-source-files-to-public-pages')
+= link_to 'Learn more', help_page_path('ci/environments/index.md', anchor: 'go-from-source-files-to-public-pages')
diff --git a/app/views/projects/blob/viewers/_route_map_loading.html.haml b/app/views/projects/blob/viewers/_route_map_loading.html.haml
index 8610847fbc9..c48ab84654f 100644
--- a/app/views/projects/blob/viewers/_route_map_loading.html.haml
+++ b/app/views/projects/blob/viewers/_route_map_loading.html.haml
@@ -1,4 +1,4 @@
= loading_icon(css_class: "gl-vertical-align-text-bottom gl-mr-1")
Validating Route Map…
-= link_to 'Learn more', help_page_path('ci/environments/index.md', anchor: 'going-from-source-files-to-public-pages')
+= link_to 'Learn more', help_page_path('ci/environments/index.md', anchor: 'go-from-source-files-to-public-pages')
diff --git a/app/views/projects/branches/_branch.html.haml b/app/views/projects/branches/_branch.html.haml
index 60cb06f71ba..99a9535b8e8 100644
--- a/app/views/projects/branches/_branch.html.haml
+++ b/app/views/projects/branches/_branch.html.haml
@@ -4,7 +4,7 @@
%li{ class: "branch-item js-branch-item js-branch-#{branch.name}", data: { name: branch.name } }
.branch-info
.branch-title
- = sprite_icon('fork', size: 12, css_class: 'gl-flex-shrink-0')
+ = sprite_icon('branch', size: 12, css_class: 'gl-flex-shrink-0')
= link_to project_tree_path(@project, branch.name), class: 'item-title str-truncated-100 ref-name gl-ml-3 qa-branch-name' do
= branch.name
- if branch.name == @repository.root_ref
diff --git a/app/views/projects/ci/builds/_build.html.haml b/app/views/projects/ci/builds/_build.html.haml
index 824e876500b..1a3813ba99f 100644
--- a/app/views/projects/ci/builds/_build.html.haml
+++ b/app/views/projects/ci/builds/_build.html.haml
@@ -12,12 +12,15 @@
%td.status
= render "ci/status/badge", status: job.detailed_status(current_user), title: job.status_title
- %td.branch-commit.cgray
+ %td
- if can?(current_user, :read_build, job)
- = link_to project_job_path(job.project, job) do
- %span.build-link ##{job.id}
+ = link_to job.name, project_job_path(job.project, job), class: 'gl-text-blue-600!'
- else
- %span.build-link ##{job.id}
+ %span.gl-text-blue-600!
+ = job.name
+
+ %td.branch-commit.gl-text-gray-900
+ %span.build-link ##{job.id}
- if ref
- if job.ref
@@ -79,9 +82,6 @@
= job.stage
%td
- = job.name
-
- %td
- if job.duration
%p.duration
= custom_icon("icon_timer")
@@ -105,7 +105,7 @@
- if can?(current_user, :update_build, job)
- if job.active?
= link_to cancel_project_job_path(job.project, job, continue: { to: request.fullpath }), method: :post, title: _('Cancel'), class: 'gl-button btn btn-default btn-icon' do
- = sprite_icon('close', css_class: 'gl-icon')
+ = sprite_icon('cancel', css_class: 'gl-icon')
- elsif job.scheduled?
.gl-button.btn.btn-default.btn-icon.disabled{ disabled: true }
= sprite_icon('planning', css_class: 'gl-icon')
diff --git a/app/views/projects/commit/_commit_box.html.haml b/app/views/projects/commit/_commit_box.html.haml
index 67007aa7448..36d3520cb59 100644
--- a/app/views/projects/commit/_commit_box.html.haml
+++ b/app/views/projects/commit/_commit_box.html.haml
@@ -57,7 +57,7 @@
#{ n_(s_('Pipeline|with stage'), s_('Pipeline|with stages'), @last_pipeline.stages_count) }
.mr-widget-pipeline-graph
.stage-cell
- .js-commit-pipeline-mini-graph{ data: { stages: @last_pipeline_stages.to_json.html_safe } }
+ .js-commit-pipeline-mini-graph{ data: { stages: @last_pipeline_stages.to_json.html_safe, full_path: @project.full_path, iid: @last_pipeline.iid } }
- if @last_pipeline.duration
in
= time_interval_in_words @last_pipeline.duration
diff --git a/app/views/projects/commit/show.html.haml b/app/views/projects/commit/show.html.haml
index c3fdfeb6f4e..e22d33e3c72 100644
--- a/app/views/projects/commit/show.html.haml
+++ b/app/views/projects/commit/show.html.haml
@@ -9,7 +9,7 @@
- page_description @commit.description
- add_page_specific_style 'page_bundles/pipelines'
-.container-fluid{ class: [limited_container_width, container_class] }
+.container-fluid.commits-container{ class: [limited_container_width, container_class] }
= render "commit_box"
= render "ci_menu"
= render "projects/diffs/diffs",
diff --git a/app/views/projects/commits/show.html.haml b/app/views/projects/commits/show.html.haml
index 463984a13a2..22a5bada311 100644
--- a/app/views/projects/commits/show.html.haml
+++ b/app/views/projects/commits/show.html.haml
@@ -26,7 +26,7 @@
= form_tag(project_commits_path(@project, @id), method: :get, class: 'commits-search-form js-signature-container', data: { 'signatures-path' => namespace_project_signatures_path }) do
= search_field_tag :search, params[:search], { placeholder: _('Search by message'), id: 'commits-search', class: 'form-control gl-form-input input-short gl-mt-3 gl-sm-mt-0 gl-min-w-full', spellcheck: false }
.control.d-none.d-md-block
- = link_to project_commits_path(@project, @ref, rss_url_options), title: _("Commits feed"), class: 'btn gl-button btn-default btn-icon' do
+ = link_to project_commits_path(@project, @id, rss_url_options), title: _("Commits feed"), class: 'btn gl-button btn-default btn-icon' do
= sprite_icon('rss', css_class: 'qa-rss-icon')
= render_if_exists 'projects/commits/mirror_status'
diff --git a/app/views/projects/deployments/_confirm_rollback_modal.html.haml b/app/views/projects/deployments/_confirm_rollback_modal.html.haml
deleted file mode 100644
index 23729d6ebf9..00000000000
--- a/app/views/projects/deployments/_confirm_rollback_modal.html.haml
+++ /dev/null
@@ -1,23 +0,0 @@
-- commit_sha = link_to deployment.short_sha, project_commit_path(@project, deployment.sha), class: "commit-sha has-tooltip", title: h(deployment.commit_title)
-.modal.ws-normal.fade{ tabindex: -1, id: "confirm-rollback-modal-#{deployment.id}" }
- .modal-dialog
- .modal-content
- .modal-header
- %h4.modal-title.d-flex.mw-100
- - if deployment.last?
- = s_("Environments|Re-deploy environment %{environment_name}?") % {environment_name: @environment.name}
- - else
- = s_("Environments|Rollback environment %{environment_name}?") % {environment_name: @environment.name}
- .modal-body
- - if deployment.last?
- %p= s_('Environments|This action will relaunch the job for commit %{commit_id}, putting the environment in a previous version. Are you sure you want to continue?').html_safe % {commit_id: commit_sha}
- - else
- %p
- = s_('Environments|This action will run the job defined by %{environment_name} for commit %{commit_id}, putting the environment in a previous version. You can revert it by re-deploying the latest version of your application. Are you sure you want to continue?').html_safe % {commit_id: commit_sha, environment_name: @environment.name}
- .modal-footer
- = button_tag _('Cancel'), type: 'button', class: 'btn gl-button btn-danger', data: { dismiss: 'modal' }
- = link_to [:retry, @project, deployment.deployable], method: :post, class: 'btn gl-button btn-danger' do
- - if deployment.last?
- = s_('Environments|Re-deploy')
- - else
- = s_('Environments|Rollback')
diff --git a/app/views/projects/deployments/_rollback.haml b/app/views/projects/deployments/_rollback.haml
index 78972a5b7b9..a7befabdc96 100644
--- a/app/views/projects/deployments/_rollback.haml
+++ b/app/views/projects/deployments/_rollback.haml
@@ -1,8 +1,7 @@
- if deployment.deployable && can?(current_user, :create_deployment, deployment)
- tooltip = deployment.last? ? s_('Environments|Re-deploy to environment') : s_('Environments|Rollback environment')
- = button_tag class: 'gl-button btn btn-default btn-icon has-tooltip', type: 'button', data: { toggle: 'modal', target: "#confirm-rollback-modal-#{deployment.id}" }, title: tooltip do
+ = button_tag class: 'js-confirm-rollback-modal-button gl-button btn btn-default btn-icon has-tooltip', type: 'button', data: { environment_name: @environment.name, commit_short_sha: deployment.short_sha, commit_url: project_commit_path(@project, deployment.sha), is_last_deployment: deployment.last?.to_s, retry_path: retry_project_job_path(@environment.project, deployment.deployable) }, title: tooltip do
- if deployment.last?
= sprite_icon('repeat', css_class: 'gl-icon')
- else
= sprite_icon('redo', css_class: 'gl-icon')
- = render 'projects/deployments/confirm_rollback_modal', deployment: deployment
diff --git a/app/views/projects/diffs/_file.html.haml b/app/views/projects/diffs/_file.html.haml
index 35e2fe1b398..418a65118f5 100644
--- a/app/views/projects/diffs/_file.html.haml
+++ b/app/views/projects/diffs/_file.html.haml
@@ -16,7 +16,7 @@
- unless diff_file.submodule?
.file-actions.gl-display-none.gl-sm-display-flex
- if diff_file.blob&.readable_text?
- %span.has-tooltip.gl-mr-3{ title: _("Toggle comments for this file") }
+ %span.has-tooltip{ title: _("Toggle comments for this file") }
= link_to '#', class: 'js-toggle-diff-comments btn gl-button btn-default btn-icon selected', disabled: @diff_notes_disabled do
= sprite_icon('comment')
\
diff --git a/app/views/projects/edit.html.haml b/app/views/projects/edit.html.haml
index 187fe608a68..926a0610577 100644
--- a/app/views/projects/edit.html.haml
+++ b/app/views/projects/edit.html.haml
@@ -19,7 +19,7 @@
.settings-content
= form_for @project, html: { multipart: true, class: "sharing-permissions-form" }, authenticity_token: true do |f|
%input{ name: 'update_section', type: 'hidden', value: 'js-shared-permissions' }
- %template.js-project-permissions-form-data{ type: "application/json" }= project_permissions_panel_data_json(@project)
+ %template.js-project-permissions-form-data{ type: "application/json" }= project_permissions_panel_data(@project).to_json.html_safe
.js-project-permissions-form
- if show_visibility_confirm_modal?(@project)
= render "visibility_modal"
@@ -54,6 +54,8 @@
.settings-content
= render 'shared/badges/badge_settings'
+= render_if_exists 'compliance_management/compliance_framework/project_settings', expanded: expanded
+
= render_if_exists 'projects/settings/default_issue_template'
= render 'projects/service_desk_settings'
diff --git a/app/views/projects/empty.html.haml b/app/views/projects/empty.html.haml
index 70d86e79282..905794c0730 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_empty_project' if can_import_members?
+= render "invite_members_empty_project" if can_admin_project_member?(@project)
%h4.gl-mt-0.gl-mb-3
= _('The repository for this project is empty')
diff --git a/app/views/projects/environments/_external_url.html.haml b/app/views/projects/environments/_external_url.html.haml
deleted file mode 100644
index b9208969fb3..00000000000
--- a/app/views/projects/environments/_external_url.html.haml
+++ /dev/null
@@ -1,4 +0,0 @@
-- if environment.external_url && can?(current_user, :read_environment, environment)
- = link_to environment.external_url, target: '_blank', rel: 'noopener noreferrer', class: 'gl-button btn external-url has-tooltip qa-view-deployment', title: s_('Environments|Open live environment') do
- = sprite_icon('external-link')
- = _("View deployment")
diff --git a/app/views/projects/environments/_form.html.haml b/app/views/projects/environments/_form.html.haml
deleted file mode 100644
index a295c8f6fb0..00000000000
--- a/app/views/projects/environments/_form.html.haml
+++ /dev/null
@@ -1,21 +0,0 @@
-.row.gl-mt-3.gl-mb-3
- .col-lg-3
- %h4.gl-mt-0
- = _("Environments")
- %p
- - link_to_read_more = link_to(_("More information"), help_page_path("ci/environments/index.md"))
- = _("Environments allow you to track deployments of your application %{link_to_read_more}.").html_safe % { link_to_read_more: link_to_read_more }
-
- = form_for [@project, @environment], html: { class: 'col-lg-9' } do |f|
- = form_errors(@environment)
-
- .form-group
- = f.label :name, _('Name'), class: 'label-bold'
- = f.text_field :name, required: true, class: 'form-control'
- .form-group
- = f.label :external_url, _('External URL'), class: 'label-bold'
- = f.url_field :external_url, class: 'form-control'
-
- .form-actions
- = f.submit _('Save'), class: 'gl-button btn btn-confirm'
- = link_to _('Cancel'), project_environments_path(@project), class: 'gl-button btn btn-cancel'
diff --git a/app/views/projects/environments/_metrics_button.html.haml b/app/views/projects/environments/_metrics_button.html.haml
deleted file mode 100644
index 65abaf44082..00000000000
--- a/app/views/projects/environments/_metrics_button.html.haml
+++ /dev/null
@@ -1,7 +0,0 @@
-- environment = local_assigns.fetch(:environment)
-
-- return unless can?(current_user, :read_environment, environment)
-
-= link_to environment_metrics_path(environment), title: _('See metrics'), class: 'gl-button btn metrics-button' do
- = sprite_icon('chart', css_class: 'gl-mr-2')
- = _("Monitoring")
diff --git a/app/views/projects/environments/_pin_button.html.haml b/app/views/projects/environments/_pin_button.html.haml
deleted file mode 100644
index ec3e7e20365..00000000000
--- a/app/views/projects/environments/_pin_button.html.haml
+++ /dev/null
@@ -1,3 +0,0 @@
-- if environment.auto_stop_at? && environment.available?
- = button_to cancel_auto_stop_project_environment_path(environment.project, environment), class: 'gl-button btn btn-secondary has-tooltip', title: _('Prevent environment from auto-stopping') do
- = sprite_icon('thumbtack')
diff --git a/app/views/projects/environments/_terminal_button.html.haml b/app/views/projects/environments/_terminal_button.html.haml
deleted file mode 100644
index ab3363bbb07..00000000000
--- a/app/views/projects/environments/_terminal_button.html.haml
+++ /dev/null
@@ -1,3 +0,0 @@
-- if environment.has_terminals? && can?(current_user, :admin_environment, @project)
- = link_to terminal_project_environment_path(@project, environment), class: 'gl-button btn terminal-button' do
- = sprite_icon('terminal')
diff --git a/app/views/projects/environments/edit.html.haml b/app/views/projects/environments/edit.html.haml
index c4e2c1eb63d..dcd5fb2574e 100644
--- a/app/views/projects/environments/edit.html.haml
+++ b/app/views/projects/environments/edit.html.haml
@@ -1,7 +1,6 @@
- page_title _("Edit"), @environment.name, _("Environments")
- add_page_specific_style 'page_bundles/environments'
-%h3.page-title
- = _('Edit environment')
-%hr
-= render 'form'
+#js-edit-environment{ data: { project_environments_path: project_environments_path(@project),
+ update_environment_path: project_environment_path(@project, @environment),
+ environment: environment_data(@environment)} }
diff --git a/app/views/projects/environments/new.html.haml b/app/views/projects/environments/new.html.haml
index 6b0ccc1dcc7..de7f976717b 100644
--- a/app/views/projects/environments/new.html.haml
+++ b/app/views/projects/environments/new.html.haml
@@ -2,7 +2,4 @@
- page_title _("New Environment")
- add_page_specific_style 'page_bundles/environments'
-%h3.page-title
- = _("New environment")
-%hr
-= render 'form'
+#js-new-environment{ data: { project_environments_path: project_environments_path(@project) } }
diff --git a/app/views/projects/environments/show.html.haml b/app/views/projects/environments/show.html.haml
index b3e4b7a4998..b123b81b89c 100644
--- a/app/views/projects/environments/show.html.haml
+++ b/app/views/projects/environments/show.html.haml
@@ -5,58 +5,8 @@
- add_page_specific_style 'page_bundles/environments'
- add_page_specific_style 'page_bundles/ci_status'
-#environments-detail-view{ data: { name: @environment.name, id: @environment.id, delete_path: environment_delete_path(@environment)} }
- - if @environment.available? && can?(current_user, :stop_environment, @environment)
- #stop-environment-modal.modal.fade{ tabindex: -1 }
- .modal-dialog
- .modal-content
- .modal-header
- %h4.modal-title.d-flex.mw-100
- = s_("Environments|Stopping")
- %span.has-tooltip.text-truncate.ml-1.mr-1.flex-fill{ title: @environment.name, data: { container: '#stop-environment-modal' } }
- #{@environment.name}?
- .modal-body
- %p= s_('Environments|Are you sure you want to stop this environment?')
- - unless @environment.stop_action_available?
- .warning_message
- %p= s_('Environments|Note that this action will stop the environment, but it will %{emphasis_start}not%{emphasis_end} have an effect on any existing deployment due to no “stop environment action” being defined in the %{ci_config_link_start}.gitlab-ci.yml%{ci_config_link_end} file.').html_safe % { emphasis_start: '<strong>'.html_safe,
- emphasis_end: '</strong>'.html_safe,
- ci_config_link_start: '<a href="https://docs.gitlab.com/ee/ci/yaml/" target="_blank" rel="noopener noreferrer">'.html_safe,
- ci_config_link_end: '</a>'.html_safe }
- %a{ href: 'https://docs.gitlab.com/ee/ci/environments/index.html#stopping-an-environment',
- target: '_blank',
- rel: 'noopener noreferrer' }
- = s_('Environments|Learn more about stopping environments')
- .modal-footer
- = button_tag _('Cancel'), type: 'button', class: 'gl-button btn btn-cancel', data: { dismiss: 'modal' }
- = button_to stop_project_environment_path(@project, @environment), class: 'gl-button btn btn-danger has-tooltip', method: :post do
- = s_('Environments|Stop environment')
-
- - if can_destroy_environment?(@environment)
- #delete-environment-modal
-
- .top-area.justify-content-between
- .d-flex
- %h3.page-title= @environment.name
- - if @environment.auto_stop_at?
- %p.align-self-end.gl-ml-3
- = s_('Environments|Auto stops %{auto_stop_time}').html_safe % {auto_stop_time: time_ago_with_tooltip(@environment.auto_stop_at)}
- .nav-controls.my-2
- = render 'projects/environments/pin_button', environment: @environment
- = render 'projects/environments/terminal_button', environment: @environment
- = render 'projects/environments/external_url', environment: @environment
- = render 'projects/environments/metrics_button', environment: @environment
- - if can?(current_user, :update_environment, @environment)
- = link_to _('Edit'), edit_project_environment_path(@project, @environment), class: 'btn'
- - if @environment.available? && can?(current_user, :stop_environment, @environment)
- = button_tag class: 'gl-button btn btn-danger', type: 'button', data: { toggle: 'modal',
- target: '#stop-environment-modal' } do
- = sprite_icon('stop')
- = s_('Environments|Stop')
- - if can_destroy_environment?(@environment)
- = button_tag class: 'gl-button btn btn-danger', type: 'button', data: { toggle: 'modal',
- target: '#delete-environment-modal' } do
- = s_('Environments|Delete')
+#environments-detail-view{ data: { details: environments_detail_data_json(current_user, @project, @environment) } }
+ #environments-detail-view-header
.environments-container
- if @deployments.blank?
diff --git a/app/views/projects/feature_flags/edit.html.haml b/app/views/projects/feature_flags/edit.html.haml
index f71c97c2a8f..c1c9f58265d 100644
--- a/app/views/projects/feature_flags/edit.html.haml
+++ b/app/views/projects/feature_flags/edit.html.haml
@@ -9,5 +9,5 @@
feature_flags_path: project_feature_flags_path(@project),
environments_endpoint: search_project_environments_path(@project, format: :json),
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'),
+ environments_scope_docs_path: help_page_path('ci/environments/index.md', anchor: 'scope-environments-with-specs'),
feature_flag_issues_endpoint: feature_flag_issues_links_endpoint(@project, @feature_flag, current_user) } }
diff --git a/app/views/projects/feature_flags/new.html.haml b/app/views/projects/feature_flags/new.html.haml
index bc52f52ecf7..097475d2928 100644
--- a/app/views/projects/feature_flags/new.html.haml
+++ b/app/views/projects/feature_flags/new.html.haml
@@ -10,5 +10,5 @@
user_callout_id: UserCalloutsHelper::FEATURE_FLAGS_NEW_VERSION,
show_user_callout: show_feature_flags_new_version?.to_s,
strategy_type_docs_page_path: help_page_path('operations/feature_flags', anchor: 'feature-flag-strategies'),
- environments_scope_docs_path: help_page_path('ci/environments/index.md', anchor: 'scoping-environments-with-specs'),
+ environments_scope_docs_path: help_page_path('ci/environments/index.md', anchor: 'scope-environments-with-specs'),
project_id: @project.id } }
diff --git a/app/views/projects/issues/_issue.html.haml b/app/views/projects/issues/_issue.html.haml
index 9c01d93f7d0..ee3aaee6dbb 100644
--- a/app/views/projects/issues/_issue.html.haml
+++ b/app/views/projects/issues/_issue.html.haml
@@ -12,6 +12,9 @@
- if issue.confidential?
%span.has-tooltip{ title: _('Confidential') }
= confidential_icon(issue)
+ - if Feature.enabled?(:ban_user_feature_flag) && issue.hidden?
+ %span.has-tooltip{ title: _('This issue is hidden because its author has been banned') }
+ = hidden_issue_icon(issue)
= link_to issue.title, issue_path(issue)
= render_if_exists 'projects/issues/subepic_flag', issue: issue
- if issue.tasks?
@@ -36,7 +39,7 @@
= sprite_icon('clock', css_class: 'gl-vertical-align-text-bottom')
= issue.milestone.title
- if issue.due_date
- %span.issuable-due-date.d-none.d-sm-inline-block.has-tooltip{ class: "#{'cred' if issue.overdue?}", title: _('Due date') }
+ %span.issuable-due-date.d-none.d-sm-inline-block.has-tooltip{ class: "#{'cred' if issue.overdue? && !issue.closed?}", title: _('Due date') }
&nbsp;
= sprite_icon('calendar')
= issue.due_date.to_s(:medium)
diff --git a/app/views/projects/issues/captcha_check.html.haml b/app/views/projects/issues/captcha_check.html.haml
new file mode 100644
index 00000000000..657c5c2cd8f
--- /dev/null
+++ b/app/views/projects/issues/captcha_check.html.haml
@@ -0,0 +1,7 @@
+= render layout: 'shared/captcha_check', locals: { spammable: @issue } do
+ -# These fields are for values which are passed via URL parameters, and not included in the
+ -# issue's params, so they must be yielded to the block to be rendered.
+ -# If these are removed and no longer passed via URL parameters, the support
+ -# for yielding in the layout can also be removed.
+ = hidden_field_tag(:merge_request_to_resolve_discussions_of, params[:merge_request_to_resolve_discussions_of])
+ = hidden_field_tag(:discussion_to_resolve, params[:discussion_to_resolve])
diff --git a/app/views/projects/issues/verify.html.haml b/app/views/projects/issues/verify.html.haml
deleted file mode 100644
index 935a3493a37..00000000000
--- a/app/views/projects/issues/verify.html.haml
+++ /dev/null
@@ -1,3 +0,0 @@
-= render layout: 'layouts/recaptcha_verification', locals: { spammable: @issue } do
- = hidden_field_tag(:merge_request_to_resolve_discussions_of, params[:merge_request_to_resolve_discussions_of])
- = hidden_field_tag(:discussion_to_resolve, params[:discussion_to_resolve])
diff --git a/app/views/projects/jobs/_table.html.haml b/app/views/projects/jobs/_table.html.haml
index 2d8b7315a29..cd59eae1fb7 100644
--- a/app/views/projects/jobs/_table.html.haml
+++ b/app/views/projects/jobs/_table.html.haml
@@ -21,13 +21,13 @@
%thead
%tr
%th Status
+ %th Name
%th Job
%th Pipeline
- if admin
%th Project
%th Runner
%th Stage
- %th Name
%th Duration
%th Coverage
%th
diff --git a/app/views/projects/merge_requests/_merge_request.html.haml b/app/views/projects/merge_requests/_merge_request.html.haml
index b70bc740175..3e2c5f088f7 100644
--- a/app/views/projects/merge_requests/_merge_request.html.haml
+++ b/app/views/projects/merge_requests/_merge_request.html.haml
@@ -33,7 +33,7 @@
%span.project-ref-path.has-tooltip{ title: _('Target branch') }
&nbsp;
= link_to project_ref_path(merge_request.project, merge_request.target_branch), class: 'ref-name' do
- = sprite_icon('fork', size: 12, css_class: 'fork-sprite')
+ = sprite_icon('branch', size: 12, css_class: 'fork-sprite')
= merge_request.target_branch
- if merge_request.labels.any?
&nbsp;
diff --git a/app/views/projects/merge_requests/creations/_new_submit.html.haml b/app/views/projects/merge_requests/creations/_new_submit.html.haml
index 7e1ca19d9b6..4aca13ae74a 100644
--- a/app/views/projects/merge_requests/creations/_new_submit.html.haml
+++ b/app/views/projects/merge_requests/creations/_new_submit.html.haml
@@ -40,7 +40,7 @@
#diff-notes-app.tab-content
#new.commits.tab-pane.active
= render "projects/merge_requests/commits"
- #diffs.diffs.tab-pane
+ #diffs.diffs.tab-pane{ class: "gl-m-0!" }
-# This tab is always loaded via AJAX
- if @pipelines.any?
#pipelines.pipelines.tab-pane
diff --git a/app/views/projects/merge_requests/show.html.haml b/app/views/projects/merge_requests/show.html.haml
index c4ee522bfa7..6d1ba9e693b 100644
--- a/app/views/projects/merge_requests/show.html.haml
+++ b/app/views/projects/merge_requests/show.html.haml
@@ -97,4 +97,5 @@
#js-review-bar
= render 'projects/invite_members_modal', project: @project
-
+- if Gitlab::CurrentSettings.gitpod_enabled && !current_user&.gitpod_enabled
+ = render 'shared/gitpod/enable_gitpod_modal'
diff --git a/app/views/projects/mirrors/_mirror_repos.html.haml b/app/views/projects/mirrors/_mirror_repos.html.haml
index 5a1e263141d..b89aa9d402e 100644
--- a/app/views/projects/mirrors/_mirror_repos.html.haml
+++ b/app/views/projects/mirrors/_mirror_repos.html.haml
@@ -70,10 +70,10 @@
= render 'projects/mirrors/disabled_mirror_badge'
- if mirror.last_error.present?
.badge.mirror-error-badge{ data: { toggle: 'tooltip', html: 'true', qa_selector: 'mirror_error_badge' }, title: html_escape(mirror.last_error.try(:strip)) }= _('Error')
- %td
+ %td.gl-display-flex
- if mirror_settings_enabled
- .btn-group.mirror-actions-group.float-right{ role: 'group' }
+ %button.js-delete-mirror.qa-delete-mirror.rspec-delete-mirror.btn.btn-icon.gl-button.btn-danger.gl-mr-3{ type: 'button', data: { mirror_id: mirror.id, toggle: 'tooltip', container: 'body' }, title: _('Remove') }= sprite_icon('remove')
+ .btn-group.mirror-actions-group{ role: 'group' }
- if mirror.ssh_key_auth?
= clipboard_button(text: mirror.ssh_public_key, class: 'gl-button btn btn-default', title: _('Copy SSH public key'), qa_selector: 'copy_public_key_button')
= render 'shared/remote_mirror_update_button', remote_mirror: mirror
- %button.js-delete-mirror.qa-delete-mirror.rspec-delete-mirror.btn.btn-icon.gl-button.btn-danger{ type: 'button', data: { mirror_id: mirror.id, toggle: 'tooltip', container: 'body' }, title: _('Remove') }= sprite_icon('remove')
diff --git a/app/views/projects/mirrors/_mirror_repos_push.html.haml b/app/views/projects/mirrors/_mirror_repos_push.html.haml
index 04f44f4748e..b3e0f71bf19 100644
--- a/app/views/projects/mirrors/_mirror_repos_push.html.haml
+++ b/app/views/projects/mirrors/_mirror_repos_push.html.haml
@@ -11,5 +11,5 @@
= check_box_tag :keep_divergent_refs, '1', false, class: 'js-mirror-keep-divergent-refs form-check-input'
= label_tag :keep_divergent_refs, _('Keep divergent refs'), class: 'form-check-label'
.form-text.text-muted
- = _('By default, if any ref (branch, tag, or commit) on the remote mirror has diverged from the local repository, the entire push will fail, and nothing will be updated. Choose this option to override this behavior. After the mirror is created, this can only be modified via the API.')
- = link_to _('Learn more.'), help_page_path('user/project/repository/repository_mirroring', anchor: 'keep-divergent-refs'), target: '_blank', rel: 'noopener noreferrer'
+ - link_opening_tag = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe
+ = html_escape(_('Do not force push over diverged refs. After the mirror is created, this setting can only be modified using the API. %{mirroring_docs_link_start}Learn more about this option%{link_closing_tag} and %{mirroring_api_docs_link_start}the API.%{link_closing_tag}')) % { mirroring_docs_link_start: link_opening_tag % {url: help_page_path('user/project/repository/repository_mirroring', anchor: 'keep-divergent-refs')}, mirroring_api_docs_link_start: link_opening_tag % {url: help_page_path('api/remote_mirrors')}, link_closing_tag: '</a>'.html_safe }
diff --git a/app/views/projects/packages/packages/show.html.haml b/app/views/projects/packages/packages/show.html.haml
index 76eb22109a4..42c31b3272f 100644
--- a/app/views/projects/packages/packages/show.html.haml
+++ b/app/views/projects/packages/packages/show.html.haml
@@ -6,7 +6,7 @@
.row
.col-12
- - if Feature.enabled?(:package_details_apollo)
- #js-vue-packages-detail-new{ data: package_details_data(@project) }
+ - if Feature.enabled?(:package_details_apollo, default_enabled: :yaml)
+ #js-vue-packages-detail-new{ data: package_details_data(@project, @package) }
- else
- #js-vue-packages-detail{ data: package_details_data(@project, @package) }
+ #js-vue-packages-detail{ data: package_details_data(@project, @package, true) }
diff --git a/app/views/projects/pipelines/show.html.haml b/app/views/projects/pipelines/show.html.haml
index 1c134d914e9..30ebe4f20b6 100644
--- a/app/views/projects/pipelines/show.html.haml
+++ b/app/views/projects/pipelines/show.html.haml
@@ -5,9 +5,7 @@
- add_page_specific_style 'page_bundles/pipeline'
- add_page_specific_style 'page_bundles/reports'
- add_page_specific_style 'page_bundles/ci_status'
-
-- if Feature.enabled?(:graphql_pipeline_details, @project, default_enabled: :yaml) || Feature.enabled?(:graphql_pipeline_details_users, @current_user, default_enabled: :yaml)
- - add_page_startup_graphql_call('pipelines/get_pipeline_details', { projectPath: @project.full_path, iid: @pipeline.iid })
+- add_page_startup_graphql_call('pipelines/get_pipeline_details', { projectPath: @project.full_path, iid: @pipeline.iid })
.js-pipeline-container{ data: { controller_action: "#{controller.action_name}" } }
#js-pipeline-header-vue.pipeline-header-container{ data: { full_path: @project.full_path, pipeline_iid: @pipeline.iid, pipeline_id: @pipeline.id, pipelines_path: project_pipelines_path(@project) } }
diff --git a/app/views/projects/project_members/index.html.haml b/app/views/projects/project_members/index.html.haml
index d1b6db95392..0239e408e87 100644
--- a/app/views/projects/project_members/index.html.haml
+++ b/app/views/projects/project_members/index.html.haml
@@ -1,7 +1,6 @@
- add_page_specific_style 'page_bundles/members'
- page_title _("Members")
-.js-remove-member-modal
.row.gl-mt-3
.col-lg-12
- if can_invite_members_for_project?(@project) || can_invite_group_for_project?(@project)
@@ -11,21 +10,21 @@
%h4
= _("Project members")
.gl-justify-content-bottom.gl-display-flex.align-items-center
- - if can_manage_project_members?(@project)
+ - if can?(current_user, :admin_project_member, @project)
%p= share_project_description(@project)
- else
%p
= html_escape(_("Members can be added by project %{i_open}Maintainers%{i_close} or %{i_open}Owners%{i_close}")) % { i_open: '<i>'.html_safe, i_close: '</i>'.html_safe }
.col-md-12.col-lg-6
.gl-display-flex.gl-flex-wrap.gl-justify-content-end
- - if can_import_members?
+ - if can_admin_project_member?(@project)
= link_to _("Import a project"),
import_project_project_members_path(@project),
class: "btn btn-default btn-md gl-button gl-mt-3 gl-sm-w-auto gl-w-full",
title: _("Import members from another project")
- if @project.allowed_to_share_with_group?
.js-invite-group-trigger{ data: { classes: 'gl-mt-3 gl-sm-w-auto gl-w-full gl-sm-ml-3', display_text: _('Invite a group') } }
- - if can_manage_project_members?(@project) && !membership_locked?
+ - if can_admin_project_member?(@project)
.js-invite-members-trigger{ data: { variant: 'success',
classes: 'gl-mt-3 gl-sm-w-auto gl-w-full gl-sm-ml-3',
trigger_source: 'project-members-page',
@@ -36,13 +35,13 @@
- if project_can_be_shared?
%h4
= _("Project members")
- - if can_manage_project_members?(@project)
+ - if can?(current_user, :admin_project_member, @project)
%p= share_project_description(@project)
- else
%p
= html_escape(_("Members can be added by project %{i_open}Maintainers%{i_close} or %{i_open}Owners%{i_close}")) % { i_open: '<i>'.html_safe, i_close: '</i>'.html_safe }
- - if Feature.disabled?(:invite_members_group_modal, @project.group) && can_manage_project_members?(@project) && project_can_be_shared?
+ - if Feature.disabled?(:invite_members_group_modal, @project.group) && can?(current_user, :admin_project_member, @project) && project_can_be_shared?
- if !membership_locked? && @project.allowed_to_share_with_group?
%ul.nav-links.nav.nav-tabs.gitlab-tabs{ role: 'tablist' }
%li.nav-tab{ role: 'presentation' }
@@ -52,13 +51,37 @@
.tab-content.gitlab-tab-content
.tab-pane.active{ id: 'invite-member-pane', role: 'tabpanel' }
- = render 'shared/members/invite_member', submit_url: project_project_members_path(@project), access_levels: ProjectMember.access_level_roles, default_access_level: @project_member.access_level, can_import_members?: can_import_members?, import_path: import_project_project_members_path(@project)
+ = render 'shared/members/invite_member',
+ submit_url: project_project_members_path(@project),
+ access_levels: ProjectMember.access_level_roles,
+ default_access_level: @project_member.access_level,
+ can_import_members?: can_admin_project_member?(@project),
+ import_path: import_project_project_members_path(@project)
.tab-pane{ id: 'invite-group-pane', role: 'tabpanel', class: ('active' if membership_locked?) }
- = render 'shared/members/invite_group', submit_url: project_group_links_path(@project), access_levels: ProjectGroupLink.access_options, default_access_level: ProjectGroupLink.default_access, group_link_field: 'link_group_id', group_access_field: 'link_group_access', groups_select_tag_data: { skip_groups: @skip_groups }
+ = render 'shared/members/invite_group',
+ submit_url: project_group_links_path(@project),
+ access_levels: ProjectGroupLink.access_options,
+ default_access_level: ProjectGroupLink.default_access,
+ group_link_field: 'link_group_id',
+ group_access_field: 'link_group_access',
+ groups_select_tag_data: { skip_groups: @skip_groups }
- elsif !membership_locked?
- .invite-member= render 'shared/members/invite_member', submit_url: project_project_members_path(@project), access_levels: ProjectMember.access_level_roles, default_access_level: @project_member.access_level, can_import_members?: can_import_members?, import_path: import_project_project_members_path(@project)
+ .invite-member
+ = render 'shared/members/invite_member',
+ submit_url: project_project_members_path(@project),
+ access_levels: ProjectMember.access_level_roles,
+ default_access_level: @project_member.access_level,
+ can_import_members?: can_admin_project_member?(@project),
+ import_path: import_project_project_members_path(@project)
- elsif @project.allowed_to_share_with_group?
- .invite-group= render 'shared/members/invite_group', access_levels: ProjectGroupLink.access_options, default_access_level: ProjectGroupLink.default_access, submit_url: project_group_links_path(@project), group_link_field: 'link_group_id', group_access_field: 'link_group_access', groups_select_tag_data: { skip_groups: @skip_groups }
+ .invite-group
+ = render 'shared/members/invite_group',
+ access_levels: ProjectGroupLink.access_options,
+ default_access_level: ProjectGroupLink.default_access,
+ submit_url: project_group_links_path(@project),
+ group_link_field: 'link_group_id',
+ group_access_field: 'link_group_access',
+ groups_select_tag_data: { skip_groups: @skip_groups }
.js-project-members-list-app{ data: { members_data: project_members_app_data_json(@project,
members: @project_members,
group_links: @group_links,
diff --git a/app/views/projects/runners/_specific_runners.html.haml b/app/views/projects/runners/_specific_runners.html.haml
index eb376ff7960..5e999b7afb3 100644
--- a/app/views/projects/runners/_specific_runners.html.haml
+++ b/app/views/projects/runners/_specific_runners.html.haml
@@ -4,10 +4,6 @@
.bs-callout.help-callout
- if valid_runner_registrars.include?('project')
= _('These runners are specific to this project.')
- %hr
- = 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',
diff --git a/app/views/projects/security/configuration/show.html.haml b/app/views/projects/security/configuration/show.html.haml
index d4a85893fa4..e8ac572df1d 100644
--- a/app/views/projects/security/configuration/show.html.haml
+++ b/app/views/projects/security/configuration/show.html.haml
@@ -1,6 +1,5 @@
- 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
+- @content_class = "limit-container-width" unless fluid_layout
#js-security-configuration-static{ data: { project_path: @project.full_path, upgrade_path: security_upgrade_path } }
diff --git a/app/views/projects/settings/_general.html.haml b/app/views/projects/settings/_general.html.haml
index 0891e3e0526..b185f45d129 100644
--- a/app/views/projects/settings/_general.html.haml
+++ b/app/views/projects/settings/_general.html.haml
@@ -19,8 +19,6 @@
= f.text_field :topics, value: @project.topic_list.join(', '), maxlength: 2000, class: "form-control gl-form-input"
%p.form-text.text-muted= _('Separate topics with commas.')
- = render_if_exists 'compliance_management/compliance_framework/project_settings', f: f
-
.row
.form-group.col-md-9
= f.label :description, _('Project description (optional)'), class: 'label-bold'
diff --git a/app/views/projects/show.html.haml b/app/views/projects/show.html.haml
index 4757f50739b..e515f1e7320 100644
--- a/app/views/projects/show.html.haml
+++ b/app/views/projects/show.html.haml
@@ -19,6 +19,7 @@
= render "archived_notice", project: @project
= render_if_exists "projects/marked_for_deletion_notice", project: @project
= render_if_exists "projects/ancestor_group_marked_for_deletion_notice", project: @project
+= render_if_exists 'projects/sast_entry_points', project: @project
- view_path = @project.default_view
diff --git a/app/views/projects/snippets/show.html.haml b/app/views/projects/snippets/show.html.haml
index a296394a2e0..8ef53c40b11 100644
--- a/app/views/projects/snippets/show.html.haml
+++ b/app/views/projects/snippets/show.html.haml
@@ -3,7 +3,7 @@
- breadcrumb_title @snippet.to_reference
- page_title "#{@snippet.title} (#{@snippet.to_reference})", _("Snippets")
-#js-snippet-view{ data: {'qa-selector': 'snippet_view', 'snippet-gid': @snippet.to_global_id} }
+#js-snippet-view{ data: {'qa-selector': 'snippet_view', 'snippet-gid': @snippet.to_global_id, 'report-abuse-path': snippet_report_abuse_path(@snippet) } }
.row-content-block.top-block.content-component-block
= render 'award_emoji/awards_block', awardable: @snippet, inline: true, api_awards_path: project_snippets_award_api_path(@snippet)
diff --git a/app/views/search/results/_blob_data.html.haml b/app/views/search/results/_blob_data.html.haml
index fb2825ad15e..2f13d7d96c7 100644
--- a/app/views/search/results/_blob_data.html.haml
+++ b/app/views/search/results/_blob_data.html.haml
@@ -1,5 +1,5 @@
-.blob-result{ data: { qa_selector: 'result_item_content' } }
- .file-holder
+.blob-result.gl-mt-3.gl-mb-5{ data: { qa_selector: 'result_item_content' } }
+ .file-holder.file-holder-top-border
.js-file-title.file-title{ data: { qa_selector: 'file_title_content' } }
= link_to blob_link, data: {track_event: 'click_text', track_label: 'blob_path', track_property: 'search_result'} do
= sprite_icon('document')
@@ -7,5 +7,12 @@
= 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
+ - if blob.data.size > 0
+ .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
+ - else
+ .file-content.code
+ .nothing-here-block
+ .gl-text-gray-600.gl-font-sm
+ - max_file_size_indexed = Gitlab::CurrentSettings.elasticsearch_indexed_file_size_limit_kb.kilobytes
+ = _('The file could not be displayed because it is empty or larger than the maximum file size indexed (%{size}).') % { size: number_to_human_size(max_file_size_indexed) }
diff --git a/app/views/search/results/_issuable.html.haml b/app/views/search/results/_issuable.html.haml
index 551f5c048bc..63524bbf00e 100644
--- a/app/views/search/results/_issuable.html.haml
+++ b/app/views/search/results/_issuable.html.haml
@@ -12,7 +12,7 @@
.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
+ - if 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
diff --git a/app/views/search/show.html.haml b/app/views/search/show.html.haml
index d54310bfa82..ab5ca0cd90f 100644
--- a/app/views/search/show.html.haml
+++ b/app/views/search/show.html.haml
@@ -5,10 +5,14 @@
= hidden_field_tag :group_id, params[:group_id]
- if params[:project_id].present?
= hidden_field_tag :project_id, params[:project_id]
+- group_attributes = @group&.attributes&.slice('id', 'name')&.merge(full_name: @group&.full_name)
- project_attributes = @project&.attributes&.slice('id', 'namespace_id', 'name')&.merge(name_with_namespace: @project&.name_with_namespace)
- if @search_results
- - page_description(_("%{count} %{scope} for term '%{term}'") % { count: @search_results.formatted_count(@scope), scope: @scope, term: @search_term })
+ - if @without_count
+ - page_description(_("%{scope} results for term '%{term}'") % { scope: @scope, term: @search_term })
+ - else
+ - page_description(_("%{count} %{scope} for term '%{term}'") % { count: @search_results.formatted_count(@scope), scope: @scope, term: @search_term })
- page_card_attributes("Namespace" => @group&.full_path, "Project" => @project&.full_path)
.page-title-holder.d-flex.flex-wrap.justify-content-between
@@ -16,7 +20,7 @@
= render_if_exists 'search/form_elasticsearch', attrs: { class: 'mb-2 mb-sm-0 align-self-center' }
.gl-mt-3
- #js-search-topbar{ data: { "group-initial-data": @group.to_json, "project-initial-data": project_attributes.to_json } }
+ #js-search-topbar{ data: { "group-initial-data": group_attributes.to_json, "project-initial-data": project_attributes.to_json } }
- if @search_term
= render 'search/category'
= render 'search/results'
diff --git a/app/views/shared/_allow_request_access.html.haml b/app/views/shared/_allow_request_access.html.haml
index 93868f13e58..ca09fd39dc1 100644
--- a/app/views/shared/_allow_request_access.html.haml
+++ b/app/views/shared/_allow_request_access.html.haml
@@ -1,6 +1,6 @@
- label_class = local_assigns.fetch(:bold_label, false) ? 'font-weight-bold' : ''
-.gl-form-checkbox.custom-control.custom-checkbox
- = form.check_box :request_access_enabled, class: 'custom-control-input', data: { qa_selector: 'request_access_checkbox' }
- = form.label :request_access_enabled, class: 'custom-control-label' do
- %span{ class: label_class }= _('Allow users to request access (if visibility is public or internal)')
+= form.gitlab_ui_checkbox_component :request_access_enabled,
+ _('Allow users to request access (if visibility is public or internal)'),
+ label_options: { class: label_class },
+ checkbox_options: { data: { qa_selector: 'request_access_checkbox' } }
diff --git a/app/views/shared/_captcha_check.html.haml b/app/views/shared/_captcha_check.html.haml
new file mode 100644
index 00000000000..3d611c22491
--- /dev/null
+++ b/app/views/shared/_captcha_check.html.haml
@@ -0,0 +1,37 @@
+- resource_name = spammable.class.model_name.singular
+- humanized_resource_name = spammable.class.model_name.human.downcase
+- script = local_assigns.fetch(:script, true)
+- method = params[:action] == 'create' ? :post : :put
+
+%h3.page-title
+ = _('Anti-spam verification')
+%hr
+
+%p
+ = _("We detected potential spam in the %{humanized_resource_name}. Please solve the reCAPTCHA to proceed.") % { humanized_resource_name: humanized_resource_name }
+
+= form_for resource_name, method: method, html: { class: 'recaptcha-form js-recaptcha-form' } do |f|
+ .recaptcha
+ -# Create a hidden field for each param of the resource
+ - params[resource_name].each do |field, value|
+ = hidden_field(resource_name, field, value: value)
+
+ -# The reCAPTCHA response value will be returned in the 'g-recaptcha-response' field in non-test environments
+ = recaptcha_tags script: script, callback: 'recaptchaDialogCallback', nonce: content_security_policy_nonce unless Rails.env.test?
+
+ -# Fake the 'g-recaptcha-response' field in the test environment, so that the feature spec
+ -# can get to the (mocked) SpamVerdictService check.
+ = hidden_field_tag('g-recaptcha-response', 'abc123') if Rails.env.test?
+
+ -# Create a hidden field to pass back the ID of the spam_log record which was previously created
+ = hidden_field_tag(:spam_log_id, spammable.spam_log.id)
+
+ -# Yields a block with given extra params which are not included in `params[resource_name]`.
+ -# Currently, this is only used for these params which are passed via URL parameters,
+ -# and can be removed once they are no longer needed to be passed:
+ -# - merge_request_to_resolve_discussions_of
+ -# - discussion_to_resolve
+ = yield
+
+ .row-content-block.footer-block
+ = f.submit _("Create %{humanized_resource_name}") % { humanized_resource_name: humanized_resource_name }, class: 'gl-button btn btn-confirm'
diff --git a/app/views/shared/_check_recovery_settings.html.haml b/app/views/shared/_check_recovery_settings.html.haml
index 7ac90e5af03..2ba0cca9ef6 100644
--- a/app/views/shared/_check_recovery_settings.html.haml
+++ b/app/views/shared/_check_recovery_settings.html.haml
@@ -1,6 +1,11 @@
-.gl-alert.gl-alert-warning.js-recovery-settings-callout{ role: 'alert', data: { feature_id: "account_recovery_regular_check", dismiss_endpoint: user_callouts_path, defer_links: "true" } }
- %button.js-close.gl-alert-dismiss.gl-cursor-pointer{ type: 'button', 'aria-label' => _('Dismiss') }
- = sprite_icon('close', css_class: 'gl-icon')
+= render 'shared/global_alert',
+ variant: :warning,
+ alert_class: 'js-recovery-settings-callout',
+ alert_data: { feature_id: 'account_recovery_regular_check', dismiss_endpoint: user_callouts_path, defer_links: 'true' },
+ close_button_data: { testid: 'close-account-recovery-regular-check-callout' } do
.gl-alert-body
- - account_link_start = '<a class="deferred-link" href="%{url}">'.html_safe % { url: profile_account_path }
- = _("Please ensure your account's %{account_link_start}recovery settings%{account_link_end} are up to date.").html_safe % { account_link_start: account_link_start, account_link_end: '</a>'.html_safe }
+ = s_('Profiles|Ensure you have two-factor authentication recovery codes stored in a safe place.')
+ = link_to _('Learn more.'), help_page_path('user/profile/account/two_factor_authentication', anchor: 'recovery-codes'), target: '_blank', rel: 'noopener noreferrer'
+ .gl-alert-actions
+ = link_to profile_two_factor_auth_path, class: 'deferred-link btn gl-alert-action btn-confirm btn-md gl-button' do
+ = s_('Profiles|Manage two-factor authentication')
diff --git a/app/views/shared/_group_form.html.haml b/app/views/shared/_group_form.html.haml
index e96372a29db..63468340992 100644
--- a/app/views/shared/_group_form.html.haml
+++ b/app/views/shared/_group_form.html.haml
@@ -25,7 +25,8 @@
= f.text_field :path, placeholder: _('my-awesome-group'), class: 'form-control js-validate-group-path js-autofill-group-path', data: { qa_selector: 'group_path_field' },
autofocus: local_assigns[:autofocus] || false, required: true,
pattern: Gitlab::PathRegex::NAMESPACE_FORMAT_REGEX_JS,
- title: _('Please choose a group URL with no special characters.'),
+ title: group_url_error_message,
+ maxlength: ::Namespace::URL_MAX_LENGTH,
"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. We've suggested one that is available.")
diff --git a/app/views/shared/_recaptcha_form.html.haml b/app/views/shared/_recaptcha_form.html.haml
deleted file mode 100644
index ae0a22fd255..00000000000
--- a/app/views/shared/_recaptcha_form.html.haml
+++ /dev/null
@@ -1,23 +0,0 @@
-- resource_name = spammable.class.model_name.singular
-- humanized_resource_name = spammable.class.model_name.human.downcase
-- script = local_assigns.fetch(:script, true)
-- method = params[:action] == 'create' ? :post : :put
-- has_submit = local_assigns.fetch(:has_submit, true)
-
-= form_for resource_name, method: method, html: { class: 'recaptcha-form js-recaptcha-form' } do |f|
- .recaptcha
- - params[resource_name].each do |field, value|
- = hidden_field(resource_name, field, value: value)
- = hidden_field_tag(:spam_log_id, spammable.spam_log.id)
- -# The reCAPTCHA response value will be returned in the 'g-recaptcha-response' field
- = recaptcha_tags script: script, callback: 'recaptchaDialogCallback', nonce: content_security_policy_nonce unless Rails.env.test?
- -# Fake the 'g-recaptcha-response' field in the test environment, so that the feature spec
- -# can get to the (mocked) SpamVerdictService check.
- = hidden_field_tag('g-recaptcha-response', 'abc123') if Rails.env.test?
-
- -# Yields a block with given extra params.
- = yield
-
- - if has_submit
- .row-content-block.footer-block
- = f.submit _("Create %{humanized_resource_name}") % { humanized_resource_name: humanized_resource_name }, class: 'gl-button btn btn-confirm'
diff --git a/app/views/shared/_service_ping_consent.html.haml b/app/views/shared/_service_ping_consent.html.haml
index 77597124e5c..821d92e9d7e 100644
--- a/app/views/shared/_service_ping_consent.html.haml
+++ b/app/views/shared/_service_ping_consent.html.haml
@@ -1,8 +1,8 @@
- if session[:ask_for_usage_stats_consent]
- .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')
+ = render 'shared/global_alert',
+ variant: :info,
+ is_contained: true,
+ alert_class: 'service-ping-consent-message' do
.gl-alert-body
- docs_link = link_to _('collect usage information'), help_page_path('user/admin_area/settings/usage_statistics.md'), class: 'gl-link'
- settings_link = link_to _('your settings'), metrics_and_profiling_admin_application_settings_path(anchor: 'js-usage-settings'), class: 'gl-link'
@@ -11,4 +11,4 @@
- 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 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'
+ = 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-3'
diff --git a/app/views/shared/access_tokens/_table.html.haml b/app/views/shared/access_tokens/_table.html.haml
index 1f08bff9858..33d6b9573d4 100644
--- a/app/views/shared/access_tokens/_table.html.haml
+++ b/app/views/shared/access_tokens/_table.html.haml
@@ -7,6 +7,7 @@
%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.")
@@ -14,6 +15,9 @@
%p.profile-settings-content
= _("To see all the user's personal access tokens you must impersonate them first.")
+- if personal
+ = render_if_exists 'profiles/personal_access_tokens/token_expiry_notification', active_tokens: active_tokens
+
- if active_tokens.present?
.table-responsive
%table.table.active-tokens
@@ -42,7 +46,7 @@
%span.token-never-used-label= _('Never')
%td
- if token.expires?
- - if token.expires_at.past? || token.expires_at.today?
+ - if token.expired? || token.expired_but_not_enforced?
%span{ class: 'text-danger has-tooltip', title: _('Token valid until revoked') }
= _('Expired')
- else
diff --git a/app/views/shared/blob/_markdown_buttons.html.haml b/app/views/shared/blob/_markdown_buttons.html.haml
index 033ed69da41..e02c24b93f1 100644
--- a/app/views/shared/blob/_markdown_buttons.html.haml
+++ b/app/views/shared/blob/_markdown_buttons.html.haml
@@ -24,5 +24,5 @@
title: _("Add a collapsible section") })
= markdown_toolbar_button({ icon: "table", data: { "md-tag" => "| header | header |\n| ------ | ------ |\n| cell | cell |\n| cell | cell |", "md-prepend" => true }, title: _("Add a table") })
- if show_fullscreen_button
- %button.toolbar-btn.toolbar-fullscreen-btn.js-zen-enter.has-tooltip{ type: "button", tabindex: -1, "aria-label": "Go full screen", title: _("Go full screen"), data: { container: "body" } }
+ %button.gl-button.btn.btn-default-tertiary.btn-icon.js-zen-enter.has-tooltip{ type: "button", tabindex: -1, "aria-label": "Go full screen", title: _("Go full screen"), data: { container: "body" } }
= sprite_icon("maximize")
diff --git a/app/views/shared/boards/_show.html.haml b/app/views/shared/boards/_show.html.haml
index 9ccd5655fb0..a49c17e9265 100644
--- a/app/views/shared/boards/_show.html.haml
+++ b/app/views/shared/boards/_show.html.haml
@@ -4,7 +4,8 @@
- @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"
+- is_epic_board = board.to_type == "EpicBoard"
+- if is_epic_board
- breadcrumb_title _("Epic Boards")
- else
- breadcrumb_title _("Issue Boards")
@@ -19,5 +20,6 @@
= render 'shared/issuable/search_bar', type: :boards, board: board
#board-app.boards-app.position-relative{ "v-cloak" => "true", data: board_data, ":class" => "{ 'is-compact': detailIssueVisible }" }
%board-content{ ":lists" => "state.lists", ":disabled" => "disabled" }
- = render "shared/boards/components/sidebar", group: group
+ - if !is_epic_board && !Feature.enabled?(:graphql_board_lists, default_enabled: :yaml)
+ = render "shared/boards/components/sidebar", group: group
%board-settings-sidebar
diff --git a/app/views/shared/deploy_tokens/_form.html.haml b/app/views/shared/deploy_tokens/_form.html.haml
index 5d351bd11fd..e7bbb351633 100644
--- a/app/views/shared/deploy_tokens/_form.html.haml
+++ b/app/views/shared/deploy_tokens/_form.html.haml
@@ -1,5 +1,7 @@
%p.profile-settings-content
- = s_("DeployTokens|Pick a name for your unique deploy token.")
+ - group_deploy_tokens_help_link_url = help_page_path('user/project/deploy_tokens/index.md')
+ - group_deploy_tokens_help_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: group_deploy_tokens_help_link_url }
+ = s_('DeployTokens|Create a new deploy token for all projects in this group. %{link_start}What are deploy tokens?%{link_end}').html_safe % { link_start: group_deploy_tokens_help_link_start, link_end: '</a>'.html_safe }
= form_for token, url: create_deploy_token_path(group_or_project, anchor: 'js-deploy-tokens'), method: :post, remote: Feature.enabled?(:ajax_new_deploy_token, group_or_project) do |f|
= form_errors(token)
@@ -7,23 +9,26 @@
.form-group
= f.label :name, class: 'label-bold'
= f.text_field :name, class: 'form-control gl-form-input', data: { qa_selector: 'deploy_token_name_field' }, required: true
+ .text-secondary= s_('DeployTokens|Enter a unique name for your deploy token.')
.form-group
- = f.label :expires_at, _('Expires at (optional)'), class: 'label-bold'
+ = f.label :expires_at, _('Expiration date (optional)'), class: 'label-bold'
= f.text_field :expires_at, class: 'datepicker form-control', data: { qa_selector: 'deploy_token_expires_at_field' }, value: f.object.expires_at
- .text-secondary= s_('DeployTokens|Unless you enter a date, the token does not expire.')
+ .text-secondary= s_('DeployTokens|Enter an expiration date for your token. Defaults to never expire.')
.form-group
= f.label :username, _('Username (optional)'), class: 'label-bold'
= f.text_field :username, class: 'form-control'
- .text-secondary= s_('DeployTokens|Unless you specify a username, it is set to "gitlab+deploy-token-{n}".')
+ .text-secondary
+ = html_escape(s_('DeployTokens|Enter a username for your token. Defaults to %{code_start}gitlab+deploy-token-{n}%{code_end}.')) % { code_start: '<code>'.html_safe, code_end: '</code>'.html_safe }
.form-group
- = f.label :scopes, _('Scopes [Select 1 or more]'), class: 'label-bold'
+ = f.label :scopes, _('Scopes (select at least one)'), class: 'label-bold'
%fieldset.form-group.form-check
= f.check_box :read_repository, class: 'form-check-input', data: { qa_selector: 'deploy_token_read_repository_checkbox' }
= f.label :read_repository, 'read_repository', class: 'label-bold form-check-label'
- .text-secondary= s_('DeployTokens|Allows read-only access to the repository.')
+ .text-secondary
+ = s_('DeployTokens|Allows read-only access to the repository.')
- if container_registry_enabled?(group_or_project)
%fieldset.form-group.form-check
@@ -34,18 +39,18 @@
%fieldset.form-group.form-check
= f.check_box :write_registry, class: 'form-check-input'
= f.label :write_registry, 'write_registry', class: 'label-bold form-check-label'
- .text-secondary= s_('DeployTokens|Allows write access to registry images.')
+ .text-secondary= s_('DeployTokens|Allows read and write access to registry images.')
- if packages_registry_enabled?(group_or_project)
%fieldset.form-group.form-check
= 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.')
+ .text-secondary= s_('DeployTokens|Allows read-only access to the package registry.')
%fieldset.form-group.form-check
= f.check_box :write_package_registry, class: 'form-check-input'
= f.label :write_package_registry, 'write_package_registry', class: 'label-bold form-check-label'
- .text-secondary= s_('DeployTokens|Allows write access to the package registry.')
+ .text-secondary= s_('DeployTokens|Allows read and write access to the package registry.')
.gl-mt-3
= f.submit s_('DeployTokens|Create deploy token'), class: 'btn gl-button btn-confirm', data: { qa_selector: 'create_deploy_token_button' }
diff --git a/app/views/shared/deploy_tokens/_index.html.haml b/app/views/shared/deploy_tokens/_index.html.haml
index 3e8368b7b78..860fb5614af 100644
--- a/app/views/shared/deploy_tokens/_index.html.haml
+++ b/app/views/shared/deploy_tokens/_index.html.haml
@@ -11,7 +11,7 @@
- if @new_deploy_token.persisted?
= render 'shared/deploy_tokens/new_deploy_token', deploy_token: @new_deploy_token
%h5.gl-mt-0
- = s_('DeployTokens|Add a deploy token')
+ = s_('DeployTokens|New deploy token')
= render 'shared/deploy_tokens/form', group_or_project: group_or_project, token: @new_deploy_token, presenter: @deploy_tokens
%hr
= render 'shared/deploy_tokens/table', group_or_project: group_or_project, active_tokens: @deploy_tokens
diff --git a/app/views/shared/doorkeeper/applications/_show.html.haml b/app/views/shared/doorkeeper/applications/_show.html.haml
index b690aa74ff0..8d6b9604c1c 100644
--- a/app/views/shared/doorkeeper/applications/_show.html.haml
+++ b/app/views/shared/doorkeeper/applications/_show.html.haml
@@ -1,3 +1,5 @@
+- show_trusted_row = local_assigns.fetch(:show_trusted_row, false)
+
.table-holder.oauth-application-show
%table.table
%tr
@@ -13,11 +15,7 @@
%td
= _('Secret')
%td
- .clipboard-group
- .input-group
- %input.label.label-monospace.monospace{ id: "secret", type: "text", autocomplete: 'off', value: @application.secret, readonly: true }
- .input-group-append
- = clipboard_button(target: '#secret', title: _("Copy secret"), class: "gl-button btn btn-default")
+ = clipboard_button(clipboard_text: @application.secret, button_text: _('Copy'), title: _("Copy secret"), class: "btn btn-default btn-md gl-button")
%tr
%td
= _('Callback URL')
@@ -26,6 +24,13 @@
%div
%span.monospace= uri
+ - if show_trusted_row
+ %tr
+ %td
+ = _('Trusted')
+ %td
+ = @application.trusted? ? _('Yes') : _('No')
+
%tr
%td
= _('Confidential')
diff --git a/app/views/shared/groups/_empty_state.html.haml b/app/views/shared/groups/_empty_state.html.haml
index 506954c53ca..aaba9697fea 100644
--- a/app/views/shared/groups/_empty_state.html.haml
+++ b/app/views/shared/groups/_empty_state.html.haml
@@ -6,8 +6,3 @@
%h4= s_("GroupsEmptyState|A group is a collection of several projects.")
%p= s_("GroupsEmptyState|If you organize your projects under a group, it works like a folder.")
%p= s_("GroupsEmptyState|You can manage your group member’s permissions and access to each project in the group.")
- - if invite_group_members?(@group)
- = link_to _('Invite your team'),
- group_group_members_path(@group),
- class: 'gl-button btn btn-confirm-secondary',
- data: { track_event: 'click_invite_team_group_empty_state', track_label: 'invite_team_group_empty_state' }
diff --git a/app/views/shared/icons/_dev_ops_report_overview.svg b/app/views/shared/icons/_dev_ops_report_overview.svg
deleted file mode 100644
index 2f31113bad7..00000000000
--- a/app/views/shared/icons/_dev_ops_report_overview.svg
+++ /dev/null
@@ -1,64 +0,0 @@
-<svg xmlns="http://www.w3.org/2000/svg" width="208" height="127" viewBox="0 0 208 127" xmlns:xlink="http://www.w3.org/1999/xlink">
- <defs>
- <rect id="a" width="58" height="98" y="17" rx="6"/>
- <rect id="b" width="58" height="98" x="3.5" y="17" rx="6"/>
- <rect id="c" width="58" height="98.394" rx="6"/>
- </defs>
- <g fill="none" fill-rule="evenodd" transform="translate(1)">
- <path fill="#000" fill-opacity=".06" fill-rule="nonzero" d="M16 11.06c0-1.39.56-2.69 1.534-3.635.398-.386.41-1.025.027-1.426-.382-.402-1.015-.414-1.413-.028C14.785 7.294 14 9.116 14 11.062c0 .556.448 1.007 1 1.007s1-.452 1-1.01zm6.432-5.043h4.8c.552 0 1-.452 1-1.01 0-.556-.448-1.007-1-1.007h-4.8c-.552 0-1 .45-1 1.008 0 .557.448 1.01 1 1.01zm10.8 0h4.8c.552 0 1-.452 1-1.01 0-.556-.448-1.007-1-1.007h-4.8c-.552 0-1 .45-1 1.008 0 .557.448 1.01 1 1.01zm10.8 0h4.8c.552 0 1-.452 1-1.01 0-.556-.448-1.007-1-1.007h-4.8c-.552 0-1 .45-1 1.008 0 .557.448 1.01 1 1.01zm10.8 0h4.8c.552 0 1-.452 1-1.01 0-.556-.448-1.007-1-1.007h-4.8c-.552 0-1 .45-1 1.008 0 .557.448 1.01 1 1.01zm10.8 0h4.8c.552 0 1-.452 1-1.01 0-.556-.448-1.007-1-1.007h-4.8c-.552 0-1 .45-1 1.008 0 .557.448 1.01 1 1.01zm10.8 0h4.8c.552 0 1-.452 1-1.01 0-.556-.448-1.007-1-1.007h-4.8c-.552 0-1 .45-1 1.008 0 .557.448 1.01 1 1.01zm10.8 0h4.8c.552 0 1-.452 1-1.01 0-.556-.448-1.007-1-1.007h-4.8c-.552 0-1 .45-1 1.008 0 .557.448 1.01 1 1.01zm10.8 0h4.8c.552 0 1-.452 1-1.01 0-.556-.448-1.007-1-1.007h-4.8c-.552 0-1 .45-1 1.008 0 .557.448 1.01 1 1.01zm10.8 0h4.8c.552 0 1-.452 1-1.01 0-.556-.448-1.007-1-1.007h-4.8c-.552 0-1 .45-1 1.008 0 .557.448 1.01 1 1.01zm10.8 0h4.8c.552 0 1-.452 1-1.01 0-.556-.448-1.007-1-1.007h-4.8c-.552 0-1 .45-1 1.008 0 .557.448 1.01 1 1.01zm10.8 0h4.8c.552 0 1-.452 1-1.01 0-.556-.448-1.007-1-1.007h-4.8c-.552 0-1 .45-1 1.008 0 .557.448 1.01 1 1.01zm10.8 0h4.8c.552 0 1-.452 1-1.01 0-.556-.448-1.007-1-1.007h-4.8c-.552 0-1 .45-1 1.008 0 .557.448 1.01 1 1.01zm10.8 0h4.8c.552 0 1-.452 1-1.01 0-.556-.448-1.007-1-1.007h-4.8c-.552 0-1 .45-1 1.008 0 .557.448 1.01 1 1.01zm10.8 0h4.8c.552 0 1-.452 1-1.01 0-.556-.448-1.007-1-1.007h-4.8c-.552 0-1 .45-1 1.008 0 .557.448 1.01 1 1.01zm10.8 0h4.8c.552 0 1-.452 1-1.01 0-.556-.448-1.007-1-1.007h-4.8c-.552 0-1 .45-1 1.008 0 .557.448 1.01 1 1.01zm10.8 0H185c1.21 0 2.354.435 3.254 1.215.42.362 1.05.314 1.41-.108.36-.423.312-1.06-.107-1.422C188.297 4.612 186.694 4 185 4h-.568c-.552 0-1 .45-1 1.008 0 .557.448 1.01 1 1.01zM190 11.932v4.84c0 .557.448 1.008 1 1.008s1-.45 1-1.008v-4.84c0-.556-.448-1.008-1-1.008s-1 .452-1 1.008zm0 10.89v4.84c0 .556.448 1.008 1 1.008s1-.452 1-1.01v-4.838c0-.557-.448-1.01-1-1.01s-1 .453-1 1.01zm0 10.89v4.84c0 .555.448 1.007 1 1.007s1-.453 1-1.01v-4.84c0-.556-.448-1.007-1-1.007s-1 .45-1 1.008zm0 10.888v4.84c0 .557.448 1.008 1 1.008s1-.45 1-1.008V44.6c0-.557-.448-1.008-1-1.008s-1 .45-1 1.008zm0 10.89v4.84c0 .556.448 1.007 1 1.007s1-.45 1-1.008v-4.84c0-.557-.448-1.01-1-1.01s-1 .453-1 1.01zm0 10.89v4.838c0 .557.448 1.01 1 1.01s1-.453 1-1.01v-4.84c0-.556-.448-1.008-1-1.008s-1 .452-1 1.01zm0 10.888v4.84c0 .556.448 1.008 1 1.008s1-.452 1-1.008v-4.84c0-.557-.448-1.008-1-1.008s-1 .45-1 1.008zm0 10.89v4.84c0 .556.448 1.007 1 1.007s1-.45 1-1.008v-4.84c0-.557-.448-1.008-1-1.008s-1 .45-1 1.007zm0 10.888v4.84c0 .557.448 1.008 1 1.008s1-.45 1-1.008v-4.84c0-.556-.448-1.008-1-1.008s-1 .452-1 1.008zm-.24 21.446c-.42 1.304-1.353 2.385-2.572 2.985-.497.244-.703.847-.46 1.348.24.5.84.708 1.336.464 1.707-.84 3.013-2.35 3.598-4.178.17-.53-.12-1.098-.644-1.27-.526-.17-1.09.12-1.26.65zm-8.063 3.49h-4.8c-.552 0-1 .453-1 1.01 0 .557.448 1.008 1 1.008h4.8c.553 0 1-.45 1-1.008 0-.557-.447-1.01-1-1.01zm-10.8 0h-4.8c-.552 0-1 .453-1 1.01 0 .557.448 1.008 1 1.008h4.8c.553 0 1-.45 1-1.008 0-.557-.447-1.01-1-1.01zm-10.8 0h-4.8c-.552 0-1 .453-1 1.01 0 .557.448 1.008 1 1.008h4.8c.553 0 1-.45 1-1.008 0-.557-.447-1.01-1-1.01zm-10.8 0h-4.8c-.552 0-1 .453-1 1.01 0 .557.448 1.008 1 1.008h4.8c.553 0 1-.45 1-1.008 0-.557-.447-1.01-1-1.01zm-10.8 0h-4.8c-.552 0-1 .453-1 1.01 0 .557.448 1.008 1 1.008h4.8c.553 0 1-.45 1-1.008 0-.557-.447-1.01-1-1.01zm-10.8 0h-4.8c-.552 0-1 .453-1 1.01 0 .557.448 1.008 1 1.008h4.8c.553 0 1-.45 1-1.008 0-.557-.447-1.01-1-1.01zm-10.8 0h-4.8c-.552 0-1 .453-1 1.01 0 .557.448 1.008 1 1.008h4.8c.553 0 1-.45 1-1.008 0-.557-.447-1.01-1-1.01zm-10.8 0h-4.8c-.552 0-1 .453-1 1.01 0 .557.448 1.008 1 1.008h4.8c.553 0 1-.45 1-1.008 0-.557-.447-1.01-1-1.01zm-10.8 0h-4.8c-.552 0-1 .453-1 1.01 0 .557.448 1.008 1 1.008h4.8c.553 0 1-.45 1-1.008 0-.557-.447-1.01-1-1.01zm-10.8 0h-4.8c-.552 0-1 .453-1 1.01 0 .557.448 1.008 1 1.008h4.8c.553 0 1-.45 1-1.008 0-.557-.447-1.01-1-1.01zm-10.8 0h-4.8c-.552 0-1 .453-1 1.01 0 .557.448 1.008 1 1.008h4.8c.553 0 1-.45 1-1.008 0-.557-.447-1.01-1-1.01zm-10.8 0h-4.8c-.552 0-1 .453-1 1.01 0 .557.448 1.008 1 1.008h4.8c.553 0 1-.45 1-1.008 0-.557-.447-1.01-1-1.01zm-10.8 0h-4.8c-.552 0-1 .453-1 1.01 0 .557.448 1.008 1 1.008h4.8c.553 0 1-.45 1-1.008 0-.557-.447-1.01-1-1.01zm-10.8 0h-4.8c-.552 0-1 .453-1 1.01 0 .557.448 1.008 1 1.008h4.8c.553 0 1-.45 1-1.008 0-.557-.447-1.01-1-1.01zm-10.8 0h-4.8c-.552 0-1 .453-1 1.01 0 .557.448 1.008 1 1.008h4.8c.553 0 1-.45 1-1.008 0-.557-.447-1.01-1-1.01zm-10.577-.116c-1.33-.295-2.48-1.13-3.19-2.3-.287-.474-.902-.623-1.373-.333-.472.29-.62.91-.332 1.386.99 1.632 2.6 2.8 4.465 3.215.54.12 1.073-.224 1.192-.768.12-.544-.222-1.082-.762-1.2zM16 105.292v-4.84c0-.556-.448-1.008-1-1.008s-1 .452-1 1.01v4.838c0 .557.448 1.01 1 1.01s1-.453 1-1.01zm0-10.89v-4.84c0-.555-.448-1.007-1-1.007s-1 .452-1 1.008v4.84c0 .557.448 1.008 1 1.008s1-.45 1-1.007zm0-10.888v-4.84c0-.557-.448-1.008-1-1.008s-1 .45-1 1.008v4.84c0 .557.448 1.008 1 1.008s1-.45 1-1.008zm0-10.89v-4.84c0-.556-.448-1.007-1-1.007s-1 .45-1 1.008v4.84c0 .556.448 1.008 1 1.008s1-.452 1-1.008zm0-10.89v-4.838c0-.557-.448-1.01-1-1.01s-1 .453-1 1.01v4.84c0 .556.448 1.008 1 1.008s1-.452 1-1.01zm0-11.888v-4.84c0-.556-.448-1.008-1-1.008s-1 .452-1 1.008v4.84c0 .557.448 1.008 1 1.008s1-.45 1-1.008zm0-9.89v-4.84c0-.556-.448-1.007-1-1.007s-1 .45-1 1.007v4.84c0 .557.448 1.008 1 1.008s1-.45 1-1.008zm0-10.888v-4.84c0-.557-.448-1.008-1-1.008s-1 .45-1 1.008v4.84c0 .556.448 1.008 1 1.008s1-.452 1-1.008zm0-10.89v-4.84c0-.556-.448-1.008-1-1.008s-1 .452-1 1.01v4.838c0 .557.448 1.01 1 1.01s1-.453 1-1.01z"/>
- <g transform="translate(74)">
- <rect width="58" height="98" y="20" fill="#000" fill-opacity=".02" rx="6"/>
- <use fill="#FFF" xlink:href="#a"/>
- <rect width="56" height="96" x="1" y="18" stroke="#EEE" stroke-width="2" rx="6"/>
- <g transform="translate(16 45.185)">
- <path fill="#333" d="M.59 33.815h5.655V32.15H4.58v-7.225H3.066c-.63.378-1.246.63-2.212.812v1.274H2.52v5.14H.59v1.665zm10.093.168c-1.778 0-3.094-.994-3.094-2.436 0-1.078.67-1.736 1.51-2.184v-.056c-.685-.518-1.19-1.162-1.19-2.1 0-1.512 1.19-2.45 2.843-2.45 1.624 0 2.702.966 2.702 2.436 0 .854-.546 1.54-1.162 1.946v.055c.854.462 1.54 1.148 1.54 2.324 0 1.4-1.26 2.463-3.15 2.463zm.56-5.348c.35-.406.546-.84.546-1.302 0-.686-.407-1.148-1.08-1.148-.545 0-.993.336-.993 1.022 0 .728.616 1.078 1.526 1.428zm-.518 3.92c.686 0 1.19-.364 1.19-1.106 0-.785-.756-1.08-1.876-1.555-.393.364-.687.868-.687 1.414 0 .783.63 1.245 1.372 1.245zm6.3-2.24c-1.316 0-2.268-1.078-2.268-2.912 0-1.82.952-2.884 2.268-2.884 1.316 0 2.282 1.063 2.282 2.883 0 1.834-.966 2.912-2.282 2.912zm0-1.148c.462 0 .84-.462.84-1.764s-.378-1.736-.84-1.736c-.462 0-.84.434-.84 1.736s.378 1.764.84 1.764zm.308 4.816l4.928-9.464h1.19l-4.927 9.463h-1.19zm6.426 0c-1.317 0-2.27-1.078-2.27-2.912 0-1.82.953-2.883 2.27-2.883 1.315 0 2.28 1.064 2.28 2.884 0 1.835-.965 2.913-2.28 2.913zm0-1.148c.46 0 .84-.462.84-1.764 0-1.3-.38-1.735-.84-1.735-.463 0-.84.434-.84 1.736 0 1.303.377 1.765.84 1.765z"/>
- <rect width="13" height="2" x="6" y=".815" fill="#FB722E" rx="1"/>
- <path fill="#F0EDF8" d="M3 47.815c0-.552.455-1 .992-1h18.016c.548 0 .992.444.992 1 0 .553-.455 1-.992 1H3.992c-.548 0-.992-.444-.992-1zm0 6c0-.552.455-1 .992-1h18.016c.548 0 .992.444.992 1 0 .553-.455 1-.992 1H3.992c-.548 0-.992-.444-.992-1z"/>
- <rect width="20" height="2" x="3" y="6.815" fill="#FEE1D3" rx="1"/>
- </g>
- <g transform="translate(10.81)">
- <circle cx="18.19" cy="18" r="18" fill="#FFF"/>
- <path fill="#F0EDF8" fill-rule="nonzero" d="M18.19 34c8.837 0 16-7.163 16-16s-7.163-16-16-16-16 7.163-16 16 7.163 16 16 16zm0 2c-9.94 0-18-8.06-18-18s8.06-18 18-18 18 8.06 18 18-8.06 18-18 18z"/>
- <g transform="translate(10 11)">
- <path fill="#C3B8E3" fill-rule="nonzero" d="M2.19 13.32L5.397 11h7.783c.566 0 1.01-.444 1.01-1V3c0-.55-.45-1-1.01-1H3.2c-.566 0-1.01.444-1.01 1v10.32zM6.045 13l-3.422 2.476C1.28 16.45.19 15.892.19 14.23V3c0-1.657 1.337-3 3.01-3h9.98c1.663 0 3.01 1.342 3.01 3v7c0 1.657-1.337 3-3.01 3H6.045z"/>
- <rect width="4" height="2" x="5.19" y="4" fill="#6B4FBB" rx="1"/>
- <rect width="6" height="2" x="5.19" y="7" fill="#6B4FBB" rx="1"/>
- </g>
- </g>
- </g>
- <g transform="translate(144.5)">
- <rect width="58" height="98" x=".5" y="20" fill="#000" fill-opacity=".02" rx="6"/>
- <use fill="#FFF" xlink:href="#b"/>
- <rect width="56" height="96" x="4.5" y="18" stroke="#EEE" stroke-width="2" rx="6"/>
- <g transform="translate(19 46.185)">
- <path fill="#333" d="M4.01 33.746c1.793 0 3.305-.938 3.305-2.59 0-1.148-.742-1.876-1.764-2.17v-.056c.953-.406 1.485-1.05 1.485-1.974 0-1.554-1.232-2.436-3.066-2.436-1.093 0-1.99.434-2.8 1.134l1.035 1.26c.56-.49 1.036-.784 1.666-.784.7 0 1.093.364 1.093.98 0 .714-.504 1.19-2.1 1.19v1.456c1.932 0 2.394.49 2.394 1.274 0 .672-.574 1.05-1.442 1.05-.756 0-1.414-.378-1.946-.896l-.953 1.302c.644.756 1.652 1.26 3.094 1.26zm4.51-.168h6.257v-1.736h-1.792c-.42 0-1.036.056-1.484.112 1.443-1.512 2.843-3.108 2.843-4.606 0-1.708-1.19-2.828-2.94-2.828-1.274 0-2.1.476-2.982 1.414l1.12 1.106c.45-.476.94-.91 1.583-.91.77 0 1.26.476 1.26 1.344 0 1.26-1.596 2.786-3.864 4.928v1.176zm9.505-3.5c-1.316 0-2.268-1.078-2.268-2.912 0-1.82.952-2.884 2.268-2.884 1.316 0 2.282 1.064 2.282 2.884 0 1.834-.966 2.912-2.282 2.912zm0-1.148c.462 0 .84-.462.84-1.764s-.378-1.736-.84-1.736c-.462 0-.84.434-.84 1.736s.378 1.764.84 1.764zm.308 4.816l4.928-9.464h1.19l-4.927 9.464h-1.19zm6.426 0c-1.317 0-2.27-1.078-2.27-2.912 0-1.82.953-2.884 2.27-2.884 1.315 0 2.28 1.064 2.28 2.884 0 1.834-.965 2.912-2.28 2.912zm0-1.148c.46 0 .84-.462.84-1.764s-.38-1.736-.84-1.736c-.463 0-.84.434-.84 1.736s.377 1.764.84 1.764z"/>
- <rect width="13" height="2.008" x="7.5" fill="#FB722E" rx="1.004"/>
- <path fill="#F0EDF8" d="M3.5 47.19c0-.556.455-1.005 1.006-1.005h17.988c.556 0 1.006.445 1.006 1.004 0 .553-.455 1.003-1.006 1.003H4.506c-.556 0-1.006-.446-1.006-1.004zm0 6.023c0-.555.455-1.004 1.006-1.004h17.988c.556 0 1.006.444 1.006 1.003 0 .554-.455 1.004-1.006 1.004H4.506c-.556 0-1.006-.446-1.006-1.004z"/>
- <rect width="20" height="2.008" x="4" y="6.024" fill="#FEE1D3" rx="1.004"/>
- </g>
- <g transform="translate(14.413)">
- <circle cx="18.087" cy="18" r="18" fill="#FFF"/>
- <path fill="#F0EDF8" fill-rule="nonzero" d="M18.087 34c8.836 0 16-7.163 16-16s-7.164-16-16-16c-8.837 0-16 7.163-16 16s7.163 16 16 16zm0 2c-9.942 0-18-8.06-18-18s8.058-18 18-18c9.94 0 18 8.06 18 18s-8.06 18-18 18z"/>
- <path fill="#C3B8E3" fill-rule="nonzero" d="M18.087 24c3.313 0 6-2.686 6-6s-2.687-6-6-6c-3.314 0-6 2.686-6 6s2.686 6 6 6zm0 2c-4.42 0-8-3.582-8-8s3.58-8 8-8c4.418 0 8 3.582 8 8s-3.582 8-8 8z"/>
- <path fill="#6B4FBB" d="M19.087 17v-2c0-.556-.448-1-1-1-.557 0-1 .448-1 1v3c0 .278.11.528.292.71.18.18.43.29.706.29h3c.557 0 1-.448 1-1 0-.556-.447-1-1-1h-2z"/>
- </g>
- </g>
- <rect width="58" height="98" x="3" y="20" fill="#000" fill-opacity=".02" rx="6"/>
- <g transform="translate(0 16.754)">
- <use fill="#FFF" xlink:href="#c"/>
- <rect width="56" height="96.394" x="1" y="1" stroke="#EEE" stroke-width="2" rx="6"/>
- <g transform="translate(16 29.618)">
- <path fill="#333" d="M3.137 27.84c.462 0 .98-.253 1.33-.883-.182-1.4-.756-1.848-1.386-1.848-.6 0-1.12.433-1.12 1.44 0 .94.505 1.29 1.177 1.29zm-.322 4.955C1.64 32.795.77 32.29.21 31.73l1.093-1.23c.294.335.854.63 1.372.63.994 0 1.764-.7 1.834-2.773-.463.588-1.233.938-1.78.938-1.51 0-2.645-.868-2.645-2.744 0-1.847 1.344-2.98 2.954-2.98 1.72 0 3.373 1.287 3.373 4.41 0 3.317-1.736 4.815-3.598 4.815zm8.12 0c-1.722 0-3.36-1.288-3.36-4.41 0-3.318 1.722-4.816 3.598-4.816 1.176 0 2.03.49 2.59 1.063l-1.078 1.232c-.308-.336-.868-.63-1.386-.63-.98 0-1.765.7-1.835 2.772.462-.588 1.232-.938 1.778-.938 1.526 0 2.646.867 2.646 2.743 0 1.848-1.345 2.982-2.955 2.982zm-.042-1.54c.616 0 1.12-.434 1.12-1.442 0-.938-.49-1.288-1.162-1.288-.46 0-.98.252-1.343.882.182 1.4.77 1.848 1.386 1.848zm6.132-2.128c-1.316 0-2.268-1.078-2.268-2.912 0-1.82.952-2.884 2.268-2.884 1.316 0 2.282 1.065 2.282 2.885 0 1.834-.966 2.912-2.282 2.912zm0-1.148c.462 0 .84-.463.84-1.765 0-1.302-.378-1.736-.84-1.736-.462 0-.84.433-.84 1.735s.378 1.764.84 1.764zm.308 4.815l4.928-9.464h1.19l-4.927 9.465h-1.19zm6.426 0c-1.317 0-2.27-1.078-2.27-2.912 0-1.82.953-2.884 2.27-2.884 1.315 0 2.28 1.063 2.28 2.883 0 1.834-.965 2.912-2.28 2.912zm0-1.148c.46 0 .84-.462.84-1.764s-.38-1.736-.84-1.736c-.463 0-.84.434-.84 1.736s.377 1.764.84 1.764z"/>
- <rect width="13" height="2.008" x="6.5" y=".314" fill="#FEE1D3" rx="1.004"/>
- <path fill="#F0EDF8" d="M3 46.627c0-.552.455-1 .992-1h18.016c.548 0 .992.444.992 1 0 .553-.455 1-.992 1H3.992c-.548 0-.992-.444-.992-1zm0 6c0-.552.455-1 .992-1h18.016c.548 0 .992.444.992 1 0 .553-.455 1-.992 1H3.992c-.548 0-.992-.444-.992-1z"/>
- <rect width="20" height="2" x="3" y="5.627" fill="#FB722E" rx="1"/>
- </g>
- </g>
- <g transform="translate(10.41)">
- <circle cx="18.589" cy="18" r="18" fill="#FFF"/>
- <path fill="#F0EDF8" fill-rule="nonzero" d="M18.59 34c8.836 0 16-7.163 16-16s-7.164-16-16-16c-8.837 0-16 7.163-16 16s7.163 16 16 16zm0 2c-9.942 0-18-8.06-18-18s8.058-18 18-18c9.94 0 18 8.06 18 18s-8.06 18-18 18z"/>
- <path fill="#C3B8E3" d="M17.05 19.262h3.367l.248-2.808H17.3l-.25 2.808zm-.177 2.008l-.144 1.627c-.06.662-.646 1.2-1.3 1.2h.25c-.658 0-1.144-.534-1.085-1.2l.144-1.627H13.59c-.554 0-1.003-.446-1.003-1.004 0-.555.455-1.004 1.002-1.004h1.325l.248-2.808h-1.15c-.555 0-1.004-.445-1.004-1.004 0-.554.457-1.004 1.004-1.004h1.33l.106-1.2c.058-.66.644-1.198 1.298-1.198h-.25c.66 0 1.145.533 1.086 1.2l-.106 1.198h3.365l.107-1.2c.058-.66.644-1.198 1.298-1.198h-.25c.66 0 1.145.533 1.086 1.2l-.106 1.198h1.03c.554 0 1.003.446 1.003 1.004 0 .555-.455 1.004-1 1.004H22.8l-.25 2.808h1.037c.554 0 1.002.446 1.002 1.004 0 .554-.456 1.004-1.003 1.004h-1.214l-.144 1.627c-.06.662-.646 1.2-1.3 1.2h.25c-.658 0-1.144-.534-1.085-1.2l.144-1.627h-3.367z"/>
- <path fill="#6B4FBB" d="M17.05 19.262l-.177 2.008H14.74l.177-2.008h2.134zm-1.707-4.816h2.135l-.178 2.008h-2.135l.178-2.008zm5.5 0h2.135l-.178 2.008h-2.135l.178-2.008zm1.708 4.816l-.177 2.008H20.24l.177-2.008h2.134z"/>
- </g>
- </g>
-</svg>
diff --git a/app/views/shared/integrations/_form.html.haml b/app/views/shared/integrations/_form.html.haml
index 62f8d986296..35f302a28a6 100644
--- a/app/views/shared/integrations/_form.html.haml
+++ b/app/views/shared/integrations/_form.html.haml
@@ -1,7 +1,4 @@
- integration = local_assigns.fetch(:integration)
-%h3.page-title
- = integration.title
-
= form_for integration, as: :service, url: scoped_integration_path(integration), method: :put, html: { class: 'gl-show-field-errors integration-settings-form js-integration-settings-form', data: { 'test-url' => scoped_test_integration_path(integration) } } do |form|
= render 'shared/service_settings', form: form, integration: integration
diff --git a/app/views/shared/integrations/_tabs.html.haml b/app/views/shared/integrations/_tabs.html.haml
new file mode 100644
index 00000000000..553401e47bd
--- /dev/null
+++ b/app/views/shared/integrations/_tabs.html.haml
@@ -0,0 +1,18 @@
+- active_tab = local_assigns.fetch(:active_tab, 'edit')
+- active_classes = 'gl-tab-nav-item-active gl-tab-nav-item-active-indigo active'
+- tabs = integration_tabs(integration: integration)
+
+- if tabs.length <= 1
+ = yield
+- else
+ .tabs.gl-tabs
+ %div
+ %ul.nav.gl-tabs-nav{ role: 'tablist' }
+ - tabs.each do |tab|
+ %li.nav-item{ role: 'presentation' }
+ %a.nav-link.gl-tab-nav-item{ role: 'tab', class: (active_classes if tab[:key] == active_tab), href: tab[:href] }
+ = tab[:text]
+
+ .tab-content.gl-tab-content
+ .tab-pane.gl-pt-3.active{ role: 'tabpanel' }
+ = yield
diff --git a/app/views/shared/integrations/edit.html.haml b/app/views/shared/integrations/edit.html.haml
index a996f72e2f4..02cb94e3555 100644
--- a/app/views/shared/integrations/edit.html.haml
+++ b/app/views/shared/integrations/edit.html.haml
@@ -3,4 +3,8 @@
- page_title @integration.title, _('Integrations')
- @content_class = 'limit-container-width' unless fluid_layout
-= render 'shared/integrations/form', integration: @integration
+%h3.page-title
+ = @integration.title
+
+= render 'shared/integrations/tabs', integration: @integration, active_tab: 'edit' do
+ = render 'shared/integrations/form', integration: @integration
diff --git a/app/views/shared/integrations/overrides.html.haml b/app/views/shared/integrations/overrides.html.haml
new file mode 100644
index 00000000000..dc87fae704c
--- /dev/null
+++ b/app/views/shared/integrations/overrides.html.haml
@@ -0,0 +1,10 @@
+- add_to_breadcrumbs _('Integrations'), scoped_integrations_path
+- breadcrumb_title @integration.title
+- page_title @integration.title, _('Integrations')
+- @content_class = 'limit-container-width' unless fluid_layout
+
+%h3.page-title
+ = @integration.title
+
+= render 'shared/integrations/tabs', integration: @integration, active_tab: 'overrides' do
+ .js-vue-integration-overrides{ data: integration_overrides_data(@integration) }
diff --git a/app/views/shared/issuable/_form.html.haml b/app/views/shared/issuable/_form.html.haml
index 6aa80e6808d..dc93442d6cd 100644
--- a/app/views/shared/issuable/_form.html.haml
+++ b/app/views/shared/issuable/_form.html.haml
@@ -31,8 +31,6 @@
= render 'shared/issuable/form/metadata', issuable: issuable, form: form, project: project, presenter: presenter
-= render_if_exists 'shared/issuable/approvals', issuable: issuable, presenter: presenter, form: form
-
= render 'shared/issuable/form/merge_params', issuable: issuable, project: project
= render 'shared/issuable/form/contribution', issuable: issuable, form: form
diff --git a/app/views/shared/issuable/_sidebar_assignees.html.haml b/app/views/shared/issuable/_sidebar_assignees.html.haml
index 7416fda6b44..9a0b25f4015 100644
--- a/app/views/shared/issuable/_sidebar_assignees.html.haml
+++ b/app/views/shared/issuable/_sidebar_assignees.html.haml
@@ -4,7 +4,7 @@
#js-vue-sidebar-assignees{ data: { field: issuable_type,
signed_in: signed_in,
max_assignees: dropdown_options[:data][:"max-select"],
- directly_invite_members: directly_invite_members? } }
+ directly_invite_members: can_admin_project_member?(@project) } }
.title.hide-collapsed
= _('Assignee')
= loading_icon(css_class: 'gl-vertical-align-text-bottom')
diff --git a/app/views/shared/issuable/_sidebar_user_dropdown.html.haml b/app/views/shared/issuable/_sidebar_user_dropdown.html.haml
index 3a17db5acf8..84d2fc033c8 100644
--- a/app/views/shared/issuable/_sidebar_user_dropdown.html.haml
+++ b/app/views/shared/issuable/_sidebar_user_dropdown.html.haml
@@ -1,7 +1,7 @@
- options = local_assigns.fetch(:options)
- data = options[:data]
-- if directly_invite_members?
+- if can_admin_project_member?(@project)
- options[:dropdown_class] += ' dropdown-extended-height'
- options[:footer_content] = true
- options[:wrapper_class] = local_assigns.fetch(:wrapper_class)
diff --git a/app/views/shared/issuable/_sort_dropdown.html.haml b/app/views/shared/issuable/_sort_dropdown.html.haml
index caf271e9ee9..f5bf010e4db 100644
--- a/app/views/shared/issuable/_sort_dropdown.html.haml
+++ b/app/views/shared/issuable/_sort_dropdown.html.haml
@@ -19,6 +19,7 @@
= 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_closed_date, page_filter_path(sort: sort_value_closed_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/issuable/form/_metadata_issuable_reviewer.html.haml b/app/views/shared/issuable/form/_metadata_issuable_reviewer.html.haml
index a0df007f8ca..fad13c78e26 100644
--- a/app/views/shared/issuable/form/_metadata_issuable_reviewer.html.haml
+++ b/app/views/shared/issuable/form/_metadata_issuable_reviewer.html.haml
@@ -8,5 +8,4 @@
= hidden_field_tag "#{issuable.to_ability_name}[reviewer_ids][]", 0, id: nil, data: { meta: '' }
= dropdown_tag(users_dropdown_label(issuable.reviewers), options: reviewers_dropdown_options(issuable.to_ability_name, issuable.iid, issuable.target_branch))
- - if Feature.enabled?(:mr_collapsed_approval_rules, @project)
- = render_if_exists 'shared/issuable/approver_suggestion', issuable: issuable, presenter: presenter
+ = render_if_exists 'shared/issuable/approver_suggestion', issuable: issuable, presenter: presenter
diff --git a/app/views/shared/issuable/form/_type_selector.html.haml b/app/views/shared/issuable/form/_type_selector.html.haml
index b5c5e2fa091..3b4ab22ce32 100644
--- a/app/views/shared/issuable/form/_type_selector.html.haml
+++ b/app/views/shared/issuable/form/_type_selector.html.haml
@@ -16,14 +16,14 @@
= _("Select type")
%button.dropdown-title-button.dropdown-menu-close.gl-ml-auto{ type: 'button', "aria-label" => _('Close') }
= sprite_icon('close', size: 16, css_class: 'dropdown-menu-close-icon')
- .dropdown-content
+ .dropdown-content{ data: { testid: 'issue-type-select-dropdown' } }
%ul
%li.js-filter-issuable-type
= link_to new_project_issue_path(@project), class: ("is-active" if issuable.issue?) do
- = _("Issue")
+ #{sprite_icon(work_item_type_icon(:issue), css_class: 'gl-icon')} #{_("Issue")}
%li.js-filter-issuable-type{ data: { track: { event: "select_issue_type_incident", label: "select_issue_type_incident_dropdown_option" } } }
= link_to new_project_issue_path(@project, { issuable_template: 'incident', issue: { issue_type: 'incident' } }), class: ("is-active" if issuable.incident?) do
- = _("Incident")
+ #{sprite_icon(work_item_type_icon(:incident), css_class: 'gl-icon')} #{_("Incident")}
#js-type-popover
diff --git a/app/views/shared/nav/_sidebar_menu.html.haml b/app/views/shared/nav/_sidebar_menu.html.haml
index 9a04139d2f2..903d2d077ba 100644
--- a/app/views/shared/nav/_sidebar_menu.html.haml
+++ b/app/views/shared/nav/_sidebar_menu.html.haml
@@ -1,27 +1,30 @@
= nav_link(**sidebar_menu.all_active_routes, html_options: sidebar_menu.nav_link_html_options) do
- = link_to sidebar_menu.link, **sidebar_menu.container_html_options, data: { qa_selector: 'sidebar_menu_link', qa_menu_item: sidebar_menu.title } do
- - if sidebar_menu.icon_or_image?
- %span.nav-icon-container
- - if sidebar_menu.image_path
- = image_tag(sidebar_menu.image_path, **sidebar_menu.image_html_options)
- - elsif sidebar_menu.sprite_icon
- = sprite_icon(sidebar_menu.sprite_icon, **sidebar_menu.sprite_icon_html_options)
+ - if sidebar_menu.menu_with_partial?
+ = render_if_exists sidebar_menu.menu_partial, **sidebar_menu.menu_partial_options
+ - else
+ = link_to sidebar_menu.link, **sidebar_menu.container_html_options, data: { qa_selector: 'sidebar_menu_link', qa_menu_item: sidebar_menu.title } do
+ - if sidebar_menu.icon_or_image?
+ %span.nav-icon-container
+ - if sidebar_menu.image_path
+ = image_tag(sidebar_menu.image_path, **sidebar_menu.image_html_options)
+ - elsif sidebar_menu.sprite_icon
+ = sprite_icon(sidebar_menu.sprite_icon, **sidebar_menu.sprite_icon_html_options)
- %span.nav-item-name{ **sidebar_menu.title_html_options }
- = sidebar_menu.title
- - if sidebar_menu.has_pill?
- %span.badge.badge-pill.count{ **sidebar_menu.pill_html_options }
- = number_with_delimiter(sidebar_menu.pill_count)
+ %span.nav-item-name{ **sidebar_menu.title_html_options }
+ = sidebar_menu.title
+ - if sidebar_menu.has_pill?
+ %span.badge.badge-pill.count{ **sidebar_menu.pill_html_options }
+ = number_with_delimiter(sidebar_menu.pill_count)
- %ul.sidebar-sub-level-items{ class: ('is-fly-out-only' unless sidebar_menu.has_renderable_items?) }
- = nav_link(**sidebar_menu.all_active_routes, html_options: { class: 'fly-out-top-item' } ) do
- %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)
+ %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
+ %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
- = render partial: 'shared/nav/sidebar_menu_item', collection: sidebar_menu.renderable_items
+ - if sidebar_menu.has_renderable_items?
+ %li.divider.fly-out-top-item
+ = render partial: 'shared/nav/sidebar_menu_item', collection: sidebar_menu.renderable_items
diff --git a/app/views/shared/notes/_comment_button.html.haml b/app/views/shared/notes/_comment_button.html.haml
index 1129fed9c3b..d0a2d97df0f 100644
--- a/app/views/shared/notes/_comment_button.html.haml
+++ b/app/views/shared/notes/_comment_button.html.haml
@@ -1,6 +1,6 @@
- noteable_name = @note.noteable.human_class_name
-.float-left.btn-group.gl-mr-3.droplab-dropdown.comment-type-dropdown.js-comment-type-dropdown
+.float-left.btn-group.gl-sm-mr-3.droplab-dropdown.comment-type-dropdown.js-comment-type-dropdown
%input.btn.gl-button.btn-confirm.js-comment-button.js-comment-submit-button{ type: 'submit', value: _('Comment'), data: { qa_selector: 'comment_button' } }
- if @note.can_be_discussion_note?
diff --git a/app/views/shared/notes/_form.html.haml b/app/views/shared/notes/_form.html.haml
index 6f54c54d0a9..98008fede90 100644
--- a/app/views/shared/notes/_form.html.haml
+++ b/app/views/shared/notes/_form.html.haml
@@ -35,7 +35,7 @@
= render 'shared/notes/hints', supports_quick_actions: supports_quick_actions
.error-alert
- .note-form-actions.clearfix
+ .note-form-actions.clearfix.gl-display-flex.gl-flex-wrap
= render partial: 'shared/notes/comment_button'
%a.btn.gl-button.btn-cancel.js-close-discussion-note-form.hide{ role: "button", data: { cancel_text: _("Cancel") } }
diff --git a/app/views/shared/projects/_project.html.haml b/app/views/shared/projects/_project.html.haml
index 7466f360f67..2136d287f53 100644
--- a/app/views/shared/projects/_project.html.haml
+++ b/app/views/shared/projects/_project.html.haml
@@ -65,6 +65,10 @@
.description.d-none.d-sm-block.gl-mr-3
= markdown_field(project, :description)
+ - if project.topics.any?
+ .gl-mt-2
+ = render "shared/projects/topics", project: project.present(current_user: current_user)
+
= render_if_exists 'shared/projects/removed', project: project
.controls.d-flex.flex-sm-column.align-items-center.align-items-sm-end.flex-wrap.flex-shrink-0.text-secondary{ class: css_controls_class.join(" ") }
diff --git a/app/views/shared/projects/_topics.html.haml b/app/views/shared/projects/_topics.html.haml
new file mode 100644
index 00000000000..a7429483da1
--- /dev/null
+++ b/app/views/shared/projects/_topics.html.haml
@@ -0,0 +1,32 @@
+- cache_enabled = false unless local_assigns[:cache_enabled] == true
+- max_project_topic_length = 15
+- project_topics_classes = "badge badge-pill badge-secondary gl-mr-2"
+
+- if project.topics.present?
+ = cache_if(cache_enabled, [project, :topic_list], expires_in: 1.day) do
+ %span.gl-w-full.gl-display-inline-flex.gl-font-base.gl-font-weight-normal.gl-align-items-center{ 'data-testid': 'project_topic_list' }
+ = sprite_icon('tag', css_class: 'icon gl-relative gl-mr-2')
+
+ - project.topics_to_show.each do |topic|
+ - explore_project_topic_path = explore_projects_path(topic: topic)
+ - if topic.length > max_project_topic_length
+ %a{ class: "#{ project_topics_classes } str-truncated-30 has-tooltip", data: { container: "body" }, title: topic, href: explore_project_topic_path, itemprop: 'keywords' }
+ = truncate(topic, length: max_project_topic_length)
+ - else
+ %a{ class: project_topics_classes, href: explore_project_topic_path, itemprop: 'keywords' }
+ = topic
+
+ - if project.has_extra_topics?
+ - title = _('More topics')
+ - content = capture do
+ %span.gl-display-inline-flex.gl-flex-wrap
+ - project.topics_not_shown.each do |topic|
+ - explore_project_topic_path = explore_projects_path(topic: topic)
+ - if topic.length > max_project_topic_length
+ %a{ class: "#{ project_topics_classes } gl-mb-3 str-truncated has-tooltip", data: { container: "body" }, title: topic, href: explore_project_topic_path, itemprop: 'keywords' }
+ = truncate(topic, length: max_project_topic_length)
+ - else
+ %a{ class: "#{ project_topics_classes } gl-mb-3", href: explore_project_topic_path, itemprop: 'keywords' }
+ = topic
+ .text-nowrap{ role: 'button', tabindex: 0, data: { toggle: 'popover', html: 'true', placement: 'top', title: title, content: content } }
+ = _("+ %{count} more") % { count: project.count_of_extra_topics_not_shown }
diff --git a/app/views/snippets/show.html.haml b/app/views/snippets/show.html.haml
index 4fdb9e70742..ca52a1f8f46 100644
--- a/app/views/snippets/show.html.haml
+++ b/app/views/snippets/show.html.haml
@@ -12,7 +12,7 @@
- content_for :prefetch_asset_tags do
- webpack_preload_asset_tag('monaco', prefetch: true)
-#js-snippet-view{ data: {'qa-selector': 'snippet_view', 'snippet-gid': @snippet.to_global_id} }
+#js-snippet-view{ data: {'qa-selector': 'snippet_view', 'snippet-gid': @snippet.to_global_id, 'report-abuse-path': snippet_report_abuse_path(@snippet) } }
.row-content-block.top-block.content-component-block
= render 'award_emoji/awards_block', awardable: @snippet, inline: true
diff --git a/app/views/users/show.html.haml b/app/views/users/show.html.haml
index effd58ad200..363909c54e2 100644
--- a/app/views/users/show.html.haml
+++ b/app/views/users/show.html.haml
@@ -62,6 +62,10 @@
- if @user&.status && user_status_set_to_busy?(@user.status)
%span.gl-font-base.gl-text-gray-500.gl-vertical-align-middle= s_("UserProfile|(Busy)")
+ - if @user.pronunciation.present?
+ .gl-align-items-center
+ %p.gl-mb-4.gl-text-gray-500= s_("UserProfile|Pronounced as: %{pronunciation}") % { pronunciation: @user.pronunciation }
+
- if show_status_emoji?(@user.status)
.cover-status.gl-display-inline-flex.gl-align-items-center
= emoji_icon(@user.status.emoji, class: 'gl-mr-2')
@@ -73,6 +77,10 @@
= sprite_icon('location', css_class: 'fgray')
%span{ itemprop: 'addressLocality' }
= @user.location
+ .profile-link-holder.middle-dot-divider-sm.d-block.d-sm-inline.mb-1.mb-sm-0
+ = sprite_icon('clock', css_class: 'fgray')
+ %span
+ = local_time(@user.timezone)
- unless work_information(@user).blank?
.profile-link-holder.middle-dot-divider-sm.d-block.d-sm-inline
= sprite_icon('work', css_class: 'fgray')