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

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/app/views
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2021-12-20 16:37:47 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2021-12-20 16:37:47 +0300
commitaee0a117a889461ce8ced6fcf73207fe017f1d99 (patch)
tree891d9ef189227a8445d83f35c1b0fc99573f4380 /app/views
parent8d46af3258650d305f53b819eabf7ab18d22f59e (diff)
Add latest changes from gitlab-org/gitlab@14-6-stable-eev14.6.0-rc42
Diffstat (limited to 'app/views')
-rw-r--r--app/views/admin/application_settings/_account_and_limit.html.haml1
-rw-r--r--app/views/admin/application_settings/_package_registry.html.haml3
-rw-r--r--app/views/admin/application_settings/_snowplow.html.haml6
-rw-r--r--app/views/admin/application_settings/network.html.haml21
-rw-r--r--app/views/admin/dashboard/_security_newsletter_callout.html.haml2
-rw-r--r--app/views/admin/dashboard/index.html.haml2
-rw-r--r--app/views/admin/groups/show.html.haml14
-rw-r--r--app/views/admin/hooks/edit.html.haml2
-rw-r--r--app/views/admin/labels/index.html.haml24
-rw-r--r--app/views/admin/projects/_archived.html.haml3
-rw-r--r--app/views/admin/projects/_projects.html.haml3
-rw-r--r--app/views/admin/projects/show.html.haml4
-rw-r--r--app/views/admin/users/_access_levels.html.haml5
-rw-r--r--app/views/admin/users/_user_detail.html.haml20
-rw-r--r--app/views/admin/users/projects.html.haml4
-rw-r--r--app/views/admin/users/show.html.haml2
-rw-r--r--app/views/clusters/clusters/_gcp_signup_offer_banner.html.haml2
-rw-r--r--app/views/clusters/clusters/show.html.haml5
-rw-r--r--app/views/devise/confirmations/almost_there.haml2
-rw-r--r--app/views/devise/sessions/new.html.haml2
-rw-r--r--app/views/devise/shared/_tab_single.html.haml5
-rw-r--r--app/views/groups/_import_group_from_file_panel.html.haml14
-rw-r--r--app/views/groups/_invite_members_side_nav_link.html.haml1
-rw-r--r--app/views/groups/_personalize.html.haml2
-rw-r--r--app/views/groups/_project_badges.html.haml2
-rw-r--r--app/views/groups/crm/contacts.html.haml4
-rw-r--r--app/views/groups/crm/contacts/index.html.haml4
-rw-r--r--app/views/groups/crm/organizations.html.haml4
-rw-r--r--app/views/groups/crm/organizations/index.html.haml4
-rw-r--r--app/views/groups/packages/index.html.haml6
-rw-r--r--app/views/groups/projects.html.haml5
-rw-r--r--app/views/groups/registry/repositories/index.html.haml4
-rw-r--r--app/views/groups/runners/_group_runners.html.haml2
-rw-r--r--app/views/groups/settings/_advanced.html.haml5
-rw-r--r--app/views/groups/settings/_export.html.haml14
-rw-r--r--app/views/groups/settings/_transfer.html.haml11
-rw-r--r--app/views/groups/settings/ci_cd/_auto_devops_form.html.haml2
-rw-r--r--app/views/groups/settings/packages_and_registries/show.html.haml3
-rw-r--r--app/views/groups/show.html.haml2
-rw-r--r--app/views/help/instance_configuration/_package_registry.html.haml4
-rw-r--r--app/views/import/bitbucket/deploy_key.js.haml3
-rw-r--r--app/views/jira_connect/subscriptions/index.html.haml7
-rw-r--r--app/views/layouts/_flash.html.haml4
-rw-r--r--app/views/layouts/_google_tag_manager_body.html.haml2
-rw-r--r--app/views/layouts/_google_tag_manager_head.html.haml15
-rw-r--r--app/views/layouts/_page.html.haml2
-rw-r--r--app/views/layouts/_snowplow.html.haml6
-rw-r--r--app/views/layouts/header/_current_user_dropdown.html.haml2
-rw-r--r--app/views/layouts/header/_default.html.haml16
-rw-r--r--app/views/layouts/header/_help_dropdown.html.haml2
-rw-r--r--app/views/layouts/header/_registration_enabled_callout.html.haml2
-rw-r--r--app/views/layouts/in_product_marketing_mailer.html.haml194
-rw-r--r--app/views/notify/_note_email.html.haml2
-rw-r--r--app/views/notify/account_validation_email.html.haml16
-rw-r--r--app/views/notify/account_validation_email.text.erb15
-rw-r--r--app/views/notify/attention_requested_merge_request_email.html.haml2
-rw-r--r--app/views/notify/attention_requested_merge_request_email.text.erb1
-rw-r--r--app/views/notify/in_product_marketing_email.html.haml286
-rw-r--r--app/views/notify/issue_due_email.html.haml2
-rw-r--r--app/views/notify/member_invited_email.html.haml20
-rw-r--r--app/views/notify/new_issue_email.html.haml2
-rw-r--r--app/views/notify/new_merge_request_email.html.haml2
-rw-r--r--app/views/notify/new_release_email.html.haml2
-rw-r--r--app/views/notify/service_desk_new_note_email.html.haml2
-rw-r--r--app/views/profiles/accounts/_providers.html.haml7
-rw-r--r--app/views/profiles/keys/_form.html.haml5
-rw-r--r--app/views/profiles/notifications/_group_settings.html.haml2
-rw-r--r--app/views/profiles/personal_access_tokens/index.html.haml116
-rw-r--r--app/views/profiles/show.html.haml2
-rw-r--r--app/views/profiles/two_factor_auths/show.html.haml2
-rw-r--r--app/views/projects/_files.html.haml5
-rw-r--r--app/views/projects/_invite_members_side_nav_link.html.haml1
-rw-r--r--app/views/projects/_merge_request_merge_commit_template.html.haml4
-rw-r--r--app/views/projects/_merge_request_settings.html.haml2
-rw-r--r--app/views/projects/_merge_request_squash_commit_template.html.haml16
-rw-r--r--app/views/projects/_new_project_fields.html.haml23
-rw-r--r--app/views/projects/_project_templates.html.haml2
-rw-r--r--app/views/projects/_remove_fork.html.haml5
-rw-r--r--app/views/projects/_transfer.html.haml10
-rw-r--r--app/views/projects/blame/show.html.haml2
-rw-r--r--app/views/projects/blob/_content.html.haml1
-rw-r--r--app/views/projects/blob/_header.html.haml1
-rw-r--r--app/views/projects/blob/show.html.haml4
-rw-r--r--app/views/projects/branches/index.html.haml2
-rw-r--r--app/views/projects/buttons/_dropdown.html.haml42
-rw-r--r--app/views/projects/buttons/_fork.html.haml14
-rw-r--r--app/views/projects/ci/builds/_build.html.haml11
-rw-r--r--app/views/projects/commit/pipelines.html.haml1
-rw-r--r--app/views/projects/compare/index.html.haml2
-rw-r--r--app/views/projects/default_branch/_show.html.haml2
-rw-r--r--app/views/projects/diffs/_content.html.haml1
-rw-r--r--app/views/projects/diffs/_text_file.html.haml2
-rw-r--r--app/views/projects/feature_flags/new.html.haml4
-rw-r--r--app/views/projects/forks/index.html.haml44
-rw-r--r--app/views/projects/generic_commit_statuses/_generic_commit_status.html.haml6
-rw-r--r--app/views/projects/google_cloud/errors/gcp_error.html.haml6
-rw-r--r--app/views/projects/google_cloud/errors/no_gcp_projects.html.haml6
-rw-r--r--app/views/projects/google_cloud/service_accounts/index.html.haml8
-rw-r--r--app/views/projects/hooks/edit.html.haml4
-rw-r--r--app/views/projects/integrations/shimos/show.html.haml10
-rw-r--r--app/views/projects/issues/_issue.html.haml8
-rw-r--r--app/views/projects/issues/_new_branch.html.haml2
-rw-r--r--app/views/projects/issues/_related_branches.html.haml2
-rw-r--r--app/views/projects/issues/index.html.haml2
-rw-r--r--app/views/projects/jobs/show.html.haml5
-rw-r--r--app/views/projects/learn_gitlab/index.html.haml3
-rw-r--r--app/views/projects/merge_requests/_merge_request.html.haml5
-rw-r--r--app/views/projects/merge_requests/_mr_title.html.haml2
-rw-r--r--app/views/projects/merge_requests/creations/_new_submit.html.haml6
-rw-r--r--app/views/projects/merge_requests/index.html.haml2
-rw-r--r--app/views/projects/merge_requests/invalid.html.haml29
-rw-r--r--app/views/projects/merge_requests/show.html.haml8
-rw-r--r--app/views/projects/mirrors/_disabled_mirror_badge.html.haml3
-rw-r--r--app/views/projects/mirrors/_regenerate_public_ssh_key_confirm_modal.html.haml13
-rw-r--r--app/views/projects/network/show.json.erb2
-rw-r--r--app/views/projects/packages/packages/index.html.haml6
-rw-r--r--app/views/projects/pages_domains/_dns.html.haml2
-rw-r--r--app/views/projects/pipeline_schedules/edit.html.haml2
-rw-r--r--app/views/projects/pipelines/_with_tabs.html.haml31
-rw-r--r--app/views/projects/pipelines/charts.html.haml5
-rw-r--r--app/views/projects/pipelines/show.html.haml3
-rw-r--r--app/views/projects/protected_branches/shared/_matching_branch.html.haml2
-rw-r--r--app/views/projects/protected_tags/shared/_matching_tag.html.haml2
-rw-r--r--app/views/projects/protected_tags/shared/_protected_tag.html.haml2
-rw-r--r--app/views/projects/registry/repositories/index.html.haml4
-rw-r--r--app/views/projects/remove_fork.js.haml2
-rw-r--r--app/views/projects/runners/_group_runners.html.haml2
-rw-r--r--app/views/projects/runners/_runner.html.haml3
-rw-r--r--app/views/projects/services/_form.html.haml2
-rw-r--r--app/views/projects/services/prometheus/_custom_metrics.html.haml4
-rw-r--r--app/views/projects/services/prometheus/_metrics.html.haml4
-rw-r--r--app/views/projects/settings/access_tokens/index.html.haml2
-rw-r--r--app/views/projects/settings/ci_cd/_autodevops_form.html.haml2
-rw-r--r--app/views/projects/settings/ci_cd/show.html.haml23
-rw-r--r--app/views/projects/show.html.haml1
-rw-r--r--app/views/projects/starrers/_starrer.html.haml2
-rw-r--r--app/views/projects/tags/_tag.html.haml13
-rw-r--r--app/views/projects/tags/show.html.haml3
-rw-r--r--app/views/projects/tracings/show.html.haml10
-rw-r--r--app/views/projects/transfer.js.haml2
-rw-r--r--app/views/projects/usage_quotas/index.html.haml2
-rw-r--r--app/views/root/index.html.haml10
-rw-r--r--app/views/search/results/_blob.html.haml3
-rw-r--r--app/views/search/results/_blob_data.html.haml2
-rw-r--r--app/views/search/results/_blob_highlight.html.haml22
-rw-r--r--app/views/search/results/_issuable.html.haml2
-rw-r--r--app/views/shared/_email_with_badge.html.haml9
-rw-r--r--app/views/shared/_flash_user_callout.html.haml2
-rw-r--r--app/views/shared/_milestone_expired.html.haml6
-rw-r--r--app/views/shared/_milestones_filter.html.haml11
-rw-r--r--app/views/shared/_registration_features_discovery_message.html.haml9
-rw-r--r--app/views/shared/_service_settings.html.haml4
-rw-r--r--app/views/shared/_two_factor_auth_recovery_settings_check.html.haml2
-rw-r--r--app/views/shared/builds/_tabs.html.haml14
-rw-r--r--app/views/shared/doorkeeper/applications/_form.html.haml5
-rw-r--r--app/views/shared/doorkeeper/applications/_index.html.haml2
-rw-r--r--app/views/shared/form_elements/_description.html.haml2
-rw-r--r--app/views/shared/integrations/_form.html.haml2
-rw-r--r--app/views/shared/integrations/_index.html.haml2
-rw-r--r--app/views/shared/integrations/_tabs.html.haml2
-rw-r--r--app/views/shared/integrations/edit.html.haml2
-rw-r--r--app/views/shared/integrations/overrides.html.haml2
-rw-r--r--app/views/shared/issuable/_form.html.haml2
-rw-r--r--app/views/shared/issuable/_milestone_dropdown.html.haml12
-rw-r--r--app/views/shared/issuable/_sidebar.html.haml6
-rw-r--r--app/views/shared/issuable/form/_default_templates.html.haml7
-rw-r--r--app/views/shared/issuable/form/_metadata.html.haml12
-rw-r--r--app/views/shared/issuable/form/_metadata_issuable_assignee.html.haml2
-rw-r--r--app/views/shared/issuable/form/_title.html.haml2
-rw-r--r--app/views/shared/issuable/form/_type_selector.html.haml2
-rw-r--r--app/views/shared/members/_filter_2fa_dropdown.html.haml11
-rw-r--r--app/views/shared/members/_requests.html.haml2
-rw-r--r--app/views/shared/milestones/_milestone.html.haml6
-rw-r--r--app/views/shared/milestones/_sidebar.html.haml4
-rw-r--r--app/views/shared/milestones/_tabs.html.haml30
-rw-r--r--app/views/shared/nav/_scope_menu.html.haml2
-rw-r--r--app/views/shared/nav/_sidebar_hidden_menu_item.html.haml2
-rw-r--r--app/views/shared/nav/_sidebar_menu.html.haml2
-rw-r--r--app/views/shared/nav/_sidebar_menu_item.html.haml2
-rw-r--r--app/views/shared/projects/_archived.html.haml3
-rw-r--r--app/views/shared/projects/_project.html.haml2
-rw-r--r--app/views/shared/projects/_topics.html.haml17
-rw-r--r--app/views/shared/runners/_runner_description.html.haml4
-rw-r--r--app/views/shared/runners/_runner_details.html.haml3
-rw-r--r--app/views/shared/runners/_runner_type_badge.html.haml9
-rw-r--r--app/views/shared/snippets/_embed.html.haml2
-rw-r--r--app/views/shared/web_hooks/_hook.html.haml10
-rw-r--r--app/views/shared/web_hooks/_hook_errors.html.haml41
-rw-r--r--app/views/shared/web_hooks/_title_and_docs.html.haml2
-rw-r--r--app/views/shared/wikis/_wiki_content.html.haml2
-rw-r--r--app/views/shared/wikis/show.html.haml3
-rw-r--r--app/views/snippets/_snippets_scope_menu.html.haml41
-rw-r--r--app/views/users/_overview.html.haml4
-rw-r--r--app/views/users/calendar_activities.html.haml2
-rw-r--r--app/views/users/show.html.haml3
-rw-r--r--app/views/users/terms/index.html.haml27
196 files changed, 967 insertions, 864 deletions
diff --git a/app/views/admin/application_settings/_account_and_limit.html.haml b/app/views/admin/application_settings/_account_and_limit.html.haml
index 19c38d7be62..65882491575 100644
--- a/app/views/admin/application_settings/_account_and_limit.html.haml
+++ b/app/views/admin/application_settings/_account_and_limit.html.haml
@@ -32,6 +32,7 @@
= render_if_exists 'admin/application_settings/git_two_factor_session_expiry', form: f
= render_if_exists 'admin/application_settings/personal_access_token_expiration_policy', form: f
= render_if_exists 'admin/application_settings/enforce_pat_expiration', form: f
+ = render_if_exists 'admin/application_settings/ssh_key_expiration_policy', form: f
= render_if_exists 'admin/application_settings/enforce_ssh_key_expiration', form: f
.form-group
diff --git a/app/views/admin/application_settings/_package_registry.html.haml b/app/views/admin/application_settings/_package_registry.html.haml
index 7cdadaaf37b..398e63cdfdc 100644
--- a/app/views/admin/application_settings/_package_registry.html.haml
+++ b/app/views/admin/application_settings/_package_registry.html.haml
@@ -33,6 +33,9 @@
= f.label :conan_max_file_size, _('Maximum Conan package file size in bytes'), class: 'label-bold'
= f.number_field :conan_max_file_size, class: 'form-control gl-form-input'
.form-group
+ = f.label :helm_max_file_size, _('Maximum Helm chart file size in bytes'), class: 'label-bold'
+ = f.number_field :helm_max_file_size, class: 'form-control gl-form-input'
+ .form-group
= f.label :maven_max_file_size, _('Maximum Maven package file size in bytes'), class: 'label-bold'
= f.number_field :maven_max_file_size, class: 'form-control gl-form-input'
.form-group
diff --git a/app/views/admin/application_settings/_snowplow.html.haml b/app/views/admin/application_settings/_snowplow.html.haml
index 756c0e770a6..f7a6a26c645 100644
--- a/app/views/admin/application_settings/_snowplow.html.haml
+++ b/app/views/admin/application_settings/_snowplow.html.haml
@@ -1,5 +1,5 @@
- expanded = integration_expanded?('snowplow_')
-%section.settings.as-snowplow.no-animate#js-snowplow-settings{ class: ('expanded' if expanded) }
+%section.settings.as-snowplow.no-animate#js-snowplow-settings{ class: ('expanded' if expanded), data: { qa_selector: 'snowplow_settings_content' } }
.settings-header
%h4
= _('Snowplow')
@@ -15,7 +15,7 @@
%fieldset
.form-group
.form-check
- = f.check_box :snowplow_enabled, class: 'form-check-input'
+ = f.check_box :snowplow_enabled, class: 'form-check-input', data: { qa_selector: 'snowplow_enabled_checkbox' }
= f.label :snowplow_enabled, _('Enable Snowplow tracking'), class: 'form-check-label'
.form-group
= f.label :snowplow_collector_hostname, _('Collector hostname'), class: 'label-light'
@@ -33,4 +33,4 @@
.form-text.text-muted
= _('The Snowplow cookie domain.')
- = f.submit _('Save changes'), class: 'gl-button btn btn-confirm'
+ = f.submit _('Save changes'), class: 'gl-button btn btn-confirm', data: { qa_selector: 'save_changes_button' }
diff --git a/app/views/admin/application_settings/network.html.haml b/app/views/admin/application_settings/network.html.haml
index 3a053205725..61a2f97764f 100644
--- a/app/views/admin/application_settings/network.html.haml
+++ b/app/views/admin/application_settings/network.html.haml
@@ -37,17 +37,16 @@
.settings-content
= render partial: 'network_rate_limits', locals: { anchor: 'js-packages-limits-settings', setting_fragment: 'packages_api' }
-- if Feature.enabled?(:files_api_throttling, default_enabled: :yaml)
- %section.settings.as-files-limits.no-animate#js-files-limits-settings{ class: ('expanded' if expanded_by_default?) }
- .settings-header
- %h4
- = _('Files API Rate Limits')
- %button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' }
- = expanded_by_default? ? _('Collapse') : _('Expand')
- %p
- = _('Configure specific limits for Files API requests that supersede the general user and IP rate limits.')
- .settings-content
- = render partial: 'network_rate_limits', locals: { anchor: 'js-files-limits-settings', setting_fragment: 'files_api' }
+%section.settings.as-files-limits.no-animate#js-files-limits-settings{ class: ('expanded' if expanded_by_default?) }
+ .settings-header
+ %h4
+ = _('Files API Rate Limits')
+ %button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' }
+ = expanded_by_default? ? _('Collapse') : _('Expand')
+ %p
+ = _('Configure specific limits for Files API requests that supersede the general user and IP rate limits.')
+ .settings-content
+ = render partial: 'network_rate_limits', locals: { anchor: 'js-files-limits-settings', setting_fragment: 'files_api' }
%section.settings.as-deprecated-limits.no-animate#js-deprecated-limits-settings{ class: ('expanded' if expanded_by_default?) }
.settings-header
diff --git a/app/views/admin/dashboard/_security_newsletter_callout.html.haml b/app/views/admin/dashboard/_security_newsletter_callout.html.haml
index ece0f7ca4d9..3aba91e8765 100644
--- a/app/views/admin/dashboard/_security_newsletter_callout.html.haml
+++ b/app/views/admin/dashboard/_security_newsletter_callout.html.haml
@@ -5,7 +5,7 @@
variant: :tip,
alert_class: 'js-security-newsletter-callout',
is_contained: true,
- alert_data: { feature_id: UserCalloutsHelper::SECURITY_NEWSLETTER_CALLOUT, dismiss_endpoint: user_callouts_path, defer_links: 'true' },
+ alert_data: { feature_id: Users::CalloutsHelper::SECURITY_NEWSLETTER_CALLOUT, dismiss_endpoint: callouts_path, defer_links: 'true' },
close_button_data: { testid: 'close-security-newsletter-callout' } do
.gl-alert-body
= s_('AdminArea|Sign up for the GitLab Security Newsletter to get notified for security updates.')
diff --git a/app/views/admin/dashboard/index.html.haml b/app/views/admin/dashboard/index.html.haml
index 4197d5b961f..801b903395a 100644
--- a/app/views/admin/dashboard/index.html.haml
+++ b/app/views/admin/dashboard/index.html.haml
@@ -3,6 +3,8 @@
- billable_users_url = help_page_path('subscriptions/self_managed/index', anchor: 'billable-users')
- billable_users_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer nofollow">'.html_safe % { url: billable_users_url }
+= render_if_exists 'shared/manual_renewal_banner'
+= render_if_exists 'shared/manual_quarterly_reconciliation_banner'
= render_if_exists 'shared/qrtly_reconciliation_alert'
= render 'admin/dashboard/security_newsletter_callout'
diff --git a/app/views/admin/groups/show.html.haml b/app/views/admin/groups/show.html.haml
index ae809f01592..09f2d431197 100644
--- a/app/views/admin/groups/show.html.haml
+++ b/app/views/admin/groups/show.html.haml
@@ -70,15 +70,13 @@
.card
.card-header
= _('Projects')
- %span.badge.badge-pill
- #{@group.projects.count}
+ = gl_badge_tag @group.projects.count
%ul.content-list
- @projects.each do |project|
%li
%strong
= link_to project.full_name, [:admin, project]
- %span.badge.badge-pill
- = storage_counter(project.statistics.storage_size)
+ = gl_badge_tag storage_counter(project.statistics.storage_size)
%span.float-right.light
%span.monospace= project.full_path + '.git'
- unless @projects.size < Kaminari.config.default_per_page
@@ -90,15 +88,13 @@
.card
.card-header
= _('Projects shared with %{group_name}') % { group_name: @group.name }
- %span.badge.badge-pill
- #{shared_projects.size}
+ = gl_badge_tag shared_projects.size
%ul.content-list
- shared_projects.each do |project|
%li
%strong
= link_to project.full_name, [:admin, project]
- %span.badge.badge-pill
- = storage_counter(project.statistics.storage_size)
+ = gl_badge_tag storage_counter(project.statistics.storage_size)
%span.float-right.light
%span.monospace= project.full_path + '.git'
@@ -126,7 +122,7 @@
.card
.card-header
= html_escape(_("%{group_name} group members")) % { group_name: "<strong>#{html_escape(@group.name)}</strong>".html_safe }
- %span.badge.badge-pill= @group.users_count
+ = gl_badge_tag @group.users_count
= render 'shared/members/manage_access_button', path: group_group_members_path(@group)
%ul.content-list.group-users-list.content-list.members-list
= render partial: 'shared/members/member',
diff --git a/app/views/admin/hooks/edit.html.haml b/app/views/admin/hooks/edit.html.haml
index 93038e63a2e..9c258e10008 100644
--- a/app/views/admin/hooks/edit.html.haml
+++ b/app/views/admin/hooks/edit.html.haml
@@ -1,6 +1,8 @@
- add_to_breadcrumbs @hook.pluralized_name, admin_hooks_path
- page_title _('Edit System Hook')
+= render 'shared/web_hooks/hook_errors', hook: @hook
+
.row.gl-mt-3
.col-lg-3
= render 'shared/web_hooks/title_and_docs', hook: @hook
diff --git a/app/views/admin/labels/index.html.haml b/app/views/admin/labels/index.html.haml
index 6007d891aad..66fd18e1b76 100644
--- a/app/views/admin/labels/index.html.haml
+++ b/app/views/admin/labels/index.html.haml
@@ -6,13 +6,27 @@
%h3.page-title
= _('Labels')
%hr
-
-.labels.labels-container.admin-labels.gl-bg-gray-10.gl-border-solid.gl-border-1.gl-border-gray-100
- - if @labels.present?
+- if @labels.present?
+ .labels.labels-container.admin-labels.js-admin-labels-container.gl-bg-gray-10.gl-border-solid.gl-border-1.gl-border-gray-100
%ul.manage-labels-list
= render @labels
= paginate @labels, theme: 'gitlab'
- .nothing-here-block{ class: ('hidden' if @labels.present?) }
- = _('There are no labels yet')
+.js-admin-labels-empty-state{ class: ('gl-display-none' if @labels.present?) }
+ %section.row.empty-state.gl-text-center
+ .col-12
+ .svg-content
+ = image_tag 'illustrations/labels.svg'
+ .col-12
+ .gl-mx-auto.gl-my-0.gl-p-5
+ %h1.gl-font-size-h-display.gl-line-height-36.h4
+ = s_('AdminLabels|Define your default set of project labels')
+ %p.gl-mb-0
+ = s_('AdminLabels|Labels created here will be automatically added to new projects.')
+ %p
+ = s_('AdminLabels|They can be used to categorize issues and merge requests.')
+ .gl-display-flex.gl-flex-wrap.gl-justify-content-center
+ = link_to new_admin_label_path, class: "btn gl-mb-3 btn-confirm btn-md gl-button gl-mx-2" do
+ %span.gl-button-text
+ = _('New label')
diff --git a/app/views/admin/projects/_archived.html.haml b/app/views/admin/projects/_archived.html.haml
index 8b4d5806c47..3d79cc7ca71 100644
--- a/app/views/admin/projects/_archived.html.haml
+++ b/app/views/admin/projects/_archived.html.haml
@@ -1,3 +1,2 @@
- if project.archived
- %span.badge.badge-warning
- = _('archived')
+ = gl_badge_tag _('archived'), variant: :warning
diff --git a/app/views/admin/projects/_projects.html.haml b/app/views/admin/projects/_projects.html.haml
index 6f7cea85ed1..f56b77813b5 100644
--- a/app/views/admin/projects/_projects.html.haml
+++ b/app/views/admin/projects/_projects.html.haml
@@ -9,8 +9,7 @@
= s_('AdminProjects|Delete')
.stats
- %span.badge.badge-pill
- = storage_counter(project.statistics&.storage_size)
+ = gl_badge_tag storage_counter(project.statistics&.storage_size)
= render_if_exists 'admin/projects/archived', project: project
.title
= link_to(admin_project_path(project)) do
diff --git a/app/views/admin/projects/show.html.haml b/app/views/admin/projects/show.html.haml
index 3069aab2710..ee2e63353f0 100644
--- a/app/views/admin/projects/show.html.haml
+++ b/app/views/admin/projects/show.html.haml
@@ -178,7 +178,7 @@
.card-header
%strong= @group.name
= _('group members')
- %span.badge.badge-pill= @group_members.size
+ = gl_badge_tag @group_members.size
= render 'shared/members/manage_access_button', path: group_group_members_path(@group)
%ul.content-list.members-list
= render partial: 'shared/members/member',
@@ -195,7 +195,7 @@
.card-header
%strong= @project.name
= _('project members')
- %span.badge.badge-pill= @project.users.size
+ = gl_badge_tag @project.users.size
= render 'shared/members/manage_access_button', path: project_project_members_path(@project)
%ul.content-list.project_members.members-list
= render partial: 'shared/members/member',
diff --git a/app/views/admin/users/_access_levels.html.haml b/app/views/admin/users/_access_levels.html.haml
index 6a5f07dd2db..5977de7c84c 100644
--- a/app/views/admin/users/_access_levels.html.haml
+++ b/app/views/admin/users/_access_levels.html.haml
@@ -43,9 +43,8 @@
= s_('AdminUsers|External')
%p.light.gl-pl-2
= s_('AdminUsers|External users cannot see internal or private projects unless access is explicitly granted. Also, external users cannot create projects, groups, or personal snippets.')
- %row.hidden#warning_external_automatically_set.hidden
- .badge.badge-warning.text-white
- = s_('AdminUsers|Automatically marked as default internal user')
+ %row.hidden#warning_external_automatically_set
+ = gl_badge_tag s_('AdminUsers|Automatically marked as default internal user'), variant: :warning
.form-group.row
- @user.credit_card_validation || @user.build_credit_card_validation
diff --git a/app/views/admin/users/_user_detail.html.haml b/app/views/admin/users/_user_detail.html.haml
deleted file mode 100644
index 05e387e6479..00000000000
--- a/app/views/admin/users/_user_detail.html.haml
+++ /dev/null
@@ -1,20 +0,0 @@
-.flex-list
- .flex-row
- = image_tag avatar_icon_for_user(user), class: 'avatar s32 d-none d-md-flex', alt: _('Avatar for %{name}') % { name: sanitize_name(user.name) }
- .row-main-content
- .row-title.str-truncated-100
- = image_tag avatar_icon_for_user(user), class: 'avatar s16 d-xs-flex d-md-none mr-1 gl-mt-2', alt: _('Avatar for %{name}') % { name: sanitize_name(user.name) }
- = link_to user.name, admin_user_path(user), class: 'text-plain js-user-link', data: { user_id: user.id, qa_selector: 'username_link' }
-
- = render 'admin/users/user_listing_note', user: user
-
- - user_badges_in_admin_section(user).each do |badge|
- - css_badge = "badge gl-badge sm badge-pill badge-#{badge[:variant]}" if badge[:variant].present?
- %span.px-1.py-1
- %span{ class: css_badge }
- = badge[:text]
-
- .row-second-line.str-truncated-100
- = mail_to user.email, user.email, class: 'text-secondary'
- - unless Feature.disabled?(:security_auto_fix) || !user.internal? || user.website_url.blank?
- = link_to "(#{_('more information')})", user.website_url
diff --git a/app/views/admin/users/projects.html.haml b/app/views/admin/users/projects.html.haml
index 8c56e888dcc..b47ed38f65f 100644
--- a/app/views/admin/users/projects.html.haml
+++ b/app/views/admin/users/projects.html.haml
@@ -17,7 +17,7 @@
%span.light.vertical-align-middle= group_member.human_access
- unless group_member.owner?
= link_to group_group_member_path(group, group_member), data: { confirm: remove_member_message(group_member), testid: 'remove-user' }, method: :delete, remote: true, class: "btn btn-sm btn-danger gl-button btn-icon gl-ml-3", title: _('Remove user from group') do
- = sprite_icon('close', size: 16, css_class: 'gl-icon')
+ = sprite_icon('remove', size: 16, css_class: 'gl-icon')
.row
.col-md-6
@@ -47,6 +47,6 @@
- if member.respond_to? :project
= link_to project_project_member_path(project, member), data: { confirm: remove_member_message(member) }, remote: true, method: :delete, class: "btn btn-sm btn-danger gl-button btn-icon gl-ml-3", title: _('Remove user from project') do
- = sprite_icon('close', size: 16, css_class: 'gl-icon')
+ = sprite_icon('remove', size: 16, css_class: 'gl-icon')
= render partial: 'admin/users/modals'
diff --git a/app/views/admin/users/show.html.haml b/app/views/admin/users/show.html.haml
index 2a9b4694e7b..bdc5bdabb21 100644
--- a/app/views/admin/users/show.html.haml
+++ b/app/views/admin/users/show.html.haml
@@ -35,7 +35,7 @@
%span.light= _('Email:')
%strong
= render partial: 'shared/email_with_badge', locals: { email: mail_to(@user.email), verified: @user.confirmed? }
- - @user.emails.each do |email|
+ - @user.emails.reject(&:user_primary_email?).each do |email|
%li
%span.light= _('Secondary email:')
%strong
diff --git a/app/views/clusters/clusters/_gcp_signup_offer_banner.html.haml b/app/views/clusters/clusters/_gcp_signup_offer_banner.html.haml
index 81f4be9fce5..9d249931a34 100644
--- a/app/views/clusters/clusters/_gcp_signup_offer_banner.html.haml
+++ b/app/views/clusters/clusters/_gcp_signup_offer_banner.html.haml
@@ -1,5 +1,5 @@
- link = link_to(s_('ClusterIntegration|sign up'), 'https://console.cloud.google.com/freetrial?utm_campaign=2018_cpanel&utm_source=gitlab&utm_medium=referral', target: '_blank', rel: 'noopener noreferrer')
-.gcp-signup-offer.gl-alert.gl-alert-info.gl-my-3{ role: 'alert', data: { feature_id: UserCalloutsHelper::GCP_SIGNUP_OFFER, dismiss_endpoint: user_callouts_path } }
+.gcp-signup-offer.gl-alert.gl-alert-info.gl-my-3{ role: 'alert', data: { feature_id: Users::CalloutsHelper::GCP_SIGNUP_OFFER, dismiss_endpoint: callouts_path } }
.gl-alert-container
%button.js-close.btn.gl-dismiss-btn.btn-default.btn-sm.gl-button.btn-default-tertiary.btn-icon{ type: 'button', 'aria-label' => _('Dismiss') }
= sprite_icon('close', size: 16, css_class: 'gl-icon')
diff --git a/app/views/clusters/clusters/show.html.haml b/app/views/clusters/clusters/show.html.haml
index e4c8f225ed2..a6efe597f0c 100644
--- a/app/views/clusters/clusters/show.html.haml
+++ b/app/views/clusters/clusters/show.html.haml
@@ -24,10 +24,9 @@
.js-serverless-survey-banner{ data: { user_name: current_user.name, user_email: current_user.email } }
- %h4.gl-my-5
+ %h4.gl-my-5.gl-display-flex.gl-align-items-center
= @cluster.name
- %span.badge.badge-info.badge-pill.gl-badge.md.gl-vertical-align-middle
- = cluster_type_label(@cluster.cluster_type)
+ = gl_badge_tag cluster_type_label(@cluster.cluster_type), { variant: :info }, { class: 'gl-ml-3' }
= render 'banner'
diff --git a/app/views/devise/confirmations/almost_there.haml b/app/views/devise/confirmations/almost_there.haml
index 9fb0fb734f9..892ef730884 100644
--- a/app/views/devise/confirmations/almost_there.haml
+++ b/app/views/devise/confirmations/almost_there.haml
@@ -1,6 +1,8 @@
- user_email = "(#{params[:email]})" if params[:email].present?
- request_link_start = '<a href="%{new_user_confirmation_path}">'.html_safe % { new_user_confirmation_path: new_user_confirmation_path }
- request_link_end = '</a>'.html_safe
+- content_for :page_specific_javascripts do
+ = render "layouts/one_trust"
.well-confirmation.gl-text-center.gl-mb-6
%h1.gl-mt-0
diff --git a/app/views/devise/sessions/new.html.haml b/app/views/devise/sessions/new.html.haml
index da6232b2a2b..175b45dbbfa 100644
--- a/app/views/devise/sessions/new.html.haml
+++ b/app/views/devise/sessions/new.html.haml
@@ -1,8 +1,6 @@
- page_title _("Sign in")
- content_for :page_specific_javascripts do
- = render "layouts/google_tag_manager_head"
= render "layouts/one_trust"
-= render "layouts/google_tag_manager_body"
#signin-container
- if any_form_based_providers_enabled?
diff --git a/app/views/devise/shared/_tab_single.html.haml b/app/views/devise/shared/_tab_single.html.haml
index 5683b4207b4..1b5a932a09a 100644
--- a/app/views/devise/shared/_tab_single.html.haml
+++ b/app/views/devise/shared/_tab_single.html.haml
@@ -1,3 +1,2 @@
-%ul.nav-links.new-session-tabs.single-tab.nav-tabs.nav
- %li.nav-item
- %a.nav-link.active= tab_title
+= gl_tabs_nav({ class: 'new-session-tabs gl-border-0' }) do
+ = gl_tab_link_to tab_title, '#', { item_active: true, class: 'gl-cursor-default!', tab_class: 'gl-bg-transparent!', tabindex: '-1' }
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 8d6e043ebf7..0644910dd3e 100644
--- a/app/views/groups/_import_group_from_file_panel.html.haml
+++ b/app/views/groups/_import_group_from_file_panel.html.haml
@@ -6,9 +6,17 @@
.gl-border-l-solid.gl-border-r-solid.gl-border-gray-100.gl-border-1.gl-p-5
%h4
= _('Import group from file')
- %p
- = s_('GroupsNew|Provide credentials for another instance of GitLab to import your groups directly.')
- .form-group.gl-display-flex.gl-flex-direction-column
+ .gl-alert.gl-alert-warning{ role: 'alert' }
+ = sprite_icon('warning', css_class: 'gl-icon s16 gl-alert-icon gl-alert-icon-no-title')
+ .gl-alert-body
+ - docs_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: help_page_path('user/group/import/index.md') }
+ - link_end = '</a>'.html_safe
+ = s_('GroupsNew|This feature is deprecated and replaced by %{docs_link_start}Group Migration%{docs_link_end}.').html_safe % { docs_link_start: docs_link_start, docs_link_end: link_end }
+ - if Feature.enabled?(:bulk_import, default_enabled: :yaml)
+ - enable_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: help_page_path('user/group/import/index.md', anchor: 'enable-or-disable-gitlab-group-migration') }
+ = s_('GroupsNew|Ask your administrator to %{enable_link_start}enable%{enable_link_end} Group Migration.').html_safe % { enable_link_start: enable_link_start, enable_link_end: link_end }
+
+ .form-group.gl-display-flex.gl-flex-direction-column.gl-mt-5
= f.label :name, _('New group name'), for: 'import_group_name'
= f.text_field :name, placeholder: s_('GroupsNew|My Awesome Group'), class: 'js-autofill-group-name gl-form-input col-xs-12 col-sm-8',
required: true,
diff --git a/app/views/groups/_invite_members_side_nav_link.html.haml b/app/views/groups/_invite_members_side_nav_link.html.haml
index bccfa9897da..3046669b53b 100644
--- a/app/views/groups/_invite_members_side_nav_link.html.haml
+++ b/app/views/groups/_invite_members_side_nav_link.html.haml
@@ -1,5 +1,4 @@
.js-invite-members-trigger{ data: { trigger_source: 'group-side-nav',
- classes: 'gl-text-decoration-none! gl-shadow-none! gl-text-body!',
icon: 'users',
display_text: title,
trigger_element: 'side-nav'} }
diff --git a/app/views/groups/_personalize.html.haml b/app/views/groups/_personalize.html.haml
index 5ecb0017cd8..07b3b29c20c 100644
--- a/app/views/groups/_personalize.html.haml
+++ b/app/views/groups/_personalize.html.haml
@@ -15,7 +15,7 @@
= f.label :setup_for_company, _('Who will be using this group?')
.gl-display-flex.gl-flex-direction-column.gl-lg-flex-direction-row
.gl-flex-grow-1.gl-display-flex.gl-align-items-center
- = f.radio_button :setup_for_company, true, checked: true
+ = f.radio_button :setup_for_company, true
= f.label :setup_for_company, _('My company or team'), class: 'gl-font-weight-normal gl-mb-0 gl-ml-2', value: 'true'
.gl-flex-grow-1.gl-display-flex.gl-align-items-center
= f.radio_button :setup_for_company, false
diff --git a/app/views/groups/_project_badges.html.haml b/app/views/groups/_project_badges.html.haml
index 1f7895e216c..4ea193b08c2 100644
--- a/app/views/groups/_project_badges.html.haml
+++ b/app/views/groups/_project_badges.html.haml
@@ -1,2 +1,2 @@
- if project.archived
- %span.badge.badge-warning.badge-pill.gl-badge.md= _('archived')
+ = gl_badge_tag _('archived'), variant: :warning, size: :md
diff --git a/app/views/groups/crm/contacts.html.haml b/app/views/groups/crm/contacts.html.haml
deleted file mode 100644
index c452a969d17..00000000000
--- a/app/views/groups/crm/contacts.html.haml
+++ /dev/null
@@ -1,4 +0,0 @@
-- breadcrumb_title _('Customer Relations Contacts')
-- page_title _('Customer Relations Contacts')
-
-#js-crm-contacts-app{ data: { group_full_path: @group.full_path } }
diff --git a/app/views/groups/crm/contacts/index.html.haml b/app/views/groups/crm/contacts/index.html.haml
new file mode 100644
index 00000000000..81293937f77
--- /dev/null
+++ b/app/views/groups/crm/contacts/index.html.haml
@@ -0,0 +1,4 @@
+- breadcrumb_title _('Customer Relations Contacts')
+- page_title _('Customer Relations Contacts')
+
+#js-crm-contacts-app{ data: { group_full_path: @group.full_path, group_issues_path: issues_group_path(@group), group_id: @group.id, can_admin_crm_contact: can?(current_user, :admin_crm_contact, @group).to_s, base_path: group_crm_contacts_path(@group) } }
diff --git a/app/views/groups/crm/organizations.html.haml b/app/views/groups/crm/organizations.html.haml
deleted file mode 100644
index e83dab9fda6..00000000000
--- a/app/views/groups/crm/organizations.html.haml
+++ /dev/null
@@ -1,4 +0,0 @@
-- breadcrumb_title _('Customer Relations Organizations')
-- page_title _('Customer Relations Organizations')
-
-#js-crm-organizations-app{ data: { group_full_path: @group.full_path } }
diff --git a/app/views/groups/crm/organizations/index.html.haml b/app/views/groups/crm/organizations/index.html.haml
new file mode 100644
index 00000000000..1647805b976
--- /dev/null
+++ b/app/views/groups/crm/organizations/index.html.haml
@@ -0,0 +1,4 @@
+- breadcrumb_title _('Customer Relations Organizations')
+- page_title _('Customer Relations Organizations')
+
+#js-crm-organizations-app{ data: { base_path: group_crm_organizations_path(@group), can_admin_crm_organization: can?(current_user, :admin_crm_organization, @group).to_s, group_full_path: @group.full_path, group_id: @group.id, group_issues_path: issues_group_path(@group) } }
diff --git a/app/views/groups/packages/index.html.haml b/app/views/groups/packages/index.html.haml
index 7910217c939..d56a806f082 100644
--- a/app/views/groups/packages/index.html.haml
+++ b/app/views/groups/packages/index.html.haml
@@ -3,4 +3,8 @@
.row
.col-12
- #js-vue-packages-list{ data: packages_list_data('groups', @group) }
+ #js-vue-packages-list{ data: { resource_id: @group.id,
+ full_path: @group.full_path,
+ endpoint: group_packages_path(@group),
+ page_type: 'groups',
+ empty_list_illustration: image_path('illustrations/no-packages.svg'), } }
diff --git a/app/views/groups/projects.html.haml b/app/views/groups/projects.html.haml
index 9dbf60b119c..3507f4574ab 100644
--- a/app/views/groups/projects.html.haml
+++ b/app/views/groups/projects.html.haml
@@ -18,12 +18,11 @@
= render 'delete_project_button', project: project
.stats
- %span.badge.badge-pill
- = storage_counter(project.statistics&.storage_size)
+ = gl_badge_tag storage_counter(project.statistics&.storage_size)
= render 'project_badges', project: project
.title
- = link_to(project_path(project)) do
+ = link_to project_path(project), class: 'js-prefetch-document' do
.dash-project-avatar
.avatar-container.rect-avatar.s40
= project_icon(project, alt: '', class: 'avatar project-avatar s40', width: 40, height: 40)
diff --git a/app/views/groups/registry/repositories/index.html.haml b/app/views/groups/registry/repositories/index.html.haml
index 2901c8fa46b..f6d05959d2e 100644
--- a/app/views/groups/registry/repositories/index.html.haml
+++ b/app/views/groups/registry/repositories/index.html.haml
@@ -18,6 +18,6 @@
"gid_prefix": container_repository_gid_prefix,
connection_error: (!!@connection_error).to_s,
invalid_path_error: (!!@invalid_path_error).to_s,
- user_callouts_path: user_callouts_path,
- user_callout_id: UserCalloutsHelper::UNFINISHED_TAG_CLEANUP_CALLOUT,
+ user_callouts_path: callouts_path,
+ user_callout_id: Users::CalloutsHelper::UNFINISHED_TAG_CLEANUP_CALLOUT,
show_unfinished_tag_cleanup_callout: show_unfinished_tag_cleanup_callout?.to_s } }
diff --git a/app/views/groups/runners/_group_runners.html.haml b/app/views/groups/runners/_group_runners.html.haml
index 1cccce9f59a..e7cfc87ac88 100644
--- a/app/views/groups/runners/_group_runners.html.haml
+++ b/app/views/groups/runners/_group_runners.html.haml
@@ -10,7 +10,7 @@
= _('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')
+ - if can?(current_user, :register_group_runners, @group)
- if params[:ci_runner_templates]
%hr
= render partial: 'ci/runner/setup_runner_in_aws',
diff --git a/app/views/groups/settings/_advanced.html.haml b/app/views/groups/settings/_advanced.html.haml
index a82f7803b44..ebeec2ee95a 100644
--- a/app/views/groups/settings/_advanced.html.haml
+++ b/app/views/groups/settings/_advanced.html.haml
@@ -7,9 +7,8 @@
= form_errors(@group)
.form-group
%p
- = s_('GroupSettings|Changing group URL can have unintended side effects.')
- = succeed '.' do
- = link_to _('Learn more'), help_page_path('user/group/index', anchor: 'change-a-groups-path'), target: '_blank'
+ = s_("GroupSettings|Changing a group's URL can have unintended side effects.")
+ = link_to _('Learn more.'), help_page_path('user/group/index', anchor: 'change-a-groups-path'), target: '_blank', rel: 'noopener noreferrer'
.input-group.gl-field-error-anchor
.group-root-path.input-group-prepend.has-tooltip{ title: group_path(@group), :'data-placement' => 'bottom' }
diff --git a/app/views/groups/settings/_export.html.haml b/app/views/groups/settings/_export.html.haml
index f818f45cf53..ff00ff1f6e8 100644
--- a/app/views/groups/settings/_export.html.haml
+++ b/app/views/groups/settings/_export.html.haml
@@ -4,8 +4,17 @@
.sub-section
%h4= s_('GroupSettings|Export group')
- %p= _('Export this group with all related data to a new GitLab instance. Once complete, you can import the data file from the "New Group" page.')
-
+ %p= _('Export this group with all related data.')
+ .gl-alert.gl-alert-warning.gl-mb-4{ role: 'alert' }
+ = sprite_icon('warning', css_class: 'gl-icon s16 gl-alert-icon gl-alert-icon-no-title')
+ .gl-alert-body
+ - docs_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: help_page_path('user/group/import/index.md') }
+ - docs_link_end = '</a>'.html_safe
+ = s_('GroupsNew|This feature is deprecated and replaced by %{docs_link_start}Group Migration%{docs_link_end}.').html_safe % { docs_link_start: docs_link_start, docs_link_end: docs_link_end }
+ %p
+ - export_information = _('After the export is complete, download the data file from a notification email or from this page. You can then import the data file from the %{strong_text_start}Create new group%{strong_text_end} page of another GitLab instance.') % { strong_text_start: '<strong>'.html_safe, strong_text_end: '</strong>'.html_safe}
+ = export_information.html_safe
+ = link_to _('Learn more.'), help_page_path('user/group/settings/import_export.md'), target: '_blank', rel: 'noopener noreferrer'
.bs-callout.bs-callout-info
%p.gl-mb-0
%p= _('The following items will be exported:')
@@ -17,7 +26,6 @@
%li= _('Projects')
%li= _('Runner tokens')
%li= _('SAML discovery tokens')
- %p= _('Once the exported file is ready, you will receive a notification email with a download link, or you can download it from this page.')
- if group.export_file_exists?
= link_to _('Regenerate export'), export_group_path(group),
method: :post, class: 'btn gl-button btn-default', data: { qa_selector: 'regenerate_export_group_link' }
diff --git a/app/views/groups/settings/_transfer.html.haml b/app/views/groups/settings/_transfer.html.haml
index b2379d77314..59d52e99dec 100644
--- a/app/views/groups/settings/_transfer.html.haml
+++ b/app/views/groups/settings/_transfer.html.haml
@@ -1,18 +1,19 @@
.sub-section
%h4.warning-title= s_('GroupSettings|Transfer group')
+ %p= _('Transfer group to another parent group.')
= form_for group, url: transfer_group_path(group), method: :put, html: { class: 'js-group-transfer-form' } do |f|
- .form-group
- = dropdown_tag('Select parent group', options: { toggle_class: 'js-groups-dropdown', title: 'Parent Group', filter: true, dropdown_class: 'dropdown-open-top dropdown-group-transfer', placeholder: 'Search groups', disabled: group.paid?, data: { data: parent_group_options(group), qa_selector: 'select_group_dropdown' } })
- = hidden_field_tag 'new_parent_group_id'
%ul
- - side_effects_link_start = '<a href="https://docs.gitlab.com/ee/user/project/index.html#redirects-when-changing-repository-paths" target="_blank">'.html_safe
- - warning_text = s_("GroupSettings|Be careful. Changing a group's parent can have unintended %{side_effects_link_start}side effects%{side_effects_link_end}.") % { side_effects_link_start: side_effects_link_start, side_effects_link_end: '</a>'.html_safe }
+ - learn_more_link_start = '<a href="https://docs.gitlab.com/ee/user/project/index.html#redirects-when-changing-repository-paths" target="_blank" rel="noopener noreferrer">'.html_safe
+ - warning_text = s_("GroupSettings|Be careful. Changing a group's parent can have unintended side effects. %{learn_more_link_start}Learn more.%{learn_more_link_end}") % { learn_more_link_start: learn_more_link_start, learn_more_link_end: '</a>'.html_safe }
%li= warning_text.html_safe
%li= s_('GroupSettings|You can only transfer the group to a group you manage.')
%li= s_('GroupSettings|You will need to update your local repositories to point to the new location.')
%li= s_("GroupSettings|If the parent group's visibility is lower than the group current visibility, visibility levels for subgroups and projects will be changed to match the new parent group's visibility.")
+ .form-group
+ = dropdown_tag(s_('GroupSettings|Select parent group'), options: { toggle_class: 'js-groups-dropdown', title: s_('GroupSettings|Parent Group'), filter: true, dropdown_class: 'dropdown-open-top dropdown-group-transfer', placeholder: s_('GroupSettings|Search groups'), disabled: group.paid?, data: { data: parent_group_options(group), qa_selector: 'select_group_dropdown' } })
+ = hidden_field_tag 'new_parent_group_id'
- if group.paid?
.gl-alert.gl-alert-info.gl-mb-5
= sprite_icon('information-o', size: 16, css_class: 'gl-icon gl-alert-icon gl-alert-icon-no-title')
diff --git a/app/views/groups/settings/ci_cd/_auto_devops_form.html.haml b/app/views/groups/settings/ci_cd/_auto_devops_form.html.haml
index dedb87c51ef..32da444d058 100644
--- a/app/views/groups/settings/ci_cd/_auto_devops_form.html.haml
+++ b/app/views/groups/settings/ci_cd/_auto_devops_form.html.haml
@@ -8,7 +8,7 @@
= f.check_box :auto_devops_enabled, class: 'form-check-input', checked: group.auto_devops_enabled?
= f.label :auto_devops_enabled, class: 'form-check-label' do
%strong= s_('GroupSettings|Default to Auto DevOps pipeline for all projects within this group')
- %span.badge.badge-info#auto-devops-badge= badge_for_auto_devops_scope(group)
+ = gl_badge_tag badge_for_auto_devops_scope(group), variant: :info
.form-text.text-muted
= s_('GroupSettings|The Auto DevOps pipeline runs if no alternative CI configuration file is found.')
= link_to _('Learn more.'), help_page_path('topics/autodevops/index.md'), target: '_blank'
diff --git a/app/views/groups/settings/packages_and_registries/show.html.haml b/app/views/groups/settings/packages_and_registries/show.html.haml
index 7be6dc73c49..78ce981eb07 100644
--- a/app/views/groups/settings/packages_and_registries/show.html.haml
+++ b/app/views/groups/settings/packages_and_registries/show.html.haml
@@ -5,4 +5,5 @@
%section#js-packages-and-registries-settings{ data: { default_expanded: expanded_by_default?.to_s,
group_path: @group.full_path,
- dependency_proxy_available: dependency_proxy_available.to_s } }
+ dependency_proxy_available: dependency_proxy_available.to_s,
+ group_dependency_proxy_path: group_dependency_proxy_path(@group) } }
diff --git a/app/views/groups/show.html.haml b/app/views/groups/show.html.haml
index ed3f2b0c6db..bb409190dd8 100644
--- a/app/views/groups/show.html.haml
+++ b/app/views/groups/show.html.haml
@@ -15,7 +15,7 @@
track_label: 'invite_members_banner',
invite_members_path: group_group_members_path(@group),
callouts_path: group_callouts_path,
- callouts_feature_id: UserCalloutsHelper::INVITE_MEMBERS_BANNER,
+ callouts_feature_id: Users::GroupCalloutsHelper::INVITE_MEMBERS_BANNER,
group_id: @group.id } }
= render 'groups/invite_members_modal', group: @group
diff --git a/app/views/help/instance_configuration/_package_registry.html.haml b/app/views/help/instance_configuration/_package_registry.html.haml
index 38202b8d6e6..84b8accfebb 100644
--- a/app/views/help/instance_configuration/_package_registry.html.haml
+++ b/app/views/help/instance_configuration/_package_registry.html.haml
@@ -23,6 +23,10 @@
- package_file_size_limits.each_value do |limits|
%td= instance_configuration_human_size_cell(limits[:conan])
%tr
+ %td= 'Helm'
+ - package_file_size_limits.each_value do |limits|
+ %td= instance_configuration_human_size_cell(limits[:helm])
+ %tr
%td= 'Maven'
- package_file_size_limits.each_value do |limits|
%td= instance_configuration_human_size_cell(limits[:maven])
diff --git a/app/views/import/bitbucket/deploy_key.js.haml b/app/views/import/bitbucket/deploy_key.js.haml
deleted file mode 100644
index 99e8ac1afa1..00000000000
--- a/app/views/import/bitbucket/deploy_key.js.haml
+++ /dev/null
@@ -1,3 +0,0 @@
-:plain
- job = $("tr#repo_#{@repo_id}")
- job.find(".import-actions").html("<p class='alert alert-danger'>#{_('Access denied! Please verify you can add deploy keys to this repository.')}</p>")
diff --git a/app/views/jira_connect/subscriptions/index.html.haml b/app/views/jira_connect/subscriptions/index.html.haml
index be2be7288f8..d92c30c8840 100644
--- a/app/views/jira_connect/subscriptions/index.html.haml
+++ b/app/views/jira_connect/subscriptions/index.html.haml
@@ -1,13 +1,6 @@
%header.jira-connect-header.gl-display-flex.gl-align-items-center.gl-justify-content-center.gl-px-5.gl-border-b-solid.gl-border-b-gray-100.gl-border-b-1.gl-bg-white
= link_to brand_header_logo, Gitlab.config.gitlab.url, target: '_blank', rel: 'noopener noreferrer'
-.jira-connect-user.gl-font-base
- - if current_user
- - user_link = link_to(current_user.to_reference, jira_connect_users_path, target: '_blank', rel: 'noopener noreferrer', class: 'js-jira-connect-sign-in')
- = _('Signed in to GitLab as %{user_link}').html_safe % { user_link: user_link }
- - elsif @subscriptions.present?
- = link_to _('Sign in to GitLab'), jira_connect_users_path, target: '_blank', rel: 'noopener noreferrer', class: 'js-jira-connect-sign-in'
-
%main.jira-connect-app.gl-px-5.gl-pt-7.gl-mx-auto
.js-jira-connect-app{ data: jira_connect_app_data(@subscriptions) }
diff --git a/app/views/layouts/_flash.html.haml b/app/views/layouts/_flash.html.haml
index a302fa605e7..dded5ba76b0 100644
--- a/app/views/layouts/_flash.html.haml
+++ b/app/views/layouts/_flash.html.haml
@@ -1,9 +1,11 @@
--# We currently only support `alert`, `notice`, `success`, 'toast'
+-# We currently only support `alert`, `notice`, `success`, 'toast', and 'raw'
- icons = {'alert' => 'error', 'notice' => 'information-o', 'success' => 'check-circle'}
.flash-container.flash-container-page.sticky{ data: { qa_selector: 'flash_container' } }
- flash.each do |key, value|
- if key == 'toast' && value
.js-toast-message{ data: { message: value } }
+ - elsif key == 'raw' && value
+ = value
- elsif value == I18n.t('devise.failure.unconfirmed')
= render 'shared/confirm_your_email_alert'
- elsif value
diff --git a/app/views/layouts/_google_tag_manager_body.html.haml b/app/views/layouts/_google_tag_manager_body.html.haml
index d62e52dc91b..98d7bf5d138 100644
--- a/app/views/layouts/_google_tag_manager_body.html.haml
+++ b/app/views/layouts/_google_tag_manager_body.html.haml
@@ -1,4 +1,4 @@
- return unless google_tag_manager_enabled?
-<noscript><iframe src="https://www.googletagmanager.com/ns.html?id=#{extra_config.google_tag_manager_id}"
+<noscript><iframe src="https://www.googletagmanager.com/ns.html?id=#{google_tag_manager_id}"
height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
diff --git a/app/views/layouts/_google_tag_manager_head.html.haml b/app/views/layouts/_google_tag_manager_head.html.haml
index 48eb9e40cc4..25af51ca9cb 100644
--- a/app/views/layouts/_google_tag_manager_head.html.haml
+++ b/app/views/layouts/_google_tag_manager_head.html.haml
@@ -1,8 +1,19 @@
-- if google_tag_manager_enabled?
+- return unless google_tag_manager_enabled?
+
+- if Feature.enabled?(:gtm_nonce, type: :ops)
+ = javascript_tag nonce: content_security_policy_nonce do
+ :plain
+ (function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
+ new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
+ j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
+ 'https://www.googletagmanager.com/gtm.js?id='+i+dl;j.setAttribute('nonce',
+ '#{content_security_policy_nonce}');f.parentNode.insertBefore(j,f);
+ })(window,document,'script','dataLayer','#{google_tag_manager_id}');
+- else
= javascript_tag do
:plain
(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
- })(window,document,'script','dataLayer','#{extra_config.google_tag_manager_id}');
+ })(window,document,'script','dataLayer','#{google_tag_manager_id}');
diff --git a/app/views/layouts/_page.html.haml b/app/views/layouts/_page.html.haml
index dff1b5e3d04..3e875a0eb24 100644
--- a/app/views/layouts/_page.html.haml
+++ b/app/views/layouts/_page.html.haml
@@ -3,6 +3,7 @@
= render "layouts/nav/sidebar/#{nav}"
.content-wrapper.content-wrapper-margin{ class: "#{@content_wrapper_class}" }
.mobile-overlay
+ = render_if_exists 'layouts/header/verification_reminder'
= yield :group_invite_members_banner
.alert-wrapper.gl-force-block-formatting-context
= render 'shared/outdated_browser'
@@ -20,7 +21,6 @@
= render_if_exists "shared/namespace_user_cap_reached_alert"
= render_if_exists "shared/new_user_signups_cap_reached_alert"
= yield :page_level_alert
- = yield :customize_homepage_banner
- unless @hide_breadcrumbs
= render "layouts/nav/breadcrumbs"
%div{ class: "#{(container_class unless @no_container)} #{@content_class}" }
diff --git a/app/views/layouts/_snowplow.html.haml b/app/views/layouts/_snowplow.html.haml
index 7e242fb4a8e..8e9a5ea9406 100644
--- a/app/views/layouts/_snowplow.html.haml
+++ b/app/views/layouts/_snowplow.html.haml
@@ -1,5 +1,7 @@
- return unless Gitlab::Tracking.enabled?
+- namespace = @group || @project&.namespace
+
= javascript_tag do
:plain
;(function(p,l,o,w,i,n,g){if(!p[i]){p.GlobalSnowplowNamespace=p.GlobalSnowplowNamespace||[];
@@ -10,6 +12,6 @@
window.snowplowOptions = #{Gitlab::Tracking.options(@group).to_json}
gl = window.gl || {};
- gl.snowplowStandardContext = #{Gitlab::Tracking::StandardContext.new(namespace: @group || @project&.namespace,
+ gl.snowplowStandardContext = #{Gitlab::Tracking::StandardContext.new(namespace: namespace,
project: @project, user: current_user).to_context.to_json.to_json}
- gl.snowplowPseudonymizedPageUrl = #{masked_page_url.to_json};
+ gl.snowplowPseudonymizedPageUrl = #{masked_page_url(group: namespace, project: @project).to_json};
diff --git a/app/views/layouts/header/_current_user_dropdown.html.haml b/app/views/layouts/header/_current_user_dropdown.html.haml
index 6bb51b01c13..daa48980c5b 100644
--- a/app/views/layouts/header/_current_user_dropdown.html.haml
+++ b/app/views/layouts/header/_current_user_dropdown.html.haml
@@ -45,7 +45,7 @@
= render 'shared/user_dropdown_instance_review'
- if Gitlab.com_but_not_canary?
%li.d-md-none
- = link_to _("Switch to GitLab Next"), "https://next.gitlab.com/"
+ = link_to _("Switch to GitLab Next"), Gitlab::Saas.canary_toggle_com_url
- if current_user_menu?(:sign_out)
%li.divider
diff --git a/app/views/layouts/header/_default.html.haml b/app/views/layouts/header/_default.html.haml
index 83e8ff79aec..69b8518ef33 100644
--- a/app/views/layouts/header/_default.html.haml
+++ b/app/views/layouts/header/_default.html.haml
@@ -15,7 +15,7 @@
%span.logo-text.d-none.d-lg-block.gl-ml-3
= logo_text
- if Gitlab.com_and_canary?
- = link_to 'https://next.gitlab.com', class: 'canary-badge bg-transparent', data: { qa_selector: 'canary_badge_link' }, target: :_blank, rel: :_noopener do
+ = link_to Gitlab::Saas.canary_toggle_com_url, class: 'canary-badge bg-transparent', data: { qa_selector: 'canary_badge_link' }, target: :_blank, rel: 'noopener noreferrer' do
%span.gl-badge.gl-bg-green-500.gl-text-white.gl-rounded-pill.gl-font-weight-bold.gl-py-1
= _('Next')
@@ -36,7 +36,9 @@
'issues-path' => issues_dashboard_path,
'mr-path' => merge_requests_dashboard_path,
'autocomplete-path' => search_autocomplete_path } }
- %input{ type: "text", placeholder: _('Search or jump to...'), class: 'form-control gl-form-input' }
+ .gl-search-box-by-type
+ = sprite_icon('search', css_class: 'gl-search-box-by-type-search-icon gl-icon')
+ %input{ type: "text", placeholder: _('Search or jump to...'), class: 'form-control gl-form-input gl-search-box-by-type-input', id: 'search', autocomplete: 'off' }
- else
= render 'layouts/search'
%li.nav-item{ class: 'd-none d-sm-inline-block d-lg-none' }
@@ -44,7 +46,7 @@
= sprite_icon(search_menu_item.fetch(:icon))
- if header_link?(:issues)
= nav_link(path: 'dashboard#issues', html_options: { class: "user-counter" }) do
- = link_to assigned_issues_dashboard_path, title: _('Issues'), class: 'dashboard-shortcuts-issues', aria: { label: _('Issues') },
+ = link_to assigned_issues_dashboard_path, title: _('Issues'), class: 'dashboard-shortcuts-issues js-prefetch-document', aria: { label: _('Issues') },
data: { qa_selector: 'issues_shortcut_button', toggle: 'tooltip', placement: 'bottom',
track_label: 'main_navigation',
track_action: 'click_issues_link',
@@ -73,18 +75,18 @@
%li.dropdown-header
= _('Merge requests')
%li
- = link_to assigned_mrs_dashboard_path, class: 'gl-display-flex! gl-align-items-center' do
+ = link_to assigned_mrs_dashboard_path, class: 'gl-display-flex! gl-align-items-center js-prefetch-document' do
= _('Assigned to you')
%span.badge.gl-badge.badge-pill.badge-muted.merge-request-badge.gl-ml-auto.js-assigned-mr-count{ class: "" }
= user_merge_requests_counts[:assigned]
%li
- = link_to reviewer_mrs_dashboard_path, class: 'gl-display-flex! gl-align-items-center' do
+ = link_to reviewer_mrs_dashboard_path, class: 'gl-display-flex! gl-align-items-center js-prefetch-document' do
= _('Review requests for you')
%span.badge.gl-badge.badge-pill.badge-muted.merge-request-badge.gl-ml-auto.js-reviewer-mr-count{ class: "" }
= user_merge_requests_counts[:review_requested]
- if header_link?(:todos)
= nav_link(controller: 'dashboard/todos', html_options: { class: "user-counter" }) do
- = link_to dashboard_todos_path, title: _('To-Do List'), aria: { label: _('To-Do List') }, class: 'shortcuts-todos',
+ = link_to dashboard_todos_path, title: _('To-Do List'), aria: { label: _('To-Do List') }, class: 'shortcuts-todos js-prefetch-document',
data: { qa_selector: 'todos_shortcut_button', toggle: 'tooltip', placement: 'bottom',
track_label: 'main_navigation',
track_action: 'click_to_do_link',
@@ -94,7 +96,7 @@
%span.badge.badge-pill.todos-count.js-todos-count{ class: ('hidden' if todos_pending_count == 0) }
= todos_count_format(todos_pending_count)
%li.nav-item.header-help.dropdown.d-none.d-md-block{ **tracking_attrs('main_navigation', 'click_question_mark_link', 'navigation') }
- = link_to help_path, class: 'header-help-dropdown-toggle', data: { toggle: "dropdown" } do
+ = link_to help_path, class: 'header-help-dropdown-toggle gl-relative', data: { toggle: "dropdown" } do
%span.gl-sr-only
= s_('Nav|Help')
= sprite_icon('question-o')
diff --git a/app/views/layouts/header/_help_dropdown.html.haml b/app/views/layouts/header/_help_dropdown.html.haml
index a03cd4cd68f..e2c7781da54 100644
--- a/app/views/layouts/header/_help_dropdown.html.haml
+++ b/app/views/layouts/header/_help_dropdown.html.haml
@@ -20,4 +20,4 @@
= render 'shared/user_dropdown_instance_review'
- if Gitlab.com_but_not_canary?
%li
- = link_to _("Switch to GitLab Next"), "https://next.gitlab.com/"
+ = link_to _("Switch to GitLab Next"), Gitlab::Saas.canary_toggle_com_url
diff --git a/app/views/layouts/header/_registration_enabled_callout.html.haml b/app/views/layouts/header/_registration_enabled_callout.html.haml
index 25a7f7ba9d7..90f3ac61614 100644
--- a/app/views/layouts/header/_registration_enabled_callout.html.haml
+++ b/app/views/layouts/header/_registration_enabled_callout.html.haml
@@ -4,7 +4,7 @@
title: _('Open registration is enabled on your instance.'),
variant: :warning,
alert_class: 'js-registration-enabled-callout',
- alert_data: { feature_id: UserCalloutsHelper::REGISTRATION_ENABLED_CALLOUT, dismiss_endpoint: user_callouts_path },
+ alert_data: { feature_id: Users::CalloutsHelper::REGISTRATION_ENABLED_CALLOUT, dismiss_endpoint: callouts_path },
close_button_data: { testid: 'close-registration-enabled-callout' } do
.gl-alert-body
= html_escape(_('%{anchorOpen}Learn more%{anchorClose} about how you can customize / disable registration on your instance.')) % { anchorOpen: "<a href=\"#{help_page_path('user/admin_area/settings/sign_up_restrictions')}\" class=\"gl-link\">".html_safe, anchorClose: '</a>'.html_safe }
diff --git a/app/views/layouts/in_product_marketing_mailer.html.haml b/app/views/layouts/in_product_marketing_mailer.html.haml
new file mode 100644
index 00000000000..679a2d4b8b3
--- /dev/null
+++ b/app/views/layouts/in_product_marketing_mailer.html.haml
@@ -0,0 +1,194 @@
+!!!
+%html{ lang: "en" }
+ %head
+ %meta{ content: "text/html; charset=utf-8", "http-equiv" => "Content-Type" }
+ %meta{ content: "width=device-width, initial-scale=1", name: "viewport" }
+ %link{ href: "https://fonts.googleapis.com/css?family=Source+Sans+Pro:400,600", rel: "stylesheet", type: "text/css", data: { premailer: 'ignore' } }
+ %title= message.subject
+ :css
+ /* CLIENT-SPECIFIC STYLES */
+ body,
+ table,
+ td,
+ a {
+ -webkit-text-size-adjust: 100%;
+ -ms-text-size-adjust: 100%;
+ }
+
+ table,
+ td {
+ mso-table-lspace: 0pt;
+ mso-table-rspace: 0pt;
+ }
+
+ img {
+ -ms-interpolation-mode: bicubic;
+ }
+
+ /* RESET STYLES */
+ img {
+ border: 0;
+ height: auto;
+ line-height: 100%;
+ outline: none;
+ text-decoration: none;
+ }
+
+ table {
+ border-collapse: collapse !important;
+ }
+
+ body {
+ height: 100% !important;
+ margin: 0 !important;
+ padding: 0 !important;
+ width: 100% !important;
+ background-color: #ffffff;
+ color: #424242;
+ }
+
+ a {
+ color: #6b4fbb;
+ text-decoration: underline;
+ }
+
+ .cta_link a {
+ font-size: 24px;
+ font-family: 'Source Sans Pro', helvetica, arial, sans-serif;
+ text-decoration: none;
+ display: inline-block;
+ }
+
+ .cta_link_primary a {
+ color: #ffffff;
+ border-radius: 5px;
+ background-color: #6e49cb;
+ border-top: 15px solid #6e49cb;
+ border-bottom: 15px solid #6e49cb;
+ border-right: 40px solid #6e49cb;
+ border-left: 40px solid #6e49cb;
+ }
+
+ .cta_link_secondary a {
+ color: #6e49cb;
+ padding: 25px 40px 15px;
+ }
+
+ .footernav {
+ display: inline !important;
+ }
+
+ .footernav a {
+ color: #6e49cb;
+ }
+
+ .address {
+ margin: 0;
+ font-size: 16px;
+ line-height: 26px;
+ }
+
+ :css
+ /* iOS BLUE LINKS */
+ a[x-apple-data-detectors] {
+ color: inherit !important;
+ text-decoration: none !important;
+ font-size: inherit !important;
+ font-family: inherit !important;
+ font-weight: inherit !important;
+ line-height: inherit !important;
+ }
+ /[if gte mso 9]
+ <xml>
+ <o:OfficeDocumentSettings>
+ <o:AllowPNG/>
+ <o:PixelsPerInch>96</o:PixelsPerInch>
+ </o:OfficeDocumentSettings>
+ </xml>
+ /[if (mso)|(mso 16)]
+ <style type="text/css">
+ body, table, td, a, span { font-family: Arial, Helvetica, sans-serif !important; }
+ </style>
+ :css
+ @media only screen and (max-width: 595px) {
+
+ .wrapper {
+ width: 100% !important;
+ margin: 0 auto !important;
+ padding: 0 !important;
+ }
+
+ p,
+ li {
+ font-size: 18px !important;
+ line-height: 26px !important;
+ }
+
+ .stack {
+ width: 100% !important;
+ }
+
+ .stack-mobile-padding {
+ width: 100% !important;
+ margin-top: 20px !important;
+ }
+
+ .callout {
+ padding-bottom: 20px !important;
+ }
+
+ .redbutton {
+ text-align: center;
+ }
+
+ .stack33 {
+ display: block !important;
+ width: 100% !important;
+ max-width: 100% !important;
+ direction: ltr !important;
+ text-align: center !important;
+ }
+ }
+
+ @media only screen and (max-width: 480px) {
+ u~div {
+ width: 100vw !important;
+ }
+
+ div>u~div {
+ width: 100% !important;
+ }
+ }
+ %body#body{ width: "100%" }
+ %table{ border: "0", cellpadding: "0", cellspacing: "0", role: "presentation", width: "100%" }
+ %tr
+ %td{ align: "center", style: "padding: 0px;" }
+ %table.wrapper{ border: "0", cellpadding: "0", cellspacing: "0", role: "presentation", width: "600" }
+ %tr
+ %td{ style: "padding: 0px;" }
+ #main-story.mktEditable{ mktoname: "main-story" }
+ %table{ border: "0", cellpadding: "0", cellspacing: "0", role: "presentation", width: "100%" }
+ %tr
+ %td{ align: "left", style: "padding: 0 20px;" }
+ = about_link('mailers/in_product_marketing/gitlab-logo-gray-rgb.png', 200)
+ %tr
+ %td{ "aria-hidden" => "true", height: "30", style: "font-size: 0; line-height: 0;" }
+
+ = yield
+
+ %tr{ style: "background-color: #ffffff;" }
+ %td{ align: "center", style: "padding:75px 20px 25px;" }
+ = about_link('gitlab_logo.png', 80)
+ %tr{ style: "background-color: #ffffff;" }
+ %td{ align: "center", style: "padding:0px ;" }
+ %tr{ style: "background-color: #ffffff;" }
+ %td{ align: "center", style: "padding:0px 10px; font-family: 'Source Sans Pro', helvetica, arial, sans-serif; " }
+ %span.footernav{ style: "color: #6e49cb; font-size: 16px; line-height: 26px; font-family: 'Source Sans Pro', helvetica, arial, sans-serif;" }
+ = @message.footer_links.join('&nbsp;' * 3 + '|' + '&nbsp;' * 4).html_safe
+ %tr{ style: "background-color:#ffffff;" }
+ %td{ align: "center", style: "padding: 40px 30px 20px 30px; font-family: 'Source Sans Pro', helvetica, arial, sans-serif;" }
+ .address= @message.address
+ %tr{ style: "background-color: #ffffff;" }
+ %td{ align: "left", style: "padding:20px 30px 20px 30px;" }
+ %span.footernav{ style: "color: #6e49cb; font-size: 14px; line-height: 20px; font-family: 'Source Sans Pro', helvetica, arial, sans-serif; color:#424242;" }
+ = @message.unsubscribe.html_safe
diff --git a/app/views/notify/_note_email.html.haml b/app/views/notify/_note_email.html.haml
index 2cef6f97d48..ae9c8554e73 100644
--- a/app/views/notify/_note_email.html.haml
+++ b/app/views/notify/_note_email.html.haml
@@ -34,4 +34,4 @@
email: true }
%div{ style: note_style }
- = markdown(note.note, pipeline: :email, author: note.author)
+ = markdown(note.note, pipeline: :email, author: note.author, current_user: @recipient, issuable_reference_expansion_enabled: true)
diff --git a/app/views/notify/account_validation_email.html.haml b/app/views/notify/account_validation_email.html.haml
new file mode 100644
index 00000000000..02256443430
--- /dev/null
+++ b/app/views/notify/account_validation_email.html.haml
@@ -0,0 +1,16 @@
+%tr
+ %td{ bgcolor: "#ffffff", height: "auto", style: "max-width: 600px; width: 100%; text-align: center; height: 200px; padding: 25px 15px; mso-line-height-rule: exactly; min-height: 40px; font-family: 'Source Sans Pro', helvetica, arial, sans-serif;", valign: "middle", width: "100%" }
+ = inline_image_link(@message.logo_path, { width: '150', style: 'width: 150px;' })
+ %h1{ style: "font-size: 40px; line-height: 46x; color: #000000; padding: 20px 0 0 0; font-weight: normal;" }
+ = @message.title
+%tr
+ %td{ style: "padding: 10px 20px 30px 20px; font-family: 'Source Sans Pro', helvetica, arial, sans-serif; color:#000000; font-size: 18px; line-height: 24px;" }
+ %p{ style: "margin: 0 0 20px 0;" }
+ = @message.body_line1.html_safe
+ - @message.body_line2&.tap do |line|
+ %p{ style: "margin: 0 0 20px 0;" }
+ = line.html_safe
+%tr
+ %td{ align: "center", style: "padding: 20px; font-family: 'Source Sans Pro', helvetica, arial, sans-serif;" }
+ .cta_link.cta_link_primary= @message.cta_link
+ .cta_link.cta_link_secondary= @message.cta2_link
diff --git a/app/views/notify/account_validation_email.text.erb b/app/views/notify/account_validation_email.text.erb
new file mode 100644
index 00000000000..c167eff9803
--- /dev/null
+++ b/app/views/notify/account_validation_email.text.erb
@@ -0,0 +1,15 @@
+<%= @message.title %>
+
+<%= @message.body_line1 %>
+
+<%= @message.body_line2 %>
+
+<%= @message.cta_link %>
+
+<%= @message.cta2_link %>
+
+<%= @message.footer_links %>
+
+<%= @message.address %>
+
+<%= @message.unsubscribe %>
diff --git a/app/views/notify/attention_requested_merge_request_email.html.haml b/app/views/notify/attention_requested_merge_request_email.html.haml
new file mode 100644
index 00000000000..af42f180ae7
--- /dev/null
+++ b/app/views/notify/attention_requested_merge_request_email.html.haml
@@ -0,0 +1,2 @@
+%p
+ #{sanitize_name(@updated_by.name)} requested your attention on #{merge_request_reference_link(@merge_request)}.
diff --git a/app/views/notify/attention_requested_merge_request_email.text.erb b/app/views/notify/attention_requested_merge_request_email.text.erb
new file mode 100644
index 00000000000..97b1d4a824b
--- /dev/null
+++ b/app/views/notify/attention_requested_merge_request_email.text.erb
@@ -0,0 +1 @@
+<%= sanitize_name(@updated_by.name) %> requested your attention on <%= merge_request_reference_link(@merge_request) %>.
diff --git a/app/views/notify/in_product_marketing_email.html.haml b/app/views/notify/in_product_marketing_email.html.haml
index a85fa7c519f..a88d581c5de 100644
--- a/app/views/notify/in_product_marketing_email.html.haml
+++ b/app/views/notify/in_product_marketing_email.html.haml
@@ -1,235 +1,51 @@
-!!!
-%html{ lang: "en" }
- %head
- %meta{ content: "text/html; charset=utf-8", "http-equiv" => "Content-Type" }
- %meta{ content: "width=device-width, initial-scale=1", name: "viewport" }
- %link{ href: "https://fonts.googleapis.com/css?family=Source+Sans+Pro:400,600", rel: "stylesheet", type: "text/css", data: { premailer: 'ignore' } }
- %title= message.subject
- :css
- /* CLIENT-SPECIFIC STYLES */
- body,
- table,
- td,
- a {
- -webkit-text-size-adjust: 100%;
- -ms-text-size-adjust: 100%;
- }
-
- table,
- td {
- mso-table-lspace: 0pt;
- mso-table-rspace: 0pt;
- }
-
- img {
- -ms-interpolation-mode: bicubic;
- }
-
- /* RESET STYLES */
- img {
- border: 0;
- height: auto;
- line-height: 100%;
- outline: none;
- text-decoration: none;
- }
-
- table {
- border-collapse: collapse !important;
- }
-
- body {
- height: 100% !important;
- margin: 0 !important;
- padding: 0 !important;
- width: 100% !important;
- background-color: #ffffff;
- color: #424242;
- }
-
- a {
- color: #6b4fbb;
- text-decoration: underline;
- }
-
- .cta_link a {
- font-size: 24px;
- font-family: 'Source Sans Pro', helvetica, arial, sans-serif;
- color: #ffffff;
- text-decoration: none;
- border-radius: 5px;
- -webkit-border-radius: 5px;
- background-color: #6e49cb;
- border-top: 15px solid #6e49cb;
- border-bottom: 15px solid #6e49cb;
- border-right: 40px solid #6e49cb;
- border-left: 40px solid #6e49cb;
- display: inline-block;
- }
-
- .footernav {
- display: inline !important;
- }
-
- .footernav a {
- color: #6e49cb;
- }
-
- .address {
- margin: 0;
- font-size: 16px;
- line-height: 26px;
- }
-
- :css
- /* iOS BLUE LINKS */
- a[x-apple-data-detectors] {
- color: inherit !important;
- text-decoration: none !important;
- font-size: inherit !important;
- font-family: inherit !important;
- font-weight: inherit !important;
- line-height: inherit !important;
- }
- /[if gte mso 9]
- <xml>
- <o:OfficeDocumentSettings>
- <o:AllowPNG/>
- <o:PixelsPerInch>96</o:PixelsPerInch>
- </o:OfficeDocumentSettings>
- </xml>
- /[if (mso)|(mso 16)]
- <style type="text/css">
- body, table, td, a, span { font-family: Arial, Helvetica, sans-serif !important; }
- </style>
- :css
- @media only screen and (max-width: 595px) {
-
- .wrapper {
- width: 100% !important;
- margin: 0 auto !important;
- padding: 0 !important;
- }
-
- p,
- li {
- font-size: 18px !important;
- line-height: 26px !important;
- }
-
- .stack {
- width: 100% !important;
- }
-
- .stack-mobile-padding {
- width: 100% !important;
- margin-top: 20px !important;
- }
-
- .callout {
- padding-bottom: 20px !important;
- }
-
- .redbutton {
- text-align: center;
- }
-
- .stack33 {
- display: block !important;
- width: 100% !important;
- max-width: 100% !important;
- direction: ltr !important;
- text-align: center !important;
- }
- }
-
- @media only screen and (max-width: 480px) {
- u~div {
- width: 100vw !important;
- }
-
- div>u~div {
- width: 100% !important;
- }
- }
- %body#body{ width: "100%" }
- %table{ border: "0", cellpadding: "0", cellspacing: "0", role: "presentation", width: "100%" }
- %tr
- %td{ align: "center", style: "padding: 0px;" }
- %table.wrapper{ border: "0", cellpadding: "0", cellspacing: "0", role: "presentation", width: "600" }
- %tr
- %td{ style: "padding: 0px;" }
- #main-story.mktEditable{ mktoname: "main-story" }
- %table{ border: "0", cellpadding: "0", cellspacing: "0", role: "presentation", width: "100%" }
- %tr
- %td{ align: "left", style: "padding: 0 20px;" }
- = about_link('mailers/in_product_marketing/gitlab-logo-gray-rgb.png', 200)
- %tr
- %td{ "aria-hidden" => "true", height: "30", style: "font-size: 0; line-height: 0;" }
- - if @message.series?
- %tr{ style: "background-color: #ffffff;" }
- %td{ style: "color: #424242; padding: 10px 30px; text-align: center; font-family: 'Source Sans Pro', helvetica, arial, sans-serif;font-size: 16px; line-height: 22px; border: 1px solid #dddddd" }
- %p
- = @message.progress.html_safe
- %tr
- %td{ bgcolor: "#ffffff", height: "auto", style: "max-width: 600px; width: 100%; text-align: center; height: 200px; padding: 25px 15px; mso-line-height-rule: exactly; min-height: 40px; font-family: 'Source Sans Pro', helvetica, arial, sans-serif;", valign: "middle", width: "100%" }
- = inline_image_link(@message.logo_path, { width: '150', style: 'width: 150px;' })
- %h1{ style: "font-size: 40px; line-height: 46x; color: #000000; padding: 20px 0 0 0; font-weight: normal;" }
- = @message.title
- %h2{ style: "font-size: 28px; line-height: 34px; color: #000000; padding: 0; font-weight: 400;" }
- = @message.subtitle
- %tr
- %td{ style: "padding: 10px 20px 30px 20px; font-family: 'Source Sans Pro', helvetica, arial, sans-serif; color:#000000; font-size: 18px; line-height: 24px;" }
- %p{ style: "margin: 0 0 20px 0;" }
- = @message.body_line1.html_safe
- - @message.body_line2&.tap do |line|
- %p{ style: "margin: 0 0 20px 0;" }
- = line.html_safe
- - if @message.cta_text
- %tr
- %td{ align: "center", style: "padding: 10px 20px 80px 20px; font-family: 'Source Sans Pro', helvetica, arial, sans-serif;" }
- .cta_link= @message.cta_link
- - else
- %tr
- %td{ style: "padding: 10px 20px 10px 20px; font-family: 'Source Sans Pro', helvetica, arial, sans-serif; color:#000000; font-size: 16px; line-height: 20px;" }
- %table{ border: "0", cellpadding: "0", cellspacing: "0", width: "100%", style: "width: 100%; min-width: 100%;" }
- %tr
- %td{ width: "50%", style: "width: 50%; min-width: 50%; color: #000000; font-family: 'Source Sans Pro', helvetica, arial, sans-serif; font-size: 16px; line-height: 100%; padding-bottom: 16px; text-align: left;", align: "left" }
- = @message.feedback_ratings(1)
- %td{ width: "50%", style: "width: 50%; min-width: 50%; color: #000000; font-family: 'Source Sans Pro', helvetica, arial, sans-serif; font-size: 16px; line-height: 100%; padding-bottom: 16px; text-align: right;", align: "right" }
- = @message.feedback_ratings(5)
- %tr
- %td{ align: "center", style: "padding: 10px 1px 30px 1px;" }
- %table{ align: "center", cellpadding: "5", cellspacing: "0", width: "100%", style: "width: 100%; min-width: 100%; border: 1px solid #dae0ea; border-radius: 0; min-width: 100%; text-align: center; font-family: 'Source Sans Pro', helvetica, arial, sans-serif; font-size: 16px;" }
- %tr
- - (1..5).each do |rating|
- %td{ height: "54", style: "border-left: 1px solid #dae0ea; padding-bottom: 0; width: 9% !important;", width: "9%" }
- %a{ href: @message.feedback_link(rating), style: "color: #424242; display: block; text-decoration: none;" }
- %span{ height: "54", style: "display: block; font-size: 18px; height: 22px; line-height: 22px; padding: 16px 0; width: 100%; text-decoration: none;" }
- = rating
- %tr
- %td{ style: "padding: 10px 20px 30px 20px; font-family: 'Source Sans Pro', helvetica, arial, sans-serif; color:#000000; font-size: 18px; line-height: 24px;" }
- %p{ style: "margin: 0 0 50px 0;" }
- = @message.feedback_thanks
- - if @message.invite_members?
- %tr
- %td{ align: "center", style: "padding: 0 20px 80px 20px; font-family: 'Source Sans Pro', helvetica, arial, sans-serif;" }
- = @message.invite_text
- %br
- = @message.invite_link
- %tr{ style: "background-color: #ffffff;" }
- %td{ align: "center", style: "padding:75px 20px 25px;" }
- = about_link('gitlab_logo.png', 80)
- %tr{ style: "background-color: #ffffff;" }
- %td{ align: "center", style: "padding:0px ;" }
- %tr{ style: "background-color: #ffffff;" }
- %td{ align: "center", style: "padding:0px 10px; font-family: 'Source Sans Pro', helvetica, arial, sans-serif; " }
- %span.footernav{ style: "color: #6e49cb; font-size: 16px; line-height: 26px; font-family: 'Source Sans Pro', helvetica, arial, sans-serif;" }
- = @message.footer_links.join('&nbsp;' * 3 + '|' + '&nbsp;' * 4).html_safe
- %tr{ style: "background-color:#ffffff;" }
- %td{ align: "center", style: "padding: 40px 30px 20px 30px; font-family: 'Source Sans Pro', helvetica, arial, sans-serif;" }
- .address= @message.address
- %tr{ style: "background-color: #ffffff;" }
- %td{ align: "left", style: "padding:20px 30px 20px 30px;" }
- %span.footernav{ style: "color: #6e49cb; font-size: 14px; line-height: 20px; font-family: 'Source Sans Pro', helvetica, arial, sans-serif; color:#424242;" }
- = @message.unsubscribe.html_safe
+- if @message.series?
+ %tr{ style: "background-color: #ffffff;" }
+ %td{ style: "color: #424242; padding: 10px 30px; text-align: center; font-family: 'Source Sans Pro', helvetica, arial, sans-serif;font-size: 16px; line-height: 22px; border: 1px solid #dddddd" }
+ %p
+ = @message.progress.html_safe
+%tr
+ %td{ bgcolor: "#ffffff", height: "auto", style: "max-width: 600px; width: 100%; text-align: center; height: 200px; padding: 25px 15px; mso-line-height-rule: exactly; min-height: 40px; font-family: 'Source Sans Pro', helvetica, arial, sans-serif;", valign: "middle", width: "100%" }
+ = inline_image_link(@message.logo_path, { width: '150', style: 'width: 150px;' })
+ %h1{ style: "font-size: 40px; line-height: 46x; color: #000000; padding: 20px 0 0 0; font-weight: normal;" }
+ = @message.title
+ %h2{ style: "font-size: 28px; line-height: 34px; color: #000000; padding: 0; font-weight: 400;" }
+ = @message.subtitle
+%tr
+ %td{ style: "padding: 10px 20px 30px 20px; font-family: 'Source Sans Pro', helvetica, arial, sans-serif; color:#000000; font-size: 18px; line-height: 24px;" }
+ %p{ style: "margin: 0 0 20px 0;" }
+ = @message.body_line1.html_safe
+ - @message.body_line2&.tap do |line|
+ %p{ style: "margin: 0 0 20px 0;" }
+ = line.html_safe
+- if @message.cta_text
+ %tr
+ %td{ align: "center", style: "padding: 10px 20px 80px 20px; font-family: 'Source Sans Pro', helvetica, arial, sans-serif;" }
+ .cta_link.cta_link_primary= @message.cta_link
+- else
+ %tr
+ %td{ style: "padding: 10px 20px 10px 20px; font-family: 'Source Sans Pro', helvetica, arial, sans-serif; color:#000000; font-size: 16px; line-height: 20px;" }
+ %table{ border: "0", cellpadding: "0", cellspacing: "0", width: "100%", style: "width: 100%; min-width: 100%;" }
+ %tr
+ %td{ width: "50%", style: "width: 50%; min-width: 50%; color: #000000; font-family: 'Source Sans Pro', helvetica, arial, sans-serif; font-size: 16px; line-height: 100%; padding-bottom: 16px; text-align: left;", align: "left" }
+ = @message.feedback_ratings(1)
+ %td{ width: "50%", style: "width: 50%; min-width: 50%; color: #000000; font-family: 'Source Sans Pro', helvetica, arial, sans-serif; font-size: 16px; line-height: 100%; padding-bottom: 16px; text-align: right;", align: "right" }
+ = @message.feedback_ratings(5)
+ %tr
+ %td{ align: "center", style: "padding: 10px 1px 30px 1px;" }
+ %table{ align: "center", cellpadding: "5", cellspacing: "0", width: "100%", style: "width: 100%; min-width: 100%; border: 1px solid #dae0ea; border-radius: 0; min-width: 100%; text-align: center; font-family: 'Source Sans Pro', helvetica, arial, sans-serif; font-size: 16px;" }
+ %tr
+ - (1..5).each do |rating|
+ %td{ height: "54", style: "border-left: 1px solid #dae0ea; padding-bottom: 0; width: 9% !important;", width: "9%" }
+ %a{ href: @message.feedback_link(rating), style: "color: #424242; display: block; text-decoration: none;" }
+ %span{ height: "54", style: "display: block; font-size: 18px; height: 22px; line-height: 22px; padding: 16px 0; width: 100%; text-decoration: none;" }
+ = rating
+ %tr
+ %td{ style: "padding: 10px 20px 30px 20px; font-family: 'Source Sans Pro', helvetica, arial, sans-serif; color:#000000; font-size: 18px; line-height: 24px;" }
+ %p{ style: "margin: 0 0 50px 0;" }
+ = @message.feedback_thanks
+- if @message.invite_members?
+ %tr
+ %td{ align: "center", style: "padding: 0 20px 80px 20px; font-family: 'Source Sans Pro', helvetica, arial, sans-serif;" }
+ = @message.invite_text
+ %br
+ = @message.invite_link
diff --git a/app/views/notify/issue_due_email.html.haml b/app/views/notify/issue_due_email.html.haml
index adb9da05694..c9cd9c32b54 100644
--- a/app/views/notify/issue_due_email.html.haml
+++ b/app/views/notify/issue_due_email.html.haml
@@ -9,4 +9,4 @@
- if @issue.description
%div
- = markdown(@issue.description, pipeline: :email, author: @issue.author)
+ = markdown(@issue.description, pipeline: :email, author: @issue.author, current_user: @recipient, issuable_reference_expansion_enabled: true)
diff --git a/app/views/notify/member_invited_email.html.haml b/app/views/notify/member_invited_email.html.haml
index 1d1f696e1b2..6d5207510da 100644
--- a/app/views/notify/member_invited_email.html.haml
+++ b/app/views/notify/member_invited_email.html.haml
@@ -6,17 +6,15 @@
role: member.human_access.downcase }
- join_text = s_('InviteEmail|Join now')
- inviter_name = member.created_by.name if member.created_by
+- join_url = invite_url(@token, invite_type: Emails::Members::INITIAL_INVITE)
-- 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, invited_join_url(@token, member))
+= 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 }
@@ -32,7 +30,7 @@
- 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, invited_join_url(@token, member), class: 'invite-btn-join'
+ = link_to join_text, join_url, class: 'invite-btn-join'
%tr.border-top
%td.text-content.mailer-align-left.half-width
%h4
diff --git a/app/views/notify/new_issue_email.html.haml b/app/views/notify/new_issue_email.html.haml
index 3219ee34736..439604a950a 100644
--- a/app/views/notify/new_issue_email.html.haml
+++ b/app/views/notify/new_issue_email.html.haml
@@ -8,4 +8,4 @@
- if @issue.description
%div
- = markdown(@issue.description, pipeline: :email, author: @issue.author)
+ = markdown(@issue.description, pipeline: :email, author: @issue.author, current_user: @recipient, issuable_reference_expansion_enabled: true)
diff --git a/app/views/notify/new_merge_request_email.html.haml b/app/views/notify/new_merge_request_email.html.haml
index c8a0a6591a6..54fb6573c26 100644
--- a/app/views/notify/new_merge_request_email.html.haml
+++ b/app/views/notify/new_merge_request_email.html.haml
@@ -16,4 +16,4 @@
- if @merge_request.description
%div
- = markdown(@merge_request.description, pipeline: :email, author: @merge_request.author)
+ = markdown(@merge_request.description, pipeline: :email, author: @merge_request.author, current_user: @recipient, issuable_reference_expansion_enabled: true)
diff --git a/app/views/notify/new_release_email.html.haml b/app/views/notify/new_release_email.html.haml
index 9cef4cd85cd..1cd3a2340c6 100644
--- a/app/views/notify/new_release_email.html.haml
+++ b/app/views/notify/new_release_email.html.haml
@@ -15,4 +15,4 @@
%p
%h4= _("Release notes:")
- = markdown(@release.description, pipeline: :email, author: @release.author)
+ = markdown(@release.description, pipeline: :email, author: @release.author, current_user: @recipient)
diff --git a/app/views/notify/service_desk_new_note_email.html.haml b/app/views/notify/service_desk_new_note_email.html.haml
index 824b4ab712e..186bdf133e3 100644
--- a/app/views/notify/service_desk_new_note_email.html.haml
+++ b/app/views/notify/service_desk_new_note_email.html.haml
@@ -2,4 +2,4 @@
%div
= _("%{author_link} wrote:").html_safe % { author_link: link_to(@note.author_name, user_url(@note.author)) }
%div
- = markdown(@note.note, pipeline: :email, author: @note.author)
+ = markdown(@note.note, pipeline: :email, author: @note.author, issuable_reference_expansion_enabled: true)
diff --git a/app/views/profiles/accounts/_providers.html.haml b/app/views/profiles/accounts/_providers.html.haml
index 5c0044ed825..73a437a0702 100644
--- a/app/views/profiles/accounts/_providers.html.haml
+++ b/app/views/profiles/accounts/_providers.html.haml
@@ -6,11 +6,13 @@
- providers.each do |provider|
- unlink_allowed = unlink_provider_allowed?(provider)
- link_allowed = link_provider_allowed?(provider)
+ - has_icon = provider_has_icon?(provider)
- if unlink_allowed || link_allowed
- if auth_active?(provider)
- if unlink_allowed
= link_to unlink_profile_account_path(provider: provider), method: :delete, class: button_class do
- .social-provider-btn-image.gl-button-icon= provider_image_tag(provider)
+ - if has_icon
+ .social-provider-btn-image.gl-button-icon= provider_image_tag(provider)
.gl-button-text
= s_('Profiles|Disconnect %{provider}') % { provider: label_for_provider(provider) }
- else
@@ -19,7 +21,8 @@
= s_('Profiles|%{provider} Active') % { provider: label_for_provider(provider) }
- elsif link_allowed
= link_to omniauth_authorize_path(:user, provider), method: :post, class: button_class do
- .social-provider-btn-image.gl-button-icon= provider_image_tag(provider)
+ - if has_icon
+ .social-provider-btn-image.gl-button-icon= provider_image_tag(provider)
.gl-button-text
= s_('Profiles|Connect %{provider}') % { provider: label_for_provider(provider) }
= render_if_exists 'profiles/accounts/group_saml_unlink_buttons', group_saml_identities: group_saml_identities
diff --git a/app/views/profiles/keys/_form.html.haml b/app/views/profiles/keys/_form.html.haml
index 74b48115d0e..2b3109225a8 100644
--- a/app/views/profiles/keys/_form.html.haml
+++ b/app/views/profiles/keys/_form.html.haml
@@ -1,3 +1,4 @@
+- max_date = ::Gitlab::CurrentSettings.max_ssh_key_lifetime_from_now.to_date if ssh_key_expiration_policy_enabled?
%div
= form_for [:profile, @key], html: { class: 'js-requires-input' } do |f|
= form_errors(@key)
@@ -13,8 +14,8 @@
%p.form-text.text-muted= s_('Profiles|Give your individual key a title. This will be publicly visible.')
.col.form-group
- = f.label :expires_at, s_('Profiles|Expires at'), class: 'label-bold'
- = f.date_field :expires_at, class: "form-control input-lg", min: Date.tomorrow, data: { qa_selector: 'key_expiry_date_field' }
+ = f.label :expires_at, s_('Profiles|Expiration date'), class: 'label-bold'
+ = f.date_field :expires_at, class: "form-control input-lg", min: Date.tomorrow, max: max_date, data: { qa_selector: 'key_expiry_date_field' }
%p.form-text.text-muted{ data: { qa_selector: 'key_expiry_date_field_description' } }= ssh_key_expires_field_description
.js-add-ssh-key-validation-warning.hide
diff --git a/app/views/profiles/notifications/_group_settings.html.haml b/app/views/profiles/notifications/_group_settings.html.haml
index 82083af9ff1..23fce8e04b6 100644
--- a/app/views/profiles/notifications/_group_settings.html.haml
+++ b/app/views/profiles/notifications/_group_settings.html.haml
@@ -13,5 +13,5 @@
.js-vue-notification-dropdown{ data: { disabled: emails_disabled.to_s, dropdown_items: notification_dropdown_items(setting).to_json, notification_level: setting.level, group_id: group.id, container_class: 'gl-mr-3', show_label: "true" } }
.table-section.section-30
- = form_for setting, url: profile_notifications_group_path(group), method: :put, html: { class: 'update-notifications gl-display-flex' } do |f|
+ = form_for setting, url: profile_group_notifications_path(group), method: :put, html: { class: 'update-notifications gl-display-flex' } do |f|
= f.select :notification_email, @user.public_verified_emails, { include_blank: 'Global notification email' }, class: 'select2 js-group-notification-email'
diff --git a/app/views/profiles/personal_access_tokens/index.html.haml b/app/views/profiles/personal_access_tokens/index.html.haml
index 7c1f28345fd..a8275576327 100644
--- a/app/views/profiles/personal_access_tokens/index.html.haml
+++ b/app/views/profiles/personal_access_tokens/index.html.haml
@@ -32,62 +32,64 @@
type_plural: type_plural,
active_tokens: @active_personal_access_tokens,
revoke_route_helper: ->(token) { revoke_profile_personal_access_token_path(token) }
+- if Feature.enabled?(:hide_access_tokens, default_enabled: :yaml)
+ #js-tokens-app{ data: { tokens_data: tokens_app_data } }
+- else
+ - unless Gitlab::CurrentSettings.disable_feed_token
+ .col-lg-12
+ %hr
+ .row.gl-mt-3.js-search-settings-section
+ .col-lg-4.profile-settings-sidebar
+ %h4.gl-mt-0
+ = s_('AccessTokens|Feed token')
+ %p
+ = s_('AccessTokens|Your feed token authenticates you when your RSS reader loads a personalized RSS feed or when your calendar application loads a personalized calendar. It is visible in those feed URLs.')
+ %p
+ = s_('AccessTokens|It cannot be used to access any other data.')
+ .col-lg-8.feed-token-reset
+ = label_tag :feed_token, s_('AccessTokens|Feed token'), class: 'label-bold'
+ = text_field_tag :feed_token, current_user.feed_token, class: 'form-control gl-form-input js-select-on-focus', readonly: true
+ %p.form-text.text-muted
+ - reset_link = link_to s_('AccessTokens|reset this token'), [:reset, :feed_token, :profile], method: :put, data: { confirm: s_('AccessTokens|Are you sure? Any RSS or calendar URLs currently in use will stop working.'), testid: :reset_feed_token_link }
+ - reset_message = s_('AccessTokens|Keep this token secret. Anyone who has it can read activity and issue RSS feeds or your calendar feed as if they were you. If that happens, %{link_reset_it}.') % { link_reset_it: reset_link }
+ = reset_message.html_safe
-- unless Gitlab::CurrentSettings.disable_feed_token
- .col-lg-12
- %hr
- .row.gl-mt-3.js-search-settings-section
- .col-lg-4.profile-settings-sidebar
- %h4.gl-mt-0
- = s_('AccessTokens|Feed token')
- %p
- = s_('AccessTokens|Your feed token authenticates you when your RSS reader loads a personalized RSS feed or when your calendar application loads a personalized calendar. It is visible in those feed URLs.')
- %p
- = s_('AccessTokens|It cannot be used to access any other data.')
- .col-lg-8.feed-token-reset
- = label_tag :feed_token, s_('AccessTokens|Feed token'), class: 'label-bold'
- = text_field_tag :feed_token, current_user.feed_token, class: 'form-control gl-form-input js-select-on-focus', readonly: true
- %p.form-text.text-muted
- - reset_link = link_to s_('AccessTokens|reset this token'), [:reset, :feed_token, :profile], method: :put, data: { confirm: s_('AccessTokens|Are you sure? Any RSS or calendar URLs currently in use will stop working.'), testid: :reset_feed_token_link }
- - reset_message = s_('AccessTokens|Keep this token secret. Anyone who has it can read activity and issue RSS feeds or your calendar feed as if they were you. If that happens, %{link_reset_it}.') % { link_reset_it: reset_link }
- = reset_message.html_safe
+ - if incoming_email_token_enabled?
+ .col-lg-12
+ %hr
+ .row.gl-mt-3.js-search-settings-section
+ .col-lg-4.profile-settings-sidebar
+ %h4.gl-mt-0
+ = s_('AccessTokens|Incoming email token')
+ %p
+ = s_('AccessTokens|Your incoming email token authenticates you when you create a new issue by email, and is included in your personal project-specific email addresses.')
+ %p
+ = s_('AccessTokens|It cannot be used to access any other data.')
+ .col-lg-8.incoming-email-token-reset
+ = label_tag :incoming_email_token, s_('AccessTokens|Incoming email token'), class: 'label-bold'
+ = text_field_tag :incoming_email_token, current_user.incoming_email_token, class: 'form-control gl-form-input js-select-on-focus', readonly: true
+ %p.form-text.text-muted
+ - reset_link = link_to s_('AccessTokens|reset this token'), [:reset, :incoming_email_token, :profile], method: :put, data: { confirm: s_('AccessTokens|Are you sure? Any issue email addresses currently in use will stop working.'), testid: :reset_email_token_link }
+ - reset_message = s_('AccessTokens|Keep this token secret. Anyone who has it can create issues as if they were you. If that happens, %{link_reset_it}.') % { link_reset_it: reset_link }
+ = reset_message.html_safe
-- if incoming_email_token_enabled?
- .col-lg-12
- %hr
- .row.gl-mt-3.js-search-settings-section
- .col-lg-4.profile-settings-sidebar
- %h4.gl-mt-0
- = s_('AccessTokens|Incoming email token')
- %p
- = s_('AccessTokens|Your incoming email token authenticates you when you create a new issue by email, and is included in your personal project-specific email addresses.')
- %p
- = s_('AccessTokens|It cannot be used to access any other data.')
- .col-lg-8.incoming-email-token-reset
- = label_tag :incoming_email_token, s_('AccessTokens|Incoming email token'), class: 'label-bold'
- = text_field_tag :incoming_email_token, current_user.incoming_email_token, class: 'form-control gl-form-input js-select-on-focus', readonly: true
- %p.form-text.text-muted
- - reset_link = link_to s_('AccessTokens|reset this token'), [:reset, :incoming_email_token, :profile], method: :put, data: { confirm: s_('AccessTokens|Are you sure? Any issue email addresses currently in use will stop working.'), testid: :reset_email_token_link }
- - reset_message = s_('AccessTokens|Keep this token secret. Anyone who has it can create issues as if they were you. If that happens, %{link_reset_it}.') % { link_reset_it: reset_link }
- = reset_message.html_safe
-
-- if static_objects_external_storage_enabled?
- .col-lg-12
- %hr
- .row.gl-mt-3.js-search-settings-section
- .col-lg-4
- %h4.gl-mt-0
- = s_('AccessTokens|Static object token')
- %p
- = s_('AccessTokens|Your static object token authenticates you when repository static objects (such as archives or blobs) are served from an external storage.')
- %p
- = s_('AccessTokens|It cannot be used to access any other data.')
- .col-lg-8
- = label_tag :static_object_token, s_('AccessTokens|Static object token'), class: "label-bold"
- = text_field_tag :static_object_token, current_user.static_object_token, class: 'form-control gl-form-input', readonly: true, onclick: 'this.select()'
- %p.form-text.text-muted
- - reset_link = url_for [:reset, :static_object_token, :profile]
- - reset_link_start = '<a data-confirm="%{confirm}" rel="nofollow" data-method="put" href="%{url}">'.html_safe % { confirm: s_('AccessTokens|Are you sure?'), url: reset_link }
- - reset_link_end = '</a>'.html_safe
- - reset_message = s_('AccessTokens|Keep this token secret. Anyone who has it can access repository static objects as if they were you. If that ever happens, %{reset_link_start}reset this token%{reset_link_end}.') % { reset_link_start: reset_link_start, reset_link_end: reset_link_end }
- = reset_message.html_safe
+ - if static_objects_external_storage_enabled?
+ .col-lg-12
+ %hr
+ .row.gl-mt-3.js-search-settings-section
+ .col-lg-4
+ %h4.gl-mt-0
+ = s_('AccessTokens|Static object token')
+ %p
+ = s_('AccessTokens|Your static object token authenticates you when repository static objects (such as archives or blobs) are served from an external storage.')
+ %p
+ = s_('AccessTokens|It cannot be used to access any other data.')
+ .col-lg-8
+ = label_tag :static_object_token, s_('AccessTokens|Static object token'), class: "label-bold"
+ = text_field_tag :static_object_token, current_user.static_object_token, class: 'form-control gl-form-input', readonly: true, onclick: 'this.select()'
+ %p.form-text.text-muted
+ - reset_link = url_for [:reset, :static_object_token, :profile]
+ - reset_link_start = '<a data-confirm="%{confirm}" rel="nofollow" data-method="put" href="%{url}">'.html_safe % { confirm: s_('AccessTokens|Are you sure?'), url: reset_link }
+ - reset_link_end = '</a>'.html_safe
+ - reset_message = s_('AccessTokens|Keep this token secret. Anyone who has it can access repository static objects as if they were you. If that ever happens, %{reset_link_start}reset this token%{reset_link_end}.') % { reset_link_start: reset_link_start, reset_link_end: reset_link_end }
+ = reset_message.html_safe
diff --git a/app/views/profiles/show.html.haml b/app/views/profiles/show.html.haml
index b1470520eea..f3993ad8c33 100644
--- a/app/views/profiles/show.html.haml
+++ b/app/views/profiles/show.html.haml
@@ -116,7 +116,7 @@
%h5= _('Private profile')
.checkbox-icon-inline-wrapper
- private_profile_label = capture do
- = s_("Profiles|Don't display activity-related personal information on your profiles")
+ = s_("Profiles|Don't display activity-related personal information on your profile")
= f.check_box :private_profile, label: private_profile_label, inline: true, wrapper_class: 'mr-0'
= link_to sprite_icon('question-o'), help_page_path('user/profile/index.md', anchor: 'make-your-user-profile-page-private')
%h5= s_("Profiles|Private contributions")
diff --git a/app/views/profiles/two_factor_auths/show.html.haml b/app/views/profiles/two_factor_auths/show.html.haml
index 0eae3c95bf6..aae6212f964 100644
--- a/app/views/profiles/two_factor_auths/show.html.haml
+++ b/app/views/profiles/two_factor_auths/show.html.haml
@@ -2,7 +2,7 @@
- page_title _('Two-Factor Authentication'), _('Account')
- add_to_breadcrumbs _('Account'), profile_account_path
- @content_class = "limit-container-width" unless fluid_layout
-- webauthn_enabled = Feature.enabled?(:webauthn)
+- webauthn_enabled = Feature.enabled?(:webauthn, default_enabled: :yaml)
.js-two-factor-auth{ 'data-two-factor-skippable' => "#{two_factor_skippable?}", 'data-two_factor_skip_url' => skip_profile_two_factor_auth_path }
.row.gl-mt-3
diff --git a/app/views/projects/_files.html.haml b/app/views/projects/_files.html.haml
index cdcc98552f9..2f4a61865f8 100644
--- a/app/views/projects/_files.html.haml
+++ b/app/views/projects/_files.html.haml
@@ -10,10 +10,11 @@
.nav-block.gl-display-flex.gl-xs-flex-direction-column.gl-align-items-stretch
= render 'projects/tree/tree_header', tree: @tree
- #js-last-commit
- .info-well.gl-display-none.gl-sm-display-flex.project-last-commit
+ .info-well.gl-display-none.gl-sm-display-flex.project-last-commit.gl-flex-direction-column
+ #js-last-commit.gl-m-auto
.gl-spinner-container.m-auto
= loading_icon(size: 'md', color: 'dark', css_class: 'align-text-bottom')
+ #js-code-owners
- if is_project_overview
.project-buttons.gl-mb-3.js-show-on-project-root
diff --git a/app/views/projects/_invite_members_side_nav_link.html.haml b/app/views/projects/_invite_members_side_nav_link.html.haml
index ea6174d19f0..fae681b1a71 100644
--- a/app/views/projects/_invite_members_side_nav_link.html.haml
+++ b/app/views/projects/_invite_members_side_nav_link.html.haml
@@ -1,5 +1,4 @@
.js-invite-members-trigger{ data: { trigger_source: 'project-side-nav',
- classes: 'gl-text-decoration-none! gl-shadow-none! gl-text-body!',
icon: 'users',
display_text: title,
trigger_element: 'side-nav'} }
diff --git a/app/views/projects/_merge_request_merge_commit_template.html.haml b/app/views/projects/_merge_request_merge_commit_template.html.haml
index 185b730e0bb..869d2d5d9ec 100644
--- a/app/views/projects/_merge_request_merge_commit_template.html.haml
+++ b/app/views/projects/_merge_request_merge_commit_template.html.haml
@@ -3,7 +3,7 @@
.form-group
%b= s_('ProjectSettings|Merge commit message template')
%p.text-secondary
- - configure_the_merge_commit_message_help_link_url = help_page_path('user/project/merge_requests/commit_templates.md', anchor: 'merge-commit-message-template')
+ - configure_the_merge_commit_message_help_link_url = help_page_path('user/project/merge_requests/commit_templates.md')
- configure_the_merge_commit_message_help_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: configure_the_merge_commit_message_help_link_url }
= s_('ProjectSettings|The commit message used when merging, if the merge method creates a merge commit. %{link_start}Learn more about syntax and variables.%{link_end}').html_safe % { link_start: configure_the_merge_commit_message_help_link_start, link_end: '</a>'.html_safe }
.mb-2
@@ -12,6 +12,6 @@
%p.form-text.text-muted
= s_('ProjectSettings|Maximum 500 characters.')
= s_('ProjectSettings|Supported variables:')
- - Gitlab::MergeRequests::MergeCommitMessage::PLACEHOLDERS.keys.each do |placeholder|
+ - Gitlab::MergeRequests::CommitMessageGenerator::PLACEHOLDERS.keys.each do |placeholder|
%code
= "%{#{placeholder}}".html_safe
diff --git a/app/views/projects/_merge_request_settings.html.haml b/app/views/projects/_merge_request_settings.html.haml
index c5a25bec6eb..728ff597860 100644
--- a/app/views/projects/_merge_request_settings.html.haml
+++ b/app/views/projects/_merge_request_settings.html.haml
@@ -12,5 +12,7 @@
= render 'projects/merge_request_merge_commit_template', project: @project, form: form
+= render 'projects/merge_request_squash_commit_template', project: @project, form: form
+
- if @project.forked?
= render 'projects/merge_request_target_project_settings', project: @project, form: form
diff --git a/app/views/projects/_merge_request_squash_commit_template.html.haml b/app/views/projects/_merge_request_squash_commit_template.html.haml
new file mode 100644
index 00000000000..81e4bbed166
--- /dev/null
+++ b/app/views/projects/_merge_request_squash_commit_template.html.haml
@@ -0,0 +1,16 @@
+- form = local_assigns.fetch(:form)
+
+.form-group
+ %b= s_('ProjectSettings|Squash commit message template')
+ %p.text-secondary
+ - configure_the_squash_commit_message_help_link_url = help_page_path('user/project/merge_requests/commit_templates.md')
+ - configure_the_squash_commit_message_help_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: configure_the_squash_commit_message_help_link_url }
+ = s_('ProjectSettings|The commit message used when squashing commits. %{link_start}Learn more about syntax and variables.%{link_end}').html_safe % { link_start: configure_the_squash_commit_message_help_link_start, link_end: '</a>'.html_safe }
+ .mb-2
+ = form.text_area :squash_commit_template, class: 'form-control gl-form-input', rows: 8, maxlength: 500, placeholder: '%{title}'
+ %p.form-text.text-muted
+ = s_('ProjectSettings|Maximum 500 characters.')
+ = s_('ProjectSettings|Supported variables:')
+ - Gitlab::MergeRequests::CommitMessageGenerator::PLACEHOLDERS.keys.each do |placeholder|
+ %code
+ = "%{#{placeholder}}".html_safe
diff --git a/app/views/projects/_new_project_fields.html.haml b/app/views/projects/_new_project_fields.html.haml
index c21240b340c..6fc78003df4 100644
--- a/app/views/projects/_new_project_fields.html.haml
+++ b/app/views/projects/_new_project_fields.html.haml
@@ -49,7 +49,7 @@
.gl-alert.gl-alert-success.gl-mb-4.gl-display-none.js-user-readme-repo
= sprite_icon('check-circle', size: 16, css_class: 'gl-icon gl-alert-icon gl-alert-icon-no-title')
.gl-alert-body
- - help_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: help_page_path('user/profile/index', anchor: 'user-profile-readme') }
+ - help_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: help_page_path('user/profile/index', anchor: 'add-details-to-your-profile-with-a-readme') }
= html_escape(_('%{project_path} is a project that you can use to add a README to your GitLab profile. Create a public project and initialize the repository with a README to get started. %{help_link_start}Learn more.%{help_link_end}')) % { project_path: "<strong>#{current_user.username} / #{current_user.username}</strong>".html_safe, help_link_start: help_link_start, help_link_end: '</a>'.html_safe }
.form-group
@@ -74,7 +74,7 @@
= s_('ProjectsNew|Allows you to immediately clone this project’s repository. Skip this if you plan to push up an existing repository.')
- experiment(:new_project_sast_enabled, user: current_user) do |e|
- - e.try do
+ - e.try(:candidate) do
.form-group
.form-check.gl-mb-3
= check_box_tag 'project[initialize_with_sast]', '1', true, class: 'form-check-input', data: { qa_selector: 'initialize_with_sast_checkbox', track_experiment: e.name, track_label: track_label, track_action: 'activate_form_input', track_property: 'init_with_sast' }
@@ -83,6 +83,15 @@
.form-text.text-muted
= s_('ProjectsNew|Analyze your source code for known security vulnerabilities.')
= link_to _('Learn more.'), help_page_path('user/application_security/sast/index'), target: '_blank', rel: 'noopener noreferrer', data: { track_action: 'followed', track_experiment: e.name }
+ - e.try(:unchecked_candidate) do
+ .form-group
+ .form-check.gl-mb-3
+ = check_box_tag 'project[initialize_with_sast]', '1', false, class: 'form-check-input', data: { qa_selector: 'initialize_with_sast_checkbox', track_experiment: e.name, track_label: track_label, track_action: 'activate_form_input', track_property: 'init_with_sast' }
+ = label_tag 'project[initialize_with_sast]', class: 'form-check-label' do
+ = s_('ProjectsNew|Enable Static Application Security Testing (SAST)')
+ .form-text.text-muted
+ = s_('ProjectsNew|Analyze your source code for known security vulnerabilities.')
+ = link_to _('Learn more.'), help_page_path('user/application_security/sast/index'), target: '_blank', rel: 'noopener noreferrer', data: { track_action: 'followed', track_experiment: e.name }
- e.try(:free_indicator) do
.form-group
.form-check.gl-mb-3
@@ -93,6 +102,16 @@
.form-text.text-muted
= s_('ProjectsNew|Analyze your source code for known security vulnerabilities.')
= link_to _('Learn more.'), help_page_path('user/application_security/sast/index'), target: '_blank', rel: 'noopener noreferrer', data: { track_action: 'followed', track_experiment: e.name }
+ - e.try(:unchecked_free_indicator) do
+ .form-group
+ .form-check.gl-mb-3
+ = check_box_tag 'project[initialize_with_sast]', '1', false, class: 'form-check-input', data: { qa_selector: 'initialize_with_sast_checkbox', track_experiment: e.name, track_label: track_label, track_action: 'activate_form_input', track_property: 'init_with_sast' }
+ = label_tag 'project[initialize_with_sast]', class: 'form-check-label' do
+ = s_('ProjectsNew|Enable Static Application Security Testing (SAST)')
+ %span.badge.badge-info.badge-pill.gl-badge.sm= _('Free')
+ .form-text.text-muted
+ = s_('ProjectsNew|Analyze your source code for known security vulnerabilities.')
+ = link_to _('Learn more.'), help_page_path('user/application_security/sast/index'), target: '_blank', rel: 'noopener noreferrer', data: { track_action: 'followed', track_experiment: e.name }
= f.submit _('Create project'), class: "btn gl-button btn-confirm", data: { track_label: "#{track_label}", track_action: "click_button", track_property: "create_project", track_value: "" }
= link_to _('Cancel'), dashboard_projects_path, class: 'btn gl-button btn-default btn-cancel', data: { track_label: "#{track_label}", track_action: "click_button", track_property: "cancel", track_value: "" }
diff --git a/app/views/projects/_project_templates.html.haml b/app/views/projects/_project_templates.html.haml
index 949397755ba..68489fba06c 100644
--- a/app/views/projects/_project_templates.html.haml
+++ b/app/views/projects/_project_templates.html.haml
@@ -5,7 +5,7 @@
%li.built-in-tab
%a.nav-link.active{ href: "#built-in", data: { toggle: 'tab'} }
= _('Built-in')
- %span.badge.badge-pill= Gitlab::ProjectTemplate.all.count + Gitlab::SampleDataTemplate.all.count
+ = gl_tab_counter_badge Gitlab::ProjectTemplate.all.count + Gitlab::SampleDataTemplate.all.count
.tab-content
.project-templates-buttons.import-buttons.tab-pane.active#built-in
diff --git a/app/views/projects/_remove_fork.html.haml b/app/views/projects/_remove_fork.html.haml
index 92eb29dc407..bb51aa86170 100644
--- a/app/views/projects/_remove_fork.html.haml
+++ b/app/views/projects/_remove_fork.html.haml
@@ -1,11 +1,12 @@
- return unless @project.forked? && can?(current_user, :remove_fork_project, @project)
+- remove_form_id = "js-remove-project-fork-form"
.sub-section
%h4.danger-title= _('Remove fork relationship')
%p= remove_fork_project_description_message(@project)
- = form_for @project, url: remove_fork_project_path(@project), method: :delete, remote: true, html: { class: 'transfer-project' } do |f|
+ = form_for @project, url: remove_fork_project_path(@project), method: :delete, html: { id: remove_form_id } do |f|
%p
%strong= _('Once removed, the fork relationship cannot be restored. This project will no longer be able to receive or send merge requests to the source project or other forks.')
= link_to _('Learn more.'), help_page_path('user/project/settings/index', anchor: 'removing-a-fork-relationship'), target: '_blank', rel: 'noopener noreferrer'
- = button_to _('Remove fork relationship'), '#', class: "gl-button btn btn-danger js-legacy-confirm-danger", data: { "confirm-danger-message" => remove_fork_project_warning_message(@project) }
+ .js-confirm-danger{ data: remove_fork_project_confirm_json(@project, remove_form_id) }
diff --git a/app/views/projects/_transfer.html.haml b/app/views/projects/_transfer.html.haml
index e48008e1cc6..9f9daa7ec6f 100644
--- a/app/views/projects/_transfer.html.haml
+++ b/app/views/projects/_transfer.html.haml
@@ -1,8 +1,11 @@
- return unless can?(current_user, :change_namespace, @project)
+- form_id = "transfer-project-form"
+- hidden_input_id = "new_namespace_id"
+- initial_data = { namespaces: namespaces_as_json, button_text: s_('ProjectSettings|Transfer project'), confirm_danger_message: transfer_project_message(@project), phrase: @project.name, target_form_id: form_id, target_hidden_input_id: hidden_input_id }
.sub-section
%h4.danger-title= _('Transfer project')
- = form_for @project, url: transfer_project_path(@project), method: :put, remote: true, html: { class: 'js-project-transfer-form' } do |f|
+ = form_for @project, url: transfer_project_path(@project), method: :put, html: { class: 'js-project-transfer-form', id: form_id } do |f|
.form-group
- link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: help_page_path('user/project/settings/index', anchor: 'transferring-an-existing-project-into-another-namespace') }
%p= _("Transfer your project into another namespace. %{link_start}Learn more.%{link_end}").html_safe % { link_start: link_start, link_end: '</a>'.html_safe }
@@ -11,7 +14,6 @@
%li= _('You can only transfer the project to namespaces you manage.')
%li= _('You will need to update your local repositories to point to the new location.')
%li= _('Project visibility level will be changed to match namespace rules when transferring to a group.')
+ = hidden_field_tag(hidden_input_id)
= label_tag :new_namespace_id, _('Select a new namespace'), class: 'gl-font-weight-bold'
- .form-group
- = select_tag :new_namespace_id, namespaces_options(nil), include_blank: true, class: 'select2'
- = f.submit 'Transfer project', class: "gl-button btn btn-danger js-legacy-confirm-danger qa-transfer-button", data: { "confirm-danger-message" => transfer_project_message(@project) }
+ .js-transfer-project-form{ data: initial_data }
diff --git a/app/views/projects/blame/show.html.haml b/app/views/projects/blame/show.html.haml
index 704576619a7..ae8f89bf16a 100644
--- a/app/views/projects/blame/show.html.haml
+++ b/app/views/projects/blame/show.html.haml
@@ -27,7 +27,7 @@
- commit_data = @blame.commit_data(blame_group[:commit])
- line_count = blame_group[:lines].count
- %tr
+ %tr{ style: intrinsic_row_css(line_count) }
%td.blame-commit{ class: commit_data.age_map_class }
.commit
= commit_data.author_avatar
diff --git a/app/views/projects/blob/_content.html.haml b/app/views/projects/blob/_content.html.haml
index 7afbd85cd6d..0031be36098 100644
--- a/app/views/projects/blob/_content.html.haml
+++ b/app/views/projects/blob/_content.html.haml
@@ -1,3 +1,4 @@
+- blob = local_assigns.fetch(:blob, nil)
- simple_viewer = blob.simple_viewer
- rich_viewer = blob.rich_viewer
- rich_viewer_active = rich_viewer && params[:viewer] != 'simple'
diff --git a/app/views/projects/blob/_header.html.haml b/app/views/projects/blob/_header.html.haml
index dad4ea205b4..74df53a8d15 100644
--- a/app/views/projects/blob/_header.html.haml
+++ b/app/views/projects/blob/_header.html.haml
@@ -1,4 +1,5 @@
- blame = local_assigns.fetch(:blame, false)
+- blob = local_assigns.fetch(:blob, nil)
.js-file-title.file-title-flex-parent
= render 'projects/blob/header_content', blob: blob
diff --git a/app/views/projects/blob/show.html.haml b/app/views/projects/blob/show.html.haml
index 168b240c657..d4e7ee90a84 100644
--- a/app/views/projects/blob/show.html.haml
+++ b/app/views/projects/blob/show.html.haml
@@ -14,8 +14,8 @@
- if can_modify_blob?(@blob)
= render 'projects/blob/remove'
- - title = "Replace #{@blob.name}"
- = render 'projects/blob/upload', title: title, placeholder: title, button_title: 'Replace file', form_path: project_update_blob_path(@project, @id), method: :put
+ - title = _("Replace %{blob_name}") % { blob_name: @blob.name }
+ = render 'projects/blob/upload', title: title, placeholder: title, button_title: _('Replace file'), form_path: project_update_blob_path(@project, @id), method: :put
= render partial: 'pipeline_tour_success' if show_suggest_pipeline_creation_celebration?
= render 'shared/web_ide_path'
diff --git a/app/views/projects/branches/index.html.haml b/app/views/projects/branches/index.html.haml
index 6733db69c34..1c543d47ecf 100644
--- a/app/views/projects/branches/index.html.haml
+++ b/app/views/projects/branches/index.html.haml
@@ -42,7 +42,7 @@
%ul.content-list.all-branches
- @branches.each do |branch|
= render "projects/branches/branch", branch: branch, merged: @merged_branch_names.include?(branch.name), commit_status: @branch_pipeline_statuses[branch.name], show_commit_status: @branch_pipeline_statuses.any?
- - if Feature.enabled?(:branches_pagination_without_count, @project, default_enabled: :yaml)
+ - if Feature.enabled?(:branch_list_keyset_pagination, @project, default_enabled: :yaml)
= render('kaminari/gitlab/without_count', previous_path: @prev_path, next_path: @next_path)
- else
= paginate @branches, theme: 'gitlab'
diff --git a/app/views/projects/buttons/_dropdown.html.haml b/app/views/projects/buttons/_dropdown.html.haml
deleted file mode 100644
index 12ce4667e1a..00000000000
--- a/app/views/projects/buttons/_dropdown.html.haml
+++ /dev/null
@@ -1,42 +0,0 @@
-- can_create_issue = show_new_issue_link?(@project)
-- can_create_project_snippet = can?(current_user, :create_snippet, @project)
-- can_push_code = can?(current_user, :push_code, @project)
-- create_mr_from_new_fork = can?(current_user, :fork_project, @project) && can?(current_user, :create_merge_request_in, @project)
-- merge_project = merge_request_source_project_for_project(@project)
-
-- show_menu = can_create_issue || can_create_project_snippet || can_push_code || create_mr_from_new_fork || merge_project
-
-- if show_menu
- .project-action-button.dropdown.inline<
- %a.btn.btn-default.gl-button.dropdown-toggle.has-tooltip.qa-create-new-dropdown{ href: '#', title: _('Create new...'), 'data-toggle' => 'dropdown', 'data-container' => 'body', 'aria-label' => _('Create new...'), 'data-display' => 'static' }
- = sprite_icon('plus', css_class: 'gl-icon')
- = sprite_icon("chevron-down", css_class: 'gl-icon')
- %ul.dropdown-menu.dropdown-menu-right.project-home-dropdown
- - if can_create_issue || merge_project || can_create_project_snippet
- %li.dropdown-header= _('This project')
-
- - if can_create_issue
- %li= link_to _('New issue'), new_project_issue_path(@project)
-
- - if merge_project
- %li= link_to _('New merge request'), project_new_merge_request_path(merge_project)
-
- - if can_create_project_snippet
- %li= link_to _('New snippet'), new_project_snippet_path(@project)
-
- - if can_push_code
- %li.dropdown-header= _('This repository')
-
- - if can_push_code
- %li.qa-new-file-option= link_to _('New file'), project_new_blob_path(@project, @project.default_branch_or_main)
- - unless @project.empty_repo?
- %li= link_to _('New branch'), new_project_branch_path(@project)
- %li= link_to _('New tag'), new_project_tag_path(@project)
- - elsif can_collaborate_with_project?(@project)
- %li= link_to _('New file'), project_new_blob_path(@project, @project.default_branch_or_main)
- - elsif create_mr_from_new_fork
- - continue_params = { to: project_new_blob_path(@project, @project.default_branch_or_main),
- notice: edit_in_new_fork_notice,
- notice_now: edit_in_new_fork_notice_now }
- - fork_path = project_forks_path(@project, namespace_key: current_user.namespace.id, continue: continue_params)
- %li= link_to _('New file'), fork_path, method: :post
diff --git a/app/views/projects/buttons/_fork.html.haml b/app/views/projects/buttons/_fork.html.haml
index e4ec2e44298..3cec7fd9eb8 100644
--- a/app/views/projects/buttons/_fork.html.haml
+++ b/app/views/projects/buttons/_fork.html.haml
@@ -1,16 +1,18 @@
- unless @project.empty_repo?
- - if current_user && can?(current_user, :fork_project, @project)
+ - if current_user
.count-badge.btn-group
- if current_user.already_forked?(@project) && current_user.manageable_namespaces.size < 2
= link_to namespace_project_path(current_user, current_user.fork_of(@project)), title: s_('ProjectOverview|Go to your fork'), class: 'gl-button btn btn-default btn-sm has-tooltip fork-btn' do
= sprite_icon('fork', css_class: 'icon')
%span= s_('ProjectOverview|Fork')
- else
- - can_create_fork = current_user.can?(:create_fork)
- - disabled_fork_tooltip = s_('ProjectOverview|You have reached your project limit')
- %span.btn-group.has-tooltip{ title: (disabled_fork_tooltip unless can_create_fork) }
- = link_to new_project_fork_path(@project), class: "gl-button btn btn-default btn-sm fork-btn #{' disabled' unless can_create_fork }", 'aria-label' => (disabled_fork_tooltip unless can_create_fork) do
+ - disabled_tooltip = fork_button_disabled_tooltip(@project)
+ - count_class = 'disabled' unless can?(current_user, :download_code, @project)
+ - button_class = 'disabled' if disabled_tooltip
+
+ %span.btn-group{ class: ('has-tooltip' if disabled_tooltip), title: disabled_tooltip }
+ = link_to new_project_fork_path(@project), class: "gl-button btn btn-default btn-sm fork-btn #{button_class}" do
= sprite_icon('fork', css_class: 'icon')
%span= s_('ProjectOverview|Fork')
- = link_to project_forks_path(@project), title: n_(s_('ProjectOverview|Forks'), s_('ProjectOverview|Forks'), @project.forks_count), class: 'gl-button btn btn-default btn-sm count has-tooltip' do
+ = link_to project_forks_path(@project), title: n_(s_('ProjectOverview|Forks'), s_('ProjectOverview|Forks'), @project.forks_count), class: "gl-button btn btn-default btn-sm count has-tooltip #{count_class}" do
= @project.forks_count
diff --git a/app/views/projects/ci/builds/_build.html.haml b/app/views/projects/ci/builds/_build.html.haml
index 437529c3608..c33b9b538f3 100644
--- a/app/views/projects/ci/builds/_build.html.haml
+++ b/app/views/projects/ci/builds/_build.html.haml
@@ -50,16 +50,15 @@
.label-container
- if job.tags.any?
- job.tags.each do |tag|
- %span.badge.badge-pill.gl-badge.sm.badge-primary
- = tag
+ = gl_badge_tag tag, variant: :info, size: :sm
- if job.try(:trigger_request)
- %span.badge.badge-pill.gl-badge.sm.badge-info= _('triggered')
+ = gl_badge_tag _('triggered'), variant: :info, size: :sm
- if job.try(:allow_failure) && !job.success?
- %span.badge.badge-pill.gl-badge.sm.badge-warning= _('allowed to fail')
+ = gl_badge_tag _('allowed to fail'), variant: :warning, size: :sm
- if job.schedulable?
- %span.badge.badge-pill.gl-badge.sm.badge-info= s_('DelayedJobs|delayed')
+ = gl_badge_tag s_('DelayedJobs|delayed'), variant: :info, size: :sm
- elsif job.action?
- %span.badge.badge-pill.gl-badge.sm.badge-info= _('manual')
+ = gl_badge_tag _('manual'), variant: :info, size: :sm
- if pipeline_link
%td
diff --git a/app/views/projects/commit/pipelines.html.haml b/app/views/projects/commit/pipelines.html.haml
index cd49dd899a0..a46421120cd 100644
--- a/app/views/projects/commit/pipelines.html.haml
+++ b/app/views/projects/commit/pipelines.html.haml
@@ -1,5 +1,6 @@
- page_title _('Pipelines'), "#{@commit.title} (#{@commit.short_id})", _('Commits')
- add_page_specific_style 'page_bundles/pipelines'
+- add_page_specific_style 'page_bundles/ci_status'
= render 'commit_box'
= render 'ci_menu'
diff --git a/app/views/projects/compare/index.html.haml b/app/views/projects/compare/index.html.haml
index 426d022da26..8ca41941e07 100644
--- a/app/views/projects/compare/index.html.haml
+++ b/app/views/projects/compare/index.html.haml
@@ -8,7 +8,7 @@
%code.ref-name= @project.default_branch_or_main
- example_sha = capture do
%code.ref-name 4eedf23
- = html_escape(_("Choose a branch/tag (e.g. %{branch}) or enter a commit (e.g. %{sha}) to see what's changed or to create a merge request.")) % { branch: example_branch.html_safe, sha: example_sha.html_safe }
+ = html_escape(_("To see what's changed or create a merge request, choose a branch or tag (like %{branch}), or enter a commit (like %{sha}).")) % { branch: example_branch.html_safe, sha: example_sha.html_safe }
%br
= html_escape(_("Changes are shown as if the %{b_open}source%{b_close} revision was being merged into the %{b_open}target%{b_close} revision.")) % { b_open: '<b>'.html_safe, b_close: '</b>'.html_safe }
diff --git a/app/views/projects/default_branch/_show.html.haml b/app/views/projects/default_branch/_show.html.haml
index 68ca318e88c..e5f911d6f8b 100644
--- a/app/views/projects/default_branch/_show.html.haml
+++ b/app/views/projects/default_branch/_show.html.haml
@@ -26,6 +26,6 @@
%strong= _("Auto-close referenced issues on default branch")
.form-text.text-muted
= _("When merge requests and commits in the default branch close, any issues they reference also close.")
- = link_to sprite_icon('question-o'), help_page_path('user/project/issues/managing_issues.md', anchor: 'disabling-automatic-issue-closing'), target: '_blank'
+ = link_to sprite_icon('question-o'), help_page_path('user/project/issues/managing_issues.md', anchor: 'closing-issues-automatically'), target: '_blank'
= f.submit _('Save changes'), class: "gl-button btn btn-confirm", data: { qa_selector: 'save_changes_button' }
diff --git a/app/views/projects/diffs/_content.html.haml b/app/views/projects/diffs/_content.html.haml
index 590fcdb0234..718f129cba8 100644
--- a/app/views/projects/diffs/_content.html.haml
+++ b/app/views/projects/diffs/_content.html.haml
@@ -1,2 +1,3 @@
+- diff_file = local_assigns.fetch(:diff_file, nil)
.diff-content
= render 'projects/diffs/viewer', viewer: diff_file.viewer
diff --git a/app/views/projects/diffs/_text_file.html.haml b/app/views/projects/diffs/_text_file.html.haml
index 5a7830e306a..bf946b0ce73 100644
--- a/app/views/projects/diffs/_text_file.html.haml
+++ b/app/views/projects/diffs/_text_file.html.haml
@@ -1,4 +1,4 @@
-- too_big = diff_file.diff_lines.count > Commit.diff_safe_lines(project: @project)
+- too_big = diff_file.diff_lines.count > Commit.diff_safe_max_lines
- if too_big
.suppressed-container
%a.show-suppressed-diff.cursor-pointer.js-show-suppressed-diff= _("Changes suppressed. Click to show.")
diff --git a/app/views/projects/feature_flags/new.html.haml b/app/views/projects/feature_flags/new.html.haml
index 097475d2928..9fef9864475 100644
--- a/app/views/projects/feature_flags/new.html.haml
+++ b/app/views/projects/feature_flags/new.html.haml
@@ -6,8 +6,8 @@
#js-new-feature-flag{ data: { endpoint: project_feature_flags_path(@project, format: :json),
feature_flags_path: project_feature_flags_path(@project),
environments_endpoint: search_project_environments_path(@project, format: :json),
- user_callouts_path: user_callouts_path,
- user_callout_id: UserCalloutsHelper::FEATURE_FLAGS_NEW_VERSION,
+ user_callouts_path: callouts_path,
+ user_callout_id: Users::CalloutsHelper::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: 'scope-environments-with-specs'),
diff --git a/app/views/projects/forks/index.html.haml b/app/views/projects/forks/index.html.haml
index ba4e40a8675..d6f421e8ad6 100644
--- a/app/views/projects/forks/index.html.haml
+++ b/app/views/projects/forks/index.html.haml
@@ -1,40 +1,36 @@
+- sort_value = @sort || sort_value_recently_created
+- sort_title = forks_sort_options_hash[sort_value]
+
.top-area
.nav-text
- full_count_title = "#{@public_forks_count} public, #{@internal_forks_count} internal, and #{@private_forks_count} private"
#{pluralize(@total_forks_count, 'fork')}: #{full_count_title}
- .nav-controls
- = form_tag request.original_url, method: :get, class: 'project-filter-form', id: 'project-filter-form' do |f|
- = search_field_tag :filter_projects, nil, placeholder: _('Search forks'), class: 'projects-list-filter project-filter-form-field form-control input-short',
+ .gl-display-flex.gl-sm-flex-direction-column.gl-md-align-items-center
+ = form_tag request.original_url, method: :get, class: 'project-filter-form gl-display-flex gl-mt-3 gl-md-mt-0', id: 'project-filter-form' do |f|
+ = search_field_tag :filter_projects, nil, placeholder: _('Search forks'), class: 'projects-list-filter project-filter-form-field form-control input-short gl-flex-grow-1',
spellcheck: false, data: { 'filter-selector' => 'span.namespace-name' }
- .dropdown
- %button.dropdown-menu-toggle{ type: 'button', 'data-toggle' => 'dropdown' }
- %span.light= _("sort:")
- - if @sort.present?
- = sort_options_hash[@sort]
- - else
- = sort_title_recently_created
- = sprite_icon('chevron-down', css_class: 'dropdown-menu-toggle-icon gl-top-3')
- %ul.dropdown-menu.dropdown-menu-right
- %li
- - excluded_filters = [:state, :scope, :label_name, :milestone_id, :assignee_id, :author_id]
- = link_to page_filter_path(sort: sort_value_recently_created, without: excluded_filters) do
- = sort_title_recently_created
- = link_to page_filter_path(sort: sort_value_oldest_created, without: excluded_filters) do
- = sort_title_oldest_created
- = link_to page_filter_path(sort: sort_value_recently_updated, without: excluded_filters) do
- = sort_title_recently_updated
- = link_to page_filter_path(sort: sort_value_oldest_updated, without: excluded_filters) do
- = sort_title_oldest_updated
+ .dropdown.gl-display-inline.gl-md-ml-3.issue-sort-dropdown.gl-mt-3.gl-md-mt-0
+ .btn-group{ role: 'group' }
+ .btn-group{ role: 'group' }
+ %button.dropdown-menu-toggle{ type: 'button', data: { toggle: 'dropdown', display: 'static' }, class: 'gl-button btn btn-default' }
+ = sort_title
+ = sprite_icon('chevron-down', css_class: "dropdown-menu-toggle-icon gl-top-3")
+ %ul.dropdown-menu.dropdown-menu-right.dropdown-menu-selectable.dropdown-menu-sort
+ %li
+ - excluded_filters = [:state, :scope, :label_name, :milestone_id, :assignee_id, :author_id]
+ = sortable_item(sort_title_created_date, page_filter_path(sort: sort_value_recently_created, without: excluded_filters), sort_title)
+ = sortable_item(sort_title_latest_activity, page_filter_path(sort: sort_value_latest_activity, without: excluded_filters), sort_title)
+ = forks_sort_direction_button(sort_value)
- if current_user && can?(current_user, :fork_project, @project)
- if current_user.already_forked?(@project) && current_user.manageable_namespaces.size < 2
- = link_to namespace_project_path(current_user, current_user.fork_of(@project)), title: _('Go to your fork'), class: 'btn gl-button btn-confirm' do
+ = link_to namespace_project_path(current_user, current_user.fork_of(@project)), title: _('Go to your fork'), class: 'btn gl-button btn-confirm gl-md-ml-3' do
= sprite_icon('fork', size: 12)
%span= _('Fork')
- else
- = link_to new_project_fork_path(@project), title: _("Fork project"), class: 'btn gl-button btn-confirm' do
+ = link_to new_project_fork_path(@project), title: _("Fork project"), class: 'btn gl-button btn-confirm gl-md-ml-3 gl-mt-3 gl-md-mt-0' do
= sprite_icon('fork', size: 12)
%span= _('Fork')
diff --git a/app/views/projects/generic_commit_statuses/_generic_commit_status.html.haml b/app/views/projects/generic_commit_statuses/_generic_commit_status.html.haml
index 2627552058b..9e3d9b4258a 100644
--- a/app/views/projects/generic_commit_statuses/_generic_commit_status.html.haml
+++ b/app/views/projects/generic_commit_statuses/_generic_commit_status.html.haml
@@ -9,6 +9,9 @@
%td.status
= render 'ci/status/badge', status: generic_commit_status.detailed_status(current_user)
+ %td
+ = generic_commit_status.name
+
%td.generic-commit-status-link
- if can?(current_user, :read_commit_status, generic_commit_status) && generic_commit_status.target_url
= link_to generic_commit_status.target_url do
@@ -66,9 +69,6 @@
= generic_commit_status.stage
%td
- = generic_commit_status.name
-
- %td
- if generic_commit_status.duration
%p.duration
= custom_icon("icon_timer")
diff --git a/app/views/projects/google_cloud/errors/gcp_error.html.haml b/app/views/projects/google_cloud/errors/gcp_error.html.haml
new file mode 100644
index 00000000000..69e481501d5
--- /dev/null
+++ b/app/views/projects/google_cloud/errors/gcp_error.html.haml
@@ -0,0 +1,6 @@
+- breadcrumb_title _('Google Cloud')
+- page_title _('Google Cloud')
+
+- @content_class = "limit-container-width" unless fluid_layout
+
+#js-google-cloud{ data: @js_data }
diff --git a/app/views/projects/google_cloud/errors/no_gcp_projects.html.haml b/app/views/projects/google_cloud/errors/no_gcp_projects.html.haml
new file mode 100644
index 00000000000..69e481501d5
--- /dev/null
+++ b/app/views/projects/google_cloud/errors/no_gcp_projects.html.haml
@@ -0,0 +1,6 @@
+- breadcrumb_title _('Google Cloud')
+- page_title _('Google Cloud')
+
+- @content_class = "limit-container-width" unless fluid_layout
+
+#js-google-cloud{ data: @js_data }
diff --git a/app/views/projects/google_cloud/service_accounts/index.html.haml b/app/views/projects/google_cloud/service_accounts/index.html.haml
new file mode 100644
index 00000000000..9b82bc0acb5
--- /dev/null
+++ b/app/views/projects/google_cloud/service_accounts/index.html.haml
@@ -0,0 +1,8 @@
+- add_to_breadcrumbs _('Google Cloud'), @google_cloud_path
+- breadcrumb_title _('Service Account')
+- page_title _('Service Account')
+
+- @content_class = "limit-container-width" unless fluid_layout
+
+= form_tag project_google_cloud_service_accounts_path(@project), method: 'post' do
+ #js-google-cloud{ data: @js_data }
diff --git a/app/views/projects/hooks/edit.html.haml b/app/views/projects/hooks/edit.html.haml
index e8ea4ad90dc..7d696a988d4 100644
--- a/app/views/projects/hooks/edit.html.haml
+++ b/app/views/projects/hooks/edit.html.haml
@@ -1,7 +1,9 @@
- @content_class = 'limit-container-width' unless fluid_layout
-- add_to_breadcrumbs _('Webhook Settings'), namespace_project_hooks_path
+- add_to_breadcrumbs _('Webhook Settings'), project_hooks_path(@project)
- page_title _('Webhook')
+= render 'shared/web_hooks/hook_errors', hook: @hook
+
.row.gl-mt-3
.col-lg-3
= render 'shared/web_hooks/title_and_docs', hook: @hook
diff --git a/app/views/projects/integrations/shimos/show.html.haml b/app/views/projects/integrations/shimos/show.html.haml
new file mode 100644
index 00000000000..92b9e03d5bd
--- /dev/null
+++ b/app/views/projects/integrations/shimos/show.html.haml
@@ -0,0 +1,10 @@
+- breadcrumb_title s_('Shimo|Shimo Workspace')
+- page_title s_('Shimo|Shimo Workspace')
+- add_page_specific_style 'page_bundles/wiki'
+= render layout: 'shared/empty_states/wikis_layout', locals: { image_path: 'illustrations/wiki_login_empty.svg' } do
+ %h4
+ = s_('Shimo|Shimo Workspace integration is enabled')
+ %p
+ = s_("Shimo|You've enabled the Shimo Workspace integration. You can view your wiki directly in Shimo.")
+ = link_to @project.shimo_integration.external_wiki_url, target: '_blank', rel: 'noopener noreferrer', class: 'gl-button btn btn-confirm', title: s_('Shimo|Go to Shimo Workspace') do
+ = s_('Shimo|Go to Shimo Workspace')
diff --git a/app/views/projects/issues/_issue.html.haml b/app/views/projects/issues/_issue.html.haml
index 2de2c2cba6c..2dc21685057 100644
--- a/app/views/projects/issues/_issue.html.haml
+++ b/app/views/projects/issues/_issue.html.haml
@@ -13,7 +13,7 @@
%span.has-tooltip{ title: _('Confidential') }
= confidential_icon(issue)
= hidden_issue_icon(issue)
- = link_to issue.title, issue_path(issue)
+ = link_to issue.title, issue_path(issue), class: 'js-prefetch-document'
= render_if_exists 'projects/issues/subepic_flag', issue: issue
- if issue.tasks?
%span.task-status.d-none.d-sm-inline-block
@@ -25,10 +25,10 @@
#{issuable_reference(issue)}
%span.issuable-authored.d-none.d-sm-inline-block
&middot;
- created #{time_ago_with_tooltip(issue.created_at, placement: 'bottom')} by
- if issue.service_desk_reply_to
- #{issue.service_desk_reply_to} via
- #{link_to_member(@project, issue.author, avatar: false)}
+ #{_('created %{timeAgoString} by %{email} via %{user}').html_safe % { timeAgoString: time_ago_with_tooltip(issue.created_at, placement: 'bottom'), email: issue.service_desk_reply_to, user: link_to_member(@project, issue.author, avatar: false) }}
+ - else
+ #{s_('IssueList|created %{timeAgoString} by %{user}').html_safe % { timeAgoString: time_ago_with_tooltip(issue.created_at, placement: 'bottom'), user: link_to_member(@project, issue.author, avatar: false) }}
= render_if_exists 'shared/issuable/gitlab_team_member_badge', author: issue.author
- if issue.milestone
%span.issuable-milestone.d-none.d-sm-inline-block
diff --git a/app/views/projects/issues/_new_branch.html.haml b/app/views/projects/issues/_new_branch.html.haml
index 07fec195899..1cf0551535b 100644
--- a/app/views/projects/issues/_new_branch.html.haml
+++ b/app/views/projects/issues/_new_branch.html.haml
@@ -1,7 +1,7 @@
- if can?(current_user, :push_code, @project)
- can_create_merge_request = can?(current_user, :create_merge_request_in, @project)
- data_action = can_create_merge_request ? 'create-mr' : 'create-branch'
- - value = can_create_merge_request ? 'Create merge request' : 'Create branch'
+ - value = can_create_merge_request ? _('Create merge request') : _('Create branch')
- value = can_create_confidential_merge_request? ? _('Create confidential merge request') : value
- create_mr_text = can_create_confidential_merge_request? ? _('Create confidential merge request') : _('Create merge request')
diff --git a/app/views/projects/issues/_related_branches.html.haml b/app/views/projects/issues/_related_branches.html.haml
index c47257eec4a..310a0c1a61e 100644
--- a/app/views/projects/issues/_related_branches.html.haml
+++ b/app/views/projects/issues/_related_branches.html.haml
@@ -1,7 +1,7 @@
- if @related_branches.any?
%h2.gl-font-lg
= pluralize(@related_branches.size, 'Related Branch')
- %ul.unstyled-list.related-merge-requests
+ %ul.related-merge-requests.gl-pl-0
- @related_branches.each do |branch|
%li.gl-display-flex.gl-align-items-center
- if branch[:pipeline_status].present?
diff --git a/app/views/projects/issues/index.html.haml b/app/views/projects/issues/index.html.haml
index 53c2052bfab..10c48177ae4 100644
--- a/app/views/projects/issues/index.html.haml
+++ b/app/views/projects/issues/index.html.haml
@@ -30,7 +30,7 @@
= render 'issues'
- if new_issue_email
.gl-text-center.gl-pt-5.gl-pb-7
- .js-issueable-by-email{ data: { initial_email: new_issue_email, issuable_type: issuable_type, emails_help_page_path: help_page_path('development/emails', anchor: 'email-namespace'), quick_actions_help_path: help_page_path('user/project/quick_actions'), markdown_help_path: help_page_path('user/markdown'), reset_path: new_issuable_address_project_path(@project, issuable_type: issuable_type) } }
+ .js-issuable-by-email{ data: { initial_email: new_issue_email, issuable_type: issuable_type, emails_help_page_path: help_page_path('development/emails', anchor: 'email-namespace'), quick_actions_help_path: help_page_path('user/project/quick_actions'), markdown_help_path: help_page_path('user/markdown'), reset_path: new_issuable_address_project_path(@project, issuable_type: issuable_type) } }
- else
- new_project_issue_button_path = @project.archived? ? false : new_project_issue_path(@project)
= render 'shared/empty_states/issues', new_project_issue_button_path: new_project_issue_button_path, show_import_button: true
diff --git a/app/views/projects/jobs/show.html.haml b/app/views/projects/jobs/show.html.haml
index 44336b95e0f..7af825b2819 100644
--- a/app/views/projects/jobs/show.html.haml
+++ b/app/views/projects/jobs/show.html.haml
@@ -7,4 +7,7 @@
= render_if_exists "shared/shared_runners_minutes_limit_flash_message"
-#js-job-vue-app{ data: jobs_data }
+- if @build.is_a? ::Ci::Build
+ #js-job-page{ data: jobs_data }
+- else
+ #js-bridge-page{ data: bridge_data(@build) }
diff --git a/app/views/projects/learn_gitlab/index.html.haml b/app/views/projects/learn_gitlab/index.html.haml
index 9b17be99da0..6bca145dc18 100644
--- a/app/views/projects/learn_gitlab/index.html.haml
+++ b/app/views/projects/learn_gitlab/index.html.haml
@@ -4,9 +4,10 @@
- data = learn_gitlab_data(@project)
- invite_members_open = session.delete(:confetti_post_signup)
+= render 'projects/invite_members_modal', project: @project
+
- experiment(:confetti_post_signup, actor: current_user) do |e|
- e.control do
#js-learn-gitlab-app{ data: data }
- e.candidate do
- = render 'projects/invite_members_modal', project: @project
#js-learn-gitlab-app{ data: data.merge(invite_members_open: invite_members_open) }
diff --git a/app/views/projects/merge_requests/_merge_request.html.haml b/app/views/projects/merge_requests/_merge_request.html.haml
index 3e2c5f088f7..98d2928fc97 100644
--- a/app/views/projects/merge_requests/_merge_request.html.haml
+++ b/app/views/projects/merge_requests/_merge_request.html.haml
@@ -9,7 +9,7 @@
.issuable-main-info
.merge-request-title.title
%span.merge-request-title-text.js-onboarding-mr-item
- = link_to merge_request.title, merge_request_path(merge_request)
+ = link_to merge_request.title, merge_request_path(merge_request), class: 'js-prefetch-document'
- if merge_request.tasks?
%span.task-status.d-none.d-sm-inline-block
&nbsp;
@@ -20,8 +20,7 @@
#{issuable_reference(merge_request)}
%span.issuable-authored.d-none.d-sm-inline-block
&middot;
- created #{time_ago_with_tooltip(merge_request.created_at, placement: 'bottom')}
- by #{link_to_member(@project, merge_request.author, avatar: false)}
+ #{s_('IssueList|created %{timeAgoString} by %{user}').html_safe % { timeAgoString: time_ago_with_tooltip(merge_request.created_at, placement: 'bottom'), user: link_to_member(@project, merge_request.author, avatar: false) }}
= render_if_exists 'shared/issuable/gitlab_team_member_badge', author: merge_request.author
- if merge_request.milestone
%span.issuable-milestone.d-none.d-sm-inline-block
diff --git a/app/views/projects/merge_requests/_mr_title.html.haml b/app/views/projects/merge_requests/_mr_title.html.haml
index 0e8de3c2bb8..9d5d1de1005 100644
--- a/app/views/projects/merge_requests/_mr_title.html.haml
+++ b/app/views/projects/merge_requests/_mr_title.html.haml
@@ -4,7 +4,7 @@
- are_close_and_open_buttons_hidden = merge_request_button_hidden?(@merge_request, true) && merge_request_button_hidden?(@merge_request, false)
- cache_key = [@project, @merge_request, can_update_merge_request, can_reopen_merge_request, are_close_and_open_buttons_hidden]
-= cache_if(Feature.enabled?(:cached_mr_title, @project, default_enabled: :yaml), cache_key, expires_in: 1.day) do
+= cache(cache_key, expires_in: 1.day) do
- if @merge_request.closed_or_merged_without_fork?
.gl-alert.gl-alert-danger.gl-mb-5
.gl-alert-container
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 eb5d052ec19..0036f1b4bde 100644
--- a/app/views/projects/merge_requests/creations/_new_submit.html.haml
+++ b/app/views/projects/merge_requests/creations/_new_submit.html.haml
@@ -26,16 +26,16 @@
%li.commits-tab.new-tab
= link_to url_for(safe_params), data: {target: 'div#commits', action: 'new', toggle: 'tabvue'} do
Commits
- %span.badge.gl-tab-counter-badge.badge-muted.badge-pill.gl-badge.sm= @total_commit_count
+ = gl_badge_tag @total_commit_count, { size: :sm }, { class: 'gl-tab-counter-badge' }
- if @pipelines.any?
%li.builds-tab
= link_to url_for(safe_params.merge(action: 'pipelines')), data: {target: 'div#pipelines', action: 'pipelines', toggle: 'tabvue'} do
Pipelines
- %span.badge.gl-tab-counter-badge.badge-muted.badge-pill.gl-badge.sm= @pipelines.size
+ = gl_badge_tag @pipelines.size, { size: :sm }, { class: 'gl-tab-counter-badge' }
%li.diffs-tab
= link_to url_for(safe_params.merge(action: 'diffs')), data: {target: 'div#diffs', action: 'diffs', toggle: 'tabvue', qa_selector: 'diffs_tab'} do
Changes
- %span.badge.gl-tab-counter-badge.badge-muted.badge-pill.gl-badge.sm= @merge_request.diff_size
+ = gl_badge_tag @merge_request.diff_size, { size: :sm }, { class: 'gl-tab-counter-badge' }
#diff-notes-app.tab-content
#new.commits.tab-pane.active
diff --git a/app/views/projects/merge_requests/index.html.haml b/app/views/projects/merge_requests/index.html.haml
index 41c6696789d..a3f40207d20 100644
--- a/app/views/projects/merge_requests/index.html.haml
+++ b/app/views/projects/merge_requests/index.html.haml
@@ -26,6 +26,6 @@
= render 'merge_requests', new_merge_request_path: new_merge_request_path
- if new_merge_request_email
.gl-text-center.gl-pt-5.gl-pb-7
- .js-issueable-by-email{ data: { initial_email: new_merge_request_email, issuable_type: issuable_type, emails_help_page_path: help_page_path('development/emails', anchor: 'email-namespace'), quick_actions_help_path: help_page_path('user/project/quick_actions'), markdown_help_path: help_page_path('user/markdown'), reset_path: new_issuable_address_project_path(@project, issuable_type: issuable_type) } }
+ .js-issuable-by-email{ data: { initial_email: new_merge_request_email, issuable_type: issuable_type, emails_help_page_path: help_page_path('development/emails', anchor: 'email-namespace'), quick_actions_help_path: help_page_path('user/project/quick_actions'), markdown_help_path: help_page_path('user/markdown'), reset_path: new_issuable_address_project_path(@project, issuable_type: issuable_type) } }
- else
= render 'shared/empty_states/merge_requests', button_path: new_merge_request_path
diff --git a/app/views/projects/merge_requests/invalid.html.haml b/app/views/projects/merge_requests/invalid.html.haml
index fd1b2328a98..eb8de425f61 100644
--- a/app/views/projects/merge_requests/invalid.html.haml
+++ b/app/views/projects/merge_requests/invalid.html.haml
@@ -1,7 +1,12 @@
- page_title "#{@merge_request.title} (#{@merge_request.to_reference}", _("Merge requests")
-- badge_css_classes = "badge gl-text-white"
-- badge_info_css_classes = "#{badge_css_classes} badge-info"
-- badge_inverse_css_classes = "#{badge_css_classes} badge-inverse"
+
+- badge_start = '<span class="badge badge-pill gl-badge sm badge-info">'.html_safe
+- badge_end = '</span>'.html_safe
+
+- err_fork_project_removed = s_("MergeRequest|Can't show this merge request because the fork project was deleted.")
+- err_source_branch = s_("MergeRequest|Can't show this merge request because the source branch %{badge_start}%{source_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the source branch.")
+- err_target_branch = s_("MergeRequest|Can't show this merge request because the target branch %{badge_start}%{target_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the target branch.")
+- err_internal = s_("MergeRequest|Can't show this merge request because of an internal error. Contact your administrator.")
.merge-request
= render "projects/merge_requests/mr_title"
@@ -11,20 +16,12 @@
.gl-alert-container
= sprite_icon('error', size: 16, css_class: 'gl-icon gl-alert-icon gl-alert-icon-no-title')
.gl-alert-content{ role: 'alert' }
- %p
- We cannot render this merge request properly because
+ .gl-alert-body
- if @merge_request.for_fork? && !@merge_request.source_project
- fork project was removed
+ = err_fork_project_removed
- elsif !@merge_request.source_branch_exists?
- %span{ class: badge_inverse_css_classes }= @merge_request.source_branch
- does not exist in
- %span{ class: badge_info_css_classes }= @merge_request.source_project_path
+ = err_source_branch.html_safe % { badge_start: badge_start, badge_end: badge_end, source_branch: @merge_request.source_branch, project_path: @merge_request.source_project_path }
- elsif !@merge_request.target_branch_exists?
- %span{ class: badge_inverse_css_classes }= @merge_request.target_branch
- does not exist in
- %span{ class: badge_info_css_classes }= @merge_request.target_project_path
+ = err_target_branch.html_safe % { badge_start: badge_start, badge_end: badge_end, target_branch: @merge_request.target_branch, project_path: @merge_request.source_project_path }
- else
- of internal error
-
- %strong
- Please close merge request or change branches with existing one
+ = err_internal
diff --git a/app/views/projects/merge_requests/show.html.haml b/app/views/projects/merge_requests/show.html.haml
index 2154ef6b596..eb1c9712c52 100644
--- a/app/views/projects/merge_requests/show.html.haml
+++ b/app/views/projects/merge_requests/show.html.haml
@@ -25,21 +25,21 @@
= render "projects/merge_requests/tabs/tab", class: "notes-tab", qa_selector: "notes_tab" do
= tab_link_for @merge_request, :show, force_link: @commit.present? do
= _("Overview")
- %span.badge.badge-pill.gl-badge.badge-muted.sm= @merge_request.related_notes.user.count
+ = gl_badge_tag @merge_request.related_notes.user.count, { size: :sm }
- if @merge_request.source_project
= render "projects/merge_requests/tabs/tab", name: "commits", class: "commits-tab", qa_selector: "commits_tab" do
= tab_link_for @merge_request, :commits do
= _("Commits")
- %span.badge.badge-pill.gl-badge.badge-muted.sm= @commits_count
+ = gl_badge_tag @commits_count, { size: :sm }
- if @number_of_pipelines.nonzero?
= render "projects/merge_requests/tabs/tab", name: "pipelines", class: "pipelines-tab" do
= tab_link_for @merge_request, :pipelines do
= _("Pipelines")
- %span.badge.badge-pill.gl-badge.badge-muted.sm.js-pipelines-mr-count= @number_of_pipelines
+ = gl_badge_tag @number_of_pipelines, { size: :sm }, { class: 'js-pipelines-mr-count' }
= render "projects/merge_requests/tabs/tab", name: "diffs", class: "diffs-tab", id: "diffs-tab", qa_selector: "diffs_tab" do
= tab_link_for @merge_request, :diffs do
= _("Changes")
- %span.badge.badge-pill.gl-badge.badge-muted.sm= @diffs_count
+ = gl_badge_tag @diffs_count, { size: :sm }
.d-flex.flex-wrap.align-items-center.justify-content-lg-end
#js-vue-discussion-counter
diff --git a/app/views/projects/mirrors/_disabled_mirror_badge.html.haml b/app/views/projects/mirrors/_disabled_mirror_badge.html.haml
index 9c11b650f75..86e54acecc4 100644
--- a/app/views/projects/mirrors/_disabled_mirror_badge.html.haml
+++ b/app/views/projects/mirrors/_disabled_mirror_badge.html.haml
@@ -1 +1,2 @@
-.badge.badge-warning.qa-disabled-mirror-badge.rspec-disabled-mirror-badge{ data: { toggle: 'tooltip', html: 'true' }, title: _('Disabled mirrors can only be enabled by instance owners. It is recommended that you delete them.') }= _('Disabled')
+%span.qa-disabled-mirror-badge.rspec-disabled-mirror-badge{ data: { toggle: 'tooltip', html: 'true' }, title: _('Disabled mirrors can only be enabled by instance owners. It is recommended that you delete them.') }
+ = gl_badge_tag _('Disabled'), variant: :warning
diff --git a/app/views/projects/mirrors/_regenerate_public_ssh_key_confirm_modal.html.haml b/app/views/projects/mirrors/_regenerate_public_ssh_key_confirm_modal.html.haml
deleted file mode 100644
index e6f3060af3e..00000000000
--- a/app/views/projects/mirrors/_regenerate_public_ssh_key_confirm_modal.html.haml
+++ /dev/null
@@ -1,13 +0,0 @@
-.modal.js-regenerate-public-ssh-key-confirm-modal{ tabindex: -1 }
- .modal-dialog
- .modal-content
- .modal-header
- %h3.modal-title.page-title
- Regenerate public SSH key?
- %button.close.js-cancel{ type: 'button', 'data-dismiss': 'modal', 'aria-label' => _('Close') }
- %span{ 'aria-hidden': true } &times;
- .modal-body
- %p= _('Are you sure you want to regenerate the public key? You will have to update the public key on the remote server before mirroring will work again.')
- .form-actions.modal-footer
- = button_tag _('Cancel'), type: 'button', class: 'btn gl-button js-cancel'
- = button_tag _('Regenerate key'), type: 'button', class: 'btn gl-button btn-inverted btn-warning js-confirm'
diff --git a/app/views/projects/network/show.json.erb b/app/views/projects/network/show.json.erb
index a146d137c55..93b3c9911e2 100644
--- a/app/views/projects/network/show.json.erb
+++ b/app/views/projects/network/show.json.erb
@@ -2,7 +2,7 @@
<%= raw(
{
- days: @graph.days.compact.map { |d| [d.day, d.strftime("%b")] },
+ days: @graph.days.compact.map { |d| [d.day, d.strftime("%b"), d.year] },
commits: @graph.commits.map do |c|
{
parents: parents_zip_spaces(c.parents(@graph.map), c.parent_spaces),
diff --git a/app/views/projects/packages/packages/index.html.haml b/app/views/projects/packages/packages/index.html.haml
index 0d5350ab62b..c67b06218e2 100644
--- a/app/views/projects/packages/packages/index.html.haml
+++ b/app/views/projects/packages/packages/index.html.haml
@@ -3,4 +3,8 @@
.row
.col-12
- #js-vue-packages-list{ data: packages_list_data('projects', @project) }
+ #js-vue-packages-list{ data: { resource_id: @project.id,
+ full_path: @project.full_path,
+ endpoint: project_packages_path(@project),
+ page_type: 'projects',
+ empty_list_illustration: image_path('illustrations/no-packages.svg'), } }
diff --git a/app/views/projects/pages_domains/_dns.html.haml b/app/views/projects/pages_domains/_dns.html.haml
index 267317196f8..2732463020e 100644
--- a/app/views/projects/pages_domains/_dns.html.haml
+++ b/app/views/projects/pages_domains/_dns.html.haml
@@ -1,5 +1,5 @@
- verification_enabled = Gitlab::CurrentSettings.pages_domain_verification_enabled?
-- dns_record = "#{domain_presenter.domain} CNAME #{domain_presenter.project.pages_subdomain}.#{Settings.pages.host}."
+- dns_record = "#{domain_presenter.domain} ALIAS #{domain_presenter.project.pages_subdomain}.#{Settings.pages.host}."
.form-group.border-section
.row
diff --git a/app/views/projects/pipeline_schedules/edit.html.haml b/app/views/projects/pipeline_schedules/edit.html.haml
index 29896500ea1..51f0c58330d 100644
--- a/app/views/projects/pipeline_schedules/edit.html.haml
+++ b/app/views/projects/pipeline_schedules/edit.html.haml
@@ -4,7 +4,7 @@
- add_page_specific_style 'page_bundles/pipeline_schedules'
%h3.page-title
- = _("Edit Pipeline Schedule %{id}") % { id: @schedule.id }
+ = _("Edit Pipeline Schedule")
%hr
= render "form"
diff --git a/app/views/projects/pipelines/_with_tabs.html.haml b/app/views/projects/pipelines/_with_tabs.html.haml
index 93afddce779..e844a3d4779 100644
--- a/app/views/projects/pipelines/_with_tabs.html.haml
+++ b/app/views/projects/pipelines/_with_tabs.html.haml
@@ -11,16 +11,16 @@
%li.js-builds-tab-link
= link_to builds_project_pipeline_path(@project, @pipeline), data: { target: '#js-tab-builds', action: 'builds', toggle: 'tab' }, class: 'builds-tab' do
= _('Jobs')
- %span.badge.badge-pill.gl-badge.badge-muted.sm.js-builds-counter= pipeline.total_size
+ = gl_badge_tag @pipeline.total_size, { size: :sm }, { class: 'js-builds-counter' }
- if @pipeline.failed_builds.present?
%li.js-failures-tab-link
= link_to failures_project_pipeline_path(@project, @pipeline), data: { target: '#js-tab-failures', action: 'failures', toggle: 'tab' }, class: 'failures-tab' do
= _('Failed Jobs')
- %span.badge.badge-pill.gl-badge.badge-muted.sm.js-failures-counter= @pipeline.failed_builds.count
+ = gl_badge_tag @pipeline.failed_builds.count, { size: :sm }, { class: 'js-failures-counter' }
%li.js-tests-tab-link
= link_to test_report_project_pipeline_path(@project, @pipeline), data: { target: '#js-tab-tests', action: 'test_report', toggle: 'tab' }, class: 'test-tab' do
= s_('TestReports|Tests')
- %span.badge.badge-pill.gl-badge.badge-muted.sm.js-test-report-badge-counter= @pipeline.test_report_summary.total[:count]
+ = gl_badge_tag @pipeline.test_report_summary.total[:count], { size: :sm }, { class: 'js-test-report-badge-counter' }
= render_if_exists "projects/pipelines/tabs_holder", pipeline: @pipeline, project: @project
.tab-content
@@ -29,17 +29,20 @@
#js-tab-builds.tab-pane
- if stages.present?
- .table-holder.pipeline-holder
- %table.table.ci-table.pipeline
- %thead
- %tr
- %th= _('Status')
- %th= _('Name')
- %th= _('Job ID')
- %th
- %th= _('Coverage')
- %th
- = render partial: "projects/stage/stage", collection: stages, as: :stage
+ - if Feature.enabled?(:jobs_tab_vue, @project, default_enabled: :yaml)
+ #js-pipeline-jobs-vue{ data: { full_path: @project.full_path, pipeline_iid: @pipeline.iid } }
+ - else
+ .table-holder.pipeline-holder
+ %table.table.ci-table.pipeline
+ %thead
+ %tr
+ %th= _('Status')
+ %th= _('Name')
+ %th= _('Job ID')
+ %th
+ %th= _('Coverage')
+ %th
+ = render partial: "projects/stage/stage", collection: stages, as: :stage
- if @pipeline.failed_builds.present?
#js-tab-failures.build-failures.tab-pane.build-page
diff --git a/app/views/projects/pipelines/charts.html.haml b/app/views/projects/pipelines/charts.html.haml
index 21e871246d7..547e2c8a7f4 100644
--- a/app/views/projects/pipelines/charts.html.haml
+++ b/app/views/projects/pipelines/charts.html.haml
@@ -2,4 +2,7 @@
#js-project-pipelines-charts-app{ data: { project_path: @project.full_path,
should_render_dora_charts: should_render_dora_charts.to_s,
- should_render_quality_summary: should_render_quality_summary.to_s } }
+ should_render_quality_summary: should_render_quality_summary.to_s,
+ failed_pipelines_link: project_pipelines_path(@project, page: '1', scope: 'all', status: 'failed'),
+ coverage_chart_path: charts_project_graph_path(@project, @project.default_branch),
+ default_branch: @project.default_branch } }
diff --git a/app/views/projects/pipelines/show.html.haml b/app/views/projects/pipelines/show.html.haml
index c911fc8a203..ac5d34bfd44 100644
--- a/app/views/projects/pipelines/show.html.haml
+++ b/app/views/projects/pipelines/show.html.haml
@@ -10,8 +10,7 @@
.js-pipeline-container{ data: { controller_action: "#{controller.action_name}" } }
#js-pipeline-header-vue.pipeline-header-container{ data: { full_path: @project.full_path, pipeline_iid: @pipeline.iid, pipeline_id: @pipeline.id, pipelines_path: project_pipelines_path(@project) } }
- - if Gitlab.com? && show_cc_validation_alert?(@pipeline)
- #js-cc-validation-required-alert
+ = render_if_exists 'projects/pipelines/cc_validation_required_alert', pipeline: @pipeline
- if @pipeline.commit.present?
= render "projects/pipelines/info", commit: @pipeline.commit
diff --git a/app/views/projects/protected_branches/shared/_matching_branch.html.haml b/app/views/projects/protected_branches/shared/_matching_branch.html.haml
index 9145be5d2f2..1a2ec38fae9 100644
--- a/app/views/projects/protected_branches/shared/_matching_branch.html.haml
+++ b/app/views/projects/protected_branches/shared/_matching_branch.html.haml
@@ -3,7 +3,7 @@
= link_to matching_branch.name, project_ref_path(@project, matching_branch.name), class: 'ref-name'
- if @project.root_ref?(matching_branch.name)
- %span.badge.badge-info.gl-ml-2 default
+ = gl_badge_tag s_('ProtectedBranch|default'), { variant: :info }, { class: 'gl-ml-2' }
%td
- commit = @project.commit(matching_branch.name)
= link_to(commit.short_id, project_commit_path(@project, commit.id), class: 'commit-sha')
diff --git a/app/views/projects/protected_tags/shared/_matching_tag.html.haml b/app/views/projects/protected_tags/shared/_matching_tag.html.haml
index bf030d36cd6..3b6a6bd876f 100644
--- a/app/views/projects/protected_tags/shared/_matching_tag.html.haml
+++ b/app/views/projects/protected_tags/shared/_matching_tag.html.haml
@@ -3,7 +3,7 @@
= link_to matching_tag.name, project_ref_path(@project, matching_tag.name), class: 'ref-name'
- if @project.root_ref?(matching_tag.name)
- %span.badge.badge-info.gl-ml-2 default
+ = gl_badge_tag s_('ProtectedTag|default'), { variant: :info }, { class: 'gl-ml-2' }
%td
- commit = @project.commit(matching_tag.name)
= link_to(commit.short_id, project_commit_path(@project, commit.id), class: 'commit-sha')
diff --git a/app/views/projects/protected_tags/shared/_protected_tag.html.haml b/app/views/projects/protected_tags/shared/_protected_tag.html.haml
index 972c96dc882..70357f39e44 100644
--- a/app/views/projects/protected_tags/shared/_protected_tag.html.haml
+++ b/app/views/projects/protected_tags/shared/_protected_tag.html.haml
@@ -3,7 +3,7 @@
%span.ref-name= protected_tag.name
- if @project.root_ref?(protected_tag.name)
- %span.badge.badge-info.gl-ml-2 default
+ = gl_badge_tag s_('ProtectedTags|default'), variant: :info, class: 'gl-ml-2'
%td
- if protected_tag.wildcard?
- matching_tags = protected_tag.matching(repository.tags)
diff --git a/app/views/projects/registry/repositories/index.html.haml b/app/views/projects/registry/repositories/index.html.haml
index cfdbf3410b1..03927cd3bfa 100644
--- a/app/views/projects/registry/repositories/index.html.haml
+++ b/app/views/projects/registry/repositories/index.html.haml
@@ -22,6 +22,6 @@
"cleanup_policies_settings_path": project_settings_packages_and_registries_path(@project),
connection_error: (!!@connection_error).to_s,
invalid_path_error: (!!@invalid_path_error).to_s,
- user_callouts_path: user_callouts_path,
- user_callout_id: UserCalloutsHelper::UNFINISHED_TAG_CLEANUP_CALLOUT,
+ user_callouts_path: callouts_path,
+ user_callout_id: Users::CalloutsHelper::UNFINISHED_TAG_CLEANUP_CALLOUT,
show_unfinished_tag_cleanup_callout: show_unfinished_tag_cleanup_callout?.to_s, } }
diff --git a/app/views/projects/remove_fork.js.haml b/app/views/projects/remove_fork.js.haml
deleted file mode 100644
index 6d083c5c516..00000000000
--- a/app/views/projects/remove_fork.js.haml
+++ /dev/null
@@ -1,2 +0,0 @@
-:plain
- location.href = "#{edit_project_path(@project)}";
diff --git a/app/views/projects/runners/_group_runners.html.haml b/app/views/projects/runners/_group_runners.html.haml
index 5d737bb3901..183e747afdd 100644
--- a/app/views/projects/runners/_group_runners.html.haml
+++ b/app/views/projects/runners/_group_runners.html.haml
@@ -27,7 +27,7 @@
- elsif @group_runners.empty?
= _('This group does not have any group runners yet.')
- - if can?(current_user, :admin_pipeline, @project.group)
+ - if can?(current_user, :admin_group_runners, @project.group)
- group_link = link_to _("group's CI/CD settings."), group_settings_ci_cd_path(@project.group)
= _('Group maintainers can register group runners in the %{link}').html_safe % { link: group_link }
- else
diff --git a/app/views/projects/runners/_runner.html.haml b/app/views/projects/runners/_runner.html.haml
index bf2e746b4a4..28e5618f8b0 100644
--- a/app/views/projects/runners/_runner.html.haml
+++ b/app/views/projects/runners/_runner.html.haml
@@ -36,5 +36,4 @@
- if runner.tags.present?
.gl-my-2
- runner.tags.map(&:name).sort.each do |tag|
- %span.badge.gl-badge.sm.badge-pill.badge-primary
- = tag
+ = gl_badge_tag tag, variant: :info, size: :sm
diff --git a/app/views/projects/services/_form.html.haml b/app/views/projects/services/_form.html.haml
index 724684c9a0a..dbc204ff9bf 100644
--- a/app/views/projects/services/_form.html.haml
+++ b/app/views/projects/services/_form.html.haml
@@ -6,7 +6,7 @@
- if integration.operating?
= sprite_icon('check', css_class: 'gl-text-green-500')
-= 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' => test_project_service_path(@project, integration) } }) do |form|
+= form_for(integration, as: :service, url: scoped_integration_path(integration, project: @project, group: @group), method: :put, html: { class: 'gl-show-field-errors integration-settings-form js-integration-settings-form', data: { 'test-url' => test_project_service_path(@project, integration) } }) do |form|
= render 'shared/service_settings', form: form, integration: integration
%input{ id: 'services_redirect_to', type: 'hidden', name: 'redirect_to', value: request.referer }
diff --git a/app/views/projects/services/prometheus/_custom_metrics.html.haml b/app/views/projects/services/prometheus/_custom_metrics.html.haml
index 724950bcb39..4586ee844c0 100644
--- a/app/views/projects/services/prometheus/_custom_metrics.html.haml
+++ b/app/views/projects/services/prometheus/_custom_metrics.html.haml
@@ -10,9 +10,7 @@
.card-header
%strong
= s_('PrometheusService|Custom metrics')
- -# haml-lint:disable NoPlainNodes
- %span.badge.badge-pill.js-custom-monitored-count 0
- -# haml-lint:enable NoPlainNodes
+ = gl_badge_tag 0, nil, class: 'js-custom-monitored-count'
= link_to s_('PrometheusService|New metric'), new_project_prometheus_metric_path(project), class: 'btn gl-button btn-confirm gl-ml-auto js-new-metric-button hidden', data: { qa_selector: 'new_metric_button' }
.card-body
.flash-container.hidden
diff --git a/app/views/projects/services/prometheus/_metrics.html.haml b/app/views/projects/services/prometheus/_metrics.html.haml
index 09fe77b8a9c..0d41584652f 100644
--- a/app/views/projects/services/prometheus/_metrics.html.haml
+++ b/app/views/projects/services/prometheus/_metrics.html.haml
@@ -12,7 +12,7 @@
.card-header
%strong
= s_('PrometheusService|Common metrics')
- %span.badge.badge-pill.js-monitored-count 0
+ = gl_badge_tag 0, nil, class: 'js-monitored-count'
.card-body
.loading-metrics.js-loading-metrics
%p.m-3
@@ -28,7 +28,7 @@
= sprite_icon('chevron-lg-right', css_class: 'panel-toggle js-panel-toggle-right' )
= sprite_icon('chevron-lg-down', css_class: 'panel-toggle js-panel-toggle-down hidden' )
= s_('PrometheusService|Missing environment variable')
- %span.badge.badge-pill.js-env-var-count 0
+ = gl_badge_tag 0, nil, class: 'js-env-var-count'
.card-body.hidden
.flash-container
.flash-notice
diff --git a/app/views/projects/settings/access_tokens/index.html.haml b/app/views/projects/settings/access_tokens/index.html.haml
index 52ef2e7d1ee..4e946050881 100644
--- a/app/views/projects/settings/access_tokens/index.html.haml
+++ b/app/views/projects/settings/access_tokens/index.html.haml
@@ -39,7 +39,7 @@
access_levels: ProjectMember.access_level_roles,
default_access_level: Gitlab::Access::MAINTAINER,
prefix: :project_access_token,
- help_path: help_page_path('user/project/settings/project_access_tokens', anchor: 'limiting-scopes-of-a-project-access-token')
+ help_path: help_page_path('user/project/settings/project_access_tokens', anchor: 'scopes-for-a-project-access-token')
= render 'shared/access_tokens/table',
active_tokens: @active_project_access_tokens,
diff --git a/app/views/projects/settings/ci_cd/_autodevops_form.html.haml b/app/views/projects/settings/ci_cd/_autodevops_form.html.haml
index 8563f28eb33..e200635ba82 100644
--- a/app/views/projects/settings/ci_cd/_autodevops_form.html.haml
+++ b/app/views/projects/settings/ci_cd/_autodevops_form.html.haml
@@ -23,7 +23,7 @@
= form.label :enabled, class: 'form-check-label' do
%strong= s_('CICD|Default to Auto DevOps pipeline')
- if auto_devops_enabled
- %span.badge.badge-info.js-instance-default-badge= badge_for_auto_devops_scope(@project)
+ = gl_badge_tag badge_for_auto_devops_scope(@project), { variant: :info }, { class: 'js-instance-default-badge'}
.form-text.text-muted
= s_('CICD|The Auto DevOps pipeline runs if no alternative CI configuration file is found.')
= link_to _('Learn more.'), help_page_path('topics/autodevops/index.md'), target: '_blank'
diff --git a/app/views/projects/settings/ci_cd/show.html.haml b/app/views/projects/settings/ci_cd/show.html.haml
index 75bd985560b..f342728feee 100644
--- a/app/views/projects/settings/ci_cd/show.html.haml
+++ b/app/views/projects/settings/ci_cd/show.html.haml
@@ -96,15 +96,14 @@
.settings-content
= render 'ci/deploy_freeze/index'
-- if Feature.enabled?(:ci_scoped_job_token, @project, default_enabled: :yaml)
- %section.settings.no-animate#js-token-access{ class: ('expanded' if expanded) }
- .settings-header
- %h4.settings-title.js-settings-toggle.js-settings-toggle-trigger-only
- = _("Token Access")
- %button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' }
- = expanded ? _('Collapse') : _('Expand')
- %p
- = _("Control which projects can be accessed by API requests authenticated with this project's CI_JOB_TOKEN CI/CD variable. It is a security risk to disable this feature, because unauthorized projects might attempt to retrieve an active token and access the API.")
- = link_to _('Learn more'), help_page_path('ci/jobs/ci_job_token'), target: '_blank', rel: 'noopener noreferrer'
- .settings-content
- = render 'ci/token_access/index'
+%section.settings.no-animate#js-token-access{ class: ('expanded' if expanded) }
+ .settings-header
+ %h4.settings-title.js-settings-toggle.js-settings-toggle-trigger-only
+ = _("Token Access")
+ %button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' }
+ = expanded ? _('Collapse') : _('Expand')
+ %p
+ = _("Control which projects can be accessed by API requests authenticated with this project's CI_JOB_TOKEN CI/CD variable. It is a security risk to disable this feature, because unauthorized projects might attempt to retrieve an active token and access the API.")
+ = link_to _('Learn more'), help_page_path('ci/jobs/ci_job_token'), target: '_blank', rel: 'noopener noreferrer'
+ .settings-content
+ = render 'ci/token_access/index'
diff --git a/app/views/projects/show.html.haml b/app/views/projects/show.html.haml
index 1cbb061784e..d840ea01b89 100644
--- a/app/views/projects/show.html.haml
+++ b/app/views/projects/show.html.haml
@@ -19,7 +19,6 @@
= 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/starrers/_starrer.html.haml b/app/views/projects/starrers/_starrer.html.haml
index 28ec1ed206a..e24276fcaea 100644
--- a/app/views/projects/starrers/_starrer.html.haml
+++ b/app/views/projects/starrers/_starrer.html.haml
@@ -13,7 +13,7 @@
%span.cgray= starrer.user.to_reference
- if starrer.user == current_user
- %span.badge-pill.badge-success.gl-badge.gl-ml-2.sm= _("It's you")
+ = gl_badge_tag _("It's you"), variant: :success, size: :sm, class: 'gl-ml-2'
.block-truncated
= time_ago_with_tooltip(starrer.starred_since)
diff --git a/app/views/projects/tags/_tag.html.haml b/app/views/projects/tags/_tag.html.haml
index 83a3cac487f..0ee3b89b629 100644
--- a/app/views/projects/tags/_tag.html.haml
+++ b/app/views/projects/tags/_tag.html.haml
@@ -2,18 +2,13 @@
- release = @releases.find { |release| release.tag == tag.name }
- commit_status = @tag_pipeline_statuses[tag.name] unless @tag_pipeline_statuses.nil?
-%li.flex-row.js-tag-list{ class: "gl-white-space-normal!" }
+%li.flex-row.js-tag-list{ class: "gl-white-space-normal! gl-align-items-flex-start!" }
.row-main-content
= sprite_icon('tag')
= link_to tag.name, project_tag_path(@project, tag.name), class: 'item-title ref-name'
- if protected_tag?(@project, tag)
- %span.badge.badge-success.gl-ml-2.gl-badge.sm.badge-pill
- = s_('TagsPage|protected')
-
- - if tag.message.present?
- &nbsp;
- = strip_signature(tag.message)
+ = gl_badge_tag s_('TagsPage|protected'), variant: :success, size: :sm, class: 'gl-ml-2'
- if commit
.block-truncated
@@ -28,6 +23,10 @@
= _("Release")
= link_to release.name, project_releases_path(@project, anchor: release.tag), class: 'gl-text-blue-600!'
+ - if tag.message.present?
+ %pre.wrap
+ = strip_signature(tag.message)
+
.row-fixed-content.controls.flex-row
- if tag.has_signature?
= render partial: 'projects/commit/signature', object: tag.signature
diff --git a/app/views/projects/tags/show.html.haml b/app/views/projects/tags/show.html.haml
index b3a75494ccc..c1b78d3258d 100644
--- a/app/views/projects/tags/show.html.haml
+++ b/app/views/projects/tags/show.html.haml
@@ -13,8 +13,7 @@
= sprite_icon('tag')
= @tag.name
- if protected_tag?(@project, @tag)
- %span.badge.badge-success
- = s_('TagsPage|protected')
+ = gl_badge_tag s_('TagsPage|protected'), variant: :success
- if user
= link_to user_path(user) do
diff --git a/app/views/projects/tracings/show.html.haml b/app/views/projects/tracings/show.html.haml
index 21c1d02d92e..813908e5a57 100644
--- a/app/views/projects/tracings/show.html.haml
+++ b/app/views/projects/tracings/show.html.haml
@@ -3,10 +3,12 @@
- if @project.tracing_external_url.present?
%h3.page-title= _('Tracing')
- .gl-alert.gl-alert-info.alert.flex-alert
- = sprite_icon('information-o', css_class: 'gl-icon gl-alert-icon gl-alert-icon-no-title')
- .alert-message
- = _("Your password isn't required to view this page. If a password or any other personal details are requested, please contact your administrator to report abuse.")
+ .gl-alert.gl-alert-info.gl-mb-5
+ .gl-alert-container
+ = sprite_icon('information-o', css_class: 'gl-icon gl-alert-icon gl-alert-icon-no-title')
+ .gl-alert-content
+ .gl-alert-body
+ = _("Your password isn't required to view this page. If a password or any other personal details are requested, please contact your administrator to report abuse.")
- jaeger_link = link_to('Jaeger tracing', 'https://www.jaegertracing.io/', target: "_blank", rel: "noreferrer")
%p.light= _("GitLab uses %{jaeger_link} to monitor distributed systems.").html_safe % { jaeger_link: jaeger_link }
diff --git a/app/views/projects/transfer.js.haml b/app/views/projects/transfer.js.haml
deleted file mode 100644
index 6d083c5c516..00000000000
--- a/app/views/projects/transfer.js.haml
+++ /dev/null
@@ -1,2 +0,0 @@
-:plain
- location.href = "#{edit_project_path(@project)}";
diff --git a/app/views/projects/usage_quotas/index.html.haml b/app/views/projects/usage_quotas/index.html.haml
index 6c7cccfb9b1..de1135cf928 100644
--- a/app/views/projects/usage_quotas/index.html.haml
+++ b/app/views/projects/usage_quotas/index.html.haml
@@ -16,4 +16,4 @@
= s_('UsageQuota|Storage')
.tab-content
.tab-pane#storage-quota-tab
- #js-project-storage-count-app{ data: @storage_app_data }
+ #js-project-storage-count-app{ data: { project_path: @project.full_path } }
diff --git a/app/views/root/index.html.haml b/app/views/root/index.html.haml
deleted file mode 100644
index 97dd8e133f5..00000000000
--- a/app/views/root/index.html.haml
+++ /dev/null
@@ -1,10 +0,0 @@
-- if show_customize_homepage_banner?
- = content_for :customize_homepage_banner do
- .gl-display-none.gl-md-display-block{ class: "gl-pt-6! gl-pb-2! #{(container_class unless @no_container)} #{@content_class}" }
- .js-customize-homepage-banner{ data: { svg_path: image_path('illustrations/monitoring/getting_started.svg'),
- preferences_behavior_path: profile_preferences_path(anchor: 'behavior'),
- callouts_path: user_callouts_path,
- callouts_feature_id: UserCalloutsHelper::CUSTOMIZE_HOMEPAGE,
- track_label: 'home_page' } }
-
-= render template: 'dashboard/projects/index'
diff --git a/app/views/search/results/_blob.html.haml b/app/views/search/results/_blob.html.haml
index aeb37022f99..3681f823ef5 100644
--- a/app/views/search/results/_blob.html.haml
+++ b/app/views/search/results/_blob.html.haml
@@ -1,5 +1,6 @@
- project = blob.project
- return unless project
- blob_link = project_blob_path(project, tree_join(repository_ref(project), blob.path))
+- blame_link = project_blame_path(project, tree_join(repository_ref(project), blob.path))
-= render partial: 'search/results/blob_data', locals: { blob: blob, project: project, path: blob.path, blob_link: blob_link }
+= render partial: 'search/results/blob_data', locals: { blob: blob, project: project, path: blob.path, blob_link: blob_link, blame_link: blame_link }
diff --git a/app/views/search/results/_blob_data.html.haml b/app/views/search/results/_blob_data.html.haml
index 88a2ab4bb42..c42367f45c5 100644
--- a/app/views/search/results/_blob_data.html.haml
+++ b/app/views/search/results/_blob_data.html.haml
@@ -9,7 +9,7 @@
- if blob.data
- 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
+ = render 'search/results/blob_highlight', blob: blob, first_line_number: blob.startline, blob_link: blob_link, blame_link: blame_link, highlight_line: blob.highlight_line
- else
.file-content.code
.nothing-here-block
diff --git a/app/views/search/results/_blob_highlight.html.haml b/app/views/search/results/_blob_highlight.html.haml
new file mode 100644
index 00000000000..de1fa9a7fd5
--- /dev/null
+++ b/app/views/search/results/_blob_highlight.html.haml
@@ -0,0 +1,22 @@
+- offset = defined?(first_line_number) ? first_line_number : 1
+- highlight = defined?(highlight_line) && highlight_line ? highlight_line - offset : nil
+
+#search-blob-content.file-content.code.js-syntax-highlight{ class: 'gl-py-3!' }
+ - if blob.present?
+ .blob-content{ data: { blob_id: blob.id, path: blob.path, highlight_line: highlight, qa_selector: 'file_content' } }
+ - blob.present.highlight.lines.each_with_index do |line, index|
+ - i = index + offset
+ .line_holder.code-search-line
+ .line-numbers
+ .gl-display-flex
+ %span.diff-line-num.gl-pl-3
+ %a.has-tooltip{ href: "#{blame_link}#L#{i}", id: "blame-L#{i}", 'data-line-number' => i, title: _('View blame') }
+ = sprite_icon('git')
+ %span.diff-line-num.flex-grow-1.gl-pr-3
+ %a{ href: "#{blob_link}#L#{i}", id: "blob-L#{i}", 'data-line-number' => i, class: 'gl-display-flex! gl-align-items-center gl-justify-content-end' }
+ = sprite_icon('link', css_class: 'gl-ml-3! gl-mr-1!')
+ = i
+ %pre.code.highlight
+ %code
+ = line.html_safe
+
diff --git a/app/views/search/results/_issuable.html.haml b/app/views/search/results/_issuable.html.haml
index 41058034d6f..36458a909fc 100644
--- a/app/views/search/results/_issuable.html.haml
+++ b/app/views/search/results/_issuable.html.haml
@@ -1,7 +1,7 @@
%div{ class: 'search-result-row gl-display-flex gl-sm-flex-direction-row gl-flex-direction-column gl-align-items-center gl-pb-3! gl-mt-5 gl-mb-0!' }
.col-sm-9
%span.gl-display-flex.gl-align-items-center
- %span.badge.badge-pill.gl-badge.sm{ class: "badge-#{issuable_state_to_badge_class(issuable)}" }= issuable_state_text(issuable)
+ = gl_badge_tag issuable_state_text(issuable), variant: issuable_state_to_badge_class(issuable), size: :sm
= sprite_icon('eye-slash', css_class: 'gl-text-gray-500 gl-ml-2') if issuable.respond_to?(:confidential?) && issuable.confidential?
= link_to issuable_path(issuable), data: { track_action: 'click_text', track_label: "#{issuable.class.name.downcase}_title", track_property: 'search_result' }, class: 'gl-w-full' do
%span.term.str-truncated.gl-font-weight-bold.gl-ml-2= issuable.title
diff --git a/app/views/shared/_email_with_badge.html.haml b/app/views/shared/_email_with_badge.html.haml
index 8b9ca966ed6..5d837657943 100644
--- a/app/views/shared/_email_with_badge.html.haml
+++ b/app/views/shared/_email_with_badge.html.haml
@@ -1,8 +1,5 @@
-- css_classes = %w(badge gl-badge)
-- css_classes << (verified ? 'badge-success': 'badge-danger')
+- variant = verified ? :success : :danger
- text = verified ? _('Verified') : _('Unverified')
-.email-badge
- .email-badge-email= email
- %div{ class: css_classes }
- = text
+= email
+= gl_badge_tag text, { variant: variant }, { class: 'gl-ml-3' }
diff --git a/app/views/shared/_flash_user_callout.html.haml b/app/views/shared/_flash_user_callout.html.haml
index d8032ac521d..7b2d59407b4 100644
--- a/app/views/shared/_flash_user_callout.html.haml
+++ b/app/views/shared/_flash_user_callout.html.haml
@@ -1,4 +1,4 @@
-- callout_data = { uid: "callout_feature_#{feature_name}_dismissed", feature_id: feature_name, dismiss_endpoint: user_callouts_path }
+- callout_data = { uid: "callout_feature_#{feature_name}_dismissed", feature_id: feature_name, dismiss_endpoint: callouts_path }
- extra_flash_class = local_assigns.fetch(:extra_flash_class, nil)
.flash-container.flash-container-page.user-callout{ data: callout_data }
diff --git a/app/views/shared/_milestone_expired.html.haml b/app/views/shared/_milestone_expired.html.haml
index 925344ab2f7..8c84f96932c 100644
--- a/app/views/shared/_milestone_expired.html.haml
+++ b/app/views/shared/_milestone_expired.html.haml
@@ -1,6 +1,6 @@
- if milestone.expired? && !milestone.closed?
- .gl-badge.badge-warning.badge-pill.gl-mb-2= _('Expired')
+ = gl_badge_tag _('Expired'), { variant: :warning }, { class: "gl-mb-2" }
- if milestone.upcoming?
- .gl-badge.badge-primary.badge-pill.gl-mb-2= _('Upcoming')
+ = gl_badge_tag _('Upcoming'), { variant: :info }, { class: "gl-mb-2" }
- if milestone.closed?
- .gl-badge.badge-danger.badge-pill.gl-mb-2= _('Closed')
+ = gl_badge_tag _('Closed'), { variant: :danger }, { class: "gl-mb-2" }
diff --git a/app/views/shared/_milestones_filter.html.haml b/app/views/shared/_milestones_filter.html.haml
index 117ed212fd9..ef41dc9bb79 100644
--- a/app/views/shared/_milestones_filter.html.haml
+++ b/app/views/shared/_milestones_filter.html.haml
@@ -1,15 +1,12 @@
-- count_badge_classes = 'badge badge-muted badge-pill gl-badge gl-tab-counter-badge sm gl-display-none gl-sm-display-inline-flex'
+- count_badge_classes = 'gl-display-none gl-sm-display-inline-flex'
= gl_tabs_nav( {class: 'gl-border-b-0 gl-flex-grow-1', data: { testid: 'milestones-filter' } } ) do
= gl_tab_link_to milestones_filter_path(state: 'opened'), { item_active: params[:state].blank? || params[:state] == 'opened' } do
= _('Open')
- %span{ class: count_badge_classes }
- = counts[:opened]
+ = gl_tab_counter_badge counts[:opened], { class: count_badge_classes }
= gl_tab_link_to milestones_filter_path(state: 'closed', sort: 'due_date_desc'), { item_active: params[:state] == 'closed' } do
= _('Closed')
- %span{ class: count_badge_classes }
- = counts[:closed]
+ = gl_tab_counter_badge counts[:closed], { class: count_badge_classes }
= gl_tab_link_to milestones_filter_path(state: 'all', sort: 'due_date_desc'), { item_active: params[:state] == 'all' } do
= _('All')
- %span{ class: count_badge_classes }
- = counts[:all]
+ = gl_tab_counter_badge counts[:all], { class: count_badge_classes }
diff --git a/app/views/shared/_registration_features_discovery_message.html.haml b/app/views/shared/_registration_features_discovery_message.html.haml
new file mode 100644
index 00000000000..8bcd826d8c0
--- /dev/null
+++ b/app/views/shared/_registration_features_discovery_message.html.haml
@@ -0,0 +1,9 @@
+- license = local_assigns.fetch(:license)
+- registration_features_docs_path = help_page_path('development/service_ping/index.md', anchor: 'registration-features-program')
+- service_ping_settings_path = metrics_and_profiling_admin_application_settings_path(anchor: 'js-usage-settings')
+
+%div
+ %span= s_('RegistrationFeatures|Want to use this feature for free?')
+ - if license.present?
+ = link_to s_('RegistrationFeatures|Enable Service Ping and register for this feature.'), service_ping_settings_path
+ = sprintf(s_('RegistrationFeatures|Read more about the %{linkStart}Registration Features Program%{linkEnd}.') , { linkStart: "<a href=\"#{registration_features_docs_path}\" target=\"_blank\">", linkEnd: "</a>", }).html_safe
diff --git a/app/views/shared/_service_settings.html.haml b/app/views/shared/_service_settings.html.haml
index c70fce7a38f..adacaeadfab 100644
--- a/app/views/shared/_service_settings.html.haml
+++ b/app/views/shared/_service_settings.html.haml
@@ -2,8 +2,8 @@
.service-settings
- if @default_integration
- .js-vue-default-integration-settings{ data: integration_form_data(@default_integration, group: @group) }
- .js-vue-integration-settings{ data: integration_form_data(integration, group: @group) }
+ .js-vue-default-integration-settings{ data: integration_form_data(@default_integration, group: @group, project: @project) }
+ .js-vue-integration-settings{ data: integration_form_data(integration, group: @group, project: @project) }
.js-integration-help-html.gl-display-none
-# All content below will be repositioned in Vue
- if lookup_context.template_exists?('help', "projects/services/#{integration.to_param}", true)
diff --git a/app/views/shared/_two_factor_auth_recovery_settings_check.html.haml b/app/views/shared/_two_factor_auth_recovery_settings_check.html.haml
index d4764d1a5d9..e7239661313 100644
--- a/app/views/shared/_two_factor_auth_recovery_settings_check.html.haml
+++ b/app/views/shared/_two_factor_auth_recovery_settings_check.html.haml
@@ -1,7 +1,7 @@
= render 'shared/global_alert',
variant: :warning,
alert_class: 'js-recovery-settings-callout',
- alert_data: { feature_id: UserCalloutsHelper::TWO_FACTOR_AUTH_RECOVERY_SETTINGS_CHECK, dismiss_endpoint: user_callouts_path, defer_links: 'true' },
+ alert_data: { feature_id: Users::CalloutsHelper::TWO_FACTOR_AUTH_RECOVERY_SETTINGS_CHECK, dismiss_endpoint: callouts_path, defer_links: 'true' },
close_button_data: { testid: 'close-account-recovery-regular-check-callout' } do
.gl-alert-body
= s_('Profiles|Ensure you have two-factor authentication recovery codes stored in a safe place.')
diff --git a/app/views/shared/builds/_tabs.html.haml b/app/views/shared/builds/_tabs.html.haml
index 498e9cc33ce..3bbd7a32bda 100644
--- a/app/views/shared/builds/_tabs.html.haml
+++ b/app/views/shared/builds/_tabs.html.haml
@@ -1,19 +1,15 @@
-- count_badge_classes = 'badge badge-muted badge-pill gl-badge gl-tab-counter-badge sm gl-display-none gl-sm-display-inline-flex'
+- count_badge_classes = 'gl-display-none gl-sm-display-inline-flex'
= gl_tabs_nav( {class: 'gl-border-b-0 gl-flex-grow-1', data: { testid: 'jobs-tabs' } } ) do
= gl_tab_link_to build_path_proc.call(nil), { item_active: scope.nil? } do
= _('All')
- %span{ class: count_badge_classes }
- = limited_counter_with_delimiter(all_builds)
+ = gl_tab_counter_badge(limited_counter_with_delimiter(all_builds), { class: count_badge_classes })
= gl_tab_link_to build_path_proc.call('pending'), { item_active: scope == 'pending' } do
= _('Pending')
- %span{ class: count_badge_classes }
- = limited_counter_with_delimiter(all_builds.pending)
+ = gl_tab_counter_badge(limited_counter_with_delimiter(all_builds.pending), { class: count_badge_classes })
= gl_tab_link_to build_path_proc.call('running'), { item_active: scope == 'running' } do
= _('Running')
- %span{ class: count_badge_classes }
- = limited_counter_with_delimiter(all_builds.running)
+ = gl_tab_counter_badge(limited_counter_with_delimiter(all_builds.running), { class: count_badge_classes })
= gl_tab_link_to build_path_proc.call('finished'), { item_active: scope == 'finished' } do
= _('Finished')
- %span{ class: count_badge_classes }
- = limited_counter_with_delimiter(all_builds.finished)
+ = gl_tab_counter_badge(limited_counter_with_delimiter(all_builds.finished), { class: count_badge_classes })
diff --git a/app/views/shared/doorkeeper/applications/_form.html.haml b/app/views/shared/doorkeeper/applications/_form.html.haml
index 180c658dbdc..adfd7ea98b7 100644
--- a/app/views/shared/doorkeeper/applications/_form.html.haml
+++ b/app/views/shared/doorkeeper/applications/_form.html.haml
@@ -16,13 +16,14 @@
= f.check_box :confidential, class: 'form-check-input'
= f.label :confidential, class: 'label-bold form-check-label'
%span.form-text.text-muted
- = _('The application will be used where the client secret can be kept confidential. Native mobile apps and Single Page Apps are considered non-confidential.')
+ = _('Enable only for confidential applications exclusively used by a trusted backend server that can securely store the client secret. Do not enable for native-mobile, single-page, or other JavaScript applications because they cannot keep the client secret confidential.')
.form-group.form-check
= f.check_box :expire_access_tokens, class: 'form-check-input'
= f.label :expire_access_tokens, class: 'label-bold form-check-label'
%span.form-text.text-muted
- = _('Access tokens expire after 2 hours. A refresh token may be used at any time to generate a new access token. Non-expiring access tokens are deprecated. Clear this setting to enable backward compatibility.')
+ = _('Enable access tokens to expire after 2 hours. If disabled, tokens do not expire.')
+ = link_to _('Learn more.'), help_page_path('integration/oauth_provider.md', anchor: 'expiring-access-tokens'), target: '_blank', rel: 'noopener noreferrer'
.form-group
= f.label :scopes, class: 'label-bold'
diff --git a/app/views/shared/doorkeeper/applications/_index.html.haml b/app/views/shared/doorkeeper/applications/_index.html.haml
index 8ccb4bcdbe0..0359c28794c 100644
--- a/app/views/shared/doorkeeper/applications/_index.html.haml
+++ b/app/views/shared/doorkeeper/applications/_index.html.haml
@@ -9,7 +9,7 @@
- if oauth_authorized_applications_enabled
= _("Manage applications that can use GitLab as an OAuth provider, and applications that you've authorized to use your account.")
- else
- = _("Manage applications that can use GitLab as an OAuth provider.")
+ = _("Manage applications that use GitLab as an OAuth provider.")
- else
= _("Manage applications that you've authorized to use your account.")
.col-lg-8
diff --git a/app/views/shared/form_elements/_description.html.haml b/app/views/shared/form_elements/_description.html.haml
index f8942dddfb4..94818c13f76 100644
--- a/app/views/shared/form_elements/_description.html.haml
+++ b/app/views/shared/form_elements/_description.html.haml
@@ -7,7 +7,7 @@
- preview_url = preview_markdown_path(project, target_type: model.class.name)
.form-group.row.detail-page-description
- = form.label :description, 'Description', class: 'col-form-label col-sm-2'
+ = form.label :description, _('Description'), class: 'col-form-label col-sm-2'
.col-sm-10
- if model.is_a?(MergeRequest)
= hidden_field_tag :merge_request_diff_head_sha, model.diff_head_sha
diff --git a/app/views/shared/integrations/_form.html.haml b/app/views/shared/integrations/_form.html.haml
index 35f302a28a6..89c127408e1 100644
--- a/app/views/shared/integrations/_form.html.haml
+++ b/app/views/shared/integrations/_form.html.haml
@@ -1,4 +1,4 @@
- integration = local_assigns.fetch(:integration)
-= 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|
+= form_for integration, as: :service, url: scoped_integration_path(integration, group: @group), method: :put, html: { class: 'gl-show-field-errors integration-settings-form js-integration-settings-form', data: { 'test-url' => scoped_test_integration_path(integration, group: @group) } } do |form|
= render 'shared/service_settings', form: form, integration: integration
diff --git a/app/views/shared/integrations/_index.html.haml b/app/views/shared/integrations/_index.html.haml
index 39365280e71..872fc90f6db 100644
--- a/app/views/shared/integrations/_index.html.haml
+++ b/app/views/shared/integrations/_index.html.haml
@@ -1 +1 @@
-.js-integrations-list{ data: integration_list_data(integrations) }
+.js-integrations-list{ data: integration_list_data(integrations, group: @group, project: @project) }
diff --git a/app/views/shared/integrations/_tabs.html.haml b/app/views/shared/integrations/_tabs.html.haml
index d6ca0bd7d1e..781db59592e 100644
--- a/app/views/shared/integrations/_tabs.html.haml
+++ b/app/views/shared/integrations/_tabs.html.haml
@@ -2,7 +2,7 @@
.tabs.gl-tabs
%div
= gl_tabs_nav({ class: 'gl-mb-5' }) do
- = gl_tab_link_to _('Settings'), scoped_edit_integration_path(integration)
+ = gl_tab_link_to _('Settings'), scoped_edit_integration_path(integration, project: @project, group: @group)
= gl_tab_link_to s_('Integrations|Projects using custom settings'), scoped_overrides_integration_path(integration)
= yield
diff --git a/app/views/shared/integrations/edit.html.haml b/app/views/shared/integrations/edit.html.haml
index 02cb94e3555..acb0c7ee52e 100644
--- a/app/views/shared/integrations/edit.html.haml
+++ b/app/views/shared/integrations/edit.html.haml
@@ -1,4 +1,4 @@
-- add_to_breadcrumbs _('Integrations'), scoped_integrations_path
+- add_to_breadcrumbs _('Integrations'), scoped_integrations_path(project: @project, group: @group)
- breadcrumb_title @integration.title
- page_title @integration.title, _('Integrations')
- @content_class = 'limit-container-width' unless fluid_layout
diff --git a/app/views/shared/integrations/overrides.html.haml b/app/views/shared/integrations/overrides.html.haml
index dc87fae704c..b8585fdef1f 100644
--- a/app/views/shared/integrations/overrides.html.haml
+++ b/app/views/shared/integrations/overrides.html.haml
@@ -1,4 +1,4 @@
-- add_to_breadcrumbs _('Integrations'), scoped_integrations_path
+- add_to_breadcrumbs _('Integrations'), scoped_integrations_path(project: @project, group: @group)
- breadcrumb_title @integration.title
- page_title @integration.title, _('Integrations')
- @content_class = 'limit-container-width' unless fluid_layout
diff --git a/app/views/shared/issuable/_form.html.haml b/app/views/shared/issuable/_form.html.haml
index cb03bd4c473..4024c5b77f6 100644
--- a/app/views/shared/issuable/_form.html.haml
+++ b/app/views/shared/issuable/_form.html.haml
@@ -64,7 +64,7 @@
for this project.
- if issuable.new_record?
- = form.submit "Create #{issuable.class.model_name.human.downcase}", class: 'gl-button btn btn-confirm gl-mr-2', data: { qa_selector: 'issuable_create_button' }
+ = form.submit "#{_('Create')} #{issuable.class.model_name.human.downcase}", class: 'gl-button btn btn-confirm gl-mr-2', data: { qa_selector: 'issuable_create_button' }
- else
= form.submit _('Save changes'), class: 'gl-button btn btn-confirm gl-mr-2'
diff --git a/app/views/shared/issuable/_milestone_dropdown.html.haml b/app/views/shared/issuable/_milestone_dropdown.html.haml
index f58156b7c08..dc713337747 100644
--- a/app/views/shared/issuable/_milestone_dropdown.html.haml
+++ b/app/views/shared/issuable/_milestone_dropdown.html.haml
@@ -4,20 +4,20 @@
- selected = local_assigns.fetch(:selected, nil)
- selected_text = selected.try(:title) || params[:milestone_title]
-- dropdown_title = local_assigns.fetch(:dropdown_title, "Filter by milestone")
+- dropdown_title = local_assigns.fetch(:dropdown_title, _('Filter by milestone'))
- if selected.present? || params[:milestone_title].present?
= hidden_field_tag(name, name == :milestone_title ? selected_text : selected.id)
= dropdown_tag(milestone_dropdown_label(selected_text), options: { title: dropdown_title, toggle_class: "qa-issuable-milestone-dropdown js-milestone-select js-filter-submit #{extra_class}", filter: true, dropdown_class: "qa-issuable-dropdown-menu-milestone dropdown-menu-selectable dropdown-menu-milestone",
- placeholder: "Search milestones", footer_content: project.present?, data: { show_no: true, show_menu_above: show_menu_above, show_any: show_any, show_upcoming: show_upcoming, show_started: show_started, field_name: name, selected: selected_text, project_id: project.try(:id), default_label: "Milestone" } }) do
+ placeholder: _('Search milestones'), footer_content: project.present?, data: { show_no: true, show_menu_above: show_menu_above, show_any: show_any, show_upcoming: show_upcoming, show_started: show_started, field_name: name, selected: selected_text, project_id: project.try(:id), default_label: _('Milestone') } }) do
- if project
%ul.dropdown-footer-list
- if can? current_user, :admin_milestone, project
%li
- = link_to new_project_milestone_path(project), title: "New Milestone" do
- Create new
+ = link_to new_project_milestone_path(project), title: _('New Milestone') do
+ = _('Create new')
%li
= link_to project_milestones_path(project) do
- if can? current_user, :admin_milestone, project
- Manage milestones
+ = _('Manage milestones')
- else
- View milestones
+ = _('View milestones')
diff --git a/app/views/shared/issuable/_sidebar.html.haml b/app/views/shared/issuable/_sidebar.html.haml
index 62539bfeffd..9a703b9d355 100644
--- a/app/views/shared/issuable/_sidebar.html.haml
+++ b/app/views/shared/issuable/_sidebar.html.haml
@@ -29,13 +29,17 @@
= render_if_exists 'shared/issuable/sidebar_item_epic', issuable_sidebar: issuable_sidebar, group_path: @project.group.full_path, project_path: issuable_sidebar[:project_full_path], issue_iid: issuable_sidebar[:iid], issuable_type: issuable_type
- if issuable_sidebar[:supports_milestone]
- .block.milestone{ :class => ("gl-border-b-0!" if in_group_context_with_iterations), data: { qa_selector: 'milestone_block' } }
+ .block.milestone{ :class => ("gl-border-b-0!" if in_group_context_with_iterations), data: { qa_selector: 'milestone_block', testid: 'sidebar-milestones' } }
.js-milestone-select{ data: { can_edit: can_edit_issuable.to_s, project_path: issuable_sidebar[:project_full_path], issue_iid: issuable_sidebar[:iid] } }
- if in_group_context_with_iterations
.block{ class: 'gl-pt-0! gl-collapse-empty', data: { qa_selector: 'iteration_container', testid: 'iteration_container' } }<
= render_if_exists 'shared/issuable/iteration_select', can_edit: can_edit_issuable.to_s, group_path: @project.group.full_path, project_path: issuable_sidebar[:project_full_path], issue_iid: issuable_sidebar[:iid], issuable_type: issuable_type
+ - if @show_crm_contacts
+ .block.contact
+ #js-issue-crm-contacts{ data: { issue_id: issuable_sidebar[:id] } }
+
- if issuable_sidebar[:supports_time_tracking]
#issuable-time-tracker.block
// Fallback while content is loading
diff --git a/app/views/shared/issuable/form/_default_templates.html.haml b/app/views/shared/issuable/form/_default_templates.html.haml
index 3dc244677e2..50f30e58b35 100644
--- a/app/views/shared/issuable/form/_default_templates.html.haml
+++ b/app/views/shared/issuable/form/_default_templates.html.haml
@@ -1,4 +1,5 @@
%p.form-text.text-muted
- Add
- = link_to 'description templates', help_page_path('user/project/description_templates')
- to help your contributors communicate effectively!
+ - template_link_url = help_page_path('user/project/description_templates')
+ - template_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: template_link_url }
+ = s_('Promotions|Add %{link_start} description templates %{link_end} to help your contributors to communicate effectively!').html_safe % { link_start: template_link_start, link_end: '</a>'.html_safe }
+
diff --git a/app/views/shared/issuable/form/_metadata.html.haml b/app/views/shared/issuable/form/_metadata.html.haml
index 2f05d272ca3..9e42c528a11 100644
--- a/app/views/shared/issuable/form/_metadata.html.haml
+++ b/app/views/shared/issuable/form/_metadata.html.haml
@@ -10,7 +10,7 @@
.form-check
= form.check_box :confidential, class: 'form-check-input'
= form.label :confidential, class: 'form-check-label' do
- This issue is confidential and should only be visible to team members with at least Reporter access.
+ #{_('This issue is confidential and should only be visible to team members with at least Reporter access.')}
- if can?(current_user, :"set_#{issuable.to_ability_name}_metadata", issuable)
%hr
@@ -27,13 +27,13 @@
- if issuable.supports_milestone?
.form-group.row.issue-milestone
- = form.label :milestone_id, "Milestone", class: "col-form-label #{has_due_date ? "col-md-2 col-lg-4" : "col-sm-2"}"
+ = form.label :milestone_id, _('Milestone'), class: "col-form-label #{has_due_date ? "col-md-2 col-lg-4" : "col-sm-2"}"
.col-sm-10{ class: ("col-md-8" if has_due_date) }
.issuable-form-select-holder
- = render "shared/issuable/milestone_dropdown", selected: issuable.milestone, name: "#{issuable.class.model_name.param_key}[milestone_id]", show_any: false, show_upcoming: false, show_started: false, extra_class: "qa-issuable-milestone-dropdown js-issuable-form-dropdown js-dropdown-keep-input", dropdown_title: "Select milestone"
+ = render "shared/issuable/milestone_dropdown", selected: issuable.milestone, name: "#{issuable.class.model_name.param_key}[milestone_id]", show_any: false, show_upcoming: false, show_started: false, extra_class: "qa-issuable-milestone-dropdown js-issuable-form-dropdown js-dropdown-keep-input", dropdown_title: _('Select milestone')
.form-group.row
- = form.label :label_ids, "Labels", class: "col-form-label #{has_due_date ? "col-md-2 col-lg-4" : "col-sm-2"}"
+ = form.label :label_ids, _('Labels'), class: "col-form-label #{has_due_date ? "col-md-2 col-lg-4" : "col-sm-2"}"
= form.hidden_field :label_ids, multiple: true, value: ''
.col-sm-10{ class: "#{"col-md-8" if has_due_date}" }
.issuable-form-select-holder
@@ -45,7 +45,7 @@
.col-lg-6
= render_if_exists "shared/issuable/form/weight", issuable: issuable, form: form
.form-group.row
- = form.label :due_date, "Due date", class: "col-form-label col-md-2 col-lg-4"
+ = form.label :due_date, _('Due date'), class: "col-form-label col-md-2 col-lg-4"
.col-8
.issuable-form-select-holder
- = form.text_field :due_date, id: "issuable-due-date", class: "datepicker form-control", placeholder: "Select due date", autocomplete: 'off'
+ = form.text_field :due_date, id: "issuable-due-date", class: "datepicker form-control", placeholder: _('Select due date'), autocomplete: 'off'
diff --git a/app/views/shared/issuable/form/_metadata_issuable_assignee.html.haml b/app/views/shared/issuable/form/_metadata_issuable_assignee.html.haml
index b437ee1ec5f..781ee8b5f80 100644
--- a/app/views/shared/issuable/form/_metadata_issuable_assignee.html.haml
+++ b/app/views/shared/issuable/form/_metadata_issuable_assignee.html.haml
@@ -8,4 +8,4 @@
= hidden_field_tag "#{issuable.to_ability_name}[assignee_ids][]", 0, id: nil, data: { meta: '' }
= dropdown_tag(users_dropdown_label(issuable.assignees), options: assignees_dropdown_options(issuable.to_ability_name))
- = link_to 'Assign to me', '#', class: "assign-to-me-link qa-assign-to-me-link #{'hide' if issuable.assignees.include?(current_user)}"
+ = link_to _('Assign to me'), '#', class: "assign-to-me-link qa-assign-to-me-link #{'hide' if issuable.assignees.include?(current_user)}"
diff --git a/app/views/shared/issuable/form/_title.html.haml b/app/views/shared/issuable/form/_title.html.haml
index 561ca0afd60..c0a6322eb1b 100644
--- a/app/views/shared/issuable/form/_title.html.haml
+++ b/app/views/shared/issuable/form/_title.html.haml
@@ -5,7 +5,7 @@
- div_class = no_issuable_templates ? 'col-sm-10' : 'col-sm-7 col-lg-8'
- toggle_wip_link_start = '<a href="" class="js-toggle-wip">'
- toggle_wip_link_end = '</a>'
-- add_wip_text = (_('%{link_start}Start the title with %{draft_snippet}%{link_end} to prevent a merge request that is a work in progress from being merged before it\'s ready.') % { link_start: toggle_wip_link_start, link_end: toggle_wip_link_end, draft_snippet: '<code>Draft:</code>'.html_safe } ).html_safe
+- add_wip_text = (_('%{link_start}Start the title with %{draft_snippet}%{link_end} to prevent a merge request draft from merging before it\'s ready.') % { link_start: toggle_wip_link_start, link_end: toggle_wip_link_end, draft_snippet: '<code>Draft:</code>'.html_safe } ).html_safe
- remove_wip_text = (_('%{link_start}Remove the %{draft_snippet} prefix%{link_end} from the title to allow this merge request to be merged when it\'s ready.' ) % { link_start: toggle_wip_link_start, link_end: toggle_wip_link_end, draft_snippet: '<code>Draft</code>'.html_safe } ).html_safe
%div{ class: div_class }
diff --git a/app/views/shared/issuable/form/_type_selector.html.haml b/app/views/shared/issuable/form/_type_selector.html.haml
index ae0fe54de4f..0d86aa8c8e7 100644
--- a/app/views/shared/issuable/form/_type_selector.html.haml
+++ b/app/views/shared/issuable/form/_type_selector.html.haml
@@ -1,7 +1,7 @@
- return unless issuable.supports_issue_type? && can?(current_user, :create_issue, @project)
.form-group.row.gl-mb-0
- = form.label :type, 'Type', class: 'col-form-label col-sm-2'
+ = form.label :type, _('Type'), class: 'col-form-label col-sm-2'
.col-sm-10
.gl-display-flex.gl-align-items-center
.issuable-form-select-holder.selectbox.form-group.gl-mb-0
diff --git a/app/views/shared/members/_filter_2fa_dropdown.html.haml b/app/views/shared/members/_filter_2fa_dropdown.html.haml
deleted file mode 100644
index 8187a9bde15..00000000000
--- a/app/views/shared/members/_filter_2fa_dropdown.html.haml
+++ /dev/null
@@ -1,11 +0,0 @@
-- filter = params[:two_factor] || 'everyone'
-- filter_options = { 'everyone' => _('Everyone'), 'enabled' => _('Enabled'), 'disabled' => _('Disabled') }
-.dropdown.inline.member-filter-2fa-dropdown{ data: { testid: 'member-filter-2fa-dropdown' } }
- = dropdown_toggle(filter_options[filter], { toggle: 'dropdown', testid: 'dropdown-toggle' })
- %ul.dropdown-menu.dropdown-menu-align-right.dropdown-menu-selectable
- %li.dropdown-header
- = _("Filter by two-factor authentication")
- - filter_options.each do |value, title|
- %li
- = link_to filter_group_project_member_path(two_factor: value), class: ("is-active" if filter == value) do
- = title
diff --git a/app/views/shared/members/_requests.html.haml b/app/views/shared/members/_requests.html.haml
index 8b0a85656dc..ec08dde37bf 100644
--- a/app/views/shared/members/_requests.html.haml
+++ b/app/views/shared/members/_requests.html.haml
@@ -9,7 +9,7 @@
.card-header
= _("Users requesting access to")
%strong= membership_source.name
- %span.badge.badge-pill= requesters.size
+ = gl_badge_tag requesters.size
= render 'shared/members/manage_access_button', path: membership_source.is_a?(Project) ? project_project_members_path(@project, tab: 'access_requests') : group_group_members_path(@group, tab: 'access_requests')
%ul.content-list.members-list
= render partial: 'shared/members/member',
diff --git a/app/views/shared/milestones/_milestone.html.haml b/app/views/shared/milestones/_milestone.html.haml
index 44934a12559..4e06b7902bd 100644
--- a/app/views/shared/milestones/_milestone.html.haml
+++ b/app/views/shared/milestones/_milestone.html.haml
@@ -33,11 +33,9 @@
%div
= render('shared/milestone_expired', milestone: milestone)
- if milestone.group_milestone?
- .gl-badge.badge-info.badge-pill
- = milestone.group.full_name
+ = gl_badge_tag milestone.group.full_name, variant: :info
- if milestone.project_milestone?
- .gl-badge.badge-muted.badge-pill
- = milestone.project.full_name
+ = gl_badge_tag milestone.project.full_name, variant: :muted
.col-sm-4.milestone-progress
= milestone_progress_bar(milestone)
diff --git a/app/views/shared/milestones/_sidebar.html.haml b/app/views/shared/milestones/_sidebar.html.haml
index c66ba5ba2e1..a1e94172ec3 100644
--- a/app/views/shared/milestones/_sidebar.html.haml
+++ b/app/views/shared/milestones/_sidebar.html.haml
@@ -79,7 +79,7 @@
%span= milestone.issues_visible_to_user(current_user).count
.title.hide-collapsed
= s_('MilestoneSidebar|Issues')
- %span.badge.badge-muted.badge-pill.gl-badge.sm= milestone.issues_visible_to_user(current_user).count
+ = gl_badge_tag milestone.issues_visible_to_user(current_user).count, variant: :muted, size: :sm
- if show_new_issue_link?(project)
= link_to new_project_issue_path(project, issue: { milestone_id: milestone.id }), class: "float-right", title: s_('MilestoneSidebar|New Issue') do
= s_('MilestoneSidebar|New issue')
@@ -111,7 +111,7 @@
%span= milestone.merge_requests.count
.title.hide-collapsed
= s_('MilestoneSidebar|Merge requests')
- %span.badge.badge-muted.badge-pill.gl-badge.sm= milestone.merge_requests.count
+ = gl_badge_tag milestone.merge_requests.count, variant: :muted, size: :sm
.value.hide-collapsed.bold
- if !project || can?(current_user, :read_merge_request, project)
%span.milestone-stat
diff --git a/app/views/shared/milestones/_tabs.html.haml b/app/views/shared/milestones/_tabs.html.haml
index 3524a1b17ea..8c49977fe82 100644
--- a/app/views/shared/milestones/_tabs.html.haml
+++ b/app/views/shared/milestones/_tabs.html.haml
@@ -3,24 +3,20 @@
.scrolling-tabs-container.inner-page-scroll-tabs.is-smaller
.fade-left= sprite_icon('chevron-lg-left', size: 12)
.fade-right= sprite_icon('chevron-lg-right', size: 12)
- %ul.nav-links.scrolling-tabs.js-milestone-tabs.nav.nav-tabs
- %li.nav-item
- = link_to '#tab-issues', class: 'nav-link active', data: { toggle: 'tab', endpoint: milestone_tab_path(milestone, 'issues', show_project_name: show_project_name) } do
- = _('Issues')
- %span.badge.badge-pill= milestone.issues_visible_to_user(current_user).size
+ = gl_tabs_nav({ class: %w[scrolling-tabs js-milestone-tabs] }) do
+ = gl_tab_link_to '#tab-issues', item_active: true, data: { endpoint: milestone_tab_path(milestone, 'issues', show_project_name: show_project_name) } do
+ = _('Issues')
+ = gl_tab_counter_badge milestone.issues_visible_to_user(current_user).size
- if milestone.merge_requests_enabled?
- %li.nav-item
- = link_to '#tab-merge-requests', class: 'nav-link', data: { toggle: 'tab', endpoint: milestone_tab_path(milestone, 'merge_requests', show_project_name: show_project_name) } do
- = _('Merge requests')
- %span.badge.badge-pill= milestone.merge_requests_visible_to_user(current_user).size
- %li.nav-item
- = link_to '#tab-participants', class: 'nav-link', data: { toggle: 'tab', endpoint: milestone_tab_path(milestone, 'participants') } do
- = _('Participants')
- %span.badge.badge-pill= milestone.issue_participants_visible_by_user(current_user).count
- %li.nav-item
- = link_to '#tab-labels', class: 'nav-link', data: { toggle: 'tab', endpoint: milestone_tab_path(milestone, 'labels') } do
- = _('Labels')
- %span.badge.badge-pill= milestone.issue_labels_visible_by_user(current_user).count
+ = gl_tab_link_to '#tab-merge-requests', data: { endpoint: milestone_tab_path(milestone, 'merge_requests', show_project_name: show_project_name) } do
+ = _('Merge requests')
+ = gl_tab_counter_badge milestone.merge_requests_visible_to_user(current_user).size
+ = gl_tab_link_to '#tab-participants', data: { endpoint: milestone_tab_path(milestone, 'participants') } do
+ = _('Participants')
+ = gl_tab_counter_badge milestone.issue_participants_visible_by_user(current_user).count
+ = gl_tab_link_to '#tab-labels', data: { endpoint: milestone_tab_path(milestone, 'labels') } do
+ = _('Labels')
+ = gl_tab_counter_badge milestone.issue_labels_visible_by_user(current_user).count
.tab-content.milestone-content
.tab-pane.active#tab-issues
diff --git a/app/views/shared/nav/_scope_menu.html.haml b/app/views/shared/nav/_scope_menu.html.haml
index 1a7089fb570..4e570086bf8 100644
--- a/app/views/shared/nav/_scope_menu.html.haml
+++ b/app/views/shared/nav/_scope_menu.html.haml
@@ -1,5 +1,5 @@
= nav_link(**scope_menu.active_routes, html_options: scope_menu.nav_link_html_options) do
- = link_to scope_menu.link, **scope_menu.container_html_options, data: { qa_selector: 'sidebar_menu_link', qa_menu_item: scope_qa_menu_item(scope_menu.container) } do
+ = link_to scope_menu.link, **scope_menu.link_html_options, data: { qa_selector: 'sidebar_menu_link', qa_menu_item: scope_qa_menu_item(scope_menu.container) } do
%span{ class: scope_avatar_classes(scope_menu.container) }
= source_icon(scope_menu.container, alt: scope_menu.title, class: ['avatar', 'avatar-tile', 's32'], width: 32, height: 32)
%span.sidebar-context-title
diff --git a/app/views/shared/nav/_sidebar_hidden_menu_item.html.haml b/app/views/shared/nav/_sidebar_hidden_menu_item.html.haml
index 953f7a8ae60..d0ae5e99707 100644
--- a/app/views/shared/nav/_sidebar_hidden_menu_item.html.haml
+++ b/app/views/shared/nav/_sidebar_hidden_menu_item.html.haml
@@ -1,3 +1,3 @@
%li.hidden
- = link_to sidebar_hidden_menu_item.link, **sidebar_hidden_menu_item.container_html_options do
+ = link_to sidebar_hidden_menu_item.link, **sidebar_hidden_menu_item.link_html_options do
= sidebar_hidden_menu_item.title
diff --git a/app/views/shared/nav/_sidebar_menu.html.haml b/app/views/shared/nav/_sidebar_menu.html.haml
index 3f71368aff3..4c4ceb9ea70 100644
--- a/app/views/shared/nav/_sidebar_menu.html.haml
+++ b/app/views/shared/nav/_sidebar_menu.html.haml
@@ -2,7 +2,7 @@
- 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
+ = link_to sidebar_menu.link, **sidebar_menu.link_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
diff --git a/app/views/shared/nav/_sidebar_menu_item.html.haml b/app/views/shared/nav/_sidebar_menu_item.html.haml
index 674ce593ee2..5452cd486da 100644
--- a/app/views/shared/nav/_sidebar_menu_item.html.haml
+++ b/app/views/shared/nav/_sidebar_menu_item.html.haml
@@ -1,5 +1,5 @@
= nav_link(**sidebar_menu_item.active_routes, html_options: sidebar_menu_item.nav_link_html_options) do
- = link_to sidebar_menu_item.link, **sidebar_menu_item.container_html_options, data: { qa_selector: 'sidebar_menu_item_link', qa_menu_item: sidebar_menu_item.title } do
+ = link_to sidebar_menu_item.link, **sidebar_menu_item.link_html_options, data: { qa_selector: 'sidebar_menu_item_link', qa_menu_item: sidebar_menu_item.title } do
%span
= sidebar_menu_item.title
- if sidebar_menu_item.sprite_icon
diff --git a/app/views/shared/projects/_archived.html.haml b/app/views/shared/projects/_archived.html.haml
index f24fe3a8b89..018bf137cc6 100644
--- a/app/views/shared/projects/_archived.html.haml
+++ b/app/views/shared/projects/_archived.html.haml
@@ -1,3 +1,2 @@
- if project.archived
- %span.d-flex.badge-pill.gl-badge.badge-warning.gl-ml-3
- = _('archived')
+ = gl_badge_tag _('archived'), { variant: :warning }, { class: 'gl-display-flex gl-ml-3' }
diff --git a/app/views/shared/projects/_project.html.haml b/app/views/shared/projects/_project.html.haml
index 2136d287f53..ae264f2188f 100644
--- a/app/views/shared/projects/_project.html.haml
+++ b/app/views/shared/projects/_project.html.haml
@@ -31,7 +31,7 @@
.flex-wrapper
.d-flex.align-items-center.flex-wrap.project-title
%h2.d-flex.gl-mt-3
- = link_to project_path(project), class: 'text-plain' do
+ = link_to project_path(project), class: 'text-plain js-prefetch-document' do
%span.project-full-name.gl-mr-3><
%span.namespace-name
- if project.namespace && !skip_namespace
diff --git a/app/views/shared/projects/_topics.html.haml b/app/views/shared/projects/_topics.html.haml
index e303f05c5df..b7df369327c 100644
--- a/app/views/shared/projects/_topics.html.haml
+++ b/app/views/shared/projects/_topics.html.haml
@@ -1,6 +1,5 @@
- 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
@@ -10,11 +9,11 @@
- project.topics_to_show.each do |topic|
- explore_project_topic_path = topic_explore_projects_path(topic_name: 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)
+ %a.gl-mr-3.has-tooltip{ data: { container: "body" }, title: topic, href: explore_project_topic_path, itemprop: 'keywords' }
+ = gl_badge_tag truncate(topic, length: max_project_topic_length)
- else
- %a{ class: project_topics_classes, href: explore_project_topic_path, itemprop: 'keywords' }
- = topic
+ %a.gl-mr-3{ href: explore_project_topic_path, itemprop: 'keywords' }
+ = gl_badge_tag topic
- if project.has_extra_topics?
- title = _('More topics')
@@ -23,10 +22,10 @@
- project.topics_not_shown.each do |topic|
- explore_project_topic_path = topic_explore_projects_path(topic_name: 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)
+ %a.gl-mr-3.gl-mb-3.has-tooltip{ data: { container: "body" }, title: topic, href: explore_project_topic_path, itemprop: 'keywords' }
+ = gl_badge_tag truncate(topic, length: max_project_topic_length)
- else
- %a{ class: "#{ project_topics_classes } gl-mb-3", href: explore_project_topic_path, itemprop: 'keywords' }
- = topic
+ %a.gl-mr-3.gl-mb-3{ href: explore_project_topic_path, itemprop: 'keywords' }
+ = gl_badge_tag 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/shared/runners/_runner_description.html.haml b/app/views/shared/runners/_runner_description.html.haml
index 6a65145d42b..436dbfd2b49 100644
--- a/app/views/shared/runners/_runner_description.html.haml
+++ b/app/views/shared/runners/_runner_description.html.haml
@@ -5,8 +5,8 @@
%div
%ul
%li
- %span.badge.badge-pill.gl-badge.sm.badge-success active
+ = gl_badge_tag s_("Runners|active"), variant: :success, size: :sm
= _('- Available to run jobs.')
%li
- %span.badge.badge-pill.gl-badge.sm.badge-danger paused
+ = gl_badge_tag s_("Runners|paused"), variant: :danger, size: :sm
= _('- Not available to run jobs.')
diff --git a/app/views/shared/runners/_runner_details.html.haml b/app/views/shared/runners/_runner_details.html.haml
index a7b2947057d..7a35b1cec0a 100644
--- a/app/views/shared/runners/_runner_details.html.haml
+++ b/app/views/shared/runners/_runner_details.html.haml
@@ -28,8 +28,7 @@
%td= s_('Runners|Tags')
%td
- runner.tag_list.sort.each do |tag|
- %span.badge.badge-primary
- = tag
+ = gl_badge_tag tag, variant: :info
%tr
%td= s_('Runners|Name')
%td= runner.name
diff --git a/app/views/shared/runners/_runner_type_badge.html.haml b/app/views/shared/runners/_runner_type_badge.html.haml
index e0318006f09..c6a18c804da 100644
--- a/app/views/shared/runners/_runner_type_badge.html.haml
+++ b/app/views/shared/runners/_runner_type_badge.html.haml
@@ -1,10 +1,7 @@
- if runner.instance_type?
- %span.badge.badge-pill.gl-badge.badge-success
- = s_('Runners|shared')
+ = gl_badge_tag s_('Runners|shared'), variant: :success
- elsif runner.group_type?
- %span.badge.badge-pill.gl-badge.badge-success
- = s_('Runners|group')
+ = gl_badge_tag s_('Runners|group'), variant: :success
- else
- %span.badge.badge-pill.gl-badge.badge-info
- = s_('Runners|specific')
+ = gl_badge_tag s_('Runners|specific'), variant: :info
diff --git a/app/views/shared/snippets/_embed.html.haml b/app/views/shared/snippets/_embed.html.haml
index b5abd00b8fd..5744fc9fba6 100644
--- a/app/views/shared/snippets/_embed.html.haml
+++ b/app/views/shared/snippets/_embed.html.haml
@@ -17,5 +17,5 @@
= embedded_raw_snippet_button(@snippet, blob)
= embedded_snippet_download_button(@snippet, blob)
- %article.file-holder.snippet-file-content
+ %figure.file-holder.snippet-file-content{ "aria-label" => _('Code snippet') }
= render 'projects/blob/viewer', viewer: blob.simple_viewer, load_async: false, external_embed: true
diff --git a/app/views/shared/web_hooks/_hook.html.haml b/app/views/shared/web_hooks/_hook.html.haml
index fd124c2967d..45baa7e2184 100644
--- a/app/views/shared/web_hooks/_hook.html.haml
+++ b/app/views/shared/web_hooks/_hook.html.haml
@@ -1,7 +1,15 @@
%li
.row
.col-md-8.col-lg-7
- %strong.light-header= hook.url
+ %strong.light-header
+ = hook.url
+ - if hook.rate_limited?
+ %span.gl-badge.badge-danger.badge-pill.sm= _('Disabled')
+ - elsif hook.permanently_disabled?
+ %span.gl-badge.badge-danger.badge-pill.sm= s_('Webhooks|Failed to connect')
+ - elsif hook.temporarily_disabled?
+ %span.gl-badge.badge-warning.badge-pill.sm= s_('Webhooks|Fails to connect')
+
%div
- hook.class.triggers.each_value do |trigger|
- if hook.public_send(trigger)
diff --git a/app/views/shared/web_hooks/_hook_errors.html.haml b/app/views/shared/web_hooks/_hook_errors.html.haml
new file mode 100644
index 00000000000..23010b8349c
--- /dev/null
+++ b/app/views/shared/web_hooks/_hook_errors.html.haml
@@ -0,0 +1,41 @@
+- strong_start = '<strong>'.html_safe
+- strong_end = '</strong>'.html_safe
+- link_start = '<a href="%{url}">'.html_safe
+- link_end = '</a>'.html_safe
+
+- if hook.rate_limited?
+ - support_path = 'https://support.gitlab.com/hc/en-us/requests/new'
+ - placeholders = { strong_start: strong_start,
+ strong_end: strong_end,
+ limit: hook.rate_limit,
+ support_link_start: link_start % { url: support_path },
+ support_link_end: link_end }
+ = render 'shared/global_alert',
+ title: s_('Webhooks|Webhook was automatically disabled'),
+ variant: :danger,
+ is_contained: true,
+ close_button_class: 'js-close' do
+ .gl-alert-body
+ = s_('Webhooks|The webhook was triggered more than %{limit} times per minute and is now disabled. To re-enable this webhook, fix the problems shown in %{strong_start}Recent events%{strong_end}, then re-test your settings. %{support_link_start}Contact Support%{support_link_end} if you need help re-enabling your webhook.').html_safe % placeholders
+- elsif hook.permanently_disabled?
+ = render 'shared/global_alert',
+ title: s_('Webhooks|Webhook failed to connect'),
+ variant: :danger,
+ is_contained: true,
+ close_button_class: 'js-close' do
+ .gl-alert-body
+ = s_('Webhooks|The webhook failed to connect, and is disabled. To re-enable it, check %{strong_start}Recent events%{strong_end} for error details, then test your settings below.').html_safe % { strong_start: strong_start, strong_end: strong_end }
+- elsif hook.temporarily_disabled?
+ - help_path = help_page_path('user/project/integrations/webhooks', anchor: 'webhook-fails-or-multiple-webhook-requests-are-triggered')
+ - placeholders = { strong_start: strong_start,
+ strong_end: strong_end,
+ retry_time: time_interval_in_words(hook.disabled_until - Time.now),
+ help_link_start: link_start % { url: help_path },
+ help_link_end: link_end }
+ = render 'shared/global_alert',
+ title: s_('Webhooks|Webhook fails to connect'),
+ variant: :warning,
+ is_contained: true,
+ close_button_class: 'js-close' do
+ .gl-alert-body
+ = s_('Webhooks|The webhook %{help_link_start}failed to connect%{help_link_end}, and will retry in %{retry_time}. To re-enable it, check %{strong_start}Recent events%{strong_end} for error details, then test your settings below.').html_safe % placeholders
diff --git a/app/views/shared/web_hooks/_title_and_docs.html.haml b/app/views/shared/web_hooks/_title_and_docs.html.haml
index f00f3473efa..c220b46f70f 100644
--- a/app/views/shared/web_hooks/_title_and_docs.html.haml
+++ b/app/views/shared/web_hooks/_title_and_docs.html.haml
@@ -4,7 +4,7 @@
= page_title
- if @project
- - integrations_link_start = '<a href="%{url}">'.html_safe % { url: scoped_integrations_path }
+ - integrations_link_start = '<a href="%{url}">'.html_safe % { url: scoped_integrations_path(project: @project) }
%p= _("%{webhooks_link_start}%{webhook_type}%{link_end} enable you to send notifications to web applications in response to events in a group or project. We recommend using an %{integrations_link_start}integration%{link_end} in preference to a webhook.").html_safe % { webhooks_link_start: webhooks_link_start, webhook_type: hook.pluralized_name, integrations_link_start: integrations_link_start, link_end: '</a>'.html_safe }
- else
%p= _("%{webhooks_link_start}%{webhook_type}%{link_end} enable you to send notifications to web applications in response to events in a group or project.").html_safe % { webhooks_link_start: webhooks_link_start, webhook_type: hook.pluralized_name, link_end: '</a>'.html_safe }
diff --git a/app/views/shared/wikis/_wiki_content.html.haml b/app/views/shared/wikis/_wiki_content.html.haml
new file mode 100644
index 00000000000..42e8037bb0f
--- /dev/null
+++ b/app/views/shared/wikis/_wiki_content.html.haml
@@ -0,0 +1,2 @@
+.js-wiki-page-content.md.gl-pt-2{ data: { qa_selector: 'wiki_page_content', testid: 'wiki_page_content', tracking_context: wiki_page_tracking_context(@page).to_json } }
+ = render_wiki_content(@page)
diff --git a/app/views/shared/wikis/show.html.haml b/app/views/shared/wikis/show.html.haml
index 8a5cd94bde9..e6980aae3e1 100644
--- a/app/views/shared/wikis/show.html.haml
+++ b/app/views/shared/wikis/show.html.haml
@@ -26,7 +26,6 @@
%div
- if can?(current_user, :create_wiki, @wiki.container) && @page.latest? && @valid_encoding
= link_to sprite_icon('pencil', css_class: 'gl-icon'), wiki_page_path(@wiki, @page, action: :edit), title: 'Edit', role: "button", class: 'btn gl-button btn-icon btn-default js-wiki-edit', data: { qa_selector: 'edit_page_button', testid: 'wiki_edit_button' }
- .js-wiki-page-content.md.gl-pt-2{ data: { qa_selector: 'wiki_page_content', testid: 'wiki_page_content', tracking_context: wiki_page_tracking_context(@page).to_json } }
- = render_wiki_content(@page)
+ = render 'shared/wikis/wiki_content'
= render 'shared/wikis/sidebar'
diff --git a/app/views/snippets/_snippets_scope_menu.html.haml b/app/views/snippets/_snippets_scope_menu.html.haml
index ac6dac8b322..35d21e45c47 100644
--- a/app/views/snippets/_snippets_scope_menu.html.haml
+++ b/app/views/snippets/_snippets_scope_menu.html.haml
@@ -1,31 +1,18 @@
- subject = local_assigns.fetch(:subject, current_user)
- include_private = local_assigns.fetch(:include_private, false)
+- params[:scope] ||= []
-.nav-links.snippet-scope-menu.mobile-separator.nav.nav-tabs
- %li{ class: active_when(params[:scope].nil?) }
- = link_to subject_snippets_path(subject) do
- = _("All")
- %span.badge.badge-muted.badge-pill.gl-badge.sm
- - if include_private
- = counts[:total]
- - else
- = counts[:are_public_or_internal]
-
+= gl_tabs_nav({ class: 'js-snippets-nav-tabs gl-border-b-0 gl-overflow-x-auto gl-flex-grow-1 gl-flex-nowrap' }) do
+ = gl_tab_link_to subject_snippets_path(subject), { item_active: params[:scope].empty? } do
+ = _('All')
+ = gl_tab_counter_badge(include_private ? counts[:total] : counts[:are_public_or_internal])
- if include_private
- %li{ class: active_when(params[:scope] == "are_private") }
- = link_to subject_snippets_path(subject, scope: 'are_private') do
- = _("Private")
- %span.badge.badge-muted.badge-pill.gl-badge.sm
- = counts[:are_private]
-
- %li{ class: active_when(params[:scope] == "are_internal") }
- = link_to subject_snippets_path(subject, scope: 'are_internal') do
- = _("Internal")
- %span.badge.badge-muted.badge-pill.gl-badge.sm
- = counts[:are_internal]
-
- %li{ class: active_when(params[:scope] == "are_public") }
- = link_to subject_snippets_path(subject, scope: 'are_public') do
- = _("Public")
- %span.badge.badge-muted.badge-pill.gl-badge.sm
- = counts[:are_public]
+ = gl_tab_link_to subject_snippets_path(subject, scope: 'are_private') do
+ = _('Private')
+ = gl_tab_counter_badge(counts[:are_private])
+ = gl_tab_link_to subject_snippets_path(subject, scope: 'are_internal') do
+ = _('Internal')
+ = gl_tab_counter_badge(counts[:are_internal])
+ = gl_tab_link_to subject_snippets_path(subject, scope: 'are_public') do
+ = _('Public')
+ = gl_tab_counter_badge(counts[:are_public])
diff --git a/app/views/users/_overview.html.haml b/app/views/users/_overview.html.haml
index 0d904de9372..7e745efd069 100644
--- a/app/views/users/_overview.html.haml
+++ b/app/views/users/_overview.html.haml
@@ -2,14 +2,14 @@
.row.d-none.d-sm-flex
.col-12.calendar-block.gl-my-3
- .user-calendar.light{ data: { calendar_path: user_calendar_path(@user, :json), calendar_activities_path: user_calendar_activities_path, utc_offset: local_time_instance(@user.timezone).now.utc_offset } }
+ .user-calendar.light{ data: { calendar_path: user_calendar_path(@user, :json), calendar_activities_path: user_calendar_activities_path, utc_offset: local_timezone_instance(@user.timezone).now.utc_offset } }
.gl-spinner.gl-spinner-md.gl-my-8
.user-calendar-error.invisible
= _('There was an error loading users activity calendar.')
%a.js-retry-load{ href: '#' }
= s_('UserProfile|Retry')
.user-calendar-activities
-- if @user.user_readme
+- if @user.user_readme&.rich_viewer
.row.justify-content-center
.col-12.col-md-10.col-lg-8.gl-my-6
.gl-display-flex
diff --git a/app/views/users/calendar_activities.html.haml b/app/views/users/calendar_activities.html.haml
index cffeb55597f..8da1aa09215 100644
--- a/app/views/users/calendar_activities.html.haml
+++ b/app/views/users/calendar_activities.html.haml
@@ -7,7 +7,7 @@
%li
%span.light.js-localtime{ :data => { :datetime => event.created_at.utc.strftime('%Y-%m-%dT%H:%M:%SZ'), :toggle => 'tooltip', :placement => 'top' } }
= sprite_icon('clock', css_class: 'gl-vertical-align-text-bottom')
- = event.created_at.to_time.in_time_zone(@user.timezone).strftime('%-I:%M%P')
+ = event.created_at.to_time.in_time_zone(local_timezone_instance(@user.timezone)).strftime('%-I:%M%P')
- if event.visible_to_user?(current_user)
- if event.push_action?
#{event.action_name} #{event.ref_type}
diff --git a/app/views/users/show.html.haml b/app/views/users/show.html.haml
index 522f0f771cd..ca276519758 100644
--- a/app/views/users/show.html.haml
+++ b/app/views/users/show.html.haml
@@ -2,8 +2,7 @@
- @hide_breadcrumbs = true
- @no_container = true
- page_title user_display_name(@user)
-- page_description @user.bio
-- header_title @user.name, user_path(@user)
+- page_description @user.bio unless @user.blocked? || !@user.confirmed?
- page_itemtype 'http://schema.org/Person'
- link_classes = "flex-grow-1 mx-1 "
diff --git a/app/views/users/terms/index.html.haml b/app/views/users/terms/index.html.haml
index 92095e78f69..c461250fc9b 100644
--- a/app/views/users/terms/index.html.haml
+++ b/app/views/users/terms/index.html.haml
@@ -1,23 +1,6 @@
-- redirect_params = { redirect: @redirect } if @redirect
-- accept_term_link = accept_term_path(@term, redirect_params)
+- content_for :page_specific_javascripts do
+ = render "layouts/google_tag_manager_head"
+ = render "layouts/one_trust"
+= render "layouts/google_tag_manager_body"
-- if Feature.enabled?(:terms_of_service_vue, current_user, default_enabled: :yaml)
- #js-terms-of-service{ data: { terms_data: terms_data(@term, @redirect) } }
-- else
- .card-body.rendered-terms{ data: { qa_selector: 'terms_content' } }
- = markdown_field(@term, :terms)
- - if current_user
- = render_if_exists 'devise/shared/form_phone_verification', accept_term_link: accept_term_link, inline: true
- .card-footer.footer-block.clearfix
- - if can?(current_user, :accept_terms, @term)
- .float-right
- = button_to accept_term_link, class: 'gl-button btn btn-confirm gl-ml-3', data: { qa_selector: 'accept_terms_button' } do
- = _('Accept terms')
- - else
- .float-right
- = link_to root_path, class: 'gl-button btn btn-confirm gl-ml-3' do
- = _('Continue')
- - if can?(current_user, :decline_terms, @term)
- .float-right
- = button_to decline_term_path(@term, redirect_params), class: 'gl-button btn btn-default gl-ml-3' do
- = _('Decline and sign out')
+#js-terms-of-service{ data: { terms_data: terms_data(@term, @redirect) } }