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

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/app/views
diff options
context:
space:
mode:
Diffstat (limited to 'app/views')
-rw-r--r--app/views/admin/application_settings/_account_and_limit.html.haml4
-rw-r--r--app/views/admin/application_settings/_ai_access.html.haml5
-rw-r--r--app/views/admin/application_settings/_ci_cd.html.haml6
-rw-r--r--app/views/admin/application_settings/_diff_limits.html.haml6
-rw-r--r--app/views/admin/application_settings/_email.html.haml2
-rw-r--r--app/views/admin/application_settings/_error_tracking.html.haml6
-rw-r--r--app/views/admin/application_settings/_gitlab_shell_operation_limits.html.haml19
-rw-r--r--app/views/admin/application_settings/_help_page.html.haml2
-rw-r--r--app/views/admin/application_settings/_localization.html.haml2
-rw-r--r--app/views/admin/application_settings/_runner_registrars_form.html.haml4
-rw-r--r--app/views/admin/application_settings/_signin.html.haml2
-rw-r--r--app/views/admin/application_settings/_slack.html.haml49
-rw-r--r--app/views/admin/application_settings/_usage.html.haml8
-rw-r--r--app/views/admin/application_settings/appearances/_form.html.haml13
-rw-r--r--app/views/admin/application_settings/appearances/_system_header_footer_form.html.haml2
-rw-r--r--app/views/admin/application_settings/general.html.haml2
-rw-r--r--app/views/admin/application_settings/network.html.haml3
-rw-r--r--app/views/admin/application_settings/service_usage_data.html.haml2
-rw-r--r--app/views/admin/applications/_delete_form.html.haml4
-rw-r--r--app/views/admin/applications/_form.html.haml2
-rw-r--r--app/views/admin/cohorts/_cohorts_table.html.haml2
-rw-r--r--app/views/admin/groups/show.html.haml2
-rw-r--r--app/views/admin/hooks/_form.html.haml4
-rw-r--r--app/views/admin/hooks/edit.html.haml18
-rw-r--r--app/views/admin/hooks/index.html.haml13
-rw-r--r--app/views/admin/labels/_label.html.haml4
-rw-r--r--app/views/admin/projects/show.html.haml6
-rw-r--r--app/views/admin/runners/edit.html.haml3
-rw-r--r--app/views/admin/sessions/_new_base.html.haml10
-rw-r--r--app/views/admin/sessions/_signin_box.html.haml2
-rw-r--r--app/views/admin/sessions/new.html.haml4
-rw-r--r--app/views/admin/sessions/two_factor.html.haml2
-rw-r--r--app/views/admin/topics/_topic.html.haml4
-rw-r--r--app/views/admin/users/_profile.html.haml2
-rw-r--r--app/views/admin/users/projects.html.haml6
-rw-r--r--app/views/admin/users/show.html.haml13
-rw-r--r--app/views/clusters/clusters/_integrations.html.haml16
-rw-r--r--app/views/clusters/clusters/_integrations_tab.html.haml4
-rw-r--r--app/views/clusters/clusters/show.html.haml1
-rw-r--r--app/views/dashboard/todos/_todo.html.haml4
-rw-r--r--app/views/dashboard/todos/index.html.haml2
-rw-r--r--app/views/devise/sessions/_new_crowd.html.haml2
-rw-r--r--app/views/devise/sessions/_new_ldap.html.haml2
-rw-r--r--app/views/devise/shared/_footer.html.haml19
-rw-r--r--app/views/devise/shared/_signup_box.html.haml30
-rw-r--r--app/views/devise/shared/_signup_omniauth_provider_list.haml4
-rw-r--r--app/views/devise/unlocks/new.html.haml18
-rw-r--r--app/views/discussions/_notes.html.haml24
-rw-r--r--app/views/events/_event_push.atom.haml2
-rw-r--r--app/views/explore/projects/_project.atom.builder14
-rw-r--r--app/views/explore/projects/topic.atom.builder9
-rw-r--r--app/views/explore/projects/topic.html.haml3
-rw-r--r--app/views/groups/group_members/index.html.haml8
-rw-r--r--app/views/groups/milestones/_form.html.haml16
-rw-r--r--app/views/groups/packages/index.html.haml1
-rw-r--r--app/views/groups/settings/_general.html.haml2
-rw-r--r--app/views/groups/settings/access_tokens/index.html.haml49
-rw-r--r--app/views/groups/settings/ci_cd/_form.html.haml2
-rw-r--r--app/views/import/fogbugz/new.html.haml3
-rw-r--r--app/views/invites/show.html.haml2
-rw-r--r--app/views/layouts/_google_tag_manager_head.html.haml1
-rw-r--r--app/views/layouts/_head.html.haml39
-rw-r--r--app/views/layouts/_header_search.html.haml2
-rw-r--r--app/views/layouts/_img_loader.html.haml2
-rw-r--r--app/views/layouts/_mailer.html.haml2
-rw-r--r--app/views/layouts/_page.html.haml4
-rw-r--r--app/views/layouts/_startup_css.haml9
-rw-r--r--app/views/layouts/_startup_css_activation.haml7
-rw-r--r--app/views/layouts/devise.html.haml22
-rw-r--r--app/views/layouts/devise_empty.html.haml16
-rw-r--r--app/views/layouts/errors.html.haml2
-rw-r--r--app/views/layouts/header/_current_user_dropdown.html.haml6
-rw-r--r--app/views/layouts/header/_default.html.haml18
-rw-r--r--app/views/layouts/header/_new_dropdown.html.haml2
-rw-r--r--app/views/layouts/in_product_marketing_mailer.html.haml2
-rw-r--r--app/views/layouts/jira_connect.html.haml2
-rw-r--r--app/views/layouts/nav/_ask_duo_button.html.haml13
-rw-r--r--app/views/layouts/nav/_top_bar.html.haml9
-rw-r--r--app/views/layouts/nav/sidebar/_organization.html.haml1
-rw-r--r--app/views/layouts/notify.html.haml2
-rw-r--r--app/views/layouts/oauth_error.html.haml2
-rw-r--r--app/views/layouts/organization.html.haml6
-rw-r--r--app/views/layouts/service_desk.html.haml2
-rw-r--r--app/views/layouts/signup_onboarding.html.haml21
-rw-r--r--app/views/layouts/simple_registration.html.haml11
-rw-r--r--app/views/notify/_successful_pipeline.html.haml3
-rw-r--r--app/views/notify/_successful_pipeline.text.erb7
-rw-r--r--app/views/notify/approved_merge_request_email.html.haml2
-rw-r--r--app/views/notify/import_issues_csv_email.html.haml16
-rw-r--r--app/views/notify/import_issues_csv_email.text.erb17
-rw-r--r--app/views/notify/issue_due_email.html.haml2
-rw-r--r--app/views/notify/merge_when_pipeline_succeeds_email.html.haml2
-rw-r--r--app/views/notify/pipeline_failed_email.html.haml5
-rw-r--r--app/views/notify/pipeline_failed_email.text.erb18
-rw-r--r--app/views/notify/pipeline_fixed_email.html.haml2
-rw-r--r--app/views/notify/pipeline_fixed_email.text.erb2
-rw-r--r--app/views/notify/pipeline_success_email.html.haml2
-rw-r--r--app/views/notify/pipeline_success_email.text.erb2
-rw-r--r--app/views/notify/prometheus_alert_fired_email.html.haml4
-rw-r--r--app/views/notify/prometheus_alert_fired_email.text.erb4
-rw-r--r--app/views/notify/repository_push_email.html.haml2
-rw-r--r--app/views/notify/repository_push_email.text.haml2
-rw-r--r--app/views/notify/unapproved_merge_request_email.html.haml2
-rw-r--r--app/views/organizations/organizations/directory.html.haml2
-rw-r--r--app/views/organizations/organizations/groups_and_projects.html.haml3
-rw-r--r--app/views/organizations/organizations/show.html.haml2
-rw-r--r--app/views/profiles/accounts/_providers.html.haml4
-rw-r--r--app/views/profiles/accounts/show.html.haml144
-rw-r--r--app/views/profiles/active_sessions/_active_session.html.haml6
-rw-r--r--app/views/profiles/active_sessions/index.html.haml23
-rw-r--r--app/views/profiles/audit_log.html.haml17
-rw-r--r--app/views/profiles/chat_names/_chat_name.html.haml2
-rw-r--r--app/views/profiles/chat_names/index.html.haml44
-rw-r--r--app/views/profiles/comment_templates/index.html.haml19
-rw-r--r--app/views/profiles/emails/index.html.haml32
-rw-r--r--app/views/profiles/gpg_keys/_key.html.haml7
-rw-r--r--app/views/profiles/gpg_keys/index.html.haml40
-rw-r--r--app/views/profiles/keys/_key_details.html.haml6
-rw-r--r--app/views/profiles/keys/index.html.haml48
-rw-r--r--app/views/profiles/notifications/_email_settings.html.haml7
-rw-r--r--app/views/profiles/notifications/_group_settings.html.haml16
-rw-r--r--app/views/profiles/notifications/_project_settings.html.haml13
-rw-r--r--app/views/profiles/notifications/show.html.haml102
-rw-r--r--app/views/profiles/passwords/edit.html.haml60
-rw-r--r--app/views/profiles/personal_access_tokens/index.html.haml37
-rw-r--r--app/views/profiles/preferences/show.html.haml277
-rw-r--r--app/views/profiles/show.html.haml282
-rw-r--r--app/views/profiles/two_factor_auths/show.html.haml5
-rw-r--r--app/views/projects/_activity.html.haml3
-rw-r--r--app/views/projects/_customize_workflow.html.haml2
-rw-r--r--app/views/projects/_export.html.haml14
-rw-r--r--app/views/projects/_find_file_link.html.haml2
-rw-r--r--app/views/projects/_home_panel.html.haml4
-rw-r--r--app/views/projects/_import_project_pane.html.haml4
-rw-r--r--app/views/projects/_new_project_fields.html.haml2
-rw-r--r--app/views/projects/_readme.html.haml2
-rw-r--r--app/views/projects/_service_desk_settings.html.haml4
-rw-r--r--app/views/projects/_wiki.html.haml2
-rw-r--r--app/views/projects/artifacts/browse.html.haml6
-rw-r--r--app/views/projects/artifacts/external_file.html.haml5
-rw-r--r--app/views/projects/blob/_breadcrumb.html.haml13
-rw-r--r--app/views/projects/blob/_new_dir.html.haml2
-rw-r--r--app/views/projects/branches/_branch.html.haml62
-rw-r--r--app/views/projects/branches/_commit.html.haml4
-rw-r--r--app/views/projects/branches/_panel.html.haml4
-rw-r--r--app/views/projects/branches/index.html.haml14
-rw-r--r--app/views/projects/branches/new.html.haml2
-rw-r--r--app/views/projects/buttons/_clone.html.haml2
-rw-r--r--app/views/projects/buttons/_download.html.haml2
-rw-r--r--app/views/projects/buttons/_download_links.html.haml2
-rw-r--r--app/views/projects/buttons/_fork.html.haml12
-rw-r--r--app/views/projects/buttons/_star.html.haml9
-rw-r--r--app/views/projects/ci/builds/_build.html.haml29
-rw-r--r--app/views/projects/commit/_commit_box.html.haml2
-rw-r--r--app/views/projects/commit/_pipelines_list.haml1
-rw-r--r--app/views/projects/commit/_signature_badge_user.html.haml21
-rw-r--r--app/views/projects/commit/_verified_system_signature_badge.html.haml5
-rw-r--r--app/views/projects/commit/x509/_signature_badge_user.html.haml19
-rw-r--r--app/views/projects/commits/_commit.html.haml2
-rw-r--r--app/views/projects/commits/_commit_list.html.haml2
-rw-r--r--app/views/projects/commits/show.html.haml5
-rw-r--r--app/views/projects/compare/index.html.haml14
-rw-r--r--app/views/projects/compare/show.html.haml10
-rw-r--r--app/views/projects/confluences/show.html.haml2
-rw-r--r--app/views/projects/deploy_keys/edit.html.haml2
-rw-r--r--app/views/projects/diffs/_diffs.html.haml2
-rw-r--r--app/views/projects/diffs/_file.html.haml4
-rw-r--r--app/views/projects/edit.html.haml14
-rw-r--r--app/views/projects/environments/edit.html.haml4
-rw-r--r--app/views/projects/environments/empty_metrics.html.haml14
-rw-r--r--app/views/projects/environments/metrics.html.haml6
-rw-r--r--app/views/projects/environments/new.html.haml2
-rw-r--r--app/views/projects/environments/terminal.html.haml3
-rw-r--r--app/views/projects/find_file/show.html.haml8
-rw-r--r--app/views/projects/forks/error.html.haml2
-rw-r--r--app/views/projects/forks/index.html.haml10
-rw-r--r--app/views/projects/hook_logs/show.html.haml2
-rw-r--r--app/views/projects/hooks/edit.html.haml15
-rw-r--r--app/views/projects/hooks/index.html.haml13
-rw-r--r--app/views/projects/integrations/shimos/show.html.haml2
-rw-r--r--app/views/projects/issues/_related_branches.html.haml41
-rw-r--r--app/views/projects/issues/service_desk.html.haml31
-rw-r--r--app/views/projects/issues/service_desk/_issue.html.haml2
-rw-r--r--app/views/projects/issues/service_desk/_nav_btns.html.haml11
-rw-r--r--app/views/projects/issues/service_desk/_service_desk_empty_state.html.haml2
-rw-r--r--app/views/projects/issues/service_desk/_service_desk_info_content.html.haml2
-rw-r--r--app/views/projects/jobs/_table.html.haml2
-rw-r--r--app/views/projects/jobs/show.html.haml2
-rw-r--r--app/views/projects/labels/index.html.haml27
-rw-r--r--app/views/projects/mattermosts/_no_teams.html.haml2
-rw-r--r--app/views/projects/merge_requests/_close_reopen_draft_report_toggle.html.haml2
-rw-r--r--app/views/projects/merge_requests/_form.html.haml1
-rw-r--r--app/views/projects/merge_requests/_mr_box.html.haml2
-rw-r--r--app/views/projects/merge_requests/_source_and_target.html.haml10
-rw-r--r--app/views/projects/merge_requests/_widget.html.haml7
-rw-r--r--app/views/projects/merge_requests/creations/_new_submit.html.haml1
-rw-r--r--app/views/projects/milestones/_form.html.haml21
-rw-r--r--app/views/projects/milestones/index.html.haml6
-rw-r--r--app/views/projects/ml/models/index.html.haml5
-rw-r--r--app/views/projects/no_repo.html.haml10
-rw-r--r--app/views/projects/packages/packages/index.html.haml1
-rw-r--r--app/views/projects/pages/_access.html.haml2
-rw-r--r--app/views/projects/pages/_list.html.haml4
-rw-r--r--app/views/projects/pages/new.html.haml8
-rw-r--r--app/views/projects/pages/show.html.haml4
-rw-r--r--app/views/projects/pages_domains/_dns.html.haml6
-rw-r--r--app/views/projects/pages_domains/_lets_encrypt_callout.html.haml2
-rw-r--r--app/views/projects/pages_domains/new.html.haml2
-rw-r--r--app/views/projects/pages_domains/show.html.haml2
-rw-r--r--app/views/projects/pipeline_schedules/_form.html.haml2
-rw-r--r--app/views/projects/pipeline_schedules/_pipeline_schedule.html.haml9
-rw-r--r--app/views/projects/pipeline_schedules/edit.html.haml3
-rw-r--r--app/views/projects/pipeline_schedules/index.html.haml6
-rw-r--r--app/views/projects/pipeline_schedules/new.html.haml2
-rw-r--r--app/views/projects/pipelines/_info.html.haml75
-rw-r--r--app/views/projects/pipelines/show.html.haml8
-rw-r--r--app/views/projects/project_templates/_template.html.haml2
-rw-r--r--app/views/projects/protected_tags/shared/_index.html.haml2
-rw-r--r--app/views/projects/protected_tags/shared/_protected_tag.html.haml2
-rw-r--r--app/views/projects/runners/_group_runners.html.haml4
-rw-r--r--app/views/projects/runners/_project_runners.html.haml26
-rw-r--r--app/views/projects/runners/_runner.html.haml13
-rw-r--r--app/views/projects/settings/_archive.html.haml12
-rw-r--r--app/views/projects/settings/_general.html.haml2
-rw-r--r--app/views/projects/settings/access_tokens/index.html.haml29
-rw-r--r--app/views/projects/settings/ci_cd/_form.html.haml2
-rw-r--r--app/views/projects/settings/ci_cd/show.html.haml5
-rw-r--r--app/views/projects/settings/slacks/edit.html.haml2
-rw-r--r--app/views/projects/snippets/index.html.haml2
-rw-r--r--app/views/projects/tags/_edit_release_button.html.haml3
-rw-r--r--app/views/projects/tags/index.html.haml5
-rw-r--r--app/views/projects/tags/show.html.haml6
-rw-r--r--app/views/projects/tracing/index.html.haml4
-rw-r--r--app/views/protected_branches/shared/_protected_branch.html.haml2
-rw-r--r--app/views/registrations/welcome/show.html.haml1
-rw-r--r--app/views/search/results/_issuable.html.haml7
-rw-r--r--app/views/search/results/_wiki_blob.html.haml5
-rw-r--r--app/views/sent_notifications/unsubscribe.html.haml2
-rw-r--r--app/views/shared/_auto_devops_implicitly_enabled_banner.html.haml4
-rw-r--r--app/views/shared/_md_preview.html.haml11
-rw-r--r--app/views/shared/_new_merge_request_checkbox.html.haml3
-rw-r--r--app/views/shared/_no_ssh.html.haml4
-rw-r--r--app/views/shared/_project_limit.html.haml4
-rw-r--r--app/views/shared/_prometheus_configuration_banner.html.haml4
-rw-r--r--app/views/shared/_registration_features_discovery_message.html.haml2
-rw-r--r--app/views/shared/_remote_mirror_update_button.html.haml3
-rw-r--r--app/views/shared/_service_ping_consent.html.haml13
-rw-r--r--app/views/shared/_two_factor_auth_recovery_settings_check.html.haml2
-rw-r--r--app/views/shared/access_tokens/_form.html.haml35
-rw-r--r--app/views/shared/blob/_markdown_buttons.html.haml27
-rw-r--r--app/views/shared/deploy_tokens/_form.html.haml2
-rw-r--r--app/views/shared/deploy_tokens/_table.html.haml2
-rw-r--r--app/views/shared/doorkeeper/applications/_form.html.haml2
-rw-r--r--app/views/shared/doorkeeper/applications/_index.html.haml164
-rw-r--r--app/views/shared/doorkeeper/applications/_show.html.haml4
-rw-r--r--app/views/shared/empty_states/_issues.html.haml8
-rw-r--r--app/views/shared/empty_states/_labels.html.haml6
-rw-r--r--app/views/shared/empty_states/_merge_requests.html.haml6
-rw-r--r--app/views/shared/empty_states/_priority_labels.html.haml6
-rw-r--r--app/views/shared/empty_states/_profile_tabs.html.haml4
-rw-r--r--app/views/shared/empty_states/_snippets.html.haml4
-rw-r--r--app/views/shared/empty_states/_wikis.html.haml4
-rw-r--r--app/views/shared/file_hooks/_index.html.haml50
-rw-r--r--app/views/shared/form_elements/_apply_generated_description_warning.haml13
-rw-r--r--app/views/shared/form_elements/_description.html.haml3
-rw-r--r--app/views/shared/hook_logs/_index.html.haml13
-rw-r--r--app/views/shared/integrations/gitlab_slack_application/_slack_button.html.haml4
-rw-r--r--app/views/shared/integrations/gitlab_slack_application/_slack_integration_form.html.haml13
-rw-r--r--app/views/shared/integrations/prometheus/_custom_metrics.html.haml2
-rw-r--r--app/views/shared/integrations/slack_slash_commands/_help.html.haml2
-rw-r--r--app/views/shared/issuable/_form.html.haml6
-rw-r--r--app/views/shared/issuable/_search_bar.html.haml56
-rw-r--r--app/views/shared/issuable/_sidebar.html.haml4
-rw-r--r--app/views/shared/issuable/_sidebar_assignees.html.haml1
-rw-r--r--app/views/shared/issuable/_status_box.html.haml2
-rw-r--r--app/views/shared/issue_type/_details_header.html.haml3
-rw-r--r--app/views/shared/members/_manage_access_button.html.haml6
-rw-r--r--app/views/shared/members/_member.html.haml2
-rw-r--r--app/views/shared/milestones/_labels_tab.html.haml8
-rw-r--r--app/views/shared/milestones/_milestone.html.haml4
-rw-r--r--app/views/shared/milestones/_sidebar.html.haml4
-rw-r--r--app/views/shared/nav/_sidebar.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/notes/_form.html.haml6
-rw-r--r--app/views/shared/notes/_hints.html.haml12
-rw-r--r--app/views/shared/projects/_search_form.html.haml2
-rw-r--r--app/views/shared/web_hooks/_form.html.haml35
-rw-r--r--app/views/shared/web_hooks/_hook.html.haml10
-rw-r--r--app/views/shared/web_hooks/_index.html.haml33
-rw-r--r--app/views/shared/web_hooks/_title_and_docs.html.haml10
-rw-r--r--app/views/shared/web_hooks/_web_hook_disabled_alert.html.haml2
-rw-r--r--app/views/shared/wikis/_main_links.html.haml4
-rw-r--r--app/views/shared/wikis/_sidebar.html.haml2
-rw-r--r--app/views/shared/wikis/diff.html.haml2
-rw-r--r--app/views/shared/wikis/pages.html.haml3
-rw-r--r--app/views/shared/wikis/show.html.haml17
-rw-r--r--app/views/users/_follow_user.html.haml11
-rw-r--r--app/views/users/_overview.html.haml6
-rw-r--r--app/views/users/_profile_basic_info.html.haml7
-rw-r--r--app/views/users/_view_gpg_keys.html.haml5
-rw-r--r--app/views/users/_view_user_in_admin_area.html.haml4
-rw-r--r--app/views/users/calendar_activities.html.haml2
-rw-r--r--app/views/users/show.html.haml56
304 files changed, 1754 insertions, 1825 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 d29fa9c5b85..af67ed28309 100644
--- a/app/views/admin/application_settings/_account_and_limit.html.haml
+++ b/app/views/admin/application_settings/_account_and_limit.html.haml
@@ -51,11 +51,11 @@
= f.text_field :user_default_internal_regex, placeholder: _('Regex pattern'), class: 'form-control gl-form-input gl-mt-2'
.help-block
= _('Specify an email address regex pattern to identify default internal users.')
- = link_to _('Learn more.'), help_page_path('user/admin_area/external_users', anchor: 'set-a-new-user-to-external'), target: '_blank', rel: 'noopener noreferrer'
+ = link_to _('Learn more.'), help_page_path('administration/external_users', anchor: 'set-a-new-user-to-external'), target: '_blank', rel: 'noopener noreferrer'
- unless Gitlab.com?
.form-group
= f.label :deactivate_dormant_users, _('Dormant users'), class: 'label-bold'
- - dormant_users_help_link = help_page_path('user/admin_area/moderate_users', anchor: 'automatically-deactivate-dormant-users')
+ - dormant_users_help_link = help_page_path('administration/moderate_users', anchor: 'automatically-deactivate-dormant-users')
- dormant_users_help_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: dormant_users_help_link }
= f.gitlab_ui_checkbox_component :deactivate_dormant_users, _('Deactivate dormant users after a period of inactivity'), help_text: _('Users can reactivate their account by signing in. %{link_start}Learn more.%{link_end}').html_safe % { link_start: dormant_users_help_link_start, link_end: '</a>'.html_safe }
.form-group
diff --git a/app/views/admin/application_settings/_ai_access.html.haml b/app/views/admin/application_settings/_ai_access.html.haml
index 41b0a08128e..97f46adef51 100644
--- a/app/views/admin/application_settings/_ai_access.html.haml
+++ b/app/views/admin/application_settings/_ai_access.html.haml
@@ -12,8 +12,7 @@
= render Pajamas::ButtonComponent.new(button_options: { class: 'js-settings-toggle' }) do
= expanded ? _('Collapse') : _('Expand')
%p
- = s_('CodeSuggestionsSM|Enable Code Suggestion for users of this GitLab instance.')
- = link_to sprite_icon('question-o'), code_suggestions_docs_url, target: '_blank', class: 'has-tooltip', title: _('More information')
+ = code_suggestions_description
.settings-content
= gitlab_ui_form_for @application_setting, url: general_admin_application_settings_path(anchor: 'js-ai-access-settings'), html: { class: 'fieldset-form', id: 'ai-access-settings' } do |f|
@@ -22,7 +21,7 @@
%fieldset
.form-group
= f.gitlab_ui_checkbox_component :instance_level_code_suggestions_enabled,
- s_('CodeSuggestionsSM|Turn on Code Suggestions for this instance. By turning on this feature, you:'),
+ s_('CodeSuggestionsSM|Enable Code Suggestions for this instance %{beta}').html_safe % { beta: gl_badge_tag(_('Beta'), variant: :neutral, size: :sm) },
help_text: code_suggestions_agreement
= f.label :ai_access_token, token_label, class: 'label-bold'
= f.password_field :ai_access_token, value: token_value, autocomplete: 'on', class: 'form-control gl-form-input', aria: { describedby: 'code_suggestions_token_explanation' }
diff --git a/app/views/admin/application_settings/_ci_cd.html.haml b/app/views/admin/application_settings/_ci_cd.html.haml
index 0c9d5a5a8df..0125c83dc72 100644
--- a/app/views/admin/application_settings/_ci_cd.html.haml
+++ b/app/views/admin/application_settings/_ci_cd.html.haml
@@ -28,13 +28,13 @@
= f.number_field :max_artifacts_size, class: 'form-control gl-form-input'
.form-text.text-muted
= _("The maximum file size for job artifacts.")
- = link_to _('Learn more.'), help_page_path('user/admin_area/settings/continuous_integration', anchor: 'maximum-artifacts-size')
+ = link_to _('Learn more.'), help_page_path('administration/settings/continuous_integration', anchor: 'maximum-artifacts-size')
.form-group
= f.label :default_artifacts_expire_in, _('Default artifacts expiration'), class: 'label-bold'
= f.text_field :default_artifacts_expire_in, class: 'form-control gl-form-input'
.form-text.text-muted
= html_escape(_("Set the default expiration time for job artifacts in all projects. Set to %{code_open}0%{code_close} to never expire artifacts by default. If no unit is written, it defaults to seconds. For example, these are all equivalent: %{code_open}3600%{code_close}, %{code_open}60 minutes%{code_close}, or %{code_open}one hour%{code_close}.")) % { code_open: '<code>'.html_safe, code_close: '</code>'.html_safe }
- = link_to _('Learn more.'), help_page_path('user/admin_area/settings/continuous_integration', anchor: 'default-artifacts-expiration')
+ = link_to _('Learn more.'), help_page_path('administration/settings/continuous_integration', anchor: 'default-artifacts-expiration')
.form-group
= f.gitlab_ui_checkbox_component :keep_latest_artifact, s_('AdminSettings|Keep the latest artifacts for all jobs in the latest successful pipelines'), help_text: s_('AdminSettings|The latest artifacts for all jobs in the most recent successful pipelines in each project are stored and do not expire.')
.form-group
@@ -42,7 +42,7 @@
= f.text_field :archive_builds_in_human_readable, class: 'form-control gl-form-input'
.form-text.text-muted
= html_escape(_("Jobs older than the configured time are considered expired and are archived. Archived jobs can no longer be retried. Leave empty to never archive jobs automatically. The default unit is in days, but you can use other units, for example %{code_open}15 days%{code_close}, %{code_open}1 month%{code_close}, %{code_open}2 years%{code_close}. Minimum value is 1 day.")) % { code_open: '<code>'.html_safe, code_close: '</code>'.html_safe }
- = link_to _('Learn more.'), help_page_path('user/admin_area/settings/continuous_integration', anchor: 'archive-jobs')
+ = link_to _('Learn more.'), help_page_path('administration/settings/continuous_integration', anchor: 'archive-jobs')
.form-group
= f.gitlab_ui_checkbox_component :protected_ci_variables, s_('AdminSettings|Protect CI/CD variables by default'), help_text: s_('AdminSettings|New CI/CD variables in projects and groups default to protected.')
.form-group
diff --git a/app/views/admin/application_settings/_diff_limits.html.haml b/app/views/admin/application_settings/_diff_limits.html.haml
index 153600f1299..f8bd5b68431 100644
--- a/app/views/admin/application_settings/_diff_limits.html.haml
+++ b/app/views/admin/application_settings/_diff_limits.html.haml
@@ -9,7 +9,7 @@
= _("Diff files surpassing this limit will be presented as 'too large' and won't be expandable.")
= link_to sprite_icon('question-o'),
- help_page_path('user/admin_area/diff_limits',
+ help_page_path('administration/diff_limits',
anchor: 'diff-limits-administration')
= f.label :diff_max_files, _('Maximum files in a diff'), class: 'label-light'
@@ -18,7 +18,7 @@
= _("Diff files surpassing this limit will be presented as 'too large' and won't be expandable.")
= link_to sprite_icon('question-o'),
- help_page_path('user/admin_area/diff_limits',
+ help_page_path('administration/diff_limits',
anchor: 'diff-limits-administration')
= f.label :diff_max_lines, _('Maximum lines in a diff'), class: 'label-light'
@@ -27,6 +27,6 @@
= _("Diff files surpassing this limit will be presented as 'too large' and won't be expandable.")
= link_to sprite_icon('question-o'),
- help_page_path('user/admin_area/diff_limits',
+ help_page_path('administration/diff_limits',
anchor: 'diff-limits-administration')
= f.submit _('Save changes'), pajamas_button: true
diff --git a/app/views/admin/application_settings/_email.html.haml b/app/views/admin/application_settings/_email.html.haml
index 80a7d3607ef..2f31eb5f6d1 100644
--- a/app/views/admin/application_settings/_email.html.haml
+++ b/app/views/admin/application_settings/_email.html.haml
@@ -10,7 +10,7 @@
= f.label :commit_email_hostname, _('Custom hostname (for private commit emails)'), class: 'label-bold'
= f.text_field :commit_email_hostname, class: 'form-control gl-form-input'
.form-text.text-muted
- - commit_email_hostname_docs_link = link_to _('Learn more'), help_page_path('user/admin_area/settings/email.md', anchor: 'custom-hostname-for-private-commit-emails'), target: '_blank', rel: 'noopener noreferrer'
+ - commit_email_hostname_docs_link = link_to _('Learn more'), help_page_path('administration/settings/email.md', anchor: 'custom-hostname-for-private-commit-emails'), target: '_blank', rel: 'noopener noreferrer'
= _("Hostname used in private commit emails. %{learn_more}").html_safe % { learn_more: commit_email_hostname_docs_link }
= render_if_exists 'admin/application_settings/email_additional_text_setting', form: f
diff --git a/app/views/admin/application_settings/_error_tracking.html.haml b/app/views/admin/application_settings/_error_tracking.html.haml
index aa42cd99e89..b57371286d5 100644
--- a/app/views/admin/application_settings/_error_tracking.html.haml
+++ b/app/views/admin/application_settings/_error_tracking.html.haml
@@ -20,9 +20,9 @@
%p.text-secondary
= s_("ErrorTracking|Access token is %{token_in_code_tag}").html_safe % { token_in_code_tag: content_tag(:code, Gitlab::CurrentSettings.error_tracking_access_token, id: 'error-tracking-access-token') }
.form-inline
- = button_to _("Reset error tracking access token"), reset_error_tracking_access_token_admin_application_settings_path,
- method: :put, class: 'gl-button btn btn-danger btn-sm',
- data: { confirm: _('Are you sure you want to reset the error tracking access token?') }
+ - reset_url = reset_error_tracking_access_token_admin_application_settings_url
+ = render Pajamas::ButtonComponent.new(method: :put, href: reset_url, variant: :danger, size: :small, button_options: { data: { confirm: _('Are you sure you want to reset the error tracking access token?') }}) do
+ = _("Reset error tracking access token")
= gitlab_ui_form_for @application_setting, url: general_admin_application_settings_path(anchor: 'js-error-tracking-settings'), html: { class: 'fieldset-form', id: 'error-tracking-settings' } do |f|
= form_errors(@application_setting) if expanded
diff --git a/app/views/admin/application_settings/_gitlab_shell_operation_limits.html.haml b/app/views/admin/application_settings/_gitlab_shell_operation_limits.html.haml
new file mode 100644
index 00000000000..4bd44b922fa
--- /dev/null
+++ b/app/views/admin/application_settings/_gitlab_shell_operation_limits.html.haml
@@ -0,0 +1,19 @@
+%section.settings.no-animate#js-gitlab-shell-operation-limits-settings{ class: ('expanded' if expanded_by_default?), 'data-testid': 'gitlab-shell-operation-limits' }
+ .settings-header
+ %h4.settings-title.js-settings-toggle.js-settings-toggle-trigger-only
+ = s_('ShellOperations|Git SSH operations rate limit')
+ = render Pajamas::ButtonComponent.new(button_options: { class: 'js-settings-toggle' }) do
+ = expanded_by_default? ? _('Collapse') : _('Expand')
+ %p
+ = s_('ShellOperations|Limit the number of Git operations a user can perform per minute, per repository.')
+ = link_to _('Learn more.'), help_page_path('user/admin_area/settings/rate_limits_on_git_ssh_operations.md'), target: '_blank', rel: 'noopener noreferrer'
+ .settings-content
+ = gitlab_ui_form_for @application_setting, url: network_admin_application_settings_path(anchor: 'js-gitlab-shell-operation-limits-settings'), html: { class: 'fieldset-form' } do |f|
+ = form_errors(@application_setting)
+
+ %fieldset
+ .form-group
+ = f.label :gitlab_shell_operation_limit, s_('ShellOperations|Maximum number of Git operations per minute'), class: 'gl-font-bold'
+ = f.number_field :gitlab_shell_operation_limit, class: 'form-control gl-form-input'
+
+ = f.submit _('Save changes'), pajamas_button: true
diff --git a/app/views/admin/application_settings/_help_page.html.haml b/app/views/admin/application_settings/_help_page.html.haml
index e76a83662af..9509806fc41 100644
--- a/app/views/admin/application_settings/_help_page.html.haml
+++ b/app/views/admin/application_settings/_help_page.html.haml
@@ -18,7 +18,7 @@
.form-group
= f.label :help_page_documentation_base_url, _('Documentation pages URL'), class: 'gl-font-weight-bold'
= f.text_field :help_page_documentation_base_url, class: 'form-control gl-form-input', placeholder: 'https://docs.gitlab.com'
- - docs_link_url = help_page_path('user/admin_area/settings/help_page', anchor: 'destination-requirements')
+ - docs_link_url = help_page_path('administration/settings/help_page', anchor: 'destination-requirements')
- docs_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: docs_link_url }
%span.form-text.text-muted#support_help_block= html_escape(_('Requests for pages at %{code_start}%{help_text_url}%{code_end} redirect to the URL. The destination must meet certain requirements. %{docs_link_start}Learn more.%{docs_link_end}')) % { code_start: '<code>'.html_safe, help_text_url: help_url, code_end: '</code>'.html_safe, docs_link_start: docs_link_start, docs_link_end: '</a>'.html_safe }
= f.submit _('Save changes'), pajamas_button: true
diff --git a/app/views/admin/application_settings/_localization.html.haml b/app/views/admin/application_settings/_localization.html.haml
index 669c47bafba..19d321ca205 100644
--- a/app/views/admin/application_settings/_localization.html.haml
+++ b/app/views/admin/application_settings/_localization.html.haml
@@ -7,7 +7,7 @@
= f.select :first_day_of_week, first_day_of_week_choices, {}, class: 'form-control'
.form-text.text-muted
= _('Default first day of the week in calendars and date pickers.')
- = link_to _('Learn more.'), help_page_path('user/admin_area/settings/index.md', anchor: 'default-first-day-of-the-week'), target: '_blank', rel: 'noopener noreferrer'
+ = link_to _('Learn more.'), help_page_path('administration/settings/index.md', anchor: 'default-first-day-of-the-week'), target: '_blank', rel: 'noopener noreferrer'
.form-group
= f.label :time_tracking, _('Time tracking'), class: 'label-bold'
diff --git a/app/views/admin/application_settings/_runner_registrars_form.html.haml b/app/views/admin/application_settings/_runner_registrars_form.html.haml
index 53832e93ed2..b112c273aad 100644
--- a/app/views/admin/application_settings/_runner_registrars_form.html.haml
+++ b/app/views/admin/application_settings/_runner_registrars_form.html.haml
@@ -7,7 +7,7 @@
= s_('Runners|Runner version management')
%span.form-text.gl-mb-3.gl-mt-0
- help_text = s_('Runners|Official runner version data is periodically fetched from GitLab.com to determine whether the runners need upgrades.')
- - learn_more_link = link_to _('Learn more.'), help_page_path('ci/runners/configure_runners.md', anchor: 'determine-which-runners-need-to-be-upgraded'), target: '_blank', rel: 'noopener noreferrer'
+ - learn_more_link = link_to _('Learn more.'), help_page_path('ci/runners/runners_scope.md', anchor: 'determine-which-runners-need-to-be-upgraded'), target: '_blank', rel: 'noopener noreferrer'
= f.gitlab_ui_checkbox_component :update_runner_versions_enabled,
s_('Runners|Fetch GitLab Runner release version data from GitLab.com'),
help_text: '%{help_text} %{learn_more_link}'.html_safe % { help_text: help_text, learn_more_link: learn_more_link }
@@ -16,7 +16,7 @@
= s_('Runners|Runner registration')
%span.form-text.gl-mb-3.gl-mt-0
= s_('Runners|If both settings are disabled, new runners cannot be registered.')
- = link_to _('Learn more.'), help_page_path('user/admin_area/settings/continuous_integration', anchor: 'restrict-runner-registration-by-all-users-in-an-instance'), target: '_blank', rel: 'noopener noreferrer'
+ = link_to _('Learn more.'), help_page_path('administration/settings/continuous_integration', anchor: 'restrict-runner-registration-by-all-users-in-an-instance'), target: '_blank', rel: 'noopener noreferrer'
= hidden_field_tag "application_setting[valid_runner_registrars][]", nil
- ApplicationSetting::VALID_RUNNER_REGISTRAR_TYPES.each do |type|
= f.gitlab_ui_checkbox_component :valid_runner_registrars, s_("Runners|Members of the %{type} can register runners") % { type: type },
diff --git a/app/views/admin/application_settings/_signin.html.haml b/app/views/admin/application_settings/_signin.html.haml
index 85841059c5e..5518122b5cf 100644
--- a/app/views/admin/application_settings/_signin.html.haml
+++ b/app/views/admin/application_settings/_signin.html.haml
@@ -32,7 +32,7 @@
= f.label :admin_mode, _('Admin mode'), class: 'label-bold'
= sprite_icon('lock', css_class: 'gl-icon')
- help_text = _('Require additional authentication for administrative tasks.')
- - help_link = link_to _('Learn more.'), help_page_path('user/admin_area/settings/sign_in_restrictions', anchor: 'admin-mode'), target: '_blank', rel: 'noopener noreferrer'
+ - help_link = link_to _('Learn more.'), help_page_path('administration/settings/sign_in_restrictions', anchor: 'admin-mode'), target: '_blank', rel: 'noopener noreferrer'
= f.gitlab_ui_checkbox_component :admin_mode,
_('Enable admin mode'),
help_text: '%{help_text} %{help_link}'.html_safe % { help_text: help_text, help_link: help_link }
diff --git a/app/views/admin/application_settings/_slack.html.haml b/app/views/admin/application_settings/_slack.html.haml
index 69a5e284b4c..e4f46fdf7f2 100644
--- a/app/views/admin/application_settings/_slack.html.haml
+++ b/app/views/admin/application_settings/_slack.html.haml
@@ -1,33 +1,66 @@
-- return unless Gitlab.dev_or_test_env? || Gitlab.com?
-
+- gitlab_com = Gitlab.com?
- expanded = integration_expanded?('slack_app_')
+
%section.settings.as-slack.no-animate#js-slack-settings{ class: ('expanded' if expanded) }
.settings-header
%h4.settings-title.js-settings-toggle.js-settings-toggle-trigger-only
- = _('Slack application')
+ = s_('Integrations|GitLab for Slack app')
= render Pajamas::ButtonComponent.new(button_options: { class: 'js-settings-toggle' }) do
= expanded ? _('Collapse') : _('Expand')
%p
- = _('Slack integration allows you to interact with GitLab via slash commands in a chat window.')
+ = s_('SlackIntegration|Configure your GitLab for Slack app.')
+ = link_to(_('Learn more.'), help_page_path('user/admin_area/settings/slack_app'), target: '_blank', rel: 'noopener noreferrer')
+
.settings-content
+ - unless gitlab_com
+ %h5
+ = s_('SlackIntegration|Step 1: Create your GitLab for Slack app')
+ %p
+ = s_('SlackIntegration|You must do this step only once.')
+ %p
+ = render Pajamas::ButtonComponent.new(href: slack_app_manifest_share_admin_application_settings_path) do
+ = s_("SlackIntegration|Create Slack app")
+ %hr
+ %h5
+ = s_('SlackIntegration|Step 2: Configure the app settings')
+ %p
+ - tag_pair_slack_apps = tag_pair(link_to('', 'https://api.slack.com/apps', target: '_blank', rel: 'noopener noreferrer'), :link_start, :link_end)
+ - tag_pair_strong = tag_pair(tag.strong, :strong_open, :strong_close)
+ = safe_format(s_('SlackIntegration|Copy the %{link_start}settings%{link_end} from %{strong_open}%{settings_heading}%{strong_close} in your GitLab for Slack app.'), tag_pair_slack_apps, tag_pair_strong, settings_heading: 'App Credentials')
+ = link_to(_('Learn more.'), help_page_path('user/admin_area/settings/slack_app', anchor: 'configure-the-settings'), target: '_blank', rel: 'noopener noreferrer')
= gitlab_ui_form_for @application_setting, url: general_admin_application_settings_path(anchor: 'js-slack-settings'), html: { class: 'fieldset-form' } do |f|
= form_errors(@application_setting) if expanded
-
%fieldset
.form-group
- = f.gitlab_ui_checkbox_component :slack_app_enabled, s_('ApplicationSettings|Enable Slack application'),
- help_text: s_('ApplicationSettings|This option is only available on GitLab.com')
+ = f.gitlab_ui_checkbox_component :slack_app_enabled, s_('ApplicationSettings|Enable GitLab for Slack app')
.form-group
= f.label :slack_app_id, s_('SlackIntegration|Client ID'), class: 'label-bold'
= f.text_field :slack_app_id, class: 'form-control gl-form-input'
.form-group
= f.label :slack_app_secret, s_('SlackIntegration|Client secret'), class: 'label-bold'
= f.text_field :slack_app_secret, class: 'form-control gl-form-input'
+ .form-text.text-muted
+ = s_('SlackIntegration|Used for authenticating OAuth requests from the GitLab for Slack app.')
.form-group
= f.label :slack_app_signing_secret, s_('SlackIntegration|Signing secret'), class: 'label-bold'
= f.text_field :slack_app_signing_secret, class: 'form-control gl-form-input'
+ .form-text.text-muted
+ = s_('SlackIntegration|Used for authenticating API requests from the GitLab for Slack app.')
.form-group
= f.label :slack_app_verification_token, s_('SlackIntegration|Verification token'), class: 'label-bold'
= f.text_field :slack_app_verification_token, class: 'form-control gl-form-input'
-
+ .form-text.text-muted
+ = s_('SlackIntegration|Used only for authenticating slash commands from the GitLab for Slack app. This method of authentication is deprecated by Slack.')
= f.submit _('Save changes'), pajamas_button: true
+
+ - unless gitlab_com
+ %hr
+ %h5
+ = s_('SlackIntegration|Update your Slack app')
+ %p
+ = s_('SlackIntegration|When GitLab releases new features for the GitLab for Slack app, you might have to manually update your copy to use the new features.')
+ = link_to(_('Learn more.'), help_page_path('user/admin_area/settings/slack_app', anchor: 'update-the-gitlab-for-slack-app'), target: '_blank', rel: 'noopener noreferrer')
+ %p
+ = render Pajamas::ButtonComponent.new(href: slack_app_manifest_download_admin_application_settings_path, icon: 'download') do
+ = s_("SlackIntegration|Download latest manifest file")
+
diff --git a/app/views/admin/application_settings/_usage.html.haml b/app/views/admin/application_settings/_usage.html.haml
index 2eda3eab8c7..91cd6fe7ca0 100644
--- a/app/views/admin/application_settings/_usage.html.haml
+++ b/app/views/admin/application_settings/_usage.html.haml
@@ -7,13 +7,13 @@
%fieldset
.form-group
- - help_link_start = link_start % { url: help_page_path('user/admin_area/settings/usage_statistics', anchor: 'version-check') }
+ - help_link_start = link_start % { url: help_page_path('administration/settings/usage_statistics', anchor: 'version-check') }
= f.gitlab_ui_checkbox_component :version_check_enabled, _('Enable version check'),
help_text: _("GitLab informs you if a new version is available. %{link_start}What information does GitLab Inc. collect?%{link_end}").html_safe % { link_start: help_link_start, link_end: link_end }
.form-group
- can_be_configured = @application_setting.usage_ping_can_be_configured?
- service_ping_link_start = link_start % { url: help_page_path('development/service_ping/index') }
- - deactivating_service_ping_link_start = link_start % { url: help_page_path('user/admin_area/settings/usage_statistics', anchor: 'disable-usage-statistics-with-the-configuration-file') }
+ - deactivating_service_ping_link_start = link_start % { url: help_page_path('administration/settings/usage_statistics', anchor: 'disable-usage-statistics-with-the-configuration-file') }
- usage_ping_help_text = s_('AdminSettings|To help improve GitLab and its user experience, GitLab periodically collects usage information. %{link_start}What information is shared with GitLab Inc.?%{link_end}').html_safe % { link_start: service_ping_link_start, link_end: link_end }
- disabled_help_text = s_('AdminSettings|Service ping is disabled in your configuration file, and cannot be enabled through this form. For more information, see the documentation on %{link_start}deactivating service ping%{link_end}.').html_safe % { link_start: deactivating_service_ping_link_start, link_end: link_end }
= f.gitlab_ui_checkbox_component :usage_ping_enabled, s_('AdminSettings|Enable Service Ping'),
@@ -28,7 +28,7 @@
.form-group
- usage_ping_enabled = @application_setting.usage_ping_enabled?
- label = s_('AdminSettings|Enable Registration Features')
- - label_link = link_to sprite_icon('question-o'), help_page_path('user/admin_area/settings/usage_statistics', anchor: 'registration-features-program')
+ - label_link = link_to sprite_icon('question-o'), help_page_path('administration/settings/usage_statistics', anchor: 'registration-features-program')
- help_text = usage_ping_enabled ? s_('AdminSettings|You can enable Registration Features because Service Ping is enabled. To continue using Registration Features in the future, you will also need to register with GitLab via a new cloud licensing service.') : s_('AdminSettings|To enable Registration Features, first enable Service Ping.')
= f.gitlab_ui_checkbox_component :usage_ping_features_enabled?, '%{label} %{label_link}'.html_safe % { label: label, label_link: label_link },
help_text: '<span id="service_ping_features_helper_text">%{help_text}</span>'.html_safe % { help_text: help_text },
@@ -37,7 +37,7 @@
.form-text.gl-text-gray-500.gl-pl-6
%p.gl-mb-3= s_('AdminSettings|Registration Features include:')
- email_from_gitlab_path = help_page_path('user/admin_area/email_from_gitlab')
- - repo_size_limit_path = help_page_path('user/admin_area/settings/account_and_limit_settings', anchor: 'repository-size-limit')
+ - repo_size_limit_path = help_page_path('administration/settings/account_and_limit_settings', anchor: 'repository-size-limit')
- restrict_ip_path = help_page_path('user/group/access_and_permissions', anchor: 'restrict-group-access-by-ip-address')
- email_from_gitlab_link = link_start % { url: email_from_gitlab_path }
- repo_size_limit_link = link_start % { url: repo_size_limit_path }
diff --git a/app/views/admin/application_settings/appearances/_form.html.haml b/app/views/admin/application_settings/appearances/_form.html.haml
index 1b0e974a0ca..fb5c320268e 100644
--- a/app/views/admin/application_settings/appearances/_form.html.haml
+++ b/app/views/admin/application_settings/appearances/_form.html.haml
@@ -3,9 +3,8 @@
= gitlab_ui_form_for @appearance, url: admin_application_settings_appearances_path, html: { class: 'gl-mt-3' } do |f|
= form_errors(@appearance)
-
.row
- .col-lg-4.profile-settings-sidebar
+ .col-lg-4
%h4.gl-mt-0= _('Navigation bar')
.col-lg-8
@@ -25,7 +24,7 @@
= _('Maximum file size is 1MB. Pages are optimized for a 24px tall header logo')
%hr
.row
- .col-lg-4.profile-settings-sidebar
+ .col-lg-4
%h4.gl-mt-0 Favicon
.col-lg-8
@@ -50,7 +49,7 @@
%hr
.row
- .col-lg-4.profile-settings-sidebar
+ .col-lg-4
%h4.gl-mt-0= _('Sign in/Sign up pages')
.col-lg-8
@@ -79,7 +78,7 @@
%hr
.row
- .col-lg-4.profile-settings-sidebar
+ .col-lg-4
%h4.gl-mt-0= _('Progressive Web App (PWA)')
.col-lg-8
@@ -111,7 +110,7 @@
%hr
.row
- .col-lg-4.profile-settings-sidebar
+ .col-lg-4
%h4.gl-mt-0= _('New project pages')
.col-lg-8
@@ -124,7 +123,7 @@
%hr
.row
- .col-lg-4.profile-settings-sidebar
+ .col-lg-4
%h4.gl-mt-0= _('Profile image guideline')
.col-lg-8
diff --git a/app/views/admin/application_settings/appearances/_system_header_footer_form.html.haml b/app/views/admin/application_settings/appearances/_system_header_footer_form.html.haml
index d7bb3a85f3a..2ca037db532 100644
--- a/app/views/admin/application_settings/appearances/_system_header_footer_form.html.haml
+++ b/app/views/admin/application_settings/appearances/_system_header_footer_form.html.haml
@@ -2,7 +2,7 @@
%hr
.row
- .col-lg-4.profile-settings-sidebar
+ .col-lg-4
%h4.gl-mt-0
= _('System header and footer')
diff --git a/app/views/admin/application_settings/general.html.haml b/app/views/admin/application_settings/general.html.haml
index 022930bd6b4..2d56e9dd0dd 100644
--- a/app/views/admin/application_settings/general.html.haml
+++ b/app/views/admin/application_settings/general.html.haml
@@ -96,7 +96,6 @@
= render 'admin/application_settings/plantuml'
= render 'admin/application_settings/diagramsnet'
= render 'admin/application_settings/sourcegraph'
-= render_if_exists 'admin/application_settings/slack'
-# this partial is from JiHu, see details in https://jihulab.com/gitlab-cn/gitlab/-/merge_requests/417
= render_if_exists 'admin/application_settings/dingtalk_integration'
-# this partial is from JiHu, see details in https://jihulab.com/gitlab-cn/gitlab/-/merge_requests/640
@@ -109,4 +108,5 @@
= render 'admin/application_settings/floc'
= render_if_exists 'admin/application_settings/add_license'
= render 'admin/application_settings/jira_connect'
+= render 'admin/application_settings/slack'
= render_if_exists 'admin/application_settings/ai_access'
diff --git a/app/views/admin/application_settings/network.html.haml b/app/views/admin/application_settings/network.html.haml
index 18ce7c1ceba..3b9fb930fd7 100644
--- a/app/views/admin/application_settings/network.html.haml
+++ b/app/views/admin/application_settings/network.html.haml
@@ -84,6 +84,9 @@
.settings-content
= render 'git_lfs_limits'
+
+= render 'gitlab_shell_operation_limits'
+
%section.settings.as-outbound.no-animate#js-outbound-settings{ class: ('expanded' if expanded_by_default?), data: { qa_selector: 'outbound_requests_content' } }
.settings-header
%h4.settings-title.js-settings-toggle.js-settings-toggle-trigger-only
diff --git a/app/views/admin/application_settings/service_usage_data.html.haml b/app/views/admin/application_settings/service_usage_data.html.haml
index 24f132b982a..634d006e736 100644
--- a/app/views/admin/application_settings/service_usage_data.html.haml
+++ b/app/views/admin/application_settings/service_usage_data.html.haml
@@ -23,7 +23,7 @@
title: _('Service Ping payload not found in the application cache')) do |c|
- c.with_body do
- - enable_service_ping_link_url = help_page_path('user/admin_area/settings/usage_statistics', anchor: 'enable-or-disable-usage-statistics')
+ - enable_service_ping_link_url = help_page_path('administration/settings/usage_statistics', anchor: 'enable-or-disable-usage-statistics')
- enable_service_ping_link = '<a href="%{url}">'.html_safe % { url: enable_service_ping_link_url }
- generate_manually_link_url = help_page_path('development/internal_analytics/service_ping/troubleshooting', anchor: 'generate-service-ping')
- generate_manually_link = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: generate_manually_link_url }
diff --git a/app/views/admin/applications/_delete_form.html.haml b/app/views/admin/applications/_delete_form.html.haml
index f9fd5864176..82544d36ba0 100644
--- a/app/views/admin/applications/_delete_form.html.haml
+++ b/app/views/admin/applications/_delete_form.html.haml
@@ -1,4 +1,2 @@
-- submit_btn_css ||= 'gl-button btn btn-danger btn-danger-secondary btn-sm js-application-delete-button'
-
-%button{ class: submit_btn_css, data: { path: admin_application_path(application), name: application.name } }
+= render Pajamas::ButtonComponent.new(variant: :danger, category: :secondary, size: :small, button_options: { data: { path: admin_application_path(application), name: application.name }, class: 'js-application-delete-button' }) do
= _('Destroy')
diff --git a/app/views/admin/applications/_form.html.haml b/app/views/admin/applications/_form.html.haml
index a8d5a45041d..27622dfa0bb 100644
--- a/app/views/admin/applications/_form.html.haml
+++ b/app/views/admin/applications/_form.html.haml
@@ -32,4 +32,4 @@
.gl-mt-5
= f.submit _('Save application'), pajamas_button: true, data: { qa_selector: 'save_application_button' }
- = link_to _('Cancel'), admin_applications_path, class: "gl-button btn btn-default btn-cancel"
+ = link_button_to _('Cancel'), admin_applications_path
diff --git a/app/views/admin/cohorts/_cohorts_table.html.haml b/app/views/admin/cohorts/_cohorts_table.html.haml
index 4e2292a9f67..c39e8fb0057 100644
--- a/app/views/admin/cohorts/_cohorts_table.html.haml
+++ b/app/views/admin/cohorts/_cohorts_table.html.haml
@@ -2,7 +2,7 @@
.bs-callout.clearfix
%p
= s_("Cohorts|User cohorts are shown for the last %{months_included} months. Only users with activity are counted in the 'New users' column; inactive users are counted separately.") % { months_included: @cohorts[:months_included] }
- = link_to sprite_icon('question-o'), help_page_path('user/admin_area/user_cohorts', anchor: 'cohorts'), title: 'About this feature', target: '_blank', rel: 'noopener noreferrer'
+ = link_to sprite_icon('question-o'), help_page_path('administration/user_cohorts', anchor: 'cohorts'), title: 'About this feature', target: '_blank', rel: 'noopener noreferrer'
.table-holder.d-xl-table
%table.table
diff --git a/app/views/admin/groups/show.html.haml b/app/views/admin/groups/show.html.haml
index 4ba69126906..5f5f6c98663 100644
--- a/app/views/admin/groups/show.html.haml
+++ b/app/views/admin/groups/show.html.haml
@@ -43,7 +43,7 @@
%li
%span.light= _('Created on:')
%strong
- = @group.created_at.to_s(:medium)
+ = @group.created_at.to_fs(:medium)
%li
%span.light= _('ID:')
diff --git a/app/views/admin/hooks/_form.html.haml b/app/views/admin/hooks/_form.html.haml
index a309e874317..92a664e1ca8 100644
--- a/app/views/admin/hooks/_form.html.haml
+++ b/app/views/admin/hooks/_form.html.haml
@@ -6,10 +6,10 @@
%p.form-text.text-muted= _('URL must be percent-encoded if necessary.')
.form-group
= form.label :token, _('Secret token'), class: 'label-bold'
- = form.text_field :token, class: 'form-control gl-form-input'
+ = form.password_field :token, value: hook.masked_token, autocomplete: 'new-password', class: 'form-control gl-form-input gl-max-w-48'
%p.form-text.text-muted= _('Use this token to validate received payloads.')
.form-group
- = form.label :url, _('Trigger'), class: 'label-bold'
+ = form.label :url, _('Trigger'), class: 'label-bold gl-mb-0'
.form-text.text-secondary.gl-mb-5= _('System hooks are triggered on sets of events like creating a project or adding an SSH key. You can also enable extra triggers, such as push events.')
%fieldset.form-group
= form.gitlab_ui_checkbox_component :repository_update_events, _('Repository update events'),
diff --git a/app/views/admin/hooks/edit.html.haml b/app/views/admin/hooks/edit.html.haml
index 14d37b77a41..29b90f69800 100644
--- a/app/views/admin/hooks/edit.html.haml
+++ b/app/views/admin/hooks/edit.html.haml
@@ -3,17 +3,17 @@
= render 'shared/web_hooks/hook_errors', hook: @hook
-.row.gl-mt-3
- .col-lg-3
- = render 'shared/web_hooks/title_and_docs', hook: @hook
+.gl-mt-5
+ = render 'shared/web_hooks/title_and_docs', hook: @hook
- .col-lg-9.gl-mb-3
- = gitlab_ui_form_for @hook, as: :hook, url: admin_hook_path do |f|
- = render partial: 'form', locals: { form: f, hook: @hook }
- .form-actions
- %span>= f.submit _('Save changes'), class: 'gl-mr-3', pajamas_button: true
+ = gitlab_ui_form_for @hook, as: :hook, url: admin_hook_path do |f|
+ = render partial: 'form', locals: { form: f, hook: @hook }
+
+ .gl-display-flex.gl-justify-content-space-between
+ %div
+ = f.submit _('Save changes'), pajamas_button: true, class: 'gl-sm-mr-3'
= render 'shared/web_hooks/test_button', hook: @hook
- = link_to _('Delete'), admin_hook_path(@hook), method: :delete, class: 'btn gl-button btn-danger float-right', aria: { label: s_('Webhooks|Delete webhook') }, data: { confirm: s_('Webhooks|Are you sure you want to delete this webhook?'), confirm_btn_variant: 'danger' }
+ = link_button_to _('Delete'), admin_hook_path(@hook), method: :delete, aria: { label: s_('Webhooks|Delete webhook') }, data: { confirm: s_('Webhooks|Are you sure you want to delete this webhook?'), confirm_btn_variant: 'danger' }, variant: :danger
%hr
diff --git a/app/views/admin/hooks/index.html.haml b/app/views/admin/hooks/index.html.haml
index d4aeb8dc7e8..14137e788bc 100644
--- a/app/views/admin/hooks/index.html.haml
+++ b/app/views/admin/hooks/index.html.haml
@@ -1,14 +1,7 @@
- page_title @hook.pluralized_name
-.row.gl-mt-3
- .col-lg-4
- = render 'shared/web_hooks/title_and_docs', hook: @hook
-
- .col-lg-8.gl-mb-3
- = gitlab_ui_form_for @hook, as: :hook, url: admin_hooks_path do |f|
- = render partial: 'form', locals: { form: f, hook: @hook }
- = f.submit _('Add system hook'), pajamas_button: true
-
- = render 'shared/web_hooks/index', hooks: @hooks, hook_class: @hook.class
+.settings-section
+ = render 'shared/web_hooks/title_and_docs', hook: @hook
+ = render 'shared/web_hooks/index', hooks: @hooks, hook_class: @hook.class, partial: 'form', url: admin_hooks_path
= render 'shared/file_hooks/index'
diff --git a/app/views/admin/labels/_label.html.haml b/app/views/admin/labels/_label.html.haml
index f4f64eadf21..19460ddb0e5 100644
--- a/app/views/admin/labels/_label.html.haml
+++ b/app/views/admin/labels/_label.html.haml
@@ -10,8 +10,8 @@
.dropdown-menu.dropdown-menu-right
%ul
%li
- = link_to edit_admin_label_path(label), class: 'btn gl-btn label-action dropdown-item btn-link' do
+ = link_to edit_admin_label_path(label), class: 'btn label-action dropdown-item btn-link' do
= _('Edit')
%li
- = link_to admin_label_path(label), class: 'btn gl-btn js-remove-label dropdown-item btn-link gl-text-red-500!', data: { confirm: _('Are you sure you want to delete this label?'), confirm_btn_variant: 'danger' }, aria: { label: _('Delete label') }, method: :delete, remote: true do
+ = link_to admin_label_path(label), class: 'btn js-remove-label dropdown-item btn-link gl-text-red-500!', data: { confirm: _('Are you sure you want to delete this label?'), confirm_btn_variant: 'danger' }, aria: { label: _('Delete label') }, method: :delete, remote: true do
= _('Delete')
diff --git a/app/views/admin/projects/show.html.haml b/app/views/admin/projects/show.html.haml
index 8eb72fa281e..0637b0eae47 100644
--- a/app/views/admin/projects/show.html.haml
+++ b/app/views/admin/projects/show.html.haml
@@ -60,7 +60,7 @@
%span.light
= _('Created on:')
%strong
- = @project.created_at.to_s(:medium)
+ = @project.created_at.to_fs(:medium)
%li{ class: 'gl-px-5!' }
%span.light
@@ -158,10 +158,10 @@
= _("This repository has never been checked.")
- elsif @project.last_repository_check_failed?
- failed_message = _("This repository was last checked %{last_check_timestamp}. The check %{strong_start}failed.%{strong_end} See the 'repocheck.log' file for error messages.")
- - failed_message = failed_message % { last_check_timestamp: @project.last_repository_check_at.to_s(:medium), strong_start: "<strong class='cred'>", strong_end: "</strong>" }
+ - failed_message = failed_message % { last_check_timestamp: @project.last_repository_check_at.to_fs(:medium), strong_start: "<strong class='cred'>", strong_end: "</strong>" }
= failed_message.html_safe
- else
- = _("This repository was last checked %{last_check_timestamp}. The check passed.") % { last_check_timestamp: @project.last_repository_check_at.to_s(:medium) }
+ = _("This repository was last checked %{last_check_timestamp}. The check passed.") % { last_check_timestamp: @project.last_repository_check_at.to_fs(:medium) }
= link_to sprite_icon('question-o'), help_page_path('administration/repository_checks')
diff --git a/app/views/admin/runners/edit.html.haml b/app/views/admin/runners/edit.html.haml
index 3d245722270..6ce094bacf1 100644
--- a/app/views/admin/runners/edit.html.haml
+++ b/app/views/admin/runners/edit.html.haml
@@ -39,7 +39,8 @@
.input-group
= search_field_tag :search, params[:search], class: 'form-control gl-form-input', spellcheck: false
.input-group-append
- = submit_tag _('Search'), class: 'gl-button btn btn-default'
+ = render Pajamas::ButtonComponent.new(type: 'submit', variant: :default) do
+ = _('Search')
%td
- @projects.each do |project|
diff --git a/app/views/admin/sessions/_new_base.html.haml b/app/views/admin/sessions/_new_base.html.haml
index d0ee3acf0b8..f880c2631ed 100644
--- a/app/views/admin/sessions/_new_base.html.haml
+++ b/app/views/admin/sessions/_new_base.html.haml
@@ -1,7 +1,7 @@
-= form_tag(admin_session_path, method: :post, class: 'new_user gl-show-field-errors', 'aria-live': 'assertive') do
+= gitlab_ui_form_for(:user, url: admin_session_path, html: { class: 'gl-p-5 gl-show-field-errors', aria: { live: 'assertive' } }) do |f|
.form-group
- = label_tag :user_password, _('Password'), class: 'label-bold'
- = password_field_tag 'user[password]', nil, { class: 'form-control js-password', data: { id: 'user_password', name: 'user[password]', qa_selector: 'password_field', testid: 'password-field' } }
+ = f.label :password, _('Password')
+ = f.password_field :password, class: 'form-control js-password', data: { id: 'user_password', name: 'user[password]', qa_selector: 'password_field', testid: 'password-field' }
- .submit-container
- = submit_tag _('Enter admin mode'), class: 'gl-button btn btn-confirm', data: { qa_selector: 'enter_admin_mode_button' }
+ = render Pajamas::ButtonComponent.new(type: :submit, variant: :confirm, block: true, button_options: { data: { qa_selector: 'enter_admin_mode_button' } }) do
+ = _('Enter admin mode')
diff --git a/app/views/admin/sessions/_signin_box.html.haml b/app/views/admin/sessions/_signin_box.html.haml
index 70cad880293..114b32ca581 100644
--- a/app/views/admin/sessions/_signin_box.html.haml
+++ b/app/views/admin/sessions/_signin_box.html.haml
@@ -12,6 +12,6 @@
= render_if_exists 'devise/sessions/new_smartcard'
- if allow_admin_mode_password_authentication_for_web?
- .login-box.tab-pane.gl-p-5{ id: 'login-pane', role: 'tabpanel', class: active_when(!any_form_based_providers_enabled?) }
+ .login-box.tab-pane{ id: 'login-pane', role: 'tabpanel', class: active_when(!any_form_based_providers_enabled?) }
.login-body
= render 'admin/sessions/new_base'
diff --git a/app/views/admin/sessions/new.html.haml b/app/views/admin/sessions/new.html.haml
index 7301b0f6e04..b3e24d5b3ac 100644
--- a/app/views/admin/sessions/new.html.haml
+++ b/app/views/admin/sessions/new.html.haml
@@ -1,8 +1,8 @@
- page_title _('Enter admin mode')
- add_page_specific_style 'page_bundles/login'
-.row.justify-content-center
- .col-md-5.new-session-forms-container
+.row.gl-mt-5.justify-content-center
+ .col-md-5
.login-page
#signin-container{ class: ('borderless' if Feature.enabled?(:restyle_login_page, @project)) }
- if any_form_based_providers_enabled?
diff --git a/app/views/admin/sessions/two_factor.html.haml b/app/views/admin/sessions/two_factor.html.haml
index bfe66e2477e..ef004004227 100644
--- a/app/views/admin/sessions/two_factor.html.haml
+++ b/app/views/admin/sessions/two_factor.html.haml
@@ -2,7 +2,7 @@
- add_page_specific_style 'page_bundles/login'
.row.justify-content-center
- .col-md-5.new-session-forms-container
+ .col-md-5
.login-page
#signin-container{ class: ('borderless' if Feature.enabled?(:restyle_login_page, @project)) }
= render 'devise/shared/tab_single', tab_title: _('Enter admin mode') if Feature.disabled?(:restyle_login_page, @project)
diff --git a/app/views/admin/topics/_topic.html.haml b/app/views/admin/topics/_topic.html.haml
index ce2b5ad793c..3e8a023ec9f 100644
--- a/app/views/admin/topics/_topic.html.haml
+++ b/app/views/admin/topics/_topic.html.haml
@@ -16,5 +16,5 @@
= number_with_delimiter(topic.total_projects_count)
.controls.gl-flex-shrink-0.gl-ml-5
- = link_to _('Edit'), edit_admin_topic_path(topic), id: "edit_#{dom_id(topic)}", class: 'btn gl-button btn-default'
- = link_to _('Remove'), admin_topic_path(topic), aria: { label: _('Remove') }, data: { confirm: _("Are you sure you want to remove %{topic_name}?") % { topic_name: title }, confirm_btn_variant: 'danger' }, method: :delete, class: 'gl-button btn btn-danger'
+ = link_button_to _('Edit'), edit_admin_topic_path(topic), id: "edit_#{dom_id(topic)}"
+ = link_button_to _('Remove'), admin_topic_path(topic), aria: { label: _('Remove') }, data: { confirm: _("Are you sure you want to remove %{topic_name}?") % { topic_name: title }, confirm_btn_variant: 'danger' }, method: :delete, variant: :danger
diff --git a/app/views/admin/users/_profile.html.haml b/app/views/admin/users/_profile.html.haml
index b4f61a1b665..bb89b5baf28 100644
--- a/app/views/admin/users/_profile.html.haml
+++ b/app/views/admin/users/_profile.html.haml
@@ -5,7 +5,7 @@
%ul.content-list
%li
%span.light= _('Member since')
- %strong= user.created_at.to_s(:medium)
+ %strong= user.created_at.to_fs(:medium)
- unless user.public_email.blank?
%li
%span.light= _('E-mail:')
diff --git a/app/views/admin/users/projects.html.haml b/app/views/admin/users/projects.html.haml
index 1f3e8f4bba2..fa89c3d4b4f 100644
--- a/app/views/admin/users/projects.html.haml
+++ b/app/views/admin/users/projects.html.haml
@@ -18,8 +18,7 @@
.float-right
%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), confirm_btn_variant: 'danger', testid: 'remove-user' }, aria: { label: _('Remove') }, 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('remove', size: 16, css_class: 'gl-icon')
+ = link_button_to nil, group_group_member_path(group, group_member), data: { confirm: remove_member_message(group_member), confirm_btn_variant: 'danger', testid: 'remove-user' }, aria: { label: _('Remove') }, method: :delete, remote: true, class: 'gl-ml-3', title: _('Remove user from group'), variant: :danger, size: :small, icon: 'remove'
.row
.col-md-6
@@ -50,5 +49,4 @@
%span.light.vertical-align-middle= member.human_access
- if member.respond_to? :project
- = link_to project_project_member_path(project, member), data: { confirm: remove_member_message(member), confirm_btn_variant: 'danger' }, aria: { label: _('Remove') }, 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('remove', size: 16, css_class: 'gl-icon')
+ = link_button_to nil, project_project_member_path(project, member), data: { confirm: remove_member_message(member), confirm_btn_variant: 'danger' }, aria: { label: _('Remove') }, remote: true, method: :delete, class: 'gl-ml-3', title: _('Remove user from project'), variant: :danger, size: :small, icon: 'remove'
diff --git a/app/views/admin/users/show.html.haml b/app/views/admin/users/show.html.haml
index ea6525e1b96..a4ae29bed81 100644
--- a/app/views/admin/users/show.html.haml
+++ b/app/views/admin/users/show.html.haml
@@ -42,8 +42,7 @@
%span.light= _('Secondary email:')
%strong
= render partial: 'shared/email_with_badge', locals: { email: email.email, verified: email.confirmed? }
- = link_to remove_email_admin_user_path(@user, email), data: { confirm: _("Are you sure you want to remove %{email}?") % { email: email.email }, 'confirm-btn-variant': 'danger' }, method: :delete, class: "btn btn-sm btn-danger gl-button btn-icon float-right", title: _('Remove secondary email'), id: "remove_email_#{email.id}" do
- = sprite_icon('close', size: 16, css_class: 'gl-icon')
+ = link_button_to nil, remove_email_admin_user_path(@user, email), data: { confirm: _("Are you sure you want to remove %{email}?") % { email: email.email }, 'confirm-btn-variant': 'danger' }, method: :delete, class: 'float-right', title: _('Remove secondary email'), id: "remove_email_#{email.id}", variant: :danger, size: :small, icon: 'close'
%li
%span.light ID:
%strong{ data: { qa_selector: 'user_id_content' } }
@@ -58,7 +57,7 @@
%strong{ class: @user.two_factor_enabled? ? 'cgreen' : 'cred' }
- if @user.two_factor_enabled?
= _('Enabled')
- = link_to _('Disable'), disable_two_factor_admin_user_path(@user), aria: { label: _('Disable') }, data: { confirm: _('Are you sure?'), 'confirm-btn-variant': 'danger' }, method: :patch, class: 'btn gl-button btn-sm btn-danger float-right', title: _('Disable Two-factor Authentication')
+ = link_button_to _('Disable'), disable_two_factor_admin_user_path(@user), aria: { label: _('Disable') }, data: { confirm: _('Are you sure?'), 'confirm-btn-variant': 'danger' }, method: :patch, class: 'float-right', title: _('Disable Two-factor Authentication'), variant: :danger, size: :small
- else
= _('Disabled')
@@ -86,12 +85,12 @@
%li
%span.light= _('Member since:')
%strong
- = @user.created_at.to_s(:medium)
+ = @user.created_at.to_fs(:medium)
- if @user.confirmed_at
%li
%span.light= _('Confirmed at:')
%strong
- = @user.confirmed_at.to_s(:medium)
+ = @user.confirmed_at.to_fs(:medium)
- else
%li
%span.ligh= _('Confirmed:')
@@ -106,7 +105,7 @@
%li
%span.light= _('Current sign-in at:')
%strong
- = @user.current_sign_in_at&.to_s(:medium) || _('never')
+ = @user.current_sign_in_at&.to_fs(:medium) || _('never')
%li
%span.light= _('Last sign-in IP:')
@@ -116,7 +115,7 @@
%li
%span.light= _('Last sign-in at:')
%strong
- = @user.last_sign_in_at&.to_s(:medium) || _('never')
+ = @user.last_sign_in_at&.to_fs(:medium) || _('never')
%li
%span.light= _('Sign-in count:')
diff --git a/app/views/clusters/clusters/_integrations.html.haml b/app/views/clusters/clusters/_integrations.html.haml
deleted file mode 100644
index 4d36c5094a3..00000000000
--- a/app/views/clusters/clusters/_integrations.html.haml
+++ /dev/null
@@ -1,16 +0,0 @@
-.settings.expanded.border-0.m-0
- %p
- = s_('ClusterIntegration|Integrations allow you to use applications installed in your cluster as part of your GitLab workflow.')
- = link_to _('Learn more'), help_page_path('user/clusters/integrations.md'), target: '_blank', rel: 'noopener noreferrer'
- .settings-content#integrations-settings-section
- - if can?(current_user, :admin_cluster, @cluster)
- .sub-section.form-group
- = gitlab_ui_form_for @prometheus_integration, as: :integration, namespace: :prometheus, url: @cluster.integrations_path, method: :post, html: { class: 'js-cluster-integrations-form' } do |prometheus_form|
- = prometheus_form.hidden_field :application_type, value: @prometheus_integration.application_type
- .form-group.gl-form-group
- - help_text = s_('ClusterIntegration|Allows GitLab to query a specifically configured in-cluster Prometheus for metrics.')
- - help_link = link_to(_('More information.'), help_page_path("user/clusters/integrations"), target: '_blank', rel: 'noopener noreferrer')
- = prometheus_form.gitlab_ui_checkbox_component :enabled,
- s_('ClusterIntegration|Enable Prometheus integration'),
- help_text: '%{help_text} %{help_link}'.html_safe % { help_text: help_text, help_link: help_link }
- = prometheus_form.submit _('Save changes'), class: 'btn gl-button btn-confirm'
diff --git a/app/views/clusters/clusters/_integrations_tab.html.haml b/app/views/clusters/clusters/_integrations_tab.html.haml
deleted file mode 100644
index e229c1fbe1e..00000000000
--- a/app/views/clusters/clusters/_integrations_tab.html.haml
+++ /dev/null
@@ -1,4 +0,0 @@
-- active = params[:tab] == 'integrations'
-
-= gl_tab_link_to clusterable.cluster_path(@cluster.id, params: { tab: 'integrations' }), { item_active: active } do
- = _('Integrations')
diff --git a/app/views/clusters/clusters/show.html.haml b/app/views/clusters/clusters/show.html.haml
index 57de6d980f8..1287f4e689f 100644
--- a/app/views/clusters/clusters/show.html.haml
+++ b/app/views/clusters/clusters/show.html.haml
@@ -32,7 +32,6 @@
= gl_tabs_nav do
= render 'clusters/clusters/details_tab'
= render_if_exists 'clusters/clusters/environments_tab'
- = render 'clusters/clusters/integrations_tab' if !Feature.enabled?(:remove_monitor_metrics)
= render 'clusters/clusters/advanced_settings_tab'
.tab-content.py-3
diff --git a/app/views/dashboard/todos/_todo.html.haml b/app/views/dashboard/todos/_todo.html.haml
index ebd7f20c54a..e20fccc218a 100644
--- a/app/views/dashboard/todos/_todo.html.haml
+++ b/app/views/dashboard/todos/_todo.html.haml
@@ -20,7 +20,7 @@
- else
= _("(removed)")
- .todo-body.gl-mb-2.gl-px-2.gl-display-flex.gl-align-items-flex-start.gl-lg-align-items-center
+ .todo-body.gl-mb-2.gl-px-2.gl-display-flex.gl-align-items-flex-start
.todo-avatar.gl-display-none.gl-sm-display-inline-block
= author_avatar(todo, size: 24)
.todo-note
@@ -47,6 +47,8 @@
%span.action-description<
= first_line_in_markdown(todo, :body, 125, is_todo: true, project: todo.project, group: todo.group)
+ = render_if_exists "dashboard/todos/diff_summary", local_assigns: { todo: todo }
+
.todo-timestamp.gl-white-space-nowrap.gl-sm-ml-3.gl-mt-2.gl-mb-2.gl-sm-my-0.gl-px-2.gl-sm-px-0
%span.todo-timestamp.gl-font-sm.gl-text-secondary
= todo_due_date(todo)
diff --git a/app/views/dashboard/todos/index.html.haml b/app/views/dashboard/todos/index.html.haml
index ca6b1071f03..c5f70397fad 100644
--- a/app/views/dashboard/todos/index.html.haml
+++ b/app/views/dashboard/todos/index.html.haml
@@ -53,7 +53,7 @@
- if params[:action_id].present?
= hidden_field_tag(:action_id, params[:action_id])
= dropdown_tag(todo_actions_dropdown_label(params[:action_id], _("Action")), options: { toggle_class: 'js-action-search js-filter-submit gl-xs-w-full!', dropdown_class: 'dropdown-menu-selectable dropdown-menu-action js-filter-submit', data: { data: todo_actions_options, default_label: _("Action") } })
- .filter-item.sort-filter.gl-mt-3.gl-sm-mt-0.gl-mb-0.gl-sm-mb-0
+ .filter-item.sort-filter.gl-my-2
.dropdown
%button.dropdown-menu-toggle.dropdown-menu-toggle-sort{ type: 'button', class: 'gl-xs-w-full!', 'data-toggle' => 'dropdown' }
%span.light
diff --git a/app/views/devise/sessions/_new_crowd.html.haml b/app/views/devise/sessions/_new_crowd.html.haml
index bb398eaf4be..4b1441662ab 100644
--- a/app/views/devise/sessions/_new_crowd.html.haml
+++ b/app/views/devise/sessions/_new_crowd.html.haml
@@ -7,7 +7,7 @@
= f.text_field :username, name: :username, autocomplete: :username, class: 'form-control gl-form-input', title: _('This field is required.'), autofocus: 'autofocus', required: true
.form-group
= f.label :password, _('Password')
- = f.text_field :vue_password_placeholder, class: 'form-control gl-form-input js-password', data: { id: "#{:crowd}_password", name: 'password' }
+ %input.form-control.gl-form-input.js-password{ data: { id: 'crowd_password', name: 'password' } }
- if render_remember_me
= f.gitlab_ui_checkbox_component :remember_me, _('Remember me'), checkbox_options: { name: :remember_me, autocomplete: 'off' }
diff --git a/app/views/devise/sessions/_new_ldap.html.haml b/app/views/devise/sessions/_new_ldap.html.haml
index f9b6f462661..471cc053e6e 100644
--- a/app/views/devise/sessions/_new_ldap.html.haml
+++ b/app/views/devise/sessions/_new_ldap.html.haml
@@ -9,7 +9,7 @@
= f.text_field :username, name: :username, autocomplete: :username, class: 'form-control gl-form-input', title: _('This field is required.'), autofocus: 'autofocus', data: { qa_selector: 'username_field' }, required: true
.form-group
= f.label :password, _('Password')
- = f.text_field :vue_password_placeholder, class: 'form-control gl-form-input js-password', data: { id: "#{provider}_password", name: 'password', qa_selector: 'password_field' }
+ %input.form-control.gl-form-input.js-password{ data: { id: "#{provider}_password", name: 'password', qa_selector: 'password_field' } }
- if render_remember_me
= f.gitlab_ui_checkbox_component :remember_me, _('Remember me'), checkbox_options: { name: :remember_me, autocomplete: 'off' }
diff --git a/app/views/devise/shared/_footer.html.haml b/app/views/devise/shared/_footer.html.haml
index 0744faa148c..c35e43b909e 100644
--- a/app/views/devise/shared/_footer.html.haml
+++ b/app/views/devise/shared/_footer.html.haml
@@ -1,10 +1,11 @@
-%hr.footer-fixed
-.container.footer-container.gl-display-flex.gl-justify-content-space-between
- .footer-links
- - unless public_visibility_restricted?
- = link_to _("Explore"), explore_root_path
- = link_to _("Help"), help_path
- = link_to _("About GitLab"), "https://#{ApplicationHelper.promo_host}"
- = link_to _("Community forum"), ApplicationHelper.community_forum, target: '_blank', class: 'text-nowrap', rel: 'noopener noreferrer'
- = render 'devise/shared/language_switcher'
+.footer-container.gl-w-full.gl-align-self-end
+ %hr.gl-m-0
+ .container.gl-py-5.gl-display-flex.gl-justify-content-space-between
+ .gl-display-flex.gl-gap-5.gl-flex-wrap
+ - unless public_visibility_restricted?
+ = link_to _("Explore"), explore_root_path
+ = link_to _("Help"), help_path
+ = link_to _("About GitLab"), "https://#{ApplicationHelper.promo_host}"
+ = link_to _("Community forum"), ApplicationHelper.community_forum, target: '_blank', class: 'text-nowrap', rel: 'noopener noreferrer'
+ = render 'devise/shared/language_switcher'
= footer_message
diff --git a/app/views/devise/shared/_signup_box.html.haml b/app/views/devise/shared/_signup_box.html.haml
index 684ade87720..6d37257232b 100644
--- a/app/views/devise/shared/_signup_box.html.haml
+++ b/app/views/devise/shared/_signup_box.html.haml
@@ -5,14 +5,14 @@
.gl-mb-3.gl-p-4{ class: (borderless ? '' : 'gl-border-gray-100 gl-border-1 gl-border-solid gl-rounded-base') }
= yield :omniauth_providers_top if show_omniauth_providers
- = gitlab_ui_form_for(resource, as: form_resource_name, url: url, html: { class: 'new_user gl-show-field-errors js-arkose-labs-form', 'aria-live' => 'assertive' }, data: { testid: 'signup-form' }) do |f|
+ = gitlab_ui_form_for(resource, as: form_resource_name, url: url, html: { class: 'gl-show-field-errors js-arkose-labs-form', aria: { live: 'assertive' }}, data: { testid: 'signup-form' }) do |f|
.devise-errors
= render 'devise/shared/error_messages', resource: resource
- if Gitlab::CurrentSettings.invisible_captcha_enabled
= invisible_captcha nonce: true, autocomplete: SecureRandom.alphanumeric(12)
.name.form-row
.col.form-group
- = f.label :first_name, _('First name'), for: 'new_user_first_name', class: "label-bold #{'gl-mb-1' if Feature.enabled?(:restyle_login_page, @project)}"
+ = f.label :first_name, _('First name'), for: 'new_user_first_name'
= f.text_field :first_name,
class: 'form-control gl-form-input top js-block-emoji js-validate-length',
data: { max_length: max_first_name_length,
@@ -21,7 +21,7 @@
required: true,
title: _('This field is required.')
.col.form-group
- = f.label :last_name, _('Last name'), for: 'new_user_last_name', class: "label-bold #{'gl-mb-1' if Feature.enabled?(:restyle_login_page, @project)}"
+ = f.label :last_name, _('Last name'), for: 'new_user_last_name'
= f.text_field :last_name,
class: 'form-control gl-form-input top js-block-emoji js-validate-length',
data: { max_length: max_last_name_length,
@@ -30,7 +30,7 @@
required: true,
title: _('This field is required.')
.username.form-group
- = f.label :username, class: "label-bold #{'gl-mb-1' if Feature.enabled?(:restyle_login_page, @project)}"
+ = f.label :username, _('Username')
= f.text_field :username,
class: 'form-control gl-form-input middle js-block-emoji js-validate-length js-validate-username',
data: signup_username_data_attributes,
@@ -41,7 +41,7 @@
%p.validation-success.gl-text-green-600.gl-field-error-ignore.gl-mt-2.field-validation.hide= _('Username is available.')
%p.validation-pending.gl-field-error-ignore.gl-mt-2.field-validation.hide= _('Checking username availability...')
.form-group
- = f.label :email, class: "label-bold #{'gl-mb-1' if Feature.enabled?(:restyle_login_page, @project)}"
+ = f.label :email, _('Email')
= f.email_field :email,
class: 'form-control gl-form-input middle js-validate-email',
data: { qa_selector: 'new_user_email_field' },
@@ -52,7 +52,7 @@
-# This is used for providing entry to Jihu on email verification
= render_if_exists 'devise/shared/signup_email_additional_info'
.form-group.gl-mb-5
- = f.label :password, class: "label-bold #{'gl-mb-1' if Feature.enabled?(:restyle_login_page, @project)}"
+ = f.label :password, _('Password')
%input.form-control.gl-form-input.js-password{ data: { id: "#{form_resource_name}_password",
title: s_('SignUp|Minimum length is %{minimum_password_length} characters.') % { minimum_password_length: @minimum_password_length },
minimum_password_length: @minimum_password_length,
@@ -62,18 +62,16 @@
%p.gl-field-hint-valid.text-secondary= s_('SignUp|Minimum length is %{minimum_password_length} characters.') % { minimum_password_length: @minimum_password_length }
= render_if_exists 'shared/password_requirements_list'
= render_if_exists 'devise/shared/phone_verification', form: f
- %div
- - if arkose_labs_enabled?
- = render_if_exists 'devise/registrations/arkose_labs'
- - elsif show_recaptcha_sign_up?
- = recaptcha_tags nonce: content_security_policy_nonce
+ .form-group
+ - if arkose_labs_enabled?
+ = render_if_exists 'devise/registrations/arkose_labs'
+ - elsif show_recaptcha_sign_up?
+ = recaptcha_tags nonce: content_security_policy_nonce
+
+ = render Pajamas::ButtonComponent.new(type: :submit, variant: :confirm, block: true, button_options: { data: { qa_selector: 'new_user_register_button' }}) do
+ = button_text
- .submit-container.gl-mt-5
- = f.submit button_text, pajamas_button: true, class: 'gl-w-full', data: { qa_selector: 'new_user_register_button' }
- - if Gitlab::CurrentSettings.sign_in_text.present? && Feature.enabled?(:restyle_login_page, @project)
- .gl-pt-5
- = markdown_field(Gitlab::CurrentSettings.current_application_settings, :sign_in_text)
= render 'devise/shared/terms_of_service_notice', button_text: button_text
= yield :omniauth_providers_bottom if show_omniauth_providers
diff --git a/app/views/devise/shared/_signup_omniauth_provider_list.haml b/app/views/devise/shared/_signup_omniauth_provider_list.haml
index e8c82e456ae..60c37316c62 100644
--- a/app/views/devise/shared/_signup_omniauth_provider_list.haml
+++ b/app/views/devise/shared/_signup_omniauth_provider_list.haml
@@ -4,7 +4,7 @@
= _("Register with:")
.gl-text-center.gl-ml-auto.gl-mr-auto
- providers.each do |provider|
- = button_to omniauth_authorize_path(:user, provider, register_omniauth_params(local_assigns)), class: "btn gl-button btn-default gl-w-full gl-mb-4 js-oauth-login #{qa_selector_for_provider(provider)}", data: { provider: provider, track_action: "#{provider}_sso", track_label: tracking_label }, id: "oauth-login-#{provider}" do
+ = render Pajamas::ButtonComponent.new(href: omniauth_authorize_path(:user, provider, register_omniauth_params(local_assigns)), method: :post, variant: :default, button_options: { class: "gl-w-full gl-mb-4 js-oauth-login #{qa_selector_for_provider(provider)}", data: { provider: provider, track_action: "#{provider}_sso", track_label: tracking_label}, id: "oauth-login-#{provider}" }) do
- if provider_has_icon?(provider)
= provider_image_tag(provider)
%span.gl-button-text
@@ -14,7 +14,7 @@
= _("Create an account using:")
.gl-display-flex.gl-justify-content-between.gl-flex-wrap
- providers.each do |provider|
- = button_to omniauth_authorize_path(:user, provider, register_omniauth_params(local_assigns)), class: "btn gl-button btn-default gl-w-full gl-mb-4 js-oauth-login #{qa_selector_for_provider(provider)}", data: { provider: provider, track_action: "#{provider}_sso", track_label: tracking_label }, id: "oauth-login-#{provider}" do
+ = render Pajamas::ButtonComponent.new(href: omniauth_authorize_path(:user, provider, register_omniauth_params(local_assigns)), method: :post, variant: :default, button_options: { class: "gl-w-full gl-mb-4 js-oauth-login #{qa_selector_for_provider(provider)}", data: { provider: provider, track_action: "#{provider}_sso", track_label: tracking_label}, id: "oauth-login-#{provider}" }) do
- if provider_has_icon?(provider)
= provider_image_tag(provider)
%span.gl-button-text
diff --git a/app/views/devise/unlocks/new.html.haml b/app/views/devise/unlocks/new.html.haml
index b9d50e48d05..8bae27020c2 100644
--- a/app/views/devise/unlocks/new.html.haml
+++ b/app/views/devise/unlocks/new.html.haml
@@ -1,14 +1,18 @@
= render 'devise/shared/tab_single', tab_title: _('Resend unlock instructions')
.login-box
.login-body
- = gitlab_ui_form_for(resource, as: resource_name, url: unlock_path(resource_name), html: { method: :post, class: 'gl-show-field-errors' }) do |f|
+ = gitlab_ui_form_for(resource, as: resource_name, url: unlock_path(resource_name), html: { method: :post, class: 'gl-p-5 gl-show-field-errors' }) do |f|
.devise-errors
= render "devise/shared/error_messages", resource: resource
- .form-group.gl-mb-6
- = f.label :email
- = f.email_field :email, class: 'form-control', autofocus: 'autofocus', autocapitalize: 'off', autocorrect: 'off', title: _('Please provide a valid email address.')
- .clearfix
- = f.submit _('Resend unlock instructions'), pajamas_button: true, class: 'gl-w-full'
+ .form-group
+ = f.label :email, _('Email')
+ = f.email_field :email, class: 'form-control gl-form-input', autofocus: 'autofocus', autocapitalize: 'off', autocorrect: 'off', title: _('Please provide a valid email address.')
-.clearfix.prepend-top-20
+ = render Pajamas::ButtonComponent.new(type: :submit, variant: :confirm, block: true) do
+ = _('Resend unlock instructions')
+
+- if Feature.enabled?(:restyle_login_page, @project)
= render 'devise/shared/sign_in_link'
+- else
+ .gl-mt-3
+ = render 'devise/shared/sign_in_link'
diff --git a/app/views/discussions/_notes.html.haml b/app/views/discussions/_notes.html.haml
index a35ba12dd52..e34a5cebe78 100644
--- a/app/views/discussions/_notes.html.haml
+++ b/app/views/discussions/_notes.html.haml
@@ -15,16 +15,14 @@
= badge_counter
= render partial: "shared/notes/note", collection: discussion.notes, as: :note, locals: { badge_counter: badge_counter, show_image_comment_badge: show_image_comment_badge }
- .flash-container
-
- .discussion-reply-holder
- - if can_create_note?
- .discussion-with-resolve-btn
- = link_to_reply_discussion(discussion)
- - elsif !current_user
- .disabled-comment.text-center
- Please
- = link_to "register", new_session_path(:user, redirect_to_referer: 'yes')
- or
- = link_to "sign in", new_session_path(:user, redirect_to_referer: 'yes')
- to reply
+ %li.discussion-reply-holder.clearfix{ class: 'gl-border-t-0! gl-pb-5!' }
+ - if can_create_note?
+ .discussion-with-resolve-btn
+ = link_to_reply_discussion(discussion)
+ - elsif !current_user
+ .disabled-comment.text-center
+ Please
+ = link_to "register", new_session_path(:user, redirect_to_referer: 'yes')
+ or
+ = link_to "sign in", new_session_path(:user, redirect_to_referer: 'yes')
+ to reply
diff --git a/app/views/events/_event_push.atom.haml b/app/views/events/_event_push.atom.haml
index c3786d7c16d..51b60fe0152 100644
--- a/app/views/events/_event_push.atom.haml
+++ b/app/views/events/_event_push.atom.haml
@@ -6,7 +6,7 @@
= link_to "(#{truncate_sha(event.commit_id)})", event_url if event_url
%i
at
- = event.created_at.to_s(:short)
+ = event.created_at.to_fs(:short)
- unless event.rm_ref?
.blockquote= markdown(escape_once(event.commit_title), pipeline: :atom, project: event.project, author: event.author)
- if event.commits_count > 1
diff --git a/app/views/explore/projects/_project.atom.builder b/app/views/explore/projects/_project.atom.builder
new file mode 100644
index 00000000000..f0500901a73
--- /dev/null
+++ b/app/views/explore/projects/_project.atom.builder
@@ -0,0 +1,14 @@
+# frozen_string_literal: true
+
+xml.entry do
+ xml.title project.name
+ xml.link href: project_url(project), rel: "alternate", type: "text/html"
+ xml.id project_url(project)
+ xml.updated project.created_at
+
+ if project.description.present?
+ xml.summary(type: "xhtml") do |summary|
+ summary << project.description
+ end
+ end
+end
diff --git a/app/views/explore/projects/topic.atom.builder b/app/views/explore/projects/topic.atom.builder
new file mode 100644
index 00000000000..4712d415daa
--- /dev/null
+++ b/app/views/explore/projects/topic.atom.builder
@@ -0,0 +1,9 @@
+# frozen_string_literal: true
+
+xml.title @topic.name
+xml.link href: topic_explore_projects_url(@topic.name, rss_url_options), rel: "self", type: "application/atom+xml"
+xml.link href: topic_explore_projects_url(@topic.name), rel: "alternate", type: "text/html"
+xml.id topic_explore_projects_url(@topic.id)
+xml.updated @projects[0].updated_at.xmlschema if @projects[0]
+
+xml << render(@projects) if @projects.any?
diff --git a/app/views/explore/projects/topic.html.haml b/app/views/explore/projects/topic.html.haml
index b26abefcb0e..329e7cc161c 100644
--- a/app/views/explore/projects/topic.html.haml
+++ b/app/views/explore/projects/topic.html.haml
@@ -22,9 +22,10 @@
%div{ class: container_class }
.gl-py-5.gl-border-gray-100.gl-border-b-solid.gl-border-b-1
%h3.gl-m-0= _('Projects with this topic')
- .top-area.gl-pt-2.gl-pb-2
+ .top-area.gl-pt-2.gl-pb-2.gl-justify-content-space-between
.nav-controls
= render 'shared/projects/search_form'
= render 'filter'
+ = link_button_to nil, topic_explore_projects_path(@topic.name, rss_url_options), title: s_("Topics|Subscribe to the new projects feed"), class: 'd-none d-sm-inline-flex has-tooltip', icon: 'rss'
= render 'projects', projects: @projects
diff --git a/app/views/groups/group_members/index.html.haml b/app/views/groups/group_members/index.html.haml
index 04bf3f98a1e..e5c66c2c432 100644
--- a/app/views/groups/group_members/index.html.haml
+++ b/app/views/groups/group_members/index.html.haml
@@ -3,16 +3,18 @@
.row.gl-mt-3
.col-lg-12
- .gl-display-flex.gl-flex-wrap
+ .gl-display-flex.gl-flex-wrap.gl-justify-content-space-between
- if can_admin_group_member?(@group)
%h4
= _('Group members')
%p.gl-w-full.order-md-1
= group_member_header_subtext(@group)
- .gl-display-flex.gl-flex-wrap.gl-align-items-flex-start.gl-ml-auto.gl-md-w-auto.gl-w-full.gl-mt-3
+ .gl-display-flex.gl-flex-wrap.gl-align-items-center.gl-gap-3.gl-md-w-auto.gl-w-full
.js-invite-group-trigger{ data: { classes: 'gl-md-w-auto gl-w-full', display_text: _('Invite a group') } }
+ - if can_admin_service_accounts?(@group)
+ = render_if_exists 'groups/group_members/create_service_account'
.js-invite-members-trigger{ data: { variant: 'confirm',
- classes: 'gl-md-w-auto gl-w-full gl-md-ml-3 gl-md-mt-0 gl-mt-3',
+ classes: 'gl-md-w-auto gl-w-full',
trigger_source: 'group-members-page',
display_text: _('Invite members') } }
= render 'groups/invite_groups_modal', group: @group, reload_page_on_submit: true
diff --git a/app/views/groups/milestones/_form.html.haml b/app/views/groups/milestones/_form.html.haml
index 89f460606cb..e84fd7a8692 100644
--- a/app/views/groups/milestones/_form.html.haml
+++ b/app/views/groups/milestones/_form.html.haml
@@ -10,12 +10,16 @@
= render "shared/milestones/form_dates", f: f
.form-group
= f.label :description, _("Description")
- = render layout: 'shared/md_preview', locals: { url: group_preview_markdown_path } do
- = render 'shared/zen', f: f, attr: :description,
- classes: 'note-textarea',
- qa_selector: 'milestone_description_field',
- supports_autocomplete: true,
- placeholder: _('Write milestone description...')
+ - @gfm_form = true
+ .js-markdown-editor{ data: { render_markdown_path: group_preview_markdown_path,
+ markdown_docs_path: help_page_path('user/markdown'),
+ qa_selector: 'milestone_description_field',
+ form_field_placeholder: _('Write milestone description...'),
+ supports_quick_actions: 'false',
+ enable_autocomplete: 'true',
+ autofocus: 'false',
+ form_field_classes: 'note-textarea js-gfm-input markdown-area' } }
+ = f.hidden_field :description
.clearfix
.error-alert
diff --git a/app/views/groups/packages/index.html.haml b/app/views/groups/packages/index.html.haml
index b6cf26c3677..6d0f24bf08c 100644
--- a/app/views/groups/packages/index.html.haml
+++ b/app/views/groups/packages/index.html.haml
@@ -10,4 +10,5 @@
npm_instance_url: package_registry_instance_url(:npm),
project_list_url: '',
settings_path: show_group_package_registry_settings(@group) ? group_settings_packages_and_registries_path(@group) : '',
+ can_delete_packages: can_delete_group_packages?(@group).to_s,
group_list_url: group_packages_path(@group) } }
diff --git a/app/views/groups/settings/_general.html.haml b/app/views/groups/settings/_general.html.haml
index 8c73fc95544..22ed6ea4403 100644
--- a/app/views/groups/settings/_general.html.haml
+++ b/app/views/groups/settings/_general.html.haml
@@ -33,7 +33,7 @@
= render 'shared/choose_avatar_button', f: f
- if @group.avatar?
%hr
- = link_to s_('Groups|Remove avatar'), group_avatar_path(@group.to_param), aria: { label: s_('Groups|Remove avatar') }, data: { confirm: s_('Groups|Avatar will be removed. Are you sure?'), 'confirm-btn-variant': 'danger' }, method: :delete, class: 'gl-button btn btn-danger-secondary'
+ = link_button_to s_('Groups|Remove avatar'), group_avatar_path(@group.to_param), aria: { label: s_('Groups|Remove avatar') }, data: { confirm: s_('Groups|Avatar will be removed. Are you sure?'), 'confirm-btn-variant': 'danger' }, method: :delete, variant: :danger, category: :secondary
.form-group.gl-form-group
= render 'shared/visibility_level', f: f, visibility_level: @group.visibility_level, can_change_visibility_level: can_change_group_visibility_level?(@group), form_model: @group
= f.submit s_('Groups|Save changes'), pajamas_button: true, class: 'js-dirty-submit', data: { qa_selector: 'save_name_visibility_settings_button' }
diff --git a/app/views/groups/settings/access_tokens/index.html.haml b/app/views/groups/settings/access_tokens/index.html.haml
index 96a492e599e..ac3be429461 100644
--- a/app/views/groups/settings/access_tokens/index.html.haml
+++ b/app/views/groups/settings/access_tokens/index.html.haml
@@ -4,40 +4,39 @@
- type_plural = _('group access tokens')
- @force_desktop_expanded_sidebar = true
-.row.gl-mt-3.js-search-settings-section
- .col-lg-4
- %h4.gl-mt-0
- = page_title
- %p
- - link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: help_page_path('user/group/settings/group_access_tokens') }
+.settings-section.js-search-settings-section
+ .settings-sticky-header
+ .settings-sticky-header-inner
+ %h4.gl-my-0
+ = page_title
+ %p.gl-text-secondary
+ - help_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: help_page_path('user/group/settings/group_access_tokens') }
- if current_user.can?(:create_resource_access_tokens, @group)
= _('Generate group access tokens scoped to this group for your applications that need access to the GitLab API.')
- %p
- = html_escape(_('You can also use group access tokens with Git to authenticate over HTTP(S). %{link_start}Learn more.%{link_end}')) % { link_start: link_start, link_end: '</a>'.html_safe }
+ = html_escape(_('You can also use group access tokens with Git to authenticate over HTTP(S). %{link_start}Learn more.%{link_end}')) % { link_start: help_link_start, link_end: '</a>'.html_safe }
- else
- = html_escape(_('Group access token creation is disabled in this group. You can still use and manage existing tokens. %{link_start}Learn more.%{link_end}')) % { link_start: link_start, link_end: '</a>'.html_safe }
- %p
+ = _('Group access token creation is disabled in this group.')
- root_group = @group.root_ancestor
- if current_user.can?(:admin_group, root_group)
- group_settings_link = edit_group_path(root_group)
- link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: group_settings_link }
= html_escape(_('You can enable group access token creation in %{link_start}group settings%{link_end}.')) % { link_start: link_start, link_end: '</a>'.html_safe }
+ = html_escape(_('You can still use and manage existing tokens. %{link_start}Learn more.%{link_end}')) % { link_start: help_link_start, link_end: '</a>'.html_safe }
- .col-lg-8
- #js-new-access-token-app{ data: { access_token_type: type } }
+ #js-new-access-token-app{ data: { access_token_type: type } }
- - if current_user.can?(:create_resource_access_tokens, @group)
- = render 'shared/access_tokens/form',
- ajax: true,
- type: type,
- path: group_settings_access_tokens_path(@group),
- resource: @group,
- token: @resource_access_token,
- scopes: @scopes,
- access_levels: GroupMember.access_level_roles,
- default_access_level: Gitlab::Access::GUEST,
- prefix: :resource_access_token,
- help_path: help_page_path('user/group/settings/group_access_tokens', anchor: 'scopes-for-a-group-access-token')
+ - if current_user.can?(:create_resource_access_tokens, @group)
+ = render 'shared/access_tokens/form',
+ ajax: true,
+ type: type,
+ path: group_settings_access_tokens_path(@group),
+ resource: @group,
+ token: @resource_access_token,
+ scopes: @scopes,
+ access_levels: GroupMember.access_level_roles,
+ default_access_level: Gitlab::Access::GUEST,
+ prefix: :resource_access_token,
+ help_path: help_page_path('user/group/settings/group_access_tokens', anchor: 'scopes-for-a-group-access-token')
- #js-access-token-table-app{ data: { access_token_type: type, access_token_type_plural: type_plural, initial_active_access_tokens: @active_access_tokens.to_json, no_active_tokens_message: _('This group has no active access tokens.'), show_role: true
+ #js-access-token-table-app{ data: { access_token_type: type, access_token_type_plural: type_plural, initial_active_access_tokens: @active_access_tokens.to_json, no_active_tokens_message: _('This group has no active access tokens.'), show_role: true
} }
diff --git a/app/views/groups/settings/ci_cd/_form.html.haml b/app/views/groups/settings/ci_cd/_form.html.haml
index d31d22c61be..9b23a8c5e0e 100644
--- a/app/views/groups/settings/ci_cd/_form.html.haml
+++ b/app/views/groups/settings/ci_cd/_form.html.haml
@@ -7,5 +7,5 @@
= f.number_field :max_artifacts_size, class: 'form-control'
%p.form-text.text-muted
= _("The maximum file size in megabytes for individual job artifacts.")
- = link_to _('Learn more.'), help_page_path('user/admin_area/settings/continuous_integration', anchor: 'maximum-artifacts-size'), target: '_blank', rel: 'noopener noreferrer'
+ = link_to _('Learn more.'), help_page_path('administration/settings/continuous_integration', anchor: 'maximum-artifacts-size'), target: '_blank', rel: 'noopener noreferrer'
= f.submit _('Save changes'), pajamas_button: true
diff --git a/app/views/import/fogbugz/new.html.haml b/app/views/import/fogbugz/new.html.haml
index bd0e4b51a63..2edd9cd5592 100644
--- a/app/views/import/fogbugz/new.html.haml
+++ b/app/views/import/fogbugz/new.html.haml
@@ -24,4 +24,5 @@
.col-md-4
= password_field_tag :password, nil, class: 'form-control gl-form-input'
.form-actions
- = submit_tag _('Continue to the next step'), class: 'gl-button btn btn-confirm'
+ = render Pajamas::ButtonComponent.new(type: :submit, variant: :confirm) do
+ = _('Continue to the next step')
diff --git a/app/views/invites/show.html.haml b/app/views/invites/show.html.haml
index 5f65405c8bc..d368f013e6b 100644
--- a/app/views/invites/show.html.haml
+++ b/app/views/invites/show.html.haml
@@ -6,7 +6,7 @@
%p
= _("You are already a member of this %{member_source}.") % { member_source: @invite_details[:title] }
.actions
- = link_to _("Go to %{source_name}") % { source_name: @invite_details[:title] }, @invite_details[:url], class: "btn gl-button btn-confirm"
+ = link_button_to _("Go to %{source_name}") % { source_name: @invite_details[:title] }, @invite_details[:url], variant: :confirm
- else
%p
diff --git a/app/views/layouts/_google_tag_manager_head.html.haml b/app/views/layouts/_google_tag_manager_head.html.haml
index 21b9a604a35..711a3d66ff7 100644
--- a/app/views/layouts/_google_tag_manager_head.html.haml
+++ b/app/views/layouts/_google_tag_manager_head.html.haml
@@ -1,4 +1,5 @@
- return unless google_tag_manager_enabled?
+
- if Feature.enabled?(:gitlab_gtm_datalayer, type: :ops)
= javascript_tag do
:plain
diff --git a/app/views/layouts/_head.html.haml b/app/views/layouts/_head.html.haml
index d3a4c5c5ba8..53ecad1b474 100644
--- a/app/views/layouts/_head.html.haml
+++ b/app/views/layouts/_head.html.haml
@@ -3,12 +3,11 @@
- omit_og = sign_in_with_redirect?
%head{ omit_og ? { } : { prefix: "og: http://ogp.me/ns#" } }
%meta{ charset: "utf-8" }
-
- %title= page_title(site_name)
-
- = render 'layouts/loading_hints'
-
%meta{ 'http-equiv' => 'X-UA-Compatible', content: 'IE=edge' }
+ %meta{ name: 'viewport', content: 'width=device-width, initial-scale=1, maximum-scale=1' }
+ %title= page_title(site_name)
+ = Gon::Base.render_data(nonce: content_security_policy_nonce)
+ = yield :project_javascripts
= render 'layouts/startup_js'
= yield :startup_js
@@ -18,14 +17,9 @@
= yield :prefetch_asset_tags
- = favicon_link_tag favicon, id: 'favicon', data: { original_href: favicon }, type: 'image/png'
-
- - if startup_css_enabled?
- = render 'layouts/startup_css', { startup_filename: local_assigns.fetch(:startup_filename, nil) }
- - else
- - diffs_colors = user_diffs_colors
- = stylesheet_link_tag "themes/#{user_application_theme_css_filename}" if user_application_theme_css_filename
- = render 'layouts/diffs_colors_css', diffs_colors if diffs_colors.present? || request.path == profile_preferences_path
+ - diffs_colors = user_diffs_colors
+ = stylesheet_link_tag "themes/#{user_application_theme_css_filename}" if user_application_theme_css_filename
+ = render 'layouts/diffs_colors_css', diffs_colors if diffs_colors.present? || request.path == profile_preferences_path
- if user_application_theme == 'gl-dark'
%meta{ name: 'color-scheme', content: 'dark light' }
@@ -43,13 +37,9 @@
= stylesheet_link_tag_defer "highlight/themes/#{user_color_scheme}"
- - if startup_css_enabled?
- = render 'layouts/startup_css_activation'
-
= stylesheet_link_tag 'performance_bar' if performance_bar_enabled?
= render 'layouts/snowplow'
-
- = Gon::Base.render_data(nonce: content_security_policy_nonce)
+ = render 'layouts/loading_hints'
= render_if_exists 'layouts/header/translations'
- if Feature.enabled?(:enable_new_sentry_clientside_integration, current_user) && Gitlab::CurrentSettings.sentry_enabled
@@ -64,8 +54,6 @@
= webpack_controller_bundle_tags
- = yield :project_javascripts
-
- unless omit_og
-# Open Graph - http://ogp.me/
%meta{ property: 'og:type', content: "object" }
@@ -84,16 +72,13 @@
%meta{ property: 'twitter:image', content: page_image }
= page_card_meta_tags
- %meta{ name: "description", content: page_description }
-
- %link{ rel: 'manifest', href: manifest_path(format: :json) }
- %meta{ name: 'viewport', content: 'width=device-width, initial-scale=1, maximum-scale=1' }
- %meta{ name: 'theme-color', content: user_theme_primary_color }
-
= csrf_meta_tags
= csp_meta_tag
= action_cable_meta_tag
+ %link{ rel: 'manifest', href: manifest_path(format: :json) }
+ = favicon_link_tag favicon, id: 'favicon', data: { original_href: favicon }, type: 'image/png'
+
-# Apple Safari/iOS home screen icons
= favicon_link_tag 'apple-touch-icon.png', rel: 'apple-touch-icon'
@@ -106,3 +91,5 @@
= render 'layouts/matomo' if extra_config.has_key?('matomo_url') && extra_config.has_key?('matomo_site_id')
-# This is needed by [GitLab JH](https://gitlab.com/gitlab-jh/gitlab/-/issues/184)
= render_if_exists "layouts/frontend_monitor"
+ %meta{ name: "description", content: page_description }
+ %meta{ name: 'theme-color', content: user_theme_primary_color }
diff --git a/app/views/layouts/_header_search.html.haml b/app/views/layouts/_header_search.html.haml
index 1d5f2583bbd..add518723e5 100644
--- a/app/views/layouts/_header_search.html.haml
+++ b/app/views/layouts/_header_search.html.haml
@@ -9,7 +9,7 @@
%input{ id: 'search', name: 'search', type: "text", placeholder: s_('GlobalSearch|Search GitLab'),
class: 'form-control gl-form-input gl-search-box-by-type-input',
autocomplete: 'off',
- data: { qa_selector: 'search_box' } }
+ data: { testid: 'search_box' } }
= hidden_field_tag :group_id, header_search_context[:group][:id] if header_search_context[:group]
= hidden_field_tag :project_id, header_search_context[:project][:id] if header_search_context[:project]
diff --git a/app/views/layouts/_img_loader.html.haml b/app/views/layouts/_img_loader.html.haml
index 979ebeb0a02..c1fe3ae0924 100644
--- a/app/views/layouts/_img_loader.html.haml
+++ b/app/views/layouts/_img_loader.html.haml
@@ -13,6 +13,6 @@
img.removeAttribute('data-src');
img.classList.remove('lazy');
img.classList.add('js-lazy-loaded');
- img.dataset.qa_selector = 'js_lazy_loaded_content';
+ img.dataset.testid = 'js_lazy_loaded_content';
});
}
diff --git a/app/views/layouts/_mailer.html.haml b/app/views/layouts/_mailer.html.haml
index 95ebe09a2e6..8b864c2685e 100644
--- a/app/views/layouts/_mailer.html.haml
+++ b/app/views/layouts/_mailer.html.haml
@@ -1,5 +1,5 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-%html{ lang: "en" }
+%html{ lang: I18n.locale }
%head
%meta{ content: "text/html; charset=UTF-8", "http-equiv" => "Content-Type" }/
%meta{ content: "width=device-width, initial-scale=1", name: "viewport" }/
diff --git a/app/views/layouts/_page.html.haml b/app/views/layouts/_page.html.haml
index 8e52f973e9e..3bb59db32aa 100644
--- a/app/views/layouts/_page.html.haml
+++ b/app/views/layouts/_page.html.haml
@@ -5,9 +5,9 @@
-# Render the parent group sidebar while creating a new subgroup/project, see GroupsController#new.
- group = @parent_group || @group
- - sidebar_panel = super_sidebar_nav_panel(nav: nav, user: current_user, group: group, project: @project, current_ref: current_ref, ref_type: @ref_type, viewed_user: @user)
+ - sidebar_panel = super_sidebar_nav_panel(nav: nav, user: current_user, group: group, project: @project, current_ref: current_ref, ref_type: @ref_type, viewed_user: @user, organization: @organization)
- sidebar_data = super_sidebar_context(current_user, group: group, project: @project, panel: sidebar_panel, panel_type: nav).to_json
- %aside.js-super-sidebar.super-sidebar.super-sidebar-loading{ data: { root_path: root_path, sidebar: sidebar_data, toggle_new_nav_endpoint: profile_preferences_url, force_desktop_expanded_sidebar: @force_desktop_expanded_sidebar.to_s } }
+ %aside.js-super-sidebar.super-sidebar.super-sidebar-loading{ data: { root_path: root_path, sidebar: sidebar_data, toggle_new_nav_endpoint: profile_preferences_url, force_desktop_expanded_sidebar: @force_desktop_expanded_sidebar.to_s, command_palette: command_palette_data(project: @project).to_json } }
- if display_whats_new?
#whats-new-app{ data: { version_digest: whats_new_version_digest } }
diff --git a/app/views/layouts/_startup_css.haml b/app/views/layouts/_startup_css.haml
deleted file mode 100644
index 64a86cf319e..00000000000
--- a/app/views/layouts/_startup_css.haml
+++ /dev/null
@@ -1,9 +0,0 @@
-- startup_filename_default = user_application_theme == 'gl-dark' ? 'dark' : 'general'
-- startup_filename = local_assigns.fetch(:startup_filename, nil) || startup_filename_default
-- diffs_colors = user_diffs_colors
-
-%style
- = Rails.application.assets_manifest.find_sources("themes/#{user_application_theme_css_filename}.css").first.to_s.html_safe if user_application_theme_css_filename
- = Rails.application.assets_manifest.find_sources("startup/startup-#{startup_filename}.css").first.to_s.html_safe
-
-= render 'layouts/diffs_colors_css', diffs_colors if diffs_colors.present? || request.path == profile_preferences_path
diff --git a/app/views/layouts/_startup_css_activation.haml b/app/views/layouts/_startup_css_activation.haml
deleted file mode 100644
index 7dfb9cd1530..00000000000
--- a/app/views/layouts/_startup_css_activation.haml
+++ /dev/null
@@ -1,7 +0,0 @@
-= javascript_tag do
- :plain
- document.querySelectorAll('link[media="print"]').forEach(linkTag => {
- linkTag.setAttribute('data-startupcss', 'loading');
- const startupLinkLoadedEvent = new CustomEvent('CSSStartupLinkLoaded');
- linkTag.addEventListener('load',function(){this.media='all';this.setAttribute('data-startupcss', 'loaded');document.dispatchEvent(startupLinkLoadedEvent);},{once: true});
- })
diff --git a/app/views/layouts/devise.html.haml b/app/views/layouts/devise.html.haml
index 6e1d3ba678c..94f25a9f0ae 100644
--- a/app/views/layouts/devise.html.haml
+++ b/app/views/layouts/devise.html.haml
@@ -1,19 +1,19 @@
- add_page_specific_style 'page_bundles/login'
- custom_text = custom_sign_in_description
!!! 5
-%html.devise-layout-html{ class: system_message_class }
+%html.html-devise-layout{ lang: I18n.locale }
= render "layouts/head", { startup_filename: 'signin' }
- %body.login-page.application.navless{ class: "#{user_application_theme} #{client_class_list}", data: { page: body_data_page, qa_selector: 'login_page' } }
+ %body.gl-h-full.login-page.navless{ class: "#{system_message_class} #{user_application_theme} #{client_class_list}", data: { page: body_data_page, qa_selector: 'login_page' } }
= header_message
= render "layouts/init_client_detection_flags"
- if Feature.enabled?(:restyle_login_page, @project)
- .page-wrap.borderless
- .container.navless-container
+ .gl-h-full.borderless.gl-display-flex.gl-flex-wrap
+ .container
.content
= render "layouts/flash"
- if custom_text.present?
.row
- .col-md.order-12.sm-bg-gray-10
+ .col-md.order-12.sm-bg-gray
.col-sm-12
%h1.mb-3.gl-font-size-h2
= brand_title
@@ -33,11 +33,11 @@
.gl-w-half.gl-xs-w-full.gl-ml-auto.gl-mr-auto.bar
= yield
- = render 'devise/shared/footer', footer_message: footer_message
+ = render 'devise/shared/footer'
- else
- .page-wrap
- = render "layouts/header/empty"
- .container.navless-container
+ = render "layouts/header/empty"
+ .gl-h-full.gl-display-flex.gl-flex-wrap
+ .container
.content
= render "layouts/flash"
.row.mt-3
@@ -60,7 +60,7 @@
%p
= _('This is a self-managed instance of GitLab.')
- .col-md-6.order-1.new-session-forms-container{ class: recently_confirmed_com? ? 'order-sm-first' : 'order-sm-12' }
+ .col-md-6.order-1{ class: recently_confirmed_com? ? 'order-sm-first' : 'order-sm-12' }
= yield
- = render 'devise/shared/footer', footer_message: footer_message
+ = render 'devise/shared/footer'
diff --git a/app/views/layouts/devise_empty.html.haml b/app/views/layouts/devise_empty.html.haml
index 89aba85984f..3e969b866a6 100644
--- a/app/views/layouts/devise_empty.html.haml
+++ b/app/views/layouts/devise_empty.html.haml
@@ -1,15 +1,15 @@
- add_page_specific_style 'page_bundles/login'
!!! 5
-%html.devise-layout-html{ lang: "en", class: system_message_class }
+%html.html-devise-layout{ lang: I18n.locale }
= render "layouts/head"
- %body.login-page.application.navless{ class: "#{user_application_theme} #{client_class_list}" }
+ %body.gl-h-full.login-page.navless{ class: "#{system_message_class} #{user_application_theme} #{client_class_list}" }
= header_message
= render "layouts/init_client_detection_flags"
= render "layouts/header/empty"
- = render "layouts/broadcast"
- .container.navless-container
- .content
- = render "layouts/flash"
- = yield
+ .gl-h-full.gl-display-flex.gl-flex-wrap
+ .container
+ .content
+ = render "layouts/flash"
+ = yield
- = render 'devise/shared/footer', footer_message: footer_message
+ = render 'devise/shared/footer'
diff --git a/app/views/layouts/errors.html.haml b/app/views/layouts/errors.html.haml
index 3ddd8c6780f..5ad20478f51 100644
--- a/app/views/layouts/errors.html.haml
+++ b/app/views/layouts/errors.html.haml
@@ -1,5 +1,5 @@
!!! 5
-%html{ lang: "en" }
+%html{ lang: I18n.locale }
%head
%meta{ :content => "width=device-width, initial-scale=1, maximum-scale=1", :name => "viewport" }
%title= yield(:title)
diff --git a/app/views/layouts/header/_current_user_dropdown.html.haml b/app/views/layouts/header/_current_user_dropdown.html.haml
index 65dbafc19da..e04ffc2e88a 100644
--- a/app/views/layouts/header/_current_user_dropdown.html.haml
+++ b/app/views/layouts/header/_current_user_dropdown.html.haml
@@ -3,7 +3,7 @@
%ul
%li.current-user
- if current_user_menu?(:profile)
- = link_to current_user, class: 'gl-line-height-20!', data: { user: current_user.username, testid: 'user-profile-link', track_action: "click_link", track_label: "user_profile", track_property: "navigation_top", qa_selector: 'user_profile_link' } do
+ = link_to current_user, class: 'gl-line-height-20!', data: { user: current_user.username, testid: 'user-profile-link', track_action: "click_link", track_label: "user_profile", track_property: "navigation_top" } do
= render 'layouts/header/current_user_dropdown_item'
- else
.gl-py-3.gl-px-4
@@ -19,7 +19,7 @@
= dispensable_render_if_exists 'layouts/header/start_trial'
- if current_user_menu?(:settings)
%li
- = link_to s_("CurrentUser|Edit profile"), profile_path, data: { qa_selector: 'edit_profile_link', track_action: "click_link", track_label: "user_edit_profile", track_property: "navigation_top" }
+ = link_to s_("CurrentUser|Edit profile"), profile_path, data: { testid: 'edit_profile_link', track_action: "click_link", track_label: "user_edit_profile", track_property: "navigation_top" }
%li
= link_to s_("CurrentUser|Preferences"), profile_preferences_path, data: { track_action: "click_link", track_label: "user_preferences", track_property: "navigation_top" }
= render_if_exists 'layouts/header/buy_pipeline_minutes', project: @project, namespace: @group
@@ -48,4 +48,4 @@
- if current_user_menu?(:sign_out)
%li.divider
%li
- = link_to _("Sign out"), destroy_user_session_path, method: :post, class: "sign-out-link", data: { qa_selector: 'sign_out_link', track_action: "click_link", track_label: "user_sign_out", track_property: "navigation_top" }
+ = link_to _("Sign out"), destroy_user_session_path, method: :post, class: "sign-out-link", data: { testid: 'sign_out_link', track_action: "click_link", track_label: "user_sign_out", track_property: "navigation_top" }
diff --git a/app/views/layouts/header/_default.html.haml b/app/views/layouts/header/_default.html.haml
index 2c6ccb4abaf..1c22a853dd0 100644
--- a/app/views/layouts/header/_default.html.haml
+++ b/app/views/layouts/header/_default.html.haml
@@ -1,7 +1,7 @@
- has_impersonation_link = header_link?(:admin_impersonation)
- user_status_data = user_status_properties(current_user)
-%header.navbar.navbar-gitlab.navbar-expand-sm.js-navbar{ data: { qa_selector: 'navbar' } }
+%header.navbar.navbar-gitlab.navbar-expand-sm.js-navbar{ data: { testid: 'navbar' } }
%a.gl-sr-only.gl-accessibility{ href: "#content-body" } Skip to content
.container-fluid
.header-content.js-header-content
@@ -12,7 +12,7 @@
= brand_header_logo
.gl-display-flex.gl-align-items-center
- if Gitlab.com_and_canary?
- = gl_badge_tag({ variant: :success, size: :sm }, { href: Gitlab::Saas.canary_toggle_com_url, data: { qa_selector: 'canary_badge_link' }, target: :_blank, rel: 'noopener noreferrer', class: 'canary-badge' }) do
+ = gl_badge_tag({ variant: :success, size: :sm }, { href: Gitlab::Saas.canary_toggle_com_url, data: { testid: 'canary_badge_link' }, target: :_blank, rel: 'noopener noreferrer', class: 'canary-badge' }) do
= _('Next')
- if current_user
@@ -47,7 +47,7 @@
- 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 js-prefetch-document', aria: { label: _('Issues') },
- data: { qa_selector: 'issues_shortcut_button', toggle: 'tooltip', placement: 'bottom',
+ data: { testid: 'issues_shortcut_button', toggle: 'tooltip', placement: 'bottom',
track_label: 'main_navigation',
track_action: 'click_issues_link',
track_property: 'navigation_top',
@@ -60,7 +60,7 @@
= nav_link(path: 'dashboard#merge_requests', html_options: { class: "user-counter dropdown" }) do
- top_level_link = assigned_mrs_dashboard_path
= link_to top_level_link, class: 'dashboard-shortcuts-merge_requests has-tooltip', title: _('Merge requests'), aria: { label: _('Merge requests') },
- data: { qa_selector: 'merge_requests_shortcut_button',
+ data: { testid: 'merge_requests_shortcut_button',
toggle: "dropdown",
placement: 'bottom',
track_label: 'merge_requests_menu',
@@ -92,7 +92,7 @@
- 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 js-prefetch-document',
- data: { qa_selector: 'todos_shortcut_button', toggle: 'tooltip', placement: 'bottom',
+ data: { testid: 'todos_shortcut_button', toggle: 'tooltip', placement: 'bottom',
track_label: 'main_navigation',
track_action: 'click_to_do_link',
track_property: 'navigation_top',
@@ -115,16 +115,16 @@
%li.nav-item.gl-display-none.gl-sm-display-block
= render "layouts/nav/top_nav"
- if header_link?(:user_dropdown)
- %li.nav-item.header-user.js-nav-user-dropdown.dropdown{ data: { qa_selector: 'user_menu', testid: 'user-menu' }, class: ('mr-0' if has_impersonation_link) }
+ %li.nav-item.header-user.js-nav-user-dropdown.dropdown{ data: { testid: 'user-dropdown' }, class: ('mr-0' if has_impersonation_link) }
= link_to current_user, class: user_dropdown_class, data: { toggle: "dropdown", track_label: "profile_dropdown", track_action: "click_dropdown", track_property: "navigation_top" } do
- = render Pajamas::AvatarComponent.new(current_user, size: 24, class: 'header-user-avatar', avatar_options: { data: { qa_selector: 'user_avatar_content' } })
+ = render Pajamas::AvatarComponent.new(current_user, size: 24, class: 'header-user-avatar', avatar_options: { data: { testid: 'user_avatar_content' } })
= render_if_exists 'layouts/header/user_notification_dot', project: project, namespace: group
= sprite_icon('chevron-down', css_class: 'caret-down')
.dropdown-menu.dropdown-menu-right
= render 'layouts/header/current_user_dropdown'
- if has_impersonation_link
%li.nav-item.impersonation.ml-0
- = render Pajamas::ButtonComponent.new(href: admin_impersonation_path, icon: 'incognito', button_options: { title: _('Stop impersonation'), class: 'impersonation-btn', aria: { label: _('Stop impersonation') }, data: { method: :delete, toggle: 'tooltip', placement: 'bottom', container: 'body', qa_selector: 'stop_impersonation_link' } })
+ = render Pajamas::ButtonComponent.new(href: admin_impersonation_path, icon: 'incognito', button_options: { title: _('Stop impersonation'), class: 'impersonation-btn', aria: { label: _('Stop impersonation') }, data: { method: :delete, toggle: 'tooltip', placement: 'bottom', container: 'body', testid: 'stop_impersonation_btn' } })
- if header_link?(:sign_in)
- if allow_signup?
%li.nav-item
@@ -133,7 +133,7 @@
%li.nav-item{ class: 'gl-flex-grow-0! gl-flex-basis-half!' }
= link_to _('Sign in'), new_session_path(:user, redirect_to_referer: 'yes')
- %button.navbar-toggler.d-block.d-sm-none{ type: 'button', class: 'gl-border-none!', data: { testid: 'top-nav-responsive-toggle', qa_selector: 'mobile_navbar_button' } }
+ %button.navbar-toggler.d-block.d-sm-none{ type: 'button', class: 'gl-border-none!', data: { testid: 'mobile_navbar_button' } }
%span.sr-only= _('Toggle navigation')
%span.more-icon.gl-px-3.gl-font-sm.gl-font-weight-bold
%span.gl-pr-2= _('Menu')
diff --git a/app/views/layouts/header/_new_dropdown.html.haml b/app/views/layouts/header/_new_dropdown.html.haml
index 50a2b45aa7e..3fe2894f236 100644
--- a/app/views/layouts/header/_new_dropdown.html.haml
+++ b/app/views/layouts/header/_new_dropdown.html.haml
@@ -13,7 +13,7 @@
id: "js-onboarding-new-project-link",
title: title, ref: 'tooltip', aria: { label: title },
data: { toggle: 'dropdown', placement: 'bottom', container: 'body', display: 'static',
- qa_selector: 'new_menu_toggle', testid: 'new-dropdown' } do
+ testid: 'new-menu-toggle' } do
= sprite_icon('plus-square')
= sprite_icon('chevron-down', css_class: 'caret-down')
.dropdown-menu.dropdown-menu-right.dropdown-extended-height
diff --git a/app/views/layouts/in_product_marketing_mailer.html.haml b/app/views/layouts/in_product_marketing_mailer.html.haml
index 65c68c95d9a..312e1811e3c 100644
--- a/app/views/layouts/in_product_marketing_mailer.html.haml
+++ b/app/views/layouts/in_product_marketing_mailer.html.haml
@@ -1,5 +1,5 @@
!!!
-%html{ lang: "en" }
+%html{ lang: I18n.locale }
%head
%meta{ content: "text/html; charset=utf-8", "http-equiv" => "Content-Type" }
%meta{ content: "width=device-width, initial-scale=1", name: "viewport" }
diff --git a/app/views/layouts/jira_connect.html.haml b/app/views/layouts/jira_connect.html.haml
index 80bbe578510..89d5abd4266 100644
--- a/app/views/layouts/jira_connect.html.haml
+++ b/app/views/layouts/jira_connect.html.haml
@@ -1,4 +1,4 @@
-%html{ lang: "en" }
+%html{ lang: I18n.locale }
%head
%meta{ content: "text/html; charset=utf-8", "http-equiv" => "Content-Type" }
%title
diff --git a/app/views/layouts/nav/_ask_duo_button.html.haml b/app/views/layouts/nav/_ask_duo_button.html.haml
new file mode 100644
index 00000000000..f17ccfc8afe
--- /dev/null
+++ b/app/views/layouts/nav/_ask_duo_button.html.haml
@@ -0,0 +1,13 @@
+- if Gitlab.ee? && ::Gitlab::Llm::TanukiBot.show_breadcrumbs_entry_point_for?(user: current_user)
+ - label = s_('TanukiBot|Ask GitLab Duo')
+ = render Pajamas::ButtonComponent.new(variant: :confirm,
+ category: :secondary,
+ icon: 'tanuki-ai',
+ size: 'small',
+ button_options: { class: 'js-tanuki-bot-chat-toggle gl-ml-3 gl-display-none gl-md-display-inline', data: { track_action: 'click_button', track_label: 'tanuki_bot_breadcrumbs_button' }, aria: { label: label }}) do
+ = label
+ = render Pajamas::ButtonComponent.new(variant: :confirm,
+ category: :secondary,
+ icon: 'tanuki-ai',
+ size: 'small',
+ button_options: { class: 'js-tanuki-bot-chat-toggle has-tooltip gl-ml-3 gl-md-display-none', title: label, data: { track_action: 'click_button', track_label: 'tanuki_bot_breadcrumbs_button', placement: 'left' }, aria: { label: label }})
diff --git a/app/views/layouts/nav/_top_bar.html.haml b/app/views/layouts/nav/_top_bar.html.haml
index a0e03c9c0cf..73b253e18bd 100644
--- a/app/views/layouts/nav/_top_bar.html.haml
+++ b/app/views/layouts/nav/_top_bar.html.haml
@@ -5,10 +5,11 @@
- top_bar_class = [@no_top_bar_container ? 'container-fluid' : container_class, @content_class]
- top_bar_container_class = 'gl-border-b'
-%div{ class: top_bar_class }
- .top-bar-container.gl-display-flex.gl-align-items-center{ :class => top_bar_container_class }
+%div{ class: top_bar_class, data: { testid: 'top-bar' } }
+ .top-bar-container.gl-display-flex.gl-align-items-center.gl-gap-2{ :class => top_bar_container_class }
- if show_super_sidebar?
- = render Pajamas::ButtonComponent.new(icon: 'sidebar', category: :tertiary, button_options: { class: 'js-super-sidebar-toggle-expand super-sidebar-toggle gl-ml-n3 gl-mr-2', title: _('Expand sidebar'), aria: { controls: 'super-sidebar', expanded: 'false', label: _('Navigation sidebar') } })
+ = render Pajamas::ButtonComponent.new(icon: 'sidebar', category: :tertiary, button_options: { class: 'js-super-sidebar-toggle-expand super-sidebar-toggle gl-ml-n3', title: _('Expand sidebar'), aria: { controls: 'super-sidebar', expanded: 'false', label: _('Navigation sidebar') } })
- elsif defined?(@left_sidebar)
- = render Pajamas::ButtonComponent.new(icon: 'sidebar', category: :tertiary, button_options: { class: 'toggle-mobile-nav gl-ml-n3 gl-mr-2', data: { qa_selector: 'toggle_mobile_nav_button' }, aria: { label: _('Open sidebar') } })
+ = render Pajamas::ButtonComponent.new(icon: 'sidebar', category: :tertiary, button_options: { class: 'toggle-mobile-nav gl-ml-n3', data: { testid: 'toggle_mobile_nav_button' }, aria: { label: _('Open sidebar') } })
= render "layouts/nav/breadcrumbs/breadcrumbs"
+ = render "layouts/nav/ask_duo_button"
diff --git a/app/views/layouts/nav/sidebar/_organization.html.haml b/app/views/layouts/nav/sidebar/_organization.html.haml
new file mode 100644
index 00000000000..de6c87f97d7
--- /dev/null
+++ b/app/views/layouts/nav/sidebar/_organization.html.haml
@@ -0,0 +1 @@
+= render partial: 'shared/nav/sidebar', object: Sidebars::Organizations::Panel.new(organization_sidebar_context(@organization, current_user))
diff --git a/app/views/layouts/notify.html.haml b/app/views/layouts/notify.html.haml
index c557dc36534..1f526ec221d 100644
--- a/app/views/layouts/notify.html.haml
+++ b/app/views/layouts/notify.html.haml
@@ -1,4 +1,4 @@
-%html{ lang: "en" }
+%html{ lang: I18n.locale }
%head
%meta{ content: "text/html; charset=utf-8", "http-equiv" => "Content-Type" }
%title
diff --git a/app/views/layouts/oauth_error.html.haml b/app/views/layouts/oauth_error.html.haml
index 8d241dfd207..d5e0e8e9c1d 100644
--- a/app/views/layouts/oauth_error.html.haml
+++ b/app/views/layouts/oauth_error.html.haml
@@ -1,5 +1,5 @@
!!! 5
-%html{ lang: "en" }
+%html{ lang: I18n.locale }
%head
%meta{ :content => "width=device-width, initial-scale=1, maximum-scale=1", :name => "viewport" }
%title= yield(:title)
diff --git a/app/views/layouts/organization.html.haml b/app/views/layouts/organization.html.haml
new file mode 100644
index 00000000000..5a357c6f805
--- /dev/null
+++ b/app/views/layouts/organization.html.haml
@@ -0,0 +1,6 @@
+- page_title @organization.name
+- header_title @organization.name, organization_path(@organization)
+- nav "organization"
+- @left_sidebar = true
+
+= render template: "layouts/application"
diff --git a/app/views/layouts/service_desk.html.haml b/app/views/layouts/service_desk.html.haml
index 7ac108e7f31..13e9785317c 100644
--- a/app/views/layouts/service_desk.html.haml
+++ b/app/views/layouts/service_desk.html.haml
@@ -1,4 +1,4 @@
-%html{ lang: "en" }
+%html{ lang: I18n.locale }
%head
%meta{ content: "text/html; charset=utf-8", "http-equiv" => "Content-Type" }
-# haml-lint:disable NoPlainNodes
diff --git a/app/views/layouts/signup_onboarding.html.haml b/app/views/layouts/signup_onboarding.html.haml
index 8cbea686d51..a5953021671 100644
--- a/app/views/layouts/signup_onboarding.html.haml
+++ b/app/views/layouts/signup_onboarding.html.haml
@@ -1,13 +1,14 @@
+- add_page_specific_style 'page_bundles/signup'
+- add_page_specific_style 'page_bundles/login'
!!! 5
-%html.devise-layout-html.navless{ class: system_message_class }
- - add_page_specific_style 'page_bundles/signup'
- - add_page_specific_style 'page_bundles/login'
+%html.html-devise-layout{ lang: I18n.locale }
= render "layouts/head"
- %body.signup-page{ class: "#{user_application_theme} #{client_class_list}", data: { page: body_data_page, qa_selector: 'signup_page' } }
- = render "layouts/header/logo_with_title"
+ %body.signup-page.navless{ class: "#{system_message_class} #{user_application_theme} #{client_class_list}", data: { page: body_data_page, qa_selector: 'signup_page' } }
+ = header_message
= render "layouts/init_client_detection_flags"
- .page-wrap
- .container.signup-box-container.navless-container
- = render "layouts/broadcast"
- .content
- = yield
+ = render "layouts/header/logo_with_title"
+ .container
+ .content
+ = yield
+
+ = footer_message
diff --git a/app/views/layouts/simple_registration.html.haml b/app/views/layouts/simple_registration.html.haml
deleted file mode 100644
index a68941b031f..00000000000
--- a/app/views/layouts/simple_registration.html.haml
+++ /dev/null
@@ -1,11 +0,0 @@
-!!! 5
-%html{ lang: "en" }
- = render "layouts/head"
- - add_page_specific_style 'page_bundles/login'
- %body.login-page.application.navless{ class: user_application_theme, data: { page: body_data_page } }
- = render "layouts/header/logo_with_title"
- = render "layouts/broadcast"
- .container.navless-container.pt-0
- .content.mw-460.mx-auto
- = render "layouts/flash"
- = yield
diff --git a/app/views/notify/_successful_pipeline.html.haml b/app/views/notify/_successful_pipeline.html.haml
index 88e0bbf6125..683ee97aca3 100644
--- a/app/views/notify/_successful_pipeline.html.haml
+++ b/app/views/notify/_successful_pipeline.html.haml
@@ -100,7 +100,8 @@
%tbody
%tr
- common_style = "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;font-size:15px;line-height:1.4;"
- - pipeline_link = content_tag(:a, "\##{@pipeline.id}", href: pipeline_url(@pipeline), style: "color:#3777b0;text-decoration:none;").html_safe
+ - pipeline_link_text = sanitize_name(@pipeline.name) || "##{@pipeline.id}"
+ - pipeline_link = content_tag(:a, pipeline_link_text, href: pipeline_url(@pipeline), style: "color:#3777b0;text-decoration:none;").html_safe
%td{ style: "#{common_style} font-weight:500;vertical-align:baseline;" }
= s_('Notify|Pipeline %{pipeline_link} triggered by').html_safe % { pipeline_link: pipeline_link }
- if @pipeline.user
diff --git a/app/views/notify/_successful_pipeline.text.erb b/app/views/notify/_successful_pipeline.text.erb
index 5798a2346fa..fcdeda5a213 100644
--- a/app/views/notify/_successful_pipeline.text.erb
+++ b/app/views/notify/_successful_pipeline.text.erb
@@ -24,9 +24,12 @@ Committed by: <%= commit.committer_name %>
<% job_count = @pipeline.total_size -%>
<% stage_count = @pipeline.stages_count -%>
+
+<% pipeline_link_text = sanitize_name(@pipeline.name) || "##{@pipeline.id}" %>
+
<% if @pipeline.user -%>
-Pipeline #<%= @pipeline.id %> ( <%= pipeline_url(@pipeline) %> ) triggered by <%= sanitize_name(@pipeline.user.name) %> ( <%= user_url(@pipeline.user) %> )
+Pipeline <%= pipeline_link_text %> ( <%= pipeline_url(@pipeline) %> ) triggered by <%= sanitize_name(@pipeline.user.name) %> ( <%= user_url(@pipeline.user) %> )
<% else -%>
-Pipeline #<%= @pipeline.id %> ( <%= pipeline_url(@pipeline) %> ) triggered by API
+Pipeline <%= pipeline_link_text %> ( <%= pipeline_url(@pipeline) %> ) triggered by API
<% end -%>
successfully completed <%= job_count %> <%= 'job'.pluralize(job_count) %> in <%= stage_count %> <%= 'stage'.pluralize(stage_count) %>.
diff --git a/app/views/notify/approved_merge_request_email.html.haml b/app/views/notify/approved_merge_request_email.html.haml
index 0b20d4f3d3a..0b856f87175 100644
--- a/app/views/notify/approved_merge_request_email.html.haml
+++ b/app/views/notify/approved_merge_request_email.html.haml
@@ -1,5 +1,5 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional //EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-%html{ lang: "en" }
+%html{ lang: I18n.locale }
%head
%meta{ content: "text/html; charset=UTF-8", "http-equiv" => "Content-Type" }/
%meta{ content: "width=device-width, initial-scale=1", name: "viewport" }/
diff --git a/app/views/notify/import_issues_csv_email.html.haml b/app/views/notify/import_issues_csv_email.html.haml
index 0008085025b..771495b57ba 100644
--- a/app/views/notify/import_issues_csv_email.html.haml
+++ b/app/views/notify/import_issues_csv_email.html.haml
@@ -1,4 +1,5 @@
- text_style = 'font-size:16px; text-align:center; line-height:30px;'
+- error_style = 'font-size:13px; text-align:center; line-height:16px; color:#dd2b0e;'
%p{ style: text_style }
- project_link = link_to(@project.full_name, project_url(@project), style: "color:#3777b0; text-decoration:none;")
@@ -16,3 +17,18 @@
- if @results[:parse_error]
%p{ style: text_style }
= s_('Notify|Error parsing CSV file. Please make sure it has the correct format: a delimited text file that uses a comma to separate values.')
+
+- preprocess_errors = @results[:preprocess_errors]
+- if preprocess_errors.present?
+
+ - missing_milestone_errors = preprocess_errors.dig(:milestone_errors, :missing) || []
+
+ - if missing_milestone_errors.present?
+ %p{ style: error_style }
+ = s_('Notify|Could not find the following %{column} values in %{project}%{parent_groups_clause}: %{error_lines}') % { error_lines: missing_milestone_errors[:titles].join(', '),
+ column: missing_milestone_errors[:header].downcase, project: @project.full_name,
+ parent_groups_clause: @project.group.present? ? ' or its parent groups' : ''}
+
+- if @results[:error_lines].present? || preprocess_errors.present?
+ %p{ style: text_style }
+ = s_('Notify|Please fix the errors above and try the CSV import again.')
diff --git a/app/views/notify/import_issues_csv_email.text.erb b/app/views/notify/import_issues_csv_email.text.erb
index 1117f90714d..ef99914a821 100644
--- a/app/views/notify/import_issues_csv_email.text.erb
+++ b/app/views/notify/import_issues_csv_email.text.erb
@@ -9,3 +9,20 @@ Errors found on line <%= 'number'.pluralize(@results[:error_lines].size) %>: <%=
<% if @results[:parse_error] %>
Error parsing CSV file. Please make sure it has the correct format: a delimited text file that uses a comma to separate values.
<% end %>
+
+<% preprocess_errors = @results[:preprocess_errors] %>
+<%
+ if preprocess_errors.present?
+ missing_milestone_errors = preprocess_errors.dig(:milestone_errors, :missing) || []
+%>
+
+ <% if missing_milestone_errors.present? %>
+ <%= s_('Notify|Could not find the following %{column} values in %{project}%{parent_groups_clause}: %{error_lines}') % { error_lines: missing_milestone_errors[:titles].join(', '),
+ column: missing_milestone_errors[:header].downcase, project: @project.full_name,
+ parent_groups_clause: @project.group.present? ? ' or its parent groups' : ''} %>
+ <% end %>
+<% end %>
+
+<% if @results[:error_lines].present? || preprocess_errors.present? %>
+ <%= s_('Notify|Please fix the errors above and try the CSV import again.') %>
+<% end %>
diff --git a/app/views/notify/issue_due_email.html.haml b/app/views/notify/issue_due_email.html.haml
index 9dd501022dd..f1959ce2557 100644
--- a/app/views/notify/issue_due_email.html.haml
+++ b/app/views/notify/issue_due_email.html.haml
@@ -5,7 +5,7 @@
%p
= assignees_label(@issue)
%p
- = sprintf(s_('Notify|This issue is due on: %{issue_due_date}'), { issue_due_date: @issue.due_date.to_s(:medium) }).html_safe
+ = sprintf(s_('Notify|This issue is due on: %{issue_due_date}'), { issue_due_date: @issue.due_date.to_fs(:medium) }).html_safe
- if @issue.description
.md
diff --git a/app/views/notify/merge_when_pipeline_succeeds_email.html.haml b/app/views/notify/merge_when_pipeline_succeeds_email.html.haml
index 9c25567696f..d376a1fdecf 100644
--- a/app/views/notify/merge_when_pipeline_succeeds_email.html.haml
+++ b/app/views/notify/merge_when_pipeline_succeeds_email.html.haml
@@ -1,5 +1,5 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional //EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-%html{ lang: "en" }
+%html{ lang: I18n.locale }
%head
%meta{ content: "text/html; charset=UTF-8", "http-equiv" => "Content-Type" }
%meta{ content: "width=device-width, initial-scale=1", name: "viewport" }
diff --git a/app/views/notify/pipeline_failed_email.html.haml b/app/views/notify/pipeline_failed_email.html.haml
index 5d4d2c0fcd8..bffb9f4ee5a 100644
--- a/app/views/notify/pipeline_failed_email.html.haml
+++ b/app/views/notify/pipeline_failed_email.html.haml
@@ -6,7 +6,7 @@
%td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;vertical-align:middle;color:#ffffff;text-align:center;padding-right:5px;line-height:1;" }
%img{ alt: "āœ–", height: "13", src: image_url('mailers/ci_pipeline_notif_v1/icon-x-red-inverted.gif'), style: "display:block;", width: "13" }/
%td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;vertical-align:middle;color:#ffffff;text-align:center;" }
- = s_('Notify|Pipeline #%{pipeline_id} has failed!') % { pipeline_id: @pipeline.id }
+ = s_('Notify|Pipeline %{pipeline_name_or_id} has failed!') % { pipeline_name_or_id: sanitize_name(@pipeline.name) || "##{@pipeline.id}" }
%tr.spacer
%td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;height:18px;font-size:18px;line-height:18px;" }
&nbsp;
@@ -98,7 +98,8 @@
%tbody
%tr
- common_style = "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;font-size:15px;font-weight:500;line-height:1.4;vertical-align:baseline;"
- - pipeline_link = link_to "##{@pipeline.id}", pipeline_url(@pipeline), style: "color:#3777b0;text-decoration:none;"
+ - pipeline_link_text = sanitize_name(@pipeline.name) || "##{@pipeline.id}"
+ - pipeline_link = link_to pipeline_link_text, pipeline_url(@pipeline), style: "color:#3777b0;text-decoration:none;"
%td{ style: "#{common_style}" }
= s_('Notify|Pipeline %{pipeline_link} triggered by').html_safe % { pipeline_link: pipeline_link }
- if @pipeline.user
diff --git a/app/views/notify/pipeline_failed_email.text.erb b/app/views/notify/pipeline_failed_email.text.erb
index c82b7a8dd2a..97823bf3998 100644
--- a/app/views/notify/pipeline_failed_email.text.erb
+++ b/app/views/notify/pipeline_failed_email.text.erb
@@ -1,4 +1,4 @@
-Pipeline #<%= @pipeline.id %> has failed!
+<%= "Pipeline #{sanitize_name(@pipeline.name) || "##{@pipeline.id}"} has failed!" %>
Project: <%= @project.name %> ( <%= project_url(@project) %> )
Branch: <%= @pipeline.source_ref %> ( <%= commits_url(@pipeline) %> )
@@ -22,16 +22,18 @@ Committed by: <%= commit.committer_name %>
<% end -%>
<% end -%>
-<% if @pipeline.user -%>
-Pipeline #<%= @pipeline.id %> ( <%= pipeline_url(@pipeline) %> ) triggered by <%= sanitize_name(@pipeline.user.name) %> ( <%= user_url(@pipeline.user) %> )
-<% else -%>
-Pipeline #<%= @pipeline.id %> ( <%= pipeline_url(@pipeline) %> ) triggered by API
-<% end -%>
-<% failed = @pipeline.latest_statuses.failed -%>
+<% pipeline_link_text = sanitize_name(@pipeline.name) || "##{@pipeline.id}" %>
+
+<% if @pipeline.user %>
+Pipeline <%= pipeline_link_text %> ( <%= pipeline_url(@pipeline) %> ) triggered by <%= sanitize_name(@pipeline.user.name) %> ( <%= user_url(@pipeline.user) %> )
+<% else %>
+Pipeline <%= pipeline_link_text %> ( <%= pipeline_url(@pipeline) %> ) triggered by API
+<% end %>
+<% failed = @pipeline.latest_statuses.failed %>
had <%= failed.size %> failed <%= 'job'.pluralize(failed.size) %>.
<% failed.each do |build| -%>
<%= render "notify/links/#{build.to_partial_path}", pipeline: @pipeline, build: build %>
Stage: <%= build.stage_name %>
Name: <%= build.name %>
-<% end -%>
+<% end -%> \ No newline at end of file
diff --git a/app/views/notify/pipeline_fixed_email.html.haml b/app/views/notify/pipeline_fixed_email.html.haml
index 33b83b104b1..cf5ebb0649a 100644
--- a/app/views/notify/pipeline_fixed_email.html.haml
+++ b/app/views/notify/pipeline_fixed_email.html.haml
@@ -1 +1 @@
-= render 'notify/successful_pipeline', title: s_('Notify|Pipeline has been fixed and #%{pipeline_id} has passed!') % {pipeline_id: @pipeline.id}
+= render 'notify/successful_pipeline', title: s_('Notify|Pipeline has been fixed and %{pipeline_name_or_id} has passed!') % { pipeline_name_or_id: sanitize_name(@pipeline.name) || "##{@pipeline.id}" }
diff --git a/app/views/notify/pipeline_fixed_email.text.erb b/app/views/notify/pipeline_fixed_email.text.erb
index 32334260a5e..3b8be0cf7a0 100644
--- a/app/views/notify/pipeline_fixed_email.text.erb
+++ b/app/views/notify/pipeline_fixed_email.text.erb
@@ -1 +1 @@
-<%= render 'notify/successful_pipeline', title: "Pipeline has been fixed and ##{@pipeline.id} has passed!" -%>
+<%= render 'notify/successful_pipeline', title: "Pipeline has been fixed and #{sanitize_name(@pipeline.name) || "##{@pipeline.id}"} has passed!" -%>
diff --git a/app/views/notify/pipeline_success_email.html.haml b/app/views/notify/pipeline_success_email.html.haml
index 47832907663..3139741b5c1 100644
--- a/app/views/notify/pipeline_success_email.html.haml
+++ b/app/views/notify/pipeline_success_email.html.haml
@@ -1 +1 @@
-= render 'notify/successful_pipeline', title: "Pipeline ##{@pipeline.id} has passed!"
+= render 'notify/successful_pipeline', title: s_('Notify|Pipeline %{pipeline_name_or_id} has passed!') % { pipeline_name_or_id: sanitize_name(@pipeline.name) || "##{@pipeline.id}" }
diff --git a/app/views/notify/pipeline_success_email.text.erb b/app/views/notify/pipeline_success_email.text.erb
index 83cdb72d252..58999614d05 100644
--- a/app/views/notify/pipeline_success_email.text.erb
+++ b/app/views/notify/pipeline_success_email.text.erb
@@ -1 +1 @@
-<%= render 'notify/successful_pipeline', title: "Pipeline ##{@pipeline.id} has passed!" -%>
+<%= render 'notify/successful_pipeline', title: "Pipeline #{sanitize_name(@pipeline.name) || "##{@pipeline.id}"} has passed!" -%>
diff --git a/app/views/notify/prometheus_alert_fired_email.html.haml b/app/views/notify/prometheus_alert_fired_email.html.haml
index cdc97d583df..25dc8e59073 100644
--- a/app/views/notify/prometheus_alert_fired_email.html.haml
+++ b/app/views/notify/prometheus_alert_fired_email.html.haml
@@ -25,7 +25,3 @@
- if @alert.show_incident_issues_link?
%p
= link_to(_('View incident issues.'), @alert.incident_issues_link)
-
-- if @alert.show_performance_dashboard_link?
- %p
- = link_to(_('View performance dashboard.'), @alert.performance_dashboard_link)
diff --git a/app/views/notify/prometheus_alert_fired_email.text.erb b/app/views/notify/prometheus_alert_fired_email.text.erb
index b23cd8b6ccc..a9c1d98a396 100644
--- a/app/views/notify/prometheus_alert_fired_email.text.erb
+++ b/app/views/notify/prometheus_alert_fired_email.text.erb
@@ -18,7 +18,3 @@
<% if @alert.show_incident_issues_link? %>
<%= _('View incident issues.') %> <%= @alert.incident_issues_link %>
<% end %>
-
-<% if @alert.show_performance_dashboard_link? %>
-<%= _('View the performance dashboard at') %> <%= @alert.performance_dashboard_link %>
-<% end %>
diff --git a/app/views/notify/repository_push_email.html.haml b/app/views/notify/repository_push_email.html.haml
index d493f9d5d98..199865ba644 100644
--- a/app/views/notify/repository_push_email.html.haml
+++ b/app/views/notify/repository_push_email.html.haml
@@ -19,7 +19,7 @@
%li
%strong= link_to(commit.short_id, project_commit_url(@message.project, commit))
%div
- = html_escape(s_('Notify|%{committed_by_start} by %{author_name} %{committed_by_end} %{committed_at_start} at %{committed_date} %{committed_at_end}')) % {committed_by_start: '<span>'.html_safe, author_name: commit.author_name, committed_by_end: '</span>'.html_safe, committed_at_start: '<i>'.html_safe, committed_date: commit.committed_date.to_s(:iso8601), committed_at_end: '</i>'.html_safe}
+ = html_escape(s_('Notify|%{committed_by_start} by %{author_name} %{committed_by_end} %{committed_at_start} at %{committed_date} %{committed_at_end}')) % {committed_by_start: '<span>'.html_safe, author_name: commit.author_name, committed_by_end: '</span>'.html_safe, committed_at_start: '<i>'.html_safe, committed_date: commit.committed_date.to_fs(:iso8601), committed_at_end: '</i>'.html_safe}
%pre.commit-message
= commit.safe_message
diff --git a/app/views/notify/repository_push_email.text.haml b/app/views/notify/repository_push_email.text.haml
index 2ba0a2cf4ab..38a439864b7 100644
--- a/app/views/notify/repository_push_email.text.haml
+++ b/app/views/notify/repository_push_email.text.haml
@@ -8,7 +8,7 @@
\
= @message.reverse_compare? ? "Deleted commits:" : "Commits:"
- @message.commits.each do |commit|
- #{commit.short_id} by #{commit.author_name} at #{commit.committed_date.to_s(:iso8601)}
+ #{commit.short_id} by #{commit.author_name} at #{commit.committed_date.to_fs(:iso8601)}
#{commit.safe_message}
\- - - - -
\
diff --git a/app/views/notify/unapproved_merge_request_email.html.haml b/app/views/notify/unapproved_merge_request_email.html.haml
index 94e2d0377aa..b0573251fd3 100644
--- a/app/views/notify/unapproved_merge_request_email.html.haml
+++ b/app/views/notify/unapproved_merge_request_email.html.haml
@@ -1,5 +1,5 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional //EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-%html{ lang: "en" }
+%html{ lang: I18n.locale }
%head
%meta{ content: "text/html; charset=UTF-8", "http-equiv" => "Content-Type" }/
%meta{ content: "width=device-width, initial-scale=1", name: "viewport" }/
diff --git a/app/views/organizations/organizations/directory.html.haml b/app/views/organizations/organizations/directory.html.haml
deleted file mode 100644
index 1d2fb66112b..00000000000
--- a/app/views/organizations/organizations/directory.html.haml
+++ /dev/null
@@ -1,2 +0,0 @@
-- breadcrumb_title @organization.name
-- page_title @organization.name
diff --git a/app/views/organizations/organizations/groups_and_projects.html.haml b/app/views/organizations/organizations/groups_and_projects.html.haml
new file mode 100644
index 00000000000..8890f4b1ce5
--- /dev/null
+++ b/app/views/organizations/organizations/groups_and_projects.html.haml
@@ -0,0 +1,3 @@
+- page_title _('Groups and projects')
+
+#js-organizations-groups-and-projects
diff --git a/app/views/organizations/organizations/show.html.haml b/app/views/organizations/organizations/show.html.haml
new file mode 100644
index 00000000000..8ba2a3d96ac
--- /dev/null
+++ b/app/views/organizations/organizations/show.html.haml
@@ -0,0 +1,2 @@
+- page_title s_('Organization|Organization overview')
+- @skip_current_level_breadcrumb = true
diff --git a/app/views/profiles/accounts/_providers.html.haml b/app/views/profiles/accounts/_providers.html.haml
index 6c6fa32f736..6f0c091dfdb 100644
--- a/app/views/profiles/accounts/_providers.html.haml
+++ b/app/views/profiles/accounts/_providers.html.haml
@@ -1,6 +1,6 @@
-- button_class = 'btn btn-default gl-button gl-mb-3 gl-mr-3'
+- button_class = 'btn btn-default gl-button'
-%label.label-bold
+%label.label-bold.gl-mb-0
= s_('Profiles|Connected Accounts')
%p= s_('Profiles|Select a service to sign in with.')
- providers.each do |provider|
diff --git a/app/views/profiles/accounts/show.html.haml b/app/views/profiles/accounts/show.html.haml
index fec5d2d5ff5..799dfaae8c5 100644
--- a/app/views/profiles/accounts/show.html.haml
+++ b/app/views/profiles/accounts/show.html.haml
@@ -14,90 +14,88 @@
- c.with_body do
= html_escape(_('You have set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}.')) % { anchorOpen: '<a href="%{href}">'.html_safe % { href: help_page_path('user/profile/account/two_factor_authentication', anchor: 'generate-new-recovery-codes-using-ssh') }, anchorClose: '</a>'.html_safe }
-.row.gl-mt-3.js-search-settings-section
- .col-lg-4.profile-settings-sidebar
- %h4.gl-mt-0
- = s_('Profiles|Two-factor authentication')
+.settings-section.js-search-settings-section
+ .settings-sticky-header
+ .settings-sticky-header-inner
+ %h4.gl-my-0
+ = s_('Profiles|Two-factor authentication')
+ %p.gl-text-secondary
+ = s_("Profiles|Increase your account's security by enabling two-factor authentication (2FA).")
+ %div
%p
- = s_("Profiles|Increase your account's security by enabling two-factor authentication (2FA).")
- .col-lg-8
- %p
- #{_('Status')}: #{current_user.two_factor_enabled? ? _('Enabled') : _('Disabled')}
+ %span.gl-font-weight-bold
+ #{_('Status')}:
+ #{current_user.two_factor_enabled? ? _('Enabled') : _('Disabled')}
- if current_user.two_factor_enabled?
= render Pajamas::ButtonComponent.new(variant: :confirm, href: profile_two_factor_auth_path) do
= _('Manage two-factor authentication')
- else
- .gl-mb-3
- = render Pajamas::ButtonComponent.new(variant: :confirm, href: profile_two_factor_auth_path, button_options: { data: { qa_selector: 'enable_2fa_button' }}) do
- = _('Enable two-factor authentication')
- .col-lg-12
- %hr
+ = render Pajamas::ButtonComponent.new(variant: :confirm, href: profile_two_factor_auth_path, button_options: { data: { qa_selector: 'enable_2fa_button' }}) do
+ = _('Enable two-factor authentication')
- if display_providers_on_profile?
- .row.gl-mt-3.js-search-settings-section
- .col-lg-4.profile-settings-sidebar
- %h4.gl-mt-0
- = s_('Profiles|Service sign-in')
- %p
- = s_('Profiles|Connect a service for sign-in.')
- .col-lg-8
- = render 'providers', providers: button_based_providers, group_saml_identities: local_assigns[:group_saml_identities]
- .col-lg-12
- %hr
+ .settings-section.js-search-settings-section
+ .settings-sticky-header
+ .settings-sticky-header-inner
+ %h4.gl-my-0
+ = s_('Profiles|Service sign-in')
+ %p.gl-text-secondary
+ = s_('Profiles|Connect a service for sign-in.')
+ = render 'providers', providers: button_based_providers, group_saml_identities: local_assigns[:group_saml_identities]
+
- if current_user.can_change_username?
- .row.gl-mt-3.js-search-settings-section
- .col-lg-4.profile-settings-sidebar
- %h4.gl-mt-0.warning-title
- = s_('Profiles|Change username')
- %p
- = s_('Profiles|Changing your username can have unintended side effects.')
- = succeed '.' do
- = link_to _('Learn more'), help_page_path('user/profile/index', anchor: 'change-your-username'), target: '_blank', rel: 'noopener noreferrer'
- .col-lg-8
- - data = { initial_username: current_user.username, root_url: root_url, action_url: update_username_profile_path(format: :json) }
- #update-username{ data: data }
- .col-lg-12
- %hr
+ .settings-section.js-search-settings-section
+ .settings-sticky-header
+ .settings-sticky-header-inner
+ %h4.gl-my-0.warning-title
+ = s_('Profiles|Change username')
+ %p.gl-text-secondary
+ = s_('Profiles|Changing your username can have unintended side effects.')
+ = succeed '.' do
+ = link_to _('Learn more'), help_page_path('user/profile/index', anchor: 'change-your-username'), target: '_blank', rel: 'noopener noreferrer'
+ - data = { initial_username: current_user.username, root_url: root_url, action_url: update_username_profile_path(format: :json) }
+ #update-username{ data: data }
- if prevent_delete_account?
- .row.gl-mt-3.js-search-settings-section
- .col-lg-4.profile-settings-sidebar
- %h4.gl-mt-0.danger-title
- = s_('Profiles|Delete account')
- .col-lg-8
- %p
- = s_('Profiles|Account deletion is not allowed by your administrator.')
+ .settings-section.js-search-settings-section
+ .settings-sticky-header
+ .settings-sticky-header-inner
+ %h4.gl-my-0.danger-title
+ = s_('Profiles|Delete account')
+ %p.gl-text-secondary
+ = s_('Profiles|Account deletion is not allowed by your administrator.')
- else
- .row.gl-mt-3.js-search-settings-section
- .col-lg-4.profile-settings-sidebar
- %h4.gl-mt-0.danger-title
- = s_('Profiles|Delete account')
- .col-lg-8
- - if current_user.can_be_removed? && can?(current_user, :destroy_user, current_user)
- %p
- = s_('Profiles|Deleting an account has the following effects:')
- = render 'users/deletion_guidance', user: current_user
-
- -# Delete button here
- = render Pajamas::ButtonComponent.new(variant: :danger, button_options: { id: 'delete-account-button', disabled: true, data: { qa_selector: 'delete_account_button' }}) do
+ .settings-section.js-search-settings-section
+ .settings-sticky-header
+ .settings-sticky-header-inner
+ %h4.gl-mt-0.danger-title
= s_('Profiles|Delete account')
+ - if current_user.can_be_removed? && can?(current_user, :destroy_user, current_user)
+ %p.gl-text-secondary
+ = s_('Profiles|Deleting an account has the following effects:')
+ = render 'users/deletion_guidance', user: current_user
- #delete-account-modal{ data: { action_url: user_registration_path,
- confirm_with_password: ('true' if current_user.confirm_deletion_with_password?),
- username: current_user.username } }
+ -# Delete button here
+ = render Pajamas::ButtonComponent.new(variant: :danger, button_options: { id: 'delete-account-button', disabled: true, data: { qa_selector: 'delete_account_button' }}) do
+ = s_('Profiles|Delete account')
+
+ #delete-account-modal{ data: { action_url: user_registration_path,
+ confirm_with_password: ('true' if current_user.confirm_deletion_with_password?),
+ username: current_user.username } }
+ - else
+ - if current_user.solo_owned_groups.present?
+ %p
+ = s_('Profiles|Your account is currently an owner in these groups:')
+ %ul
+ - current_user.solo_owned_groups.each do |group|
+ %li= group.name
+ %p
+ = s_('Profiles|You must transfer ownership or delete these groups before you can delete your account.')
+ - elsif !current_user.can_remove_self?
+ %p
+ = s_('Profiles|GitLab is unable to verify your identity automatically. For security purposes, you must set a password by %{openingTag}resetting your password%{closingTag} to delete your account.').html_safe % { openingTag: "<a href='#{reset_profile_password_path}' rel=\"nofollow\" data-method=\"put\">".html_safe, closingTag: '</a>'.html_safe}
+ %p
+ = s_('Profiles|If after setting a password, the option to delete your account is still not available, please %{link_start}submit a request%{link_end} to begin the account deletion process.').html_safe % { link_start: '<a href="https://support.gitlab.io/account-deletion/" rel="nofollow noreferrer noopener" target="_blank">'.html_safe, link_end: '</a>'.html_safe}
- else
- - if current_user.solo_owned_groups.present?
- %p
- = s_('Profiles|Your account is currently an owner in these groups:')
- %strong= current_user.solo_owned_groups.map(&:name).join(', ')
- %p
- = s_('Profiles|You must transfer ownership or delete these groups before you can delete your account.')
- - elsif !current_user.can_remove_self?
- %p
- = s_('Profiles|GitLab is unable to verify your identity automatically. For security purposes, you must set a password by %{openingTag}resetting your password%{closingTag} to delete your account.').html_safe % { openingTag: "<a href='#{reset_profile_password_path}' rel=\"nofollow\" data-method=\"put\">".html_safe, closingTag: '</a>'.html_safe}
- %p
- = s_('Profiles|If after setting a password, the option to delete your account is still not available, please %{link_start}submit a request%{link_end} to begin the account deletion process.').html_safe % { link_start: '<a href="https://support.gitlab.io/account-deletion/" rel="nofollow noreferrer noopener" target="_blank">'.html_safe, link_end: '</a>'.html_safe}
- - else
- %p
- = s_("Profiles|You don't have access to delete this user.")
-.gl-mb-3
+ %p
+ = s_("Profiles|You don't have access to delete this user.")
diff --git a/app/views/profiles/active_sessions/_active_session.html.haml b/app/views/profiles/active_sessions/_active_session.html.haml
index 9ec8d694dac..e91c28e6e84 100644
--- a/app/views/profiles/active_sessions/_active_session.html.haml
+++ b/app/views/profiles/active_sessions/_active_session.html.haml
@@ -27,9 +27,5 @@
- unless is_current_session
.float-right
- = link_to(revoke_session_path(active_session),
- { data: { confirm: _('Are you sure? The device will be signed out of GitLab and all remember me tokens revoked.') },
- method: :delete,
- class: "gl-button btn btn-danger gl-ml-3" }) do
- %span.sr-only= _('Revoke')
+ = link_button_to revoke_session_path(active_session), data: { confirm: _('Are you sure? The device will be signed out of GitLab and all remember me tokens revoked.'), confirm_btn_variant: :danger }, method: :delete, class: 'gl-ml-3', variant: :danger, 'aria-label': _('Revoke') do
= _('Revoke')
diff --git a/app/views/profiles/active_sessions/index.html.haml b/app/views/profiles/active_sessions/index.html.haml
index 1952655937e..baca9559e08 100644
--- a/app/views/profiles/active_sessions/index.html.haml
+++ b/app/views/profiles/active_sessions/index.html.haml
@@ -1,16 +1,15 @@
- page_title _('Active Sessions')
- @force_desktop_expanded_sidebar = true
-.row.gl-mt-3.js-search-settings-section
- .col-lg-4.profile-settings-sidebar
- %h4.gl-mt-0
- = page_title
- %p
- = _('This is a list of devices that have logged into your account. Revoke any sessions that you do not recognize.')
- .col-lg-8
- .gl-mb-3
+.settings-section.js-search-settings-section
+ .settings-sticky-header
+ .settings-sticky-header-inner
+ %h4.gl-my-0
+ = page_title
+ %p.gl-text-secondary
+ = _('This is a list of devices that have logged into your account. Revoke any sessions that you do not recognize.')
- = render Pajamas::CardComponent.new(card_options: { class: 'gl-border-0' }, body_options: { class: 'gl-p-0' }) do |c|
- - c.with_body do
- %ul.list-group.list-group-flush
- = render partial: 'profiles/active_sessions/active_session', collection: @sessions
+ = render Pajamas::CardComponent.new(card_options: { class: 'gl-border-0' }, body_options: { class: 'gl-p-0' }) do |c|
+ - c.with_body do
+ %ul.list-group.list-group-flush
+ = render partial: 'profiles/active_sessions/active_session', collection: @sessions
diff --git a/app/views/profiles/audit_log.html.haml b/app/views/profiles/audit_log.html.haml
index 44cfbc1f74f..d47f1ea7c25 100644
--- a/app/views/profiles/audit_log.html.haml
+++ b/app/views/profiles/audit_log.html.haml
@@ -1,11 +1,12 @@
- page_title _('Authentication log')
- @force_desktop_expanded_sidebar = true
-.row.gl-mt-3.js-search-settings-section
- .col-lg-4.profile-settings-sidebar
- %h4.gl-mt-0
- = page_title
- %p
- = _('This is a security log of authentication events involving your account.')
- .col-lg-8
- = render 'event_table', events: @events
+.settings-section.js-search-settings-section
+ .settings-sticky-header
+ .settings-sticky-header-inner
+ %h4.gl-my-0
+ = page_title
+ %p.gl-text-secondary
+ = _('This is a security log of authentication events involving your account.')
+
+ = render 'event_table', events: @events
diff --git a/app/views/profiles/chat_names/_chat_name.html.haml b/app/views/profiles/chat_names/_chat_name.html.haml
index afc3894c23b..0ac8ede3c62 100644
--- a/app/views/profiles/chat_names/_chat_name.html.haml
+++ b/app/views/profiles/chat_names/_chat_name.html.haml
@@ -10,4 +10,4 @@
= _('Never')
%td
- = link_to _('Remove'), profile_chat_name_path(chat_name), method: :delete, class: 'gl-button btn btn-danger float-right', aria: { label: _('Remove') }, data: { confirm: _('Are you sure you want to remove this nickname?'), confirm_btn_variant: 'danger' }
+ = link_button_to _('Remove'), profile_chat_name_path(chat_name), method: :delete, class: 'float-right', aria: { label: _('Remove') }, data: { confirm: _('Are you sure you want to remove this nickname?'), confirm_btn_variant: 'danger' }, variant: :danger
diff --git a/app/views/profiles/chat_names/index.html.haml b/app/views/profiles/chat_names/index.html.haml
index 264ee040d7d..7a63fc30d9c 100644
--- a/app/views/profiles/chat_names/index.html.haml
+++ b/app/views/profiles/chat_names/index.html.haml
@@ -2,29 +2,27 @@
- @hide_search_settings = true
- @force_desktop_expanded_sidebar = true
-.row.gl-mt-5.js-search-settings-section
- .col-lg-4.profile-settings-sidebar
- %h4.gl-mt-0
- = page_title
- %p
- = _('You can see your chat accounts.')
+.settings-section.js-search-settings-section.gl-mt-3
+ .settings-sticky-header
+ .settings-sticky-header-inner
+ %h4.gl-my-0
+ = page_title
- .col-lg-8
- %h5.gl-mt-0
- = sprintf(_('Active chat names (%{count})'), { count: @chat_names.size })
+ %h5.gl-font-lg.gl-mt-0
+ = sprintf(_('Active chat names (%{count})'), { count: @chat_names.size })
- - if @chat_names.present?
- .table-responsive
- %table.table
- %thead
- %tr
- %th= _('Team domain')
- %th= _('Nickname')
- %th= _('Last used')
- %th
- %tbody
- = render @chat_names
+ - if @chat_names.present?
+ .table-responsive
+ %table.table
+ %thead
+ %tr
+ %th= _('Team domain')
+ %th= _('Nickname')
+ %th= _('Last used')
+ %th
+ %tbody
+ = render @chat_names
- - else
- .settings-message.text-center
- = _("You don't have any active chat names.")
+ - else
+ .gl-text-secondary.settings-message
+ = _("You don't have any active chat names.")
diff --git a/app/views/profiles/comment_templates/index.html.haml b/app/views/profiles/comment_templates/index.html.haml
index dd5b43aa802..0692f5d8ebb 100644
--- a/app/views/profiles/comment_templates/index.html.haml
+++ b/app/views/profiles/comment_templates/index.html.haml
@@ -1,10 +1,11 @@
-- page_title _('Comment Templates')
+- page_title _('Comment templates')
-#js-comment-templates-root.row.gl-mt-5{ data: { base_path: profile_comment_templates_path } }
- .col-lg-4
- %h4.gl-mt-0
- = page_title
- %p
- = _('Comment templates can be used when creating comments inside issues, merge requests, and epics.')
- .col-lg-8
- = gl_loading_icon(size: 'lg')
+#js-comment-templates-root.settings-section.gl-mt-3{ data: { base_path: profile_comment_templates_path } }
+ .settings-sticky-header
+ .settings-sticky-header-inner
+ %h4.gl-my-0
+ = page_title
+ %p.gl-text-secondary
+ = _('Comment templates can be used when creating comments inside issues, merge requests, and epics.')
+
+ = gl_loading_icon(size: 'lg')
diff --git a/app/views/profiles/emails/index.html.haml b/app/views/profiles/emails/index.html.haml
index c16f3c3b12b..743c26260e4 100644
--- a/app/views/profiles/emails/index.html.haml
+++ b/app/views/profiles/emails/index.html.haml
@@ -1,24 +1,26 @@
- page_title _('Emails')
- @force_desktop_expanded_sidebar = true
-.row.gl-mt-3.js-search-settings-section
- .col-lg-4.profile-settings-sidebar
- %h4.gl-mt-0
- = page_title
- %p
- = _('Control emails linked to your account')
- .col-lg-8
- %h4.gl-mt-0
- = _('Add email address')
+.settings-section.js-search-settings-section
+ .settings-sticky-header
+ .settings-sticky-header-inner
+ %h4.gl-my-0
+ = _('Add email address')
+ %p.gl-text-secondary
+ = _('Control emails linked to your account')
+ %div
= gitlab_ui_form_for 'email', url: profile_emails_path do |f|
.form-group
= f.label :email, _('Email'), class: 'label-bold'
= f.text_field :email, class: 'form-control gl-form-input', data: { qa_selector: 'email_address_field' }
.gl-mt-3
= f.submit _('Add email address'), data: { qa_selector: 'add_email_address_button' }, pajamas_button: true
- %hr
- %h4.gl-mt-0
- = _('Linked emails (%{email_count})') % { email_count: @emails.load.size }
+
+.settings-section.js-search-settings-section
+ .settings-sticky-header
+ .settings-sticky-header-inner
+ %h4.gl-my-0
+ = _('Linked emails (%{email_count})') % { email_count: @emails.load.size }
.account-well.gl-mb-3
%ul
%li
@@ -59,8 +61,6 @@
.gl-display-flex.gl-justify-content-end.gl-align-items-flex-end.gl-flex-grow-1.gl-flex-wrap-reverse.gl-gap-3
- unless email.confirmed?
- confirm_title = "#{email.confirmation_sent_at ? _('Resend confirmation email') : _('Send confirmation email')}"
- = link_to confirm_title, resend_confirmation_instructions_profile_email_path(email), method: :put, class: 'gl-button btn btn-sm btn-default'
+ = link_button_to confirm_title, resend_confirmation_instructions_profile_email_path(email), method: :put, size: :small
- = link_to profile_email_path(email), data: { confirm: _('Are you sure?'), qa_selector: 'delete_email_link'}, method: :delete, class: 'gl-button btn btn-sm btn-danger' do
- %span.sr-only= _('Remove')
- = sprite_icon('remove')
+ = link_button_to nil, profile_email_path(email), data: { confirm: _('Are you sure?'), qa_selector: 'delete_email_link'}, method: :delete, variant: :danger, size: :small, icon: 'remove', 'aria-label': _('Remove')
diff --git a/app/views/profiles/gpg_keys/_key.html.haml b/app/views/profiles/gpg_keys/_key.html.haml
index d52b16814c0..d8b8dda29dc 100644
--- a/app/views/profiles/gpg_keys/_key.html.haml
+++ b/app/views/profiles/gpg_keys/_key.html.haml
@@ -19,9 +19,6 @@
.float-right
%span.key-created-at
= html_escape(s_('Profiles|Created %{time_ago}')) % { time_ago: time_ago_with_tooltip(key.created_at) }
- = link_to profile_gpg_key_path(key), data: { confirm: _('Are you sure? Removing this GPG key does not affect already signed commits.') }, method: :delete, class: "gl-button btn btn-icon btn-danger gl-ml-3" do
- %span.sr-only= _('Remove')
- = sprite_icon('remove')
- = link_to revoke_profile_gpg_key_path(key), data: { confirm: _('Are you sure? All commits that were signed with this GPG key will be unverified.') }, method: :put, class: "gl-button btn btn-danger gl-ml-3" do
- %span.sr-only= _('Revoke')
+ = link_button_to nil, profile_gpg_key_path(key), data: { confirm: _('Are you sure? Removing this GPG key does not affect already signed commits.') }, method: :delete, class: 'gl-ml-3', variant: :danger, icon: 'remove', 'aria-label': _('Remove')
+ = link_button_to revoke_profile_gpg_key_path(key), data: { confirm: _('Are you sure? All commits that were signed with this GPG key will be unverified.') }, method: :put, class: 'gl-ml-3', variant: :danger, 'aria-label': _('Revoke') do
= _('Revoke')
diff --git a/app/views/profiles/gpg_keys/index.html.haml b/app/views/profiles/gpg_keys/index.html.haml
index b21a4da16b9..2dfd6c7860f 100644
--- a/app/views/profiles/gpg_keys/index.html.haml
+++ b/app/views/profiles/gpg_keys/index.html.haml
@@ -2,21 +2,25 @@
- add_page_specific_style 'page_bundles/profile'
- @force_desktop_expanded_sidebar = true
-.row.gl-mt-3.js-search-settings-section
- .col-lg-4.profile-settings-sidebar
- %h4.gl-mt-0
- = page_title
- %p
- = _('GPG keys allow you to verify signed commits.')
- .col-lg-8
- %h5.gl-mt-0
- = _('Add a GPG key')
- %p.profile-settings-content
- - help_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: help_page_path('user/project/repository/gpg_signed_commits/index.md') }
- = _('Add a GPG key for secure access to GitLab. %{help_link_start}Learn more.%{help_link_end}').html_safe % {help_link_start: help_link_start, help_link_end: '</a>'.html_safe }
- = render 'form'
- %hr
- %h5
- = _('Your GPG keys (%{count})') % { count: @gpg_keys.count }
- .gl-mb-3
- = render 'key_table'
+.settings-section.js-search-settings-section
+ .settings-sticky-header
+ .settings-sticky-header-inner
+ %h4.gl-my-0
+ = page_title
+ %p.gl-text-secondary
+ = _('GPG keys allow you to verify signed commits.')
+
+ %h5.gl-font-lg.gl-mt-0
+ = _('Add a GPG key')
+ %p
+ - help_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: help_page_path('user/project/repository/gpg_signed_commits/index.md') }
+ = _('Add a GPG key for secure access to GitLab. %{help_link_start}Learn more%{help_link_end}.').html_safe % {help_link_start: help_link_start, help_link_end: '</a>'.html_safe }
+ = render 'form'
+
+.settings-section.js-search-settings-section
+ .settings-sticky-header
+ .settings-sticky-header-inner
+ %h4.gl-my-0
+ = _('Your GPG keys (%{count})') % { count: @gpg_keys.count }
+ .gl-mb-3
+ = render 'key_table'
diff --git a/app/views/profiles/keys/_key_details.html.haml b/app/views/profiles/keys/_key_details.html.haml
index 4f3d97fb90c..f1d5a127728 100644
--- a/app/views/profiles/keys/_key_details.html.haml
+++ b/app/views/profiles/keys/_key_details.html.haml
@@ -14,13 +14,13 @@
%strong= ssh_key_usage_types.invert[@key.usage_type]
%li
%span.light= _('Created on:')
- %strong= @key.created_at.to_s(:medium)
+ %strong= @key.created_at.to_fs(:medium)
%li
%span.light= _('Expires:')
- %strong= @key.expires_at.try(:to_s, :medium) || _('Never')
+ %strong= @key.expires_at&.to_fs(:medium) || _('Never')
%li
%span.light= _('Last used on:')
- %strong= @key.last_used_at.try(:to_s, :medium) || _('Never')
+ %strong= @key.last_used_at&.to_fs(:medium) || _('Never')
.col-md-8
= form_errors(@key, type: 'key') unless @key.valid?
diff --git a/app/views/profiles/keys/index.html.haml b/app/views/profiles/keys/index.html.haml
index e7c0cf813b5..c2e65dcc8ef 100644
--- a/app/views/profiles/keys/index.html.haml
+++ b/app/views/profiles/keys/index.html.haml
@@ -2,27 +2,27 @@
- add_page_specific_style 'page_bundles/profile'
- @force_desktop_expanded_sidebar = true
-.row.gl-mt-3.js-search-settings-section
- .col-lg-4.profile-settings-sidebar
- %h4.gl-mt-0
- = page_title
- %p
- = _('SSH keys allow you to establish a secure connection between your computer and GitLab.')
- %br
- %h4.gl-mt-0
- = _('SSH Fingerprints')
- %p
- - config_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: help_instance_configuration_url }
- = html_escape(s_('SSH fingerprints verify that the client is connecting to the correct host. Check the %{config_link_start}current instance configuration%{config_link_end}.')) % { config_link_start: config_link_start, config_link_end: '</a>'.html_safe }
- .col-lg-8
- %h5.gl-mt-0
- = _('Add an SSH key')
- %p.profile-settings-content
- - help_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: help_page_path('user/ssh.md') }
- = _('Add an SSH key for secure access to GitLab. %{help_link_start}Learn more.%{help_link_end}').html_safe % {help_link_start: help_link_start, help_link_end: '</a>'.html_safe }
- = render 'form'
- %hr
- %h5
- = _('Your SSH keys (%{count})') % { count: @keys.count }
- .gl-mb-3
- = render 'key_table'
+.settings-section.js-search-settings-section
+ .settings-sticky-header
+ .settings-sticky-header-inner
+ %h4.gl-my-0
+ = page_title
+ %p.gl-text-secondary
+ = _('SSH keys allow you to establish a secure connection between your computer and GitLab.')
+ - config_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: help_instance_configuration_url }
+ = html_escape(s_('SSH fingerprints verify that the client is connecting to the correct host. Check the %{config_link_start}current instance configuration%{config_link_end}.')) % { config_link_start: config_link_start, config_link_end: '</a>'.html_safe }
+
+ %h5.gl-font-lg.gl-mt-0
+ = _('Add an SSH key')
+ %p
+ - help_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: help_page_path('user/ssh.md') }
+ = _('Add an SSH key for secure access to GitLab. %{help_link_start}Learn more%{help_link_end}.').html_safe % {help_link_start: help_link_start, help_link_end: '</a>'.html_safe }
+ = render 'form'
+
+.settings-section.js-search-settings-section
+ .settings-sticky-header
+ .settings-sticky-header-inner
+ %h4.gl-my-0
+ = _('Your SSH keys (%{count})') % { count: @keys.count }
+ .gl-mb-3
+ = render 'key_table'
diff --git a/app/views/profiles/notifications/_email_settings.html.haml b/app/views/profiles/notifications/_email_settings.html.haml
index cd7a7ced1d4..60f366f8878 100644
--- a/app/views/profiles/notifications/_email_settings.html.haml
+++ b/app/views/profiles/notifications/_email_settings.html.haml
@@ -1,7 +1,6 @@
- form = local_assigns.fetch(:form)
-.form-group
- .js-notification-email-listbox-input{ data: { label: _('Notification Email'), name: 'user[notification_email]', emails: @user.public_verified_emails.to_json, empty_value_text: _('Use primary email (%{email})') % { email: @user.email }, value: @user.notification_email, disabled: local_assigns.fetch(:email_change_disabled, nil) } }
- .help-block
- = local_assigns.fetch(:help_text, nil)
+.js-notification-email-listbox-input.gl-mb-3{ data: { label: _('Global notification email'), name: 'user[notification_email]', emails: @user.public_verified_emails.to_json, empty_value_text: _('Use primary email (%{email})') % { email: @user.email }, value: @user.notification_email, disabled: local_assigns.fetch(:email_change_disabled, nil) } }
+.help-block
+ = local_assigns.fetch(:help_text, nil)
.form-group
= form.gitlab_ui_checkbox_component :email_opted_in, _('Receive product marketing emails')
diff --git a/app/views/profiles/notifications/_group_settings.html.haml b/app/views/profiles/notifications/_group_settings.html.haml
index 898762ca78a..1878634e56c 100644
--- a/app/views/profiles/notifications/_group_settings.html.haml
+++ b/app/views/profiles/notifications/_group_settings.html.haml
@@ -1,17 +1,15 @@
- emails_disabled = group.emails_disabled?
-.gl-responsive-table-row.notification-list-item
- .table-section.section-40
- %span.notification.gl-mr-2
+.notification-list-item.gl-md-display-flex.gl-justify-content-space-between.gl-align-items-center.gl-px-3.gl-py-4
+ .gl-mb-2.gl-md-mb-0
+ %span.gl-mr-2
= notification_icon(notification_icon_level(setting, emails_disabled))
- %span.str-truncated
+ %span
= link_to group.name, group_path(group)
- .table-section.section-30.text-right
+ .gl-display-flex.gl-gap-3.gl-flex-wrap
- if setting
- .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
+ .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, show_label: "true" } }
= form_for setting, url: profile_group_notifications_path(group), method: :put, html: { class: 'update-notifications gl-display-flex' } do |f|
- .js-notification-email-listbox-input{ data: { name: 'notification_setting[notification_email]', emails: @user.public_verified_emails.to_json, empty_value_text: _('Global notification email') , value: setting.notification_email } }
+ .js-notification-email-listbox-input{ data: { name: 'notification_setting[notification_email]', emails: @user.public_verified_emails.to_json, empty_value_text: _('Global notification email') , value: setting.notification_email, placement: 'right' } }
diff --git a/app/views/profiles/notifications/_project_settings.html.haml b/app/views/profiles/notifications/_project_settings.html.haml
index e6953d1b32e..955449f0ba1 100644
--- a/app/views/profiles/notifications/_project_settings.html.haml
+++ b/app/views/profiles/notifications/_project_settings.html.haml
@@ -1,12 +1,13 @@
- emails_disabled = project.emails_disabled?
-%li.notification-list-item
- %span.notification.gl-mr-2
- = notification_icon(notification_icon_level(setting, emails_disabled))
+.notification-list-item.gl-md-display-flex.gl-justify-content-space-between.gl-align-items-center.gl-px-3.gl-py-4
+ .gl-mb-2.gl-md-mb-0
+ %span.gl-mr-2
+ = notification_icon(notification_icon_level(setting, emails_disabled))
- %span.str-truncated
- = link_to_project(project)
+ %span
+ = link_to_project(project)
- .float-right
+ .gl-display-flex.gl-gap-3.gl-flex-wrap
- if setting
.js-vue-notification-dropdown{ data: { disabled: emails_disabled.to_s, dropdown_items: notification_dropdown_items(setting).to_json, notification_level: setting.level, project_id: project.id, container_class: 'gl-mr-3', show_label: "true" } }
diff --git a/app/views/profiles/notifications/show.html.haml b/app/views/profiles/notifications/show.html.haml
index 06d37787d2e..2c7ef2b7e0e 100644
--- a/app/views/profiles/notifications/show.html.haml
+++ b/app/views/profiles/notifications/show.html.haml
@@ -2,55 +2,59 @@
- page_title _('Notifications')
- @force_desktop_expanded_sidebar = true
-%div
- - if @user.errors.any?
- = render Pajamas::AlertComponent.new(variant: :danger) do |c|
- - c.with_body do
- %ul
- - @user.errors.full_messages.each do |msg|
- %li= msg
-
- = hidden_field_tag :notification_type, 'global'
- .row.gl-mt-3.js-search-settings-section
- .col-lg-4.profile-settings-sidebar
- %h4.gl-mt-0
+- if @user.errors.any?
+ = render Pajamas::AlertComponent.new(variant: :danger) do |c|
+ - c.with_body do
+ %ul
+ - @user.errors.full_messages.each do |msg|
+ %li= msg
+
+= hidden_field_tag :notification_type, 'global'
+.settings-section.js-search-settings-section
+ .settings-sticky-header
+ .settings-sticky-header-inner
+ %h4.gl-my-0
= page_title
- %p
- = _('You can specify notification level per group or per project.')
- %p
- = _('By default, all projects and groups will use the global notifications setting.')
- .col-lg-8
- %h5.gl-mt-0
- = _('Global notification settings')
-
- = gitlab_ui_form_for @user, url: profile_notifications_path, method: :put, html: { class: 'update-notifications gl-mt-3' } do |f|
- = render_if_exists 'profiles/notifications/email_settings', form: f
-
- = label_tag :global_notification_level, _('Global notification level'), class: "label-bold"
- %br
- .clearfix
- .form-group.float-left.global-notification-setting
- - if @global_notification_setting
- .js-vue-notification-dropdown{ data: { dropdown_items: notification_dropdown_items(@global_notification_setting).to_json, notification_level: @global_notification_setting.level, help_page_path: help_page_path('user/profile/notifications'), show_label: 'true' } }
-
- .clearfix
-
- = gitlab_ui_form_for @user, url: profile_notifications_path, method: :put do |f|
- .form-group
- = f.gitlab_ui_checkbox_component :notified_of_own_activity, _('Receive notifications about your own activity')
-
- %hr
- %h5
- = _('Groups (%{count})') % { count: @user_groups.total_count }
- %div
- - @group_notifications.each do |setting|
- = render 'group_settings', setting: setting, group: setting.source
- = paginate @user_groups, theme: 'gitlab'
- %h5
- = _('Projects (%{count})') % { count: @project_notifications.size }
- %p.account-well
- = _('To specify the notification level per project of a group you belong to, you need to visit project page and change notification level there.')
- .gl-mb-3
- %ul.bordered-list
+ %p.gl-text-secondary
+ = _('You can specify notification level per group or per project.')
+
+ .gl-mt-0
+ = gitlab_ui_form_for @user, url: profile_notifications_path, method: :put, html: { class: 'update-notifications gl-mt-3' } do |f|
+ = render_if_exists 'profiles/notifications/email_settings', form: f
+
+ = label_tag :global_notification_level, _('Global notification level'), class: "label-bold gl-mb-0"
+ .gl-text-secondary.gl-mb-3
+ = _('By default, all projects and groups use the global notifications setting.')
+
+ .form-group.global-notification-setting.gl-mb-3
+ - if @global_notification_setting
+ .js-vue-notification-dropdown{ data: { dropdown_items: notification_dropdown_items(@global_notification_setting).to_json, notification_level: @global_notification_setting.level, help_page_path: help_page_path('user/profile/notifications'), show_label: 'true' } }
+
+ = gitlab_ui_form_for @user, url: profile_notifications_path, method: :put do |f|
+ .form-group
+ = f.gitlab_ui_checkbox_component :notified_of_own_activity, _('Receive notifications about your own activity')
+
+ = render Pajamas::CardComponent.new(card_options: { class: 'gl-new-card' }, header_options: { class: 'gl-new-card-header'}, body_options: { class: 'gl-new-card-body' }) do |c|
+ - c.with_header do
+ %h3.gl-new-card-title
+ = _('Groups (%{count})') % { count: @user_groups.total_count }
+ - c.with_body do
+ - if @user_groups.total_count > 0
+ - @group_notifications.each do |setting|
+ = render 'group_settings', setting: setting, group: setting.source
+ = paginate @user_groups, theme: 'gitlab'
+ - else
+ .gl-new-card-empty.gl-px-3.gl-py-4= _("You do not belong to any groups yet.")
+
+ = render Pajamas::CardComponent.new(card_options: { class: 'gl-new-card' }, header_options: { class: 'gl-new-card-header gl-display-block'}, body_options: { class: 'gl-new-card-body' }) do |c|
+ - c.with_header do
+ %h3.gl-new-card-title
+ = _('Projects (%{count})') % { count: @project_notifications.size }
+ .gl-new-card-description
+ = _('To specify the notification level per project of a group you belong to, visit the project page and change the notification level there.')
+ - c.with_body do
+ - if @project_notifications.size > 0
- @project_notifications.each do |setting|
= render 'project_settings', setting: setting, project: setting.source
+ - else
+ .gl-new-card-empty.gl-px-3.gl-py-4= _("You do not belong to any projects yet.")
diff --git a/app/views/profiles/passwords/edit.html.haml b/app/views/profiles/passwords/edit.html.haml
index 4fdf80c1eb1..4848a9dc595 100644
--- a/app/views/profiles/passwords/edit.html.haml
+++ b/app/views/profiles/passwords/edit.html.haml
@@ -2,36 +2,34 @@
- page_title _('Password')
- @force_desktop_expanded_sidebar = true
-.row.gl-mt-3.js-search-settings-section
- .col-lg-4.profile-settings-sidebar
- %h4.gl-mt-0
- = page_title
- %p
- = _('After a successful password update, you will be redirected to the login page where you can log in with your new password.')
- .col-lg-8
- %h5.gl-mt-0
- - if @user.password_automatically_set
- = _('Change your password')
- - else
- = _('Change your password or recover your current one')
- = gitlab_ui_form_for @user, url: profile_password_path, method: :put, html: {class: "update-password"} do |f|
- = form_errors(@user)
+.settings-section.js-search-settings-section
+ .settings-sticky-header
+ .settings-sticky-header-inner
+ %h4.gl-my-0
+ = page_title
+ %p.gl-text-secondary
+ - if @user.password_automatically_set
+ = _('Change your password.')
+ - else
+ = _('Change your password or recover your current one.')
+ = gitlab_ui_form_for @user, url: profile_password_path, method: :put, html: {class: "update-password"} do |f|
+ = form_errors(@user)
- - unless @user.password_automatically_set?
- .form-group
- = f.label :password, _('Current password'), class: 'label-bold'
- = f.password_field :password, required: true, autocomplete: 'current-password', class: 'form-control gl-form-input', data: { qa_selector: 'current_password_field' }
- %p.form-text.text-muted
- = _('You must provide your current password in order to change it.')
- .form-group
- = f.label :new_password, _('New password'), class: 'label-bold'
- = f.password_field :new_password, required: true, autocomplete: 'new-password', class: 'form-control gl-form-input js-password-complexity-validation', data: { qa_selector: 'new_password_field' }
- = render_if_exists 'shared/password_requirements_list'
+ - unless @user.password_automatically_set?
.form-group
- = f.label :password_confirmation, _('Password confirmation'), class: 'label-bold'
- = f.password_field :password_confirmation, required: true, autocomplete: 'new-password', class: 'form-control gl-form-input', data: { qa_selector: 'confirm_password_field' }
- .gl-mt-3.gl-mb-3
- = f.submit _('Save password'), class: "gl-mr-3", data: { qa_selector: 'save_password_button' }, pajamas_button: true
- - unless @user.password_automatically_set?
- = render Pajamas::ButtonComponent.new(href: reset_profile_password_path, variant: :link, method: :put) do
- = _('I forgot my password')
+ = f.label :password, _('Current password'), class: 'label-bold'
+ = f.password_field :password, required: true, autocomplete: 'current-password', class: 'form-control gl-form-input gl-max-w-80', data: { qa_selector: 'current_password_field' }
+ %p.form-text.text-muted
+ = _('You must provide your current password in order to change it.')
+ .form-group
+ = f.label :new_password, _('New password'), class: 'label-bold'
+ = f.password_field :new_password, required: true, autocomplete: 'new-password', class: 'form-control gl-form-input js-password-complexity-validation gl-max-w-80', data: { qa_selector: 'new_password_field' }
+ = render_if_exists 'shared/password_requirements_list'
+ .form-group
+ = f.label :password_confirmation, _('Password confirmation'), class: 'label-bold'
+ = f.password_field :password_confirmation, required: true, autocomplete: 'new-password', class: 'form-control gl-form-input gl-max-w-80', data: { qa_selector: 'confirm_password_field' }
+ .gl-mt-3.gl-mb-3
+ = f.submit _('Save password'), class: "gl-mr-3", data: { qa_selector: 'save_password_button' }, pajamas_button: true
+ - unless @user.password_automatically_set?
+ = render Pajamas::ButtonComponent.new(href: reset_profile_password_path, variant: :link, method: :put) do
+ = _('I forgot my password')
diff --git a/app/views/profiles/personal_access_tokens/index.html.haml b/app/views/profiles/personal_access_tokens/index.html.haml
index 57c0badd033..5020f6cbb22 100644
--- a/app/views/profiles/personal_access_tokens/index.html.haml
+++ b/app/views/profiles/personal_access_tokens/index.html.haml
@@ -4,27 +4,26 @@
- type_plural = _('personal access tokens')
- @force_desktop_expanded_sidebar = true
-.row.gl-mt-3.js-search-settings-section
- .col-lg-4.profile-settings-sidebar
- %h4.gl-mt-0
- = page_title
- %p
- = s_('AccessTokens|You can generate a personal access token for each application you use that needs access to the GitLab API.')
- %p
- = s_('AccessTokens|You can also use personal access tokens to authenticate against Git over HTTP.')
- = s_('AccessTokens|They are the only accepted password when you have Two-Factor Authentication (2FA) enabled.')
+.settings-section.settings-section-no-bottom.js-search-settings-section
+ .settings-sticky-header
+ .settings-sticky-header-inner
+ %h4.gl-my-0
+ = page_title
+ %p.gl-text-secondary
+ = s_('AccessTokens|You can generate a personal access token for each application you use that needs access to the GitLab API.')
+ = s_('AccessTokens|You can also use personal access tokens to authenticate against Git over HTTP.')
+ = s_('AccessTokens|They are the only accepted password when you have Two-Factor Authentication (2FA) enabled.')
- .col-lg-8
- #js-new-access-token-app{ data: { access_token_type: type } }
+ #js-new-access-token-app{ data: { access_token_type: type } }
- = render 'shared/access_tokens/form',
- ajax: true,
- type: type,
- path: profile_personal_access_tokens_path,
- token: @personal_access_token,
- scopes: @scopes,
- help_path: help_page_path('user/profile/personal_access_tokens.md', anchor: 'personal-access-token-scopes')
+ = render 'shared/access_tokens/form',
+ ajax: true,
+ type: type,
+ path: profile_personal_access_tokens_path,
+ token: @personal_access_token,
+ scopes: @scopes,
+ help_path: help_page_path('user/profile/personal_access_tokens.md', anchor: 'personal-access-token-scopes')
- #js-access-token-table-app{ data: { access_token_type: type, access_token_type_plural: type_plural, initial_active_access_tokens: @active_access_tokens.to_json } }
+ #js-access-token-table-app{ data: { access_token_type: type, access_token_type_plural: type_plural, initial_active_access_tokens: @active_access_tokens.to_json } }
#js-tokens-app{ data: { tokens_data: tokens_app_data } }
diff --git a/app/views/profiles/preferences/show.html.haml b/app/views/profiles/preferences/show.html.haml
index a085840ee84..e5e7c1dc3f4 100644
--- a/app/views/profiles/preferences/show.html.haml
+++ b/app/views/profiles/preferences/show.html.haml
@@ -11,165 +11,152 @@
= stylesheet_link_tag "themes/#{theme.css_filename}" if theme.css_filename
= gitlab_ui_form_for @user, url: profile_preferences_path, remote: true, method: :put, html: { id: "profile-preferences-form" } do |f|
- .row.gl-mt-3.js-preferences-form.js-search-settings-section
- .col-lg-4.application-theme#navigation-theme
- %h4.gl-mt-0
- = s_('Preferences|Color theme')
+ .settings-section.js-preferences-form.js-search-settings-section.application-theme#navigation-theme
+ .settings-sticky-header
+ .settings-sticky-header-inner
+ %h4.gl-my-0
+ = s_('Preferences|Color theme')
+ %p.gl-text-secondary
+ = s_('Preferences|Customize the color of GitLab.')
+ - if show_super_sidebar?
%p
- = s_('Preferences|Customize the color of GitLab.')
- - if show_super_sidebar?
- %p
- = s_('Preferences|Note: You have the new navigation enabled, so only Dark Mode theme significantly changes GitLab\'s appearance.')
- .col-lg-8.application-theme
- .row
- - Gitlab::Themes.each do |theme|
- %label.col-6.col-sm-4.col-md-3.gl-mb-5.gl-text-center
- .preview{ class: theme.css_class }
- = f.gitlab_ui_radio_component :theme_id, theme.id,
- theme.name,
- radio_options: { checked: user_theme_id == theme.id }
+ = s_('Preferences|Note: You have the new navigation enabled, so only Dark Mode theme significantly changes GitLab\'s appearance.')
+ .application-theme.row
+ - Gitlab::Themes.each do |theme|
+ %label.col-6.col-sm-4.col-md-3.col-xl-2.gl-mb-5
+ .preview{ class: theme.css_class }
+ = f.gitlab_ui_radio_component :theme_id, theme.id,
+ theme.name,
+ radio_options: { checked: user_theme_id == theme.id }
- .col-sm-12
- %hr
-
- .row.js-preferences-form.js-search-settings-section
- .col-lg-4.profile-settings-sidebar#syntax-highlighting-theme
- %h4.gl-mt-0
- = s_('Preferences|Syntax highlighting theme')
- %p
- = s_('Preferences|Customize the appearance of the syntax.')
- = succeed '.' do
- = link_to _('Learn more'), help_page_path('user/profile/preferences', anchor: 'syntax-highlighting-theme'), target: '_blank', rel: 'noopener noreferrer'
- .col-lg-8.syntax-theme
+ .settings-section.js-preferences-form.js-search-settings-section#syntax-highlighting-theme
+ .settings-sticky-header
+ .settings-sticky-header-inner
+ %h4.gl-my-0
+ = s_('Preferences|Syntax highlighting theme')
+ %p.gl-text-secondary
+ = s_('Preferences|Customize the appearance of the syntax.')
+ = succeed '.' do
+ = link_to _('Learn more'), help_page_path('user/profile/preferences', anchor: 'syntax-highlighting-theme'), target: '_blank', rel: 'noopener noreferrer'
+ .syntax-theme.row
- Gitlab::ColorSchemes.each do |scheme|
- = label_tag do
+ %label.col-6.col-sm-4.col-md-3.col-lg-auto.gl-mb-5
.preview= image_tag "#{scheme.css_class}-scheme-preview.png"
= f.gitlab_ui_radio_component :color_scheme_id, scheme.id,
- scheme.name,
- radio_options: { checked: user_color_schema_id == scheme.id }
+ scheme.name,
+ radio_options: { checked: user_color_schema_id == scheme.id }
- .col-sm-12
- %hr
+ .settings-section.js-preferences-form.js-search-settings-section#diffs-colors
+ .settings-sticky-header
+ .settings-sticky-header-inner
+ %h4.gl-my-0
+ = s_('Preferences|Diff colors')
+ %p.gl-text-secondary
+ = s_('Preferences|Customize the colors of removed and added lines in diffs.')
+ .form-group
+ #js-profile-preferences-diffs-colors-app{ data: user_diffs_colors }
- .row.js-preferences-form.js-search-settings-section
- .col-lg-4.profile-settings-sidebar#diffs-colors
- %h4.gl-mt-0
- = s_('Preferences|Diff colors')
- %p
- = s_('Preferences|Customize the colors of removed and added lines in diffs.')
- .col-lg-8
- .form-group
- #js-profile-preferences-diffs-colors-app{ data: user_diffs_colors }
+ .settings-section.js-preferences-form.js-search-settings-section#behavior
+ .settings-sticky-header
+ .settings-sticky-header-inner
+ %h4.gl-my-0
+ = s_('Preferences|Behavior')
+ %p.gl-text-secondary
+ = s_('Preferences|Customize the behavior of the system layout and default views.')
+ = succeed '.' do
+ = link_to _('Learn more'), help_page_path('user/profile/preferences', anchor: 'behavior'), target: '_blank', rel: 'noopener noreferrer'
+ .form-group
+ = f.label :layout, class: 'label-bold' do
+ = s_('Preferences|Layout width')
+ = f.select :layout, layout_choices, {}, class: 'gl-form-select custom-select'
+ .form-text.text-muted
+ = s_('Preferences|Choose between fixed (max. 1280px) and fluid (%{percentage}) application layout.').html_safe % { percentage: '100%' }
+ .js-listbox-input{ data: { label: s_('Preferences|Homepage'), description: s_('Preferences|Choose what content you want to see by default on your homepage.'), name: 'user[dashboard]', items: dashboard_choices.to_json, value: current_user.dashboard, block: true.to_s, fluid_width: true.to_s } }
- .col-sm-12
- %hr
+ = render_if_exists 'profiles/preferences/group_overview_selector', f: f # EE-specific
- .row.js-preferences-form.js-search-settings-section
- .col-lg-4.profile-settings-sidebar#behavior
- %h4.gl-mt-0
- = s_('Preferences|Behavior')
- %p
- = s_('Preferences|Customize the behavior of the system layout and default views.')
- = succeed '.' do
- = link_to _('Learn more'), help_page_path('user/profile/preferences', anchor: 'behavior'), target: '_blank', rel: 'noopener noreferrer'
- .col-lg-8
- .form-group
- = f.label :layout, class: 'label-bold' do
- = s_('Preferences|Layout width')
- = f.select :layout, layout_choices, {}, class: 'gl-form-select custom-select'
- .form-text.text-muted
- = s_('Preferences|Choose between fixed (max. 1280px) and fluid (%{percentage}) application layout.').html_safe % { percentage: '100%' }
- .js-listbox-input{ data: { label: s_('Preferences|Homepage'), description: s_('Preferences|Choose what content you want to see by default on your homepage.'), name: 'user[dashboard]', items: dashboard_choices.to_json, value: current_user.dashboard } }
+ .form-group
+ = f.label :project_view, class: 'label-bold' do
+ = s_('Preferences|Project overview content')
+ = f.select :project_view, project_view_choices, {}, class: 'gl-form-select custom-select'
+ .form-text.text-muted
+ = s_('Preferences|Choose what content you want to see on a projectā€™s overview page.')
+ .form-group
+ = f.gitlab_ui_checkbox_component :project_shortcut_buttons, s_('Preferences|Show shortcut buttons above files on project overview')
+ .form-group
+ = f.gitlab_ui_checkbox_component :render_whitespace_in_code, s_('Preferences|Render whitespace characters in the Web IDE')
+ .form-group
+ = f.gitlab_ui_checkbox_component :show_whitespace_in_diffs, s_('Preferences|Show whitespace changes in diffs')
+ .form-group
+ = f.gitlab_ui_checkbox_component :view_diffs_file_by_file,
+ s_("Preferences|Show one file at a time on merge request's Changes tab"),
+ help_text: s_("Preferences|Instead of all the files changed, show only one file at a time. To switch between files, use the file browser.")
+ .form-group
+ - supported_characters = %w(" ' ` &#40; [ { < * _).map { |char| "<code>#{char}</code>" }.join(', ')
+ = f.gitlab_ui_checkbox_component :markdown_surround_selection,
+ s_('Preferences|Surround text selection when typing quotes or brackets'),
+ help_text: sprintf(s_("Preferences|When you type in a description or comment box, selected text is surrounded by the corresponding character after typing one of the following characters: %{supported_characters}."), { supported_characters: supported_characters }).html_safe
+ .form-group
+ = f.gitlab_ui_checkbox_component :markdown_automatic_lists,
+ s_('Preferences|Automatically add new list items'),
+ help_text: html_escape(s_('Preferences|When you type in a description or comment box, pressing %{kbdOpen}Enter%{kbdClose} in a list adds a new item below.')) % { kbdOpen: '<kbd>'.html_safe, kbdClose: '</kbd>'.html_safe }
- = render_if_exists 'profiles/preferences/group_overview_selector', f: f # EE-specific
+ .form-group
+ = f.label :tab_width, s_('Preferences|Tab width'), class: 'label-bold'
+ = f.number_field :tab_width,
+ class: 'form-control gl-form-input',
+ min: Gitlab::TabWidth::MIN,
+ max: Gitlab::TabWidth::MAX,
+ required: true
+ .form-text.text-muted
+ = s_('Preferences|Must be a number between %{min} and %{max}') % { min: Gitlab::TabWidth::MIN, max: Gitlab::TabWidth::MAX }
- .form-group
- = f.label :project_view, class: 'label-bold' do
- = s_('Preferences|Project overview content')
- = f.select :project_view, project_view_choices, {}, class: 'gl-form-select custom-select'
- .form-text.text-muted
- = s_('Preferences|Choose what content you want to see on a projectā€™s overview page.')
- .form-group
- = f.gitlab_ui_checkbox_component :project_shortcut_buttons, s_('Preferences|Show shortcut buttons above files on project overview')
- .form-group
- = f.gitlab_ui_checkbox_component :render_whitespace_in_code, s_('Preferences|Render whitespace characters in the Web IDE')
- .form-group
- = f.gitlab_ui_checkbox_component :show_whitespace_in_diffs, s_('Preferences|Show whitespace changes in diffs')
- .form-group
- = f.gitlab_ui_checkbox_component :view_diffs_file_by_file,
- s_("Preferences|Show one file at a time on merge request's Changes tab"),
- help_text: s_("Preferences|Instead of all the files changed, show only one file at a time. To switch between files, use the file browser.")
- .form-group
- - supported_characters = %w(" ' ` &#40; [ { < * _).map { |char| "<code>#{char}</code>" }.join(', ')
- = f.gitlab_ui_checkbox_component :markdown_surround_selection,
- s_('Preferences|Surround text selection when typing quotes or brackets'),
- help_text: sprintf(s_("Preferences|When you type in a description or comment box, selected text is surrounded by the corresponding character after typing one of the following characters: %{supported_characters}."), { supported_characters: supported_characters }).html_safe
- .form-group
- = f.gitlab_ui_checkbox_component :markdown_automatic_lists,
- s_('Preferences|Automatically add new list items'),
- help_text: html_escape(s_('Preferences|When you type in a description or comment box, pressing %{kbdOpen}Enter%{kbdClose} in a list adds a new item below.')) % { kbdOpen: '<kbd>'.html_safe, kbdClose: '</kbd>'.html_safe }
+ .settings-section.js-preferences-form.js-search-settings-section#localization
+ .settings-sticky-header
+ .settings-sticky-header-inner
+ %h4.gl-my-0
+ = _('Localization')
+ %p.gl-text-secondary
+ = _('Customize language and region related settings.')
+ = succeed '.' do
+ = link_to _('Learn more'), help_page_path('user/profile/preferences', anchor: 'localization'), target: '_blank', rel: 'noopener noreferrer'
+ .js-listbox-input{ data: { label: _('Language'), description: s_('Preferences|This feature is experimental and translations are not yet complete.'), name: 'user[preferred_language]', items: language_choices.to_json, value: current_user.preferred_language, block: true.to_s, fluid_width: true.to_s } }
+ %p.gl-mt-n5
+ = link_to help_page_url('development/i18n/translation'), class: 'text-nowrap', target: '_blank', rel: 'noopener noreferrer' do
+ = _("Help translate GitLab into your language")
+ %span{ aria: { label: _('Open new window') } }
+ = sprite_icon('external-link')
+ .form-group
+ = f.label :first_day_of_week, class: 'label-bold' do
+ = _('First day of the week')
+ = f.select :first_day_of_week, first_day_of_week_choices_with_default, {}, class: 'gl-form-select custom-select'
- .form-group
- = f.label :tab_width, s_('Preferences|Tab width'), class: 'label-bold'
- = f.number_field :tab_width,
- class: 'form-control gl-form-input',
- min: Gitlab::TabWidth::MIN,
- max: Gitlab::TabWidth::MAX,
- required: true
- .form-text.text-muted
- = s_('Preferences|Must be a number between %{min} and %{max}') % { min: Gitlab::TabWidth::MIN, max: Gitlab::TabWidth::MAX }
-
- .col-sm-12
- %hr
- .row.js-preferences-form.js-search-settings-section
- .col-lg-4.profile-settings-sidebar#localization
- %h4.gl-mt-0
- = _('Localization')
- %p
- = _('Customize language and region related settings.')
- = succeed '.' do
- = link_to _('Learn more'), help_page_path('user/profile/preferences', anchor: 'localization'), target: '_blank', rel: 'noopener noreferrer'
- .col-lg-8
- .js-listbox-input{ data: { label: _('Language'), description: s_('Preferences|This feature is experimental and translations are not yet complete.'), name: 'user[preferred_language]', items: language_choices.to_json, value: current_user.preferred_language } }
- %p.gl-mt-n5
- = link_to help_page_url('development/i18n/translation'), class: 'text-nowrap', target: '_blank', rel: 'noopener noreferrer' do
- = _("Help translate GitLab into your language")
- %span{ aria: { label: _('Open new window') } }
- = sprite_icon('external-link')
- .form-group
- = f.label :first_day_of_week, class: 'label-bold' do
- = _('First day of the week')
- = f.select :first_day_of_week, first_day_of_week_choices_with_default, {}, class: 'gl-form-select custom-select'
- .col-sm-12
- %hr
- .row.js-preferences-form.js-search-settings-section
- .col-lg-4.profile-settings-sidebar#time-preferences
- %h4.gl-mt-0
- = s_('Preferences|Time preferences')
- %p
- = s_('Preferences|Configure how dates and times display for you.')
+ .settings-section.js-preferences-form.js-search-settings-section#time-preferences
+ .settings-sticky-header
+ .settings-sticky-header-inner
+ %h4.gl-my-0
+ = s_('Preferences|Time preferences')
+ %p.gl-text-secondary
+ = s_('Preferences|Configure how dates and times display for you.')
+ = succeed '.' do
+ = link_to _('Learn more'), help_page_path('user/profile/preferences', anchor: 'time-preferences'), target: '_blank', rel: 'noopener noreferrer'
+ .form-group
+ = f.gitlab_ui_checkbox_component :time_display_relative,
+ s_('Preferences|Use relative times'),
+ help_text: s_('Preferences|For example: 30 minutes ago.')
+ - if Feature.enabled?(:disable_follow_users, @user)
+ .settings-section.js-preferences-form.js-search-settings-section#enabled_following
+ .settings-sticky-header
+ .settings-sticky-header-inner
+ %h4.gl-my-0
+ = s_('Preferences|Enable follow users feature')
+ %p.gl-text-secondary
+ = s_('Preferences|Turns on or off the ability to follow or be followed by other users.')
= succeed '.' do
- = link_to _('Learn more'), help_page_path('user/profile/preferences', anchor: 'time-preferences'), target: '_blank', rel: 'noopener noreferrer'
- .col-lg-8
+ = link_to _('Learn more'), help_page_path('user/profile/index', anchor: 'follow-users'), target: '_blank', rel: 'noopener noreferrer'
.form-group
- = f.gitlab_ui_checkbox_component :time_display_relative,
- s_('Preferences|Use relative times'),
- help_text: s_('Preferences|For example: 30 minutes ago.')
- - if Feature.enabled?(:disable_follow_users, @user)
- .row.js-preferences-form.js-search-settings-section
- .col-sm-12
- %hr
- .col-lg-4.profile-settings-sidebar#enabled_following
- %h4.gl-mt-0
- = s_('Preferences|Enable follow users feature')
- %p
- = s_('Preferences|Turns on or off the ability to follow or be followed by other users.')
- = succeed '.' do
- = link_to _('Learn more'), help_page_path('user/profile/index', anchor: 'follow-users'), target: '_blank', rel: 'noopener noreferrer'
- .col-lg-8
- .form-group
- = f.gitlab_ui_checkbox_component :enabled_following,
- s_('Preferences|Enable follow users')
+ = f.gitlab_ui_checkbox_component :enabled_following,
+ s_('Preferences|Enable follow users')
= render_if_exists 'profiles/preferences/code_suggestions_settings', form: f
= render_if_exists 'profiles/preferences/zoekt_settings', form: f
diff --git a/app/views/profiles/show.html.haml b/app/views/profiles/show.html.haml
index 1a932ed7b35..ebdea5786f5 100644
--- a/app/views/profiles/show.html.haml
+++ b/app/views/profiles/show.html.haml
@@ -7,50 +7,50 @@
- if Feature.enabled?(:edit_user_profile_vue, current_user)
.js-user-profile
- else
- = gitlab_ui_form_for @user, url: profile_path, method: :put, html: { multipart: true, class: 'edit-user js-edit-user gl-mt-3 js-quick-submit gl-show-field-errors js-password-prompt-form', remote: true }, authenticity_token: true do |f|
- .row.js-search-settings-section
- .col-lg-4.profile-settings-sidebar
- %h4.gl-mt-0
- = s_("Profiles|Public avatar")
- %p
- - if @user.avatar?
- - if gravatar_enabled?
- = s_("Profiles|You can change your avatar here or remove the current avatar to revert to %{gravatar_link}").html_safe % { gravatar_link: gravatar_link }
- - else
- = s_("Profiles|You can change your avatar here")
- - else
- - if gravatar_enabled?
- = s_("Profiles|You can upload your avatar here or change it at %{gravatar_link}").html_safe % { gravatar_link: gravatar_link }
- - else
- = s_("Profiles|You can upload your avatar here")
- - if current_appearance&.profile_image_guidelines?
- .md
- = brand_profile_image_guidelines
- .col-lg-8
- .avatar-image
- = link_to avatar_icon_for_user(@user, 400), target: '_blank', rel: 'noopener noreferrer' do
- = render Pajamas::AvatarComponent.new(@user, size: 96, alt: "", class: 'gl-float-left gl-mr-5')
- %h5.gl-mt-0= s_("Profiles|Upload new avatar")
- .gl-display-flex.gl-align-items-center.gl-my-3
- = render Pajamas::ButtonComponent.new(button_options: { class: 'js-choose-user-avatar-button' }) do
- = s_("Profiles|Choose file...")
- %span.gl-ml-3.js-avatar-filename= s_("Profiles|No file chosen.")
- = f.file_field :avatar, class: 'js-user-avatar-input hidden', accept: 'image/*'
- .gl-text-gray-500= s_("Profiles|The maximum file size allowed is 200KB.")
+ = gitlab_ui_form_for @user, url: profile_path, method: :put, html: { multipart: true, class: 'edit-user js-edit-user js-quick-submit gl-show-field-errors js-password-prompt-form', remote: true }, authenticity_token: true do |f|
+ .settings-section.js-search-settings-section
+ .settings-sticky-header
+ .settings-sticky-header-inner
+ %h4.gl-my-0
+ = s_("Profiles|Public avatar")
+ %p.gl-text-secondary
- if @user.avatar?
- = render Pajamas::ButtonComponent.new(variant: :danger,
- category: :secondary,
- href: profile_avatar_path,
- button_options: { class: 'gl-mt-3', data: { confirm: s_("Profiles|Avatar will be removed. Are you sure?") } },
- method: :delete) do
- = s_("Profiles|Remove avatar")
- .col-lg-12
- %hr
- .row.js-search-settings-section
- .col-lg-4.profile-settings-sidebar
- %h4.gl-mt-0= s_("Profiles|Current status")
- %p= s_("Profiles|This emoji and message will appear on your profile and throughout the interface.")
- .col-lg-8
+ - if gravatar_enabled?
+ = s_("Profiles|You can change your avatar here or remove the current avatar to revert to %{gravatar_link}").html_safe % { gravatar_link: gravatar_link }
+ - else
+ = s_("Profiles|You can change your avatar here")
+ - else
+ - if gravatar_enabled?
+ = s_("Profiles|You can upload your avatar here or change it at %{gravatar_link}").html_safe % { gravatar_link: gravatar_link }
+ - else
+ = s_("Profiles|You can upload your avatar here")
+ - if current_appearance&.profile_image_guidelines?
+ .md
+ = brand_profile_image_guidelines
+ .avatar-image
+ = link_to avatar_icon_for_user(@user, 400), target: '_blank', rel: 'noopener noreferrer' do
+ = render Pajamas::AvatarComponent.new(@user, size: 96, alt: "", class: 'gl-float-left gl-mr-5')
+ %h5.gl-mt-0= s_("Profiles|Upload new avatar")
+ .gl-display-flex.gl-align-items-center.gl-my-3
+ = render Pajamas::ButtonComponent.new(button_options: { class: 'js-choose-user-avatar-button' }) do
+ = s_("Profiles|Choose file...")
+ %span.gl-ml-3.js-avatar-filename= s_("Profiles|No file chosen.")
+ = f.file_field :avatar, class: 'js-user-avatar-input hidden', accept: 'image/*'
+ .gl-text-gray-500= s_("Profiles|The maximum file size allowed is 200KB.")
+ - if @user.avatar?
+ = render Pajamas::ButtonComponent.new(variant: :danger,
+ category: :secondary,
+ href: profile_avatar_path,
+ button_options: { class: 'gl-mt-3', data: { confirm: s_("Profiles|Avatar will be removed. Are you sure?") } },
+ method: :delete) do
+ = s_("Profiles|Remove avatar")
+
+ .settings-section.js-search-settings-section.gl-border-t.gl-pt-6
+ .settings-sticky-header
+ .settings-sticky-header-inner
+ %h4.gl-my-0= s_("Profiles|Current status")
+ %p.gl-text-secondary= s_("Profiles|This emoji and message will appear on your profile and throughout the interface.")
+ .gl-max-w-80
#js-user-profile-set-status-form
= f.fields_for :status, @user.status do |status_form|
= status_form.hidden_field :emoji, data: { js_name: 'emoji' }
@@ -59,121 +59,117 @@
= status_form.hidden_field :clear_status_after,
value: user_clear_status_at(@user),
data: { js_name: 'clearStatusAfter' }
- .col-lg-12
- %hr
- .row.user-time-preferences.js-search-settings-section
- .col-lg-4.profile-settings-sidebar
- %h4.gl-mt-0= s_("Profiles|Time settings")
- %p= s_("Profiles|Set your local time zone.")
- .col-lg-8
- = f.label :user_timezone, _("Time zone")
- .js-timezone-dropdown{ data: { timezone_data: timezone_data.to_json, initial_value: @user.timezone, name: 'user[timezone]' } }
- .col-lg-12
- %hr
- .row.js-search-settings-section
- .col-lg-4.profile-settings-sidebar
- %h4.gl-mt-0
- = s_("Profiles|Main settings")
- %p
- = s_("Profiles|This information will appear on your profile.")
- - if current_user.ldap_user?
- = s_("Profiles|Some options are unavailable for LDAP accounts")
- .col-lg-8
- .row
- .form-group.gl-form-group.col-md-9.rspec-full-name
- = render 'profiles/name', form: f, user: @user
- .form-group.gl-form-group.col-md-3
- = f.label :id, s_('Profiles|User ID')
- = f.text_field :id, class: 'gl-form-input form-control', readonly: true
- .form-group.gl-form-group
- = f.label :pronouns, s_('Profiles|Pronouns')
- = f.text_field :pronouns, class: 'gl-form-input form-control gl-md-form-input-lg'
- %small.form-text.text-gl-muted
- = s_("Profiles|Enter your pronouns to let people know how to refer to you.")
- .form-group.gl-form-group
- = f.label :pronunciation, s_('Profiles|Pronunciation')
- = f.text_field :pronunciation, class: 'gl-form-input form-control gl-md-form-input-lg'
- %small.form-text.text-gl-muted
- = s_("Profiles|Enter how your name is pronounced to help people address you correctly.")
- = render_if_exists 'profiles/extra_settings', form: f
- = render_if_exists 'profiles/email_settings', form: f
- .form-group.gl-form-group
- = f.label :skype
- = f.text_field :skype, class: 'gl-form-input form-control gl-md-form-input-lg', placeholder: s_("Profiles|username")
- .form-group.gl-form-group
- = f.label :linkedin
- = f.text_field :linkedin, class: 'gl-form-input form-control gl-md-form-input-lg'
- %small.form-text.text-gl-muted
- = s_("Profiles|Your LinkedIn profile name from linkedin.com/in/profilename")
- .form-group.gl-form-group
- = f.label :twitter
- = f.text_field :twitter, class: 'gl-form-input form-control gl-md-form-input-lg', placeholder: s_("Profiles|@username")
- .form-group.gl-form-group
- - external_accounts_help_url = help_page_path('user/profile/index', anchor: 'add-external-accounts-to-your-user-profile-page')
- - external_accounts_link = link_to '', external_accounts_help_url, target: "_blank", rel: "noopener noreferrer"
- - external_accounts_docs_link = safe_format(s_('Profiles|Your Discord user ID. %{external_accounts_link_start}Learn more.%{external_accounts_link_end}'), tag_pair(external_accounts_link, :external_accounts_link_start, :external_accounts_link_end))
- - min_discord_length = 17
- - max_discord_length = 20
- = f.label :discord
- = f.text_field :discord,
- class: 'gl-form-input form-control gl-md-form-input-lg js-validate-length',
- placeholder: s_("Profiles|User ID"),
- data: { min_length: min_discord_length,
- min_length_message: s_('Profiles|Discord ID is too short (minimum is %{min_length} characters).') % { min_length: min_discord_length },
- max_length: max_discord_length,
- max_length_message: s_('Profiles|Discord ID is too long (maximum is %{max_length} characters).') % { max_length: max_discord_length },
- allow_empty: true}
- %small.form-text.text-gl-muted
- = external_accounts_docs_link
- .form-group.gl-form-group
- = f.label :website_url, s_('Profiles|Website url')
- = f.text_field :website_url, class: 'gl-form-input form-control gl-md-form-input-lg', placeholder: s_("Profiles|https://website.com")
- .form-group.gl-form-group
- = f.label :location, s_('Profiles|Location')
- - if @user.read_only_attribute?(:location)
- = f.text_field :location, class: 'gl-form-input form-control gl-md-form-input-lg', readonly: true
- %small.form-text.text-gl-muted
- = s_("Profiles|Your location was automatically set based on your %{provider_label} account") % { provider_label: attribute_provider_label(:location) }
- - else
- = f.text_field :location, class: 'gl-form-input form-control gl-md-form-input-lg', placeholder: s_("Profiles|City, country")
- .form-group.gl-form-group
- = f.label :job_title, s_('Profiles|Job title')
- = f.text_field :job_title, class: 'gl-form-input form-control gl-md-form-input-lg'
- .form-group.gl-form-group
- = f.label :organization, s_('Profiles|Organization')
- = f.text_field :organization, class: 'gl-form-input form-control gl-md-form-input-lg'
- %small.form-text.text-gl-muted
- = s_("Profiles|Who you represent or work for.")
- .form-group.gl-form-group
- = f.label :bio, s_('Profiles|Bio')
- = f.text_area :bio, class: 'gl-form-input gl-form-textarea form-control', rows: 4, maxlength: 250
+ .settings-section.user-time-preferences.js-search-settings-section.gl-border-t.gl-pt-6
+ .settings-sticky-header
+ .settings-sticky-header-inner
+ %h4.gl-my-0= s_("Profiles|Time settings")
+ %p.gl-text-secondary= s_("Profiles|Set your local time zone.")
+ = f.label :user_timezone, _("Time zone")
+ .js-timezone-dropdown{ data: { timezone_data: timezone_data.to_json, initial_value: @user.timezone, name: 'user[timezone]' } }
+
+ .settings-section.js-search-settings-section.gl-border-t.gl-pt-6
+ .settings-sticky-header
+ .settings-sticky-header-inner
+ %h4.gl-my-0
+ = s_("Profiles|Main settings")
+ %p.gl-text-secondary
+ = s_("Profiles|This information will appear on your profile.")
+ - if current_user.ldap_user?
+ = s_("Profiles|Some options are unavailable for LDAP accounts")
+ .form-group.gl-form-group.rspec-full-name.gl-max-w-80
+ = render 'profiles/name', form: f, user: @user
+ .form-group.gl-form-group.gl-md-form-input-lg
+ = f.label :id, s_('Profiles|User ID')
+ = f.text_field :id, class: 'gl-form-input form-control', readonly: true
+ .form-group.gl-form-group
+ = f.label :pronouns, s_('Profiles|Pronouns')
+ = f.text_field :pronouns, class: 'gl-form-input form-control gl-md-form-input-lg'
+ %small.form-text.text-gl-muted
+ = s_("Profiles|Enter your pronouns to let people know how to refer to you.")
+ .form-group.gl-form-group
+ = f.label :pronunciation, s_('Profiles|Pronunciation')
+ = f.text_field :pronunciation, class: 'gl-form-input form-control gl-md-form-input-lg'
+ %small.form-text.text-gl-muted
+ = s_("Profiles|Enter how your name is pronounced to help people address you correctly.")
+ = render_if_exists 'profiles/extra_settings', form: f
+ = render_if_exists 'profiles/email_settings', form: f
+ .form-group.gl-form-group
+ = f.label :skype
+ = f.text_field :skype, class: 'gl-form-input form-control gl-md-form-input-lg', placeholder: s_("Profiles|username")
+ .form-group.gl-form-group
+ = f.label :linkedin
+ = f.text_field :linkedin, class: 'gl-form-input form-control gl-md-form-input-lg'
+ %small.form-text.text-gl-muted
+ = s_("Profiles|Your LinkedIn profile name from linkedin.com/in/profilename")
+ .form-group.gl-form-group
+ = f.label :twitter
+ = f.text_field :twitter, class: 'gl-form-input form-control gl-md-form-input-lg', placeholder: s_("Profiles|@username")
+ .form-group.gl-form-group
+ - external_accounts_help_url = help_page_path('user/profile/index', anchor: 'add-external-accounts-to-your-user-profile-page')
+ - external_accounts_link = link_to '', external_accounts_help_url, target: "_blank", rel: "noopener noreferrer"
+ - external_accounts_docs_link = safe_format(s_('Profiles|Your Discord user ID. %{external_accounts_link_start}Learn more.%{external_accounts_link_end}'), tag_pair(external_accounts_link, :external_accounts_link_start, :external_accounts_link_end))
+ - min_discord_length = 17
+ - max_discord_length = 20
+ = f.label :discord
+ = f.text_field :discord,
+ class: 'gl-form-input form-control gl-md-form-input-lg js-validate-length',
+ placeholder: s_("Profiles|User ID"),
+ data: { min_length: min_discord_length,
+ min_length_message: s_('Profiles|Discord ID is too short (minimum is %{min_length} characters).') % { min_length: min_discord_length },
+ max_length: max_discord_length,
+ max_length_message: s_('Profiles|Discord ID is too long (maximum is %{max_length} characters).') % { max_length: max_discord_length },
+ allow_empty: true}
+ %small.form-text.text-gl-muted
+ = external_accounts_docs_link
+
+ .form-group.gl-form-group
+ = f.label :website_url, s_('Profiles|Website url')
+ = f.text_field :website_url, class: 'gl-form-input form-control gl-md-form-input-lg', placeholder: s_("Profiles|https://website.com")
+ .form-group.gl-form-group
+ = f.label :location, s_('Profiles|Location')
+ - if @user.read_only_attribute?(:location)
+ = f.text_field :location, class: 'gl-form-input form-control gl-md-form-input-lg', readonly: true
%small.form-text.text-gl-muted
- = s_("Profiles|Tell us about yourself in fewer than 250 characters.")
- %hr
+ = s_("Profiles|Your location was automatically set based on your %{provider_label} account") % { provider_label: attribute_provider_label(:location) }
+ - else
+ = f.text_field :location, class: 'gl-form-input form-control gl-md-form-input-lg', placeholder: s_("Profiles|City, country")
+ .form-group.gl-form-group
+ = f.label :job_title, s_('Profiles|Job title')
+ = f.text_field :job_title, class: 'gl-form-input form-control gl-md-form-input-lg'
+ .form-group.gl-form-group
+ = f.label :organization, s_('Profiles|Organization')
+ = f.text_field :organization, class: 'gl-form-input form-control gl-md-form-input-lg'
+ %small.form-text.text-gl-muted
+ = s_("Profiles|Who you represent or work for.")
+ .form-group.gl-form-group.gl-mb-6.gl-max-w-80
+ = f.label :bio, s_('Profiles|Bio')
+ = f.text_area :bio, class: 'gl-form-input gl-form-textarea form-control', rows: 4, maxlength: 250
+ %small.form-text.text-gl-muted
+ = s_("Profiles|Tell us about yourself in fewer than 250 characters.")
+ .gl-border-t.gl-pt-6
%fieldset.form-group.gl-form-group
- %legend.col-form-label.col-form-label
+ %legend.col-form-label
= _('Private profile')
- private_profile_label = s_("Profiles|Don't display activity-related personal information on your profile.")
- private_profile_help_link = link_to sprite_icon('question-o'), help_page_path('user/profile/index.md', anchor: 'make-your-user-profile-page-private')
= f.gitlab_ui_checkbox_component :private_profile, '%{private_profile_label} %{private_profile_help_link}'.html_safe % { private_profile_label: private_profile_label, private_profile_help_link: private_profile_help_link.html_safe }
%fieldset.form-group.gl-form-group
- %legend.col-form-label.col-form-label
+ %legend.col-form-label
= s_("Profiles|Private contributions")
= f.gitlab_ui_checkbox_component :include_private_contributions,
s_('Profiles|Include private contributions on your profile'),
help_text: s_("Profiles|Choose to show contributions of private projects on your public profile without any project, repository or organization information.")
- %fieldset.form-group.gl-form-group
- %legend.col-form-label.col-form-label
+ %fieldset.form-group.gl-form-group.gl-mb-0
+ %legend.col-form-label
= s_("Profiles|Achievements")
= f.gitlab_ui_checkbox_component :achievements_enabled,
s_('Profiles|Display achievements on your profile')
- .row.js-hide-when-nothing-matches-search
- .col-lg-12
- %hr
- = f.submit s_("Profiles|Update profile settings"), class: 'gl-mr-3 js-password-prompt-btn', pajamas_button: true
- = render Pajamas::ButtonComponent.new(href: user_path(current_user)) do
- = s_('TagsPage|Cancel')
+
+ .js-hide-when-nothing-matches-search.settings-sticky-footer
+ = f.submit s_("Profiles|Update profile settings"), class: 'gl-mr-3 js-password-prompt-btn', pajamas_button: true
+ = render Pajamas::ButtonComponent.new(href: user_path(current_user)) do
+ = s_('TagsPage|Cancel')
#password-prompt-modal
diff --git a/app/views/profiles/two_factor_auths/show.html.haml b/app/views/profiles/two_factor_auths/show.html.haml
index 461164e1ae9..42297a0cf3d 100644
--- a/app/views/profiles/two_factor_auths/show.html.haml
+++ b/app/views/profiles/two_factor_auths/show.html.haml
@@ -55,7 +55,8 @@
= label_tag :pin_code, _('Enter verification code'), class: "label-bold"
= text_field_tag :pin_code, nil, autocomplete: 'off', inputmode: 'numeric', class: "form-control gl-form-input", required: true, data: { qa_selector: 'pin_code_field' }
.gl-mt-3
- = submit_tag _('Register with two-factor app'), class: 'gl-button btn btn-confirm', data: { qa_selector: 'register_2fa_app_button' }
+ = render Pajamas::ButtonComponent.new(type: :submit, variant: :confirm, button_options: { data: { qa_selector: 'register_2fa_app_button' } }) do
+ = _('Register with two-factor app')
%hr
@@ -101,7 +102,7 @@
- else
%span.gl-text-gray-500
= _("no name set")
- %td= registration[:created_at].to_date.to_s(:medium)
+ %td= registration[:created_at].to_date.to_fs(:medium)
%td
= render Pajamas::ButtonComponent.new(variant: :danger,
href: registration[:delete_path],
diff --git a/app/views/projects/_activity.html.haml b/app/views/projects/_activity.html.haml
index 118f6fb1296..00da6c73081 100644
--- a/app/views/projects/_activity.html.haml
+++ b/app/views/projects/_activity.html.haml
@@ -3,8 +3,7 @@
.nav-block.d-none.d-sm-flex.activities.gl-static
= render 'shared/event_filter'
.controls.gl-display-flex
- = link_to project_path(@project, rss_url_options), title: s_("ProjectActivityRSS|Subscribe"), class: 'btn gl-button btn-default btn-icon d-none d-sm-inline-flex has-tooltip' do
- = sprite_icon('rss', css_class: 'gl-icon')
+ = link_button_to nil, project_path(@project, rss_url_options), title: s_("ProjectActivityRSS|Subscribe"), class: 'd-none d-sm-inline-flex has-tooltip', icon: 'rss'
- if is_project_overview && can?(current_user, :download_code, @project)
.project-clone-holder.d-none.d-md-inline-flex.gl-ml-2
= render "projects/buttons/clone", dropdown_class: 'dropdown-menu-right'
diff --git a/app/views/projects/_customize_workflow.html.haml b/app/views/projects/_customize_workflow.html.haml
index ded43a34b48..da4b257f224 100644
--- a/app/views/projects/_customize_workflow.html.haml
+++ b/app/views/projects/_customize_workflow.html.haml
@@ -5,4 +5,4 @@
%p
Get started with GitLab by enabling features that work best for your project. From issues and wikis, to merge requests and pipelines, GitLab can help manage your workflow from idea to production!
- if can?(current_user, :admin_project, @project)
- = link_to "Get started", edit_project_path(@project), class: "gl-button btn btn-confirm"
+ = link_button_to "Get started", edit_project_path(@project), variant: :confirm
diff --git a/app/views/projects/_export.html.haml b/app/views/projects/_export.html.haml
index 97f5cdb54e5..3ef2c722e98 100644
--- a/app/views/projects/_export.html.haml
+++ b/app/views/projects/_export.html.haml
@@ -20,10 +20,12 @@
%li= _('Webhooks')
%li= _('Any encrypted tokens')
- if project.export_status == :finished
- = link_to _('Download export'), download_export_project_path(project),
- rel: 'nofollow', download: '', method: :get, class: "btn gl-button btn-default", data: { qa_selector: 'download_export_link' }
- = link_to _('Generate new export'), generate_new_export_project_path(project),
- method: :post, class: "btn gl-button btn-default"
+ = render Pajamas::ButtonComponent.new(href: download_export_project_path(project),
+ method: :get,
+ button_options: { ref: 'nofollow', download: '', data: { qa_selector: 'download_export_link' } }) do
+ = _('Download export')
+ = render Pajamas::ButtonComponent.new(href: generate_new_export_project_path(project), method: :post) do
+ = _('Generate new export')
- else
- = link_to _('Export project'), export_project_path(project),
- method: :post, class: "btn gl-button btn-default", data: { qa_selector: 'export_project_link' }
+ = render Pajamas::ButtonComponent.new(href: export_project_path(project), method: :post, button_options: { data: { qa_selector: 'export_project_link' } }) do
+ = _('Export project')
diff --git a/app/views/projects/_find_file_link.html.haml b/app/views/projects/_find_file_link.html.haml
index a4bf72edf12..4ad2c339bcc 100644
--- a/app/views/projects/_find_file_link.html.haml
+++ b/app/views/projects/_find_file_link.html.haml
@@ -1,2 +1,2 @@
-= link_to project_find_file_path(@project, @ref), class: 'gl-button btn btn-default shortcuts-find-file', rel: 'nofollow' do
+= link_button_to project_find_file_path(@project, @ref), class: 'shortcuts-find-file', rel: 'nofollow' do
= _('Find file')
diff --git a/app/views/projects/_home_panel.html.haml b/app/views/projects/_home_panel.html.haml
index 9cb5ec39de2..59147138834 100644
--- a/app/views/projects/_home_panel.html.haml
+++ b/app/views/projects/_home_panel.html.haml
@@ -27,9 +27,7 @@
.project-repo-buttons.gl-display-flex.gl-justify-content-md-end.gl-align-items-center.gl-flex-wrap.gl-gap-3
- if current_user
- if current_user.admin?
- = link_to [:admin, @project], class: 'btn btn-default gl-button btn-icon', title: _('View project in admin area'),
- data: {toggle: 'tooltip', placement: 'top', container: 'body'} do
- = sprite_icon('admin')
+ = link_button_to nil, [:admin, @project], icon: 'admin', title: _('View project in admin area'), data: {toggle: 'tooltip', placement: 'top', container: 'body'}
- if @notification_setting
.js-vue-notification-dropdown{ data: { disabled: emails_disabled.to_s, dropdown_items: notification_dropdown_items(@notification_setting).to_json, notification_level: @notification_setting.level, help_page_path: help_page_path('user/profile/notifications'), project_id: @project.id, no_flip: 'true' } }
diff --git a/app/views/projects/_import_project_pane.html.haml b/app/views/projects/_import_project_pane.html.haml
index 947a1007fd5..6315c6dc52d 100644
--- a/app/views/projects/_import_project_pane.html.haml
+++ b/app/views/projects/_import_project_pane.html.haml
@@ -43,9 +43,7 @@
- if gitea_import_enabled?
%div
- = link_to new_import_gitea_path(namespace_id: namespace_id), class: 'gl-button btn-default btn import_gitea js-import-project-btn', data: { platform: 'gitea', **tracking_attrs_data(track_label, 'click_button', 'gitea') } do
- .gl-button-icon
- = custom_icon('gitea_logo')
+ = render Pajamas::ButtonComponent.new(href: new_import_gitea_path(namespace_id: namespace_id), icon: 'gitea', button_options: { class: 'import_gitea js-import-project-btn', data: { platform: 'gitea', **tracking_attrs_data(track_label, 'click_button', 'gitea') } }) do
Gitea
- if git_import_enabled?
diff --git a/app/views/projects/_new_project_fields.html.haml b/app/views/projects/_new_project_fields.html.haml
index 6049d1cc110..983b8056358 100644
--- a/app/views/projects/_new_project_fields.html.haml
+++ b/app/views/projects/_new_project_fields.html.haml
@@ -98,4 +98,4 @@
-# this partial is from JiHu, see details in https://jihulab.com/gitlab-cn/gitlab/-/merge_requests/675
= render_if_exists 'shared/other_project_options', f: f, visibility_level: visibility_level, track_label: track_label
= f.submit _('Create project'), class: "js-create-project-button", data: { qa_selector: 'project_create_button', track_label: "#{track_label}", track_action: "click_button", track_property: "create_project", track_value: "" }, pajamas_button: true
-= link_to _('Cancel'), @parent_group || dashboard_groups_path, class: 'btn gl-button btn-default btn-cancel', data: { track_label: "#{track_label}", track_action: "click_button", track_property: "cancel", track_value: "" }
+= link_button_to _('Cancel'), @parent_group || dashboard_groups_path, data: { track_label: "#{track_label}", track_action: "click_button", track_property: "cancel", track_value: "" }
diff --git a/app/views/projects/_readme.html.haml b/app/views/projects/_readme.html.haml
index 85a53edc160..c3d66396256 100644
--- a/app/views/projects/_readme.html.haml
+++ b/app/views/projects/_readme.html.haml
@@ -24,4 +24,4 @@
distributed with computer software, forming part of its documentation.
GitLab will render it here instead of this message.
%p
- = link_to "Add Readme", @project.add_readme_path, class: 'gl-button btn btn-confirm'
+ = link_button_to "Add Readme", @project.add_readme_path, variant: :confirm
diff --git a/app/views/projects/_service_desk_settings.html.haml b/app/views/projects/_service_desk_settings.html.haml
index 14991ce3824..0a83efdb3b8 100644
--- a/app/views/projects/_service_desk_settings.html.haml
+++ b/app/views/projects/_service_desk_settings.html.haml
@@ -12,8 +12,8 @@
enabled: "#{@project.service_desk_enabled}",
issue_tracker_enabled: "#{@project.project_feature.issues_enabled?}",
incoming_email: (@project.service_desk_incoming_address if @project.service_desk_enabled),
- custom_email: (@project.service_desk_custom_address if @project.service_desk_enabled),
- custom_email_enabled: "#{Gitlab::Email::ServiceDeskEmail.enabled?}",
+ service_desk_email: (@project.service_desk_custom_address if @project.service_desk_enabled),
+ service_desk_email_enabled: "#{Gitlab::Email::ServiceDeskEmail.enabled?}",
selected_template: "#{@project.service_desk_setting&.issue_template_key}",
selected_file_template_project_id: "#{@project.service_desk_setting&.file_template_project_id}",
outgoing_name: "#{@project.service_desk_setting&.outgoing_name}",
diff --git a/app/views/projects/_wiki.html.haml b/app/views/projects/_wiki.html.haml
index 45d0aee4332..e82e0972d82 100644
--- a/app/views/projects/_wiki.html.haml
+++ b/app/views/projects/_wiki.html.haml
@@ -14,4 +14,4 @@
- if can_create_wiki
%p
= _("Add a homepage to your wiki that contains information about your project and GitLab will display it here instead of this message.")
- = link_to _("Create your first page"), wiki_path(@project.wiki) + '?view=create', class: "btn gl-button btn-confirm"
+ = link_button_to _("Create your first page"), wiki_path(@project.wiki) + '?view=create', variant: :confirm
diff --git a/app/views/projects/artifacts/browse.html.haml b/app/views/projects/artifacts/browse.html.haml
index ccda06c7e4c..ebeeaed7ae9 100644
--- a/app/views/projects/artifacts/browse.html.haml
+++ b/app/views/projects/artifacts/browse.html.haml
@@ -18,10 +18,8 @@
= link_to truncate(title, length: 40), browse_project_job_artifacts_path(@project, @build, path)
.tree-controls<
- = link_to download_project_job_artifacts_path(@project, @build),
- rel: 'nofollow', download: '', class: 'gl-button btn btn-default download' do
- = sprite_icon('download', css_class: 'gl-mr-2')
- Download artifacts archive
+ = link_button_to download_project_job_artifacts_path(@project, @build), rel: 'nofollow', download: '', class: 'download', icon: 'download' do
+ = _('Download artifacts archive')
.tree-content-holder
%table.table.tree-table
diff --git a/app/views/projects/artifacts/external_file.html.haml b/app/views/projects/artifacts/external_file.html.haml
index a014d134e31..67f6ccd5695 100644
--- a/app/views/projects/artifacts/external_file.html.haml
+++ b/app/views/projects/artifacts/external_file.html.haml
@@ -1,3 +1,4 @@
+- external_url = @blob.external_url(@build)
- page_title @path, _('Artifacts'), "#{@build.name} (##{@build.id})", _('Jobs')
= render "projects/jobs/header"
@@ -8,8 +9,8 @@
%h2= _("You are being redirected away from GitLab")
%p= _("This page is hosted on GitLab pages but contains user-generated content and may contain malicious code. Do not accept unless you trust the author and source.")
- = link_to @blob.external_url(@project, @build),
- @blob.external_url(@project, @build),
+ = link_to external_url,
+ external_url,
target: '_blank',
title: _('Opens in a new window'),
rel: 'noopener noreferrer'
diff --git a/app/views/projects/blob/_breadcrumb.html.haml b/app/views/projects/blob/_breadcrumb.html.haml
index 79b13dc861a..417c11ba37a 100644
--- a/app/views/projects/blob/_breadcrumb.html.haml
+++ b/app/views/projects/blob/_breadcrumb.html.haml
@@ -22,14 +22,11 @@
-# only show normal/blame view links for text files
- if blob.readable_text?
- if blame
- = link_to 'Normal view', project_blob_path(@project, @id),
- class: 'gl-button btn btn-default'
+ = link_button_to _('Normal view'), project_blob_path(@project, @id)
- else
- = link_to 'Blame', project_blame_path(@project, @id),
- class: 'gl-button btn btn-default js-blob-blame-link' unless blob.empty?
+ = link_button_to _('Blame'), project_blame_path(@project, @id), class: 'js-blob-blame-link' unless blob.empty?
- = link_to 'History', project_commits_path(@project, @id),
- class: 'gl-button btn btn-default'
+ = link_button_to _('History'), project_commits_path(@project, @id)
- = link_to 'Permalink', project_blob_path(@project,
- tree_join(@commit.sha, @path)), class: 'gl-button btn btn-default js-data-file-blob-permalink-url'
+ = link_button_to _('Permalink'), project_blob_path(@project, tree_join(@commit.sha, @path)),
+ class: 'js-data-file-blob-permalink-url'
diff --git a/app/views/projects/blob/_new_dir.html.haml b/app/views/projects/blob/_new_dir.html.haml
index 3ae7741d24d..f1da9154df9 100644
--- a/app/views/projects/blob/_new_dir.html.haml
+++ b/app/views/projects/blob/_new_dir.html.haml
@@ -16,6 +16,6 @@
.form-actions
= submit_tag _("Create directory"), class: 'btn gl-button btn-confirm'
- = link_to _('Cancel'), '#', class: "btn gl-button btn-default btn-cancel", "data-dismiss" => "modal"
+ = link_button_to _('Cancel'), '#', "data-dismiss" => "modal"
= render 'shared/projects/edit_information'
diff --git a/app/views/projects/branches/_branch.html.haml b/app/views/projects/branches/_branch.html.haml
index adff64fad5a..ae8d230f356 100644
--- a/app/views/projects/branches/_branch.html.haml
+++ b/app/views/projects/branches/_branch.html.haml
@@ -11,13 +11,13 @@
= branch.name
= clipboard_button(text: branch.name, title: _("Copy branch name"))
- if is_default_branch
- = gl_badge_tag s_('DefaultBranchLabel|default'), { variant: :neutral, size: :sm }, { class: 'gl-ml-2', data: { qa_selector: 'badge_content' } }
+ = gl_badge_tag s_('DefaultBranchLabel|default'), { variant: :neutral, size: :sm }, { class: 'gl-ml-2' }
- if protected_branch?(@project, branch)
- = gl_badge_tag s_('Branches|protected'), { variant: :muted, size: :sm }, { class: 'gl-ml-2', data: { qa_selector: 'badge_content' } }
+ = gl_badge_tag s_('Branches|protected'), { variant: :muted, size: :sm }, { class: 'gl-ml-2' }
= render_if_exists 'projects/branches/diverged_from_upstream', branch: branch
- .block-truncated
+ .gl-text-truncate
- if commit
= render 'projects/branches/commit', commit: commit, project: @project
- else
@@ -28,35 +28,33 @@
.pipeline-status.d-none.d-md-block<
- if commit_status
- = render 'ci/status/icon', size: 16, status: commit_status, option_css_classes: 'gl-display-inline-flex gl-vertical-align-middle gl-mr-5'
+ = render 'ci/status/icon', size: 16, status: commit_status, option_css_classes: 'gl-display-inline-flex gl-vertical-align-middle gl-mr-3'
- elsif show_commit_status
- .gl-display-inline-flex.gl-vertical-align-middle.gl-mr-5
+ .gl-display-inline-flex.gl-vertical-align-middle.gl-mr-3
%svg.s16
-
- - if mr_status.present?
- .issuable-reference.gl-display-flex.gl-justify-content-end.gl-min-w-10.gl-ml-5.gl-mr-4
- = gl_badge_tag issuable_reference(related_merge_request),
- { icon: mr_status[:icon], variant: mr_status[:variant], size: :md, href: merge_request_path(related_merge_request) },
- { class: 'gl-mr-2', title: mr_status[:title], data: { toggle: 'tooltip', container: 'body', qa_selector: 'badge_content' } }
-
- .controls.d-none.d-md-block<
- - if mr_status.nil? && create_mr_button?(from: branch.name, source_project: @project)
- = render Pajamas::ButtonComponent.new(icon: 'merge-request', href: create_mr_path(from: branch.name, source_project: @project), button_options: { class: 'has-tooltip gl-mr-2!', title: _('New merge request') }) do
- = _('New')
-
- = render 'projects/buttons/download', project: @project, ref: branch.name, pipeline: @refs_pipelines[branch.name], css_class: 'gl-mr-1!'
-
- - if !is_default_branch
- .js-branch-more-actions{ data: {
- branch_name: branch.name,
- default_branch_name: @repository.root_ref,
- can_delete_branch: user_access(@project).can_delete_branch?(branch.name).to_s,
- is_protected_branch: protected_branch?(@project, branch).to_s,
- merged: merged.to_s,
- compare_path: project_compare_index_path(@project, from: @repository.root_ref, to: branch.name),
- delete_path: project_branch_path(@project, branch.name),
- } }
- - else
- .gl-display-inline-flex.gl-w-7
- &nbsp;
+ .right-block.gl-display-flex.gl-align-items-center.gl-justify-content-end
+ .gl-mr-3
+ - if mr_status.present?
+ .issuable-reference.gl-display-flex.gl-justify-content-end.gl-overflow-hidden
+ = gl_badge_tag issuable_reference(related_merge_request),
+ { icon: mr_status[:icon], variant: mr_status[:variant], size: :md, href: merge_request_path(related_merge_request) },
+ { class: 'gl-display-block gl-text-truncate', title: mr_status[:title], data: { toggle: 'tooltip', container: 'body' } }
+
+ - elsif mr_status.nil? && create_mr_button?(from: branch.name, source_project: @project)
+ = render Pajamas::ButtonComponent.new(icon: 'merge-request', href: create_mr_path(from: branch.name, source_project: @project), button_options: { class: 'has-tooltip', title: _('New merge request') }) do
+ = _('New')
+
+ = render 'projects/buttons/download', project: @project, ref: branch.name, pipeline: @refs_pipelines[branch.name], css_class: 'gl-mr-2!'
+
+ .gl-w-7
+ - if !is_default_branch
+ .js-branch-more-actions{ data: {
+ branch_name: branch.name,
+ default_branch_name: @repository.root_ref,
+ can_delete_branch: user_access(@project).can_delete_branch?(branch.name).to_s,
+ is_protected_branch: protected_branch?(@project, branch).to_s,
+ merged: merged.to_s,
+ compare_path: project_compare_index_path(@project, from: @repository.root_ref, to: branch.name),
+ delete_path: project_branch_path(@project, branch.name),
+ } }
diff --git a/app/views/projects/branches/_commit.html.haml b/app/views/projects/branches/_commit.html.haml
index 6bbd0617598..7662caceb15 100644
--- a/app/views/projects/branches/_commit.html.haml
+++ b/app/views/projects/branches/_commit.html.haml
@@ -1,7 +1,7 @@
-.branch-commit.gl-font-sm.gl-text-gray-500
+.branch-commit.gl-font-sm.gl-text-gray-500.gl-text-truncate
= link_to commit.short_id, project_commit_path(project, commit.id), class: "commit-sha"
&middot;
- %span.str-truncated
+ %span
= link_to_markdown commit.title, project_commit_path(project, commit.id), class: "commit-row-message gl-text-gray-500!"
&middot;
%span.gl-text-secondary= time_ago_with_tooltip(commit.committed_date)
diff --git a/app/views/projects/branches/_panel.html.haml b/app/views/projects/branches/_panel.html.haml
index a632e29d34f..c01e3677c19 100644
--- a/app/views/projects/branches/_panel.html.haml
+++ b/app/views/projects/branches/_panel.html.haml
@@ -7,9 +7,9 @@
- return unless branches.any?
-= render Pajamas::CardComponent.new(card_options: {class: 'gl-mt-5 gl-bg-gray-10'}, header_options: {class: 'gl-px-5 gl-py-4 gl-bg-white'}, body_options: {class: 'gl-px-3 gl-py-0'}, footer_options: {class: 'gl-bg-white'}) do |c|
+= render Pajamas::CardComponent.new(card_options: { class: 'gl-new-card' }, header_options: { class: 'gl-new-card-header' }, body_options: { class: 'gl-new-card-body' }, footer_options: { class: 'gl-new-card-footer' }) do |c|
- c.with_header do
- %h3.card-title.h5.gl-line-height-24.gl-m-0
+ %h3.gl-new-card-title.h5
= panel_title
- c.with_body do
%ul.content-list.branches-list.all-branches{ data: { qa_selector: 'all_branches_container' } }
diff --git a/app/views/projects/branches/index.html.haml b/app/views/projects/branches/index.html.haml
index 8992753c676..c03de6646cf 100644
--- a/app/views/projects/branches/index.html.haml
+++ b/app/views/projects/branches/index.html.haml
@@ -1,8 +1,6 @@
- add_page_specific_style 'page_bundles/branches'
- page_title _('Branches')
- add_to_breadcrumbs(_('Repository'), project_tree_path(@project))
-- can_access_branch_rules = can?(current_user, :maintainer_access, @project)
-- can_push_code = (can? current_user, :push_code, @project)
-# Possible values for variables passed down from the projects/branches_controller.rb
-#
@@ -24,21 +22,21 @@
sorted_by: @sort }
}
- - if can_access_branch_rules
- = link_to project_settings_repository_path(@project, anchor: 'js-branch-rules'), class: 'gl-button btn btn-default' do
+ - if can_view_branch_rules?
+ = link_button_to project_settings_repository_path(@project, anchor: 'js-branch-rules') do
= s_('Branches|View branch rules')
- - if can_push_code
- = link_to new_project_branch_path(@project), class: 'gl-button btn btn-confirm' do
+ - if can_push_code?
+ = link_button_to new_project_branch_path(@project), variant: :confirm do
= s_('Branches|New branch')
- .js-delete-merged-branches{ data: {
+ .js-delete-merged-branches.gl-w-7{ data: {
default_branch: @project.repository.root_ref,
form_path: project_merged_branches_path(@project) }
}
= render_if_exists 'projects/commits/mirror_status'
-- if can_access_branch_rules
+- if can_view_branch_rules?
= render 'branch_rules_info'
.js-branch-list{ data: { diverging_counts_endpoint: diverging_commit_counts_namespace_project_branches_path(@project.namespace, @project, format: :json), default_branch: @project.default_branch } }
diff --git a/app/views/projects/branches/new.html.haml b/app/views/projects/branches/new.html.haml
index 9fd9943fd26..7f6a37fc210 100644
--- a/app/views/projects/branches/new.html.haml
+++ b/app/views/projects/branches/new.html.haml
@@ -20,4 +20,4 @@
= _('Existing branch name, tag, or commit SHA')
= render Pajamas::ButtonComponent.new(variant: :confirm, button_options: { type: 'submit', class: 'gl-mr-3' }) do
= _('Create branch')
- = link_to _('Cancel'), project_branches_path(@project), class: 'gl-button btn btn-default btn-cancel'
+ = link_button_to _('Cancel'), project_branches_path(@project)
diff --git a/app/views/projects/buttons/_clone.html.haml b/app/views/projects/buttons/_clone.html.haml
index ab026d9c6ac..db5d1ff5693 100644
--- a/app/views/projects/buttons/_clone.html.haml
+++ b/app/views/projects/buttons/_clone.html.haml
@@ -3,7 +3,7 @@
- if can?(current_user, :download_code, @project)
.git-clone-holder.js-git-clone-holder
- %a#clone-dropdown.gl-button.btn.btn-confirm.clone-dropdown-btn{ href: '#', data: { toggle: 'dropdown', qa_selector: 'clone_dropdown' } }
+ = render Pajamas::ButtonComponent.new(variant: :confirm, button_options: { id: 'clone-dropdown', class: 'clone-dropdown-btn', data: { toggle: 'dropdown', qa_selector: 'clone_dropdown' } }) do
%span.gl-mr-2.js-clone-dropdown-label
= _('Clone')
= sprite_icon("chevron-down", css_class: "icon")
diff --git a/app/views/projects/buttons/_download.html.haml b/app/views/projects/buttons/_download.html.haml
index bbee7d66dcb..23d18236738 100644
--- a/app/views/projects/buttons/_download.html.haml
+++ b/app/views/projects/buttons/_download.html.haml
@@ -6,7 +6,7 @@
- if !project.empty_repo? && can?(current_user, :download_code, project)
- archive_prefix = "#{project.path}-#{ref.tr('/', '-')}"
.project-action-button.dropdown.gl-dropdown.inline{ class: css_class }>
- %button.gl-button.btn.btn-default.dropdown-toggle.gl-dropdown-toggle.dropdown-icon-only.has-tooltip{ title: s_('DownloadSource|Download'), 'data-toggle' => 'dropdown', 'aria-label' => s_('DownloadSource|Download'), 'data-display' => 'static', data: { qa_selector: 'download_source_code_button' } }
+ = render Pajamas::ButtonComponent.new(button_options: { class: 'dropdown-toggle gl-dropdown-toggle dropdown-icon-only has-tooltip', title: s_('DownloadSource|Download'), 'data-toggle' => 'dropdown', 'aria-label' => s_('DownloadSource|Download'), 'data-display' => 'static', data: { qa_selector: 'download_source_code_button' } }) do
= sprite_icon('download', css_class: 'gl-icon dropdown-icon')
%span.sr-only= _('Select Archive Format')
= sprite_icon('chevron-down', css_class: 'gl-icon dropdown-chevron')
diff --git a/app/views/projects/buttons/_download_links.html.haml b/app/views/projects/buttons/_download_links.html.haml
index d36aed44e18..31185fc1532 100644
--- a/app/views/projects/buttons/_download_links.html.haml
+++ b/app/views/projects/buttons/_download_links.html.haml
@@ -1,4 +1,4 @@
.btn-group.ml-0.w-100
- Gitlab::Workhorse::ARCHIVE_FORMATS.each_with_index do |fmt, index|
- archive_path = project_archive_path(project, id: tree_join(ref, archive_prefix), path: path, format: fmt)
- = link_to fmt, external_storage_url_or_path(archive_path), rel: 'nofollow', download: '', class: "gl-button btn btn-sm #{index == 0 ? 'btn-confirm' : 'btn-default'}"
+ = link_button_to fmt, external_storage_url_or_path(archive_path), rel: 'nofollow', download: '', variant: index == 0 ? :confirm : :default, size: :small
diff --git a/app/views/projects/buttons/_fork.html.haml b/app/views/projects/buttons/_fork.html.haml
index 6d05f1dc955..c9dcfaff8c6 100644
--- a/app/views/projects/buttons/_fork.html.haml
+++ b/app/views/projects/buttons/_fork.html.haml
@@ -2,17 +2,15 @@
- if current_user
.count-badge.btn-group
- if current_user.already_forked?(@project) && current_user.forkable_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 has-tooltip fork-btn' do
- = sprite_icon('fork', css_class: 'icon')
- %span= s_('ProjectOverview|Fork')
+ = link_button_to namespace_project_path(current_user, current_user.fork_of(@project)), title: s_('ProjectOverview|Go to your fork'), class: 'has-tooltip fork-btn', icon: 'fork' do
+ = s_('ProjectOverview|Fork')
- else
- disabled_tooltip = fork_button_disabled_tooltip(@project)
- count_class = 'disabled' unless can?(current_user, :read_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 fork-btn #{button_class}", data: { qa_selector: 'fork_button' } 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 count has-tooltip fork-count #{count_class}" do
+ = link_button_to new_project_fork_path(@project), class: "fork-btn #{button_class}", data: { qa_selector: 'fork_button' }, icon: 'fork' do
+ = s_('ProjectOverview|Fork')
+ = link_button_to project_forks_path(@project), title: n_(s_('ProjectOverview|Forks'), s_('ProjectOverview|Forks'), @project.forks_count), class: "count has-tooltip fork-count #{count_class}" do
= @project.forks_count
diff --git a/app/views/projects/buttons/_star.html.haml b/app/views/projects/buttons/_star.html.haml
index d4dcfbdff54..35318f68f57 100644
--- a/app/views/projects/buttons/_star.html.haml
+++ b/app/views/projects/buttons/_star.html.haml
@@ -6,12 +6,11 @@
.count-badge.d-inline-flex.align-item-stretch.btn-group
= render Pajamas::ButtonComponent.new(size: :medium, icon: icon, button_text_classes: button_text_classes, button_options: { class: 'star-btn toggle-star', data: { endpoint: toggle_star_project_path(@project, :json) } }) do
- button_text
- = link_to project_starrers_path(@project), title: n_(s_('ProjectOverview|Starrer'), s_('ProjectOverview|Starrers'), @project.star_count), class: 'gl-button btn btn-default has-tooltip star-count count' do
+ = link_button_to project_starrers_path(@project), title: n_(s_('ProjectOverview|Starrer'), s_('ProjectOverview|Starrers'), @project.star_count), class: 'has-tooltip star-count count' do
= @project.star_count
- else
.count-badge.d-inline-flex.align-item-stretch.btn-group
- = link_to new_user_session_path, class: 'gl-button btn btn-default has-tooltip star-btn', title: s_('ProjectOverview|You must sign in to star a project') do
- = sprite_icon('star-o', css_class: 'icon')
- %span= s_('ProjectOverview|Star')
- = link_to project_starrers_path(@project), title: n_(s_('ProjectOverview|Starrer'), s_('ProjectOverview|Starrers'), @project.star_count), class: 'gl-button btn btn-default has-tooltip star-count count' do
+ = link_button_to new_user_session_path, class: 'has-tooltip star-btn', title: s_('ProjectOverview|You must sign in to star a project'), icon: 'star-o' do
+ = s_('ProjectOverview|Star')
+ = link_button_to project_starrers_path(@project), title: n_(s_('ProjectOverview|Starrer'), s_('ProjectOverview|Starrers'), @project.star_count), class: 'has-tooltip star-count count' do
= @project.star_count
diff --git a/app/views/projects/ci/builds/_build.html.haml b/app/views/projects/ci/builds/_build.html.haml
index ecdd43a54f9..4017db459a9 100644
--- a/app/views/projects/ci/builds/_build.html.haml
+++ b/app/views/projects/ci/builds/_build.html.haml
@@ -103,33 +103,28 @@
.gl-text-right
.btn-group
- if can?(current_user, :read_job_artifacts, job) && job.artifacts?
- = link_to download_project_job_artifacts_path(job.project, job), rel: 'nofollow', download: '', title: _('Download artifacts'), class: 'gl-button btn btn-default btn-icon' do
- = sprite_icon('download', css_class: 'gl-icon')
+ = link_button_to nil, download_project_job_artifacts_path(job.project, job), rel: 'nofollow', download: '', title: _('Download artifacts'), icon: 'download'
- if can?(current_user, :update_build, job)
- if job.active?
- = link_to cancel_project_job_path(job.project, job, continue: { to: request.fullpath }), method: :post, title: _('Cancel'), class: 'gl-button btn btn-default btn-icon' do
- = sprite_icon('cancel', css_class: 'gl-icon')
+ = link_button_to nil, cancel_project_job_path(job.project, job, continue: { to: request.fullpath }), method: :post, title: _('Cancel'), icon: 'cancel'
- elsif job.scheduled?
- .gl-button.btn.btn-default.btn-icon.disabled{ disabled: true }
- = sprite_icon('planning', css_class: 'gl-icon')
+ = render Pajamas::ButtonComponent.new(disabled: true, icon: 'planning') do
%time.js-remaining-time{ datetime: job.scheduled_at.utc.iso8601 }
= duration_in_numbers(job.execute_in)
- confirmation_message = s_("DelayedJobs|Are you sure you want to run %{job_name} immediately? This job will run automatically after it's timer finishes.") % { job_name: job.name }
- = link_to play_project_job_path(job.project, job, return_to: request.original_url),
+ = link_button_to nil, play_project_job_path(job.project, job, return_to: request.original_url),
method: :post,
title: s_('DelayedJobs|Start now'),
- class: 'gl-button btn btn-default btn-icon has-tooltip',
- data: { confirm: confirmation_message } do
- = sprite_icon('play', css_class: 'gl-icon')
- = link_to unschedule_project_job_path(job.project, job, return_to: request.original_url),
+ class: 'has-tooltip',
+ data: { confirm: confirmation_message },
+ icon: 'play'
+ = link_button_to nil, unschedule_project_job_path(job.project, job, return_to: request.original_url),
method: :post,
title: s_('DelayedJobs|Unschedule'),
- class: 'gl-button btn btn-default btn-icon has-tooltip' do
- = sprite_icon('time-out', css_class: 'gl-icon')
+ class: 'has-tooltip',
+ icon: 'time-out'
- elsif allow_retry
- if job.playable? && !admin && can?(current_user, :update_build, job)
- = link_to play_project_job_path(job.project, job, return_to: request.original_url), method: :post, title: _('Play'), class: 'gl-button btn btn-default btn-icon' do
- = sprite_icon('play', css_class: 'gl-icon')
+ = link_button_to nil, play_project_job_path(job.project, job, return_to: request.original_url), method: :post, title: _('Play'), icon: 'play'
- elsif job.retryable?
- = link_to retry_project_job_path(job.project, job, return_to: request.original_url), method: :post, title: _('Retry'), class: 'gl-button btn btn-default btn-icon' do
- = sprite_icon('retry', css_class: 'gl-icon')
+ = link_button_to nil, retry_project_job_path(job.project, job, return_to: request.original_url), method: :post, title: _('Retry'), icon: 'retry'
diff --git a/app/views/projects/commit/_commit_box.html.haml b/app/views/projects/commit/_commit_box.html.haml
index c161e1c9d2a..24d063d3b4d 100644
--- a/app/views/projects/commit/_commit_box.html.haml
+++ b/app/views/projects/commit/_commit_box.html.haml
@@ -19,7 +19,7 @@
#{time_ago_with_tooltip(@commit.committed_date)}
#js-commit-comments-button{ data: { comments_count: @notes_count.to_i } }
- = link_to _('Browse files'), project_tree_path(@project, @commit), class: "btn gl-button btn-default gl-mr-3 gl-xs-w-full gl-xs-mb-3"
+ = link_button_to _('Browse files'), project_tree_path(@project, @commit), class: 'gl-mr-3 gl-xs-w-full gl-xs-mb-3'
#js-commit-options-dropdown{ data: commit_options_dropdown_data(@project, @commit) }
.commit-box{ data: { project_path: project_path(@project) } }
diff --git a/app/views/projects/commit/_pipelines_list.haml b/app/views/projects/commit/_pipelines_list.haml
index f7ae462e8f9..382cb499fe1 100644
--- a/app/views/projects/commit/_pipelines_list.haml
+++ b/app/views/projects/commit/_pipelines_list.haml
@@ -4,6 +4,7 @@
#commit-pipeline-table-view{ data: { disable_initialization: disable_initialization,
endpoint: endpoint,
full_path: @project.full_path,
+ graphql_path: api_graphql_path,
"empty-state-svg-path" => image_path('illustrations/empty-state/empty-pipeline-md.svg'),
"error-state-svg-path" => image_path('illustrations/pipelines_failed.svg'),
"project-id": @project.id,
diff --git a/app/views/projects/commit/_signature_badge_user.html.haml b/app/views/projects/commit/_signature_badge_user.html.haml
deleted file mode 100644
index 656adef6a72..00000000000
--- a/app/views/projects/commit/_signature_badge_user.html.haml
+++ /dev/null
@@ -1,21 +0,0 @@
-- user = signature.signed_by_user
-
-- if user
- = link_to user_path(user), class: 'gpg-popover-user-link' do
- %div
- = user_avatar_without_link(user: user, size: 32)
-
- %div
- %strong= user.name
- %div= user.to_reference
-- elsif signature.gpg? # SSH signatures do not have an email embedded in them
- - user_name = signature.gpg_key_user_name
- - user_email = signature.gpg_key_user_email
- - if user_name && user_email
- = mail_to user_email do
- %div
- = user_avatar_without_link(user_name: user_name, user_email: user_email, size: 32)
-
- %div
- %strong= user_name
- %div= user_email
diff --git a/app/views/projects/commit/_verified_system_signature_badge.html.haml b/app/views/projects/commit/_verified_system_signature_badge.html.haml
new file mode 100644
index 00000000000..96ff26ecbd7
--- /dev/null
+++ b/app/views/projects/commit/_verified_system_signature_badge.html.haml
@@ -0,0 +1,5 @@
+- title = _('Verified commit')
+- description = _('This commit was created in the GitLab UI, and signed with a GitLab-verified signature.')
+- locals = { signature: signature, title: title, description: description, label: _('Verified'), variant: 'success' }
+
+= render partial: 'projects/commit/signature_badge', locals: locals
diff --git a/app/views/projects/commit/x509/_signature_badge_user.html.haml b/app/views/projects/commit/x509/_signature_badge_user.html.haml
deleted file mode 100644
index da749172369..00000000000
--- a/app/views/projects/commit/x509/_signature_badge_user.html.haml
+++ /dev/null
@@ -1,19 +0,0 @@
-- user_email = signature.x509_certificate.email
-- user = signature.signed_by_user
-
-- if user
- = link_to user_path(user), class: 'gpg-popover-user-link' do
- %div
- = user_avatar_without_link(user: user, size: 32)
-
- %div
- %strong= user.name
- %div= user.to_reference
-
-- else
- = mail_to user_email do
- %div
- = user_avatar_without_link(user_email: user_email, size: 32)
-
- %div
- %strong= user_email
diff --git a/app/views/projects/commits/_commit.html.haml b/app/views/projects/commits/_commit.html.haml
index 6209ef48f96..13a406d442d 100644
--- a/app/views/projects/commits/_commit.html.haml
+++ b/app/views/projects/commits/_commit.html.haml
@@ -25,7 +25,7 @@
.avatar-cell.d-none.d-sm-block
= author_avatar(commit, size: 40, has_tooltip: false)
- .commit-detail.flex-list.gl-display-flex.gl-justify-content-space-between.gl-align-items-flex-start.gl-flex-grow-1.gl-min-w-0
+ .commit-detail.flex-list.gl-display-flex.gl-justify-content-space-between.gl-align-items-center.gl-flex-grow-1.gl-min-w-0
.commit-content{ data: { qa_selector: 'commit_content' } }
- if view_details && merge_request
= link_to commit.title, project_commit_path(project, commit.id, merge_request_iid: merge_request.iid), class: ["commit-row-message item-title js-onboarding-commit-item", ("font-italic" if commit.message.empty?)]
diff --git a/app/views/projects/commits/_commit_list.html.haml b/app/views/projects/commits/_commit_list.html.haml
index 22f4594c1d5..721040f9a09 100644
--- a/app/views/projects/commits/_commit_list.html.haml
+++ b/app/views/projects/commits/_commit_list.html.haml
@@ -4,7 +4,7 @@
= render Pajamas::CardComponent.new(card_options: { class: 'gl-mb-5'}, body_options: { class: 'gl-py-0'}) do |c|
- c.with_header do
- Commits (#{@total_commit_count})
+ = s_('CompareRevisions|Commits on Source (%{commits_amount})').html_safe % { commits_amount: @total_commit_count }
- c.with_body do
- if hidden > 0
%ul.content-list
diff --git a/app/views/projects/commits/show.html.haml b/app/views/projects/commits/show.html.haml
index 4c5a9acdf83..8afc9ade3e1 100644
--- a/app/views/projects/commits/show.html.haml
+++ b/app/views/projects/commits/show.html.haml
@@ -18,7 +18,7 @@
.tree-controls
- if @merge_request.present?
.control.d-none.d-md-block
- = link_to _("View open merge request"), project_merge_request_path(@project, @merge_request), class: 'btn gl-button'
+ = link_button_to _("View open merge request"), project_merge_request_path(@project, @merge_request)
- elsif create_mr_button?(from: @ref, source_project: @project)
.control.d-none.d-md-block
= render Pajamas::ButtonComponent.new(variant: :confirm, href: create_mr_path(from: @ref, source_project: @project)) do
@@ -28,8 +28,7 @@
= form_tag(project_commits_path(@project, @id, ref_type: @ref_type), method: :get, class: 'commits-search-form js-signature-container', data: { 'signatures-path' => namespace_project_signatures_path(ref_type: @ref_type)}) do
= search_field_tag :search, params[:search], { placeholder: _('Search by message'), id: 'commits-search', class: 'form-control gl-form-input input-short gl-mt-3 gl-sm-mt-0 gl-min-w-full', spellcheck: false }
.control.d-none.d-md-block
- = link_to project_commits_path(@project, @id, rss_url_options), title: _("Commits feed"), class: 'btn gl-button btn-default btn-icon' do
- = sprite_icon('rss')
+ = link_button_to nil, project_commits_path(@project, @id, rss_url_options), title: _("Commits feed"), icon: 'rss'
= render_if_exists 'projects/commits/mirror_status'
diff --git a/app/views/projects/compare/index.html.haml b/app/views/projects/compare/index.html.haml
index 58da76a3231..4a29402bfe7 100644
--- a/app/views/projects/compare/index.html.haml
+++ b/app/views/projects/compare/index.html.haml
@@ -1,16 +1,6 @@
-- breadcrumb_title _("Compare revisions")
-- page_title _("Compare revisions")
+- breadcrumb_title s_("CompareRevisions|Compare revisions")
-%h1.page-title.gl-font-size-h-display
- = _("Compare Git revisions")
-%div
- - example_branch = capture do
- %code.ref-name= @project.default_branch_or_main
- - example_sha = capture do
- %code.ref-name 4eedf23
- = 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 }
+- page_title _("CompareRevisions|Compare revisions")
.prepend-top-20
#js-compare-selector{ data: project_compare_selector_data(@project, @merge_request, @compare_params) }
diff --git a/app/views/projects/compare/show.html.haml b/app/views/projects/compare/show.html.haml
index 9185afc0771..5b6f7c392dd 100644
--- a/app/views/projects/compare/show.html.haml
+++ b/app/views/projects/compare/show.html.haml
@@ -1,7 +1,7 @@
-- add_to_breadcrumbs _("Compare revisions"), project_compare_index_path(@project)
-- page_title "#{params[:from]}...#{params[:to]}"
+- add_to_breadcrumbs s_("CompareRevisions|Compare revisions"), project_compare_index_path(@project)
+- page_title "#{params[:from]} to #{params[:to]}"
-.sub-header-block.gl-border-b-0.gl-mb-0
+.sub-header-block.gl-border-b-0.gl-mb-0.gl-pt-4
.js-signature-container{ data: { 'signatures-path' => signatures_namespace_project_compare_index_path } }
#js-compare-selector{ data: project_compare_selector_data(@project, @merge_request, params) }
@@ -20,13 +20,13 @@
= render Pajamas::CardComponent.new(card_options: { class: "gl-bg-gray-50 gl-mb-5 gl-border-none gl-text-center" }) do |c|
- c.with_body do
%h4
- = s_("CompareBranches|There isn't anything to compare.")
+ = s_("CompareRevisions|There isn't anything to compare.")
%p.gl-mb-4.gl-line-height-24
- if params[:to] == params[:from]
- source_branch = capture do
%span.ref-name= params[:from]
- target_branch = capture do
%span.ref-name= params[:to]
- = (s_("CompareBranches|%{source_branch} and %{target_branch} are the same.") % { source_branch: source_branch, target_branch: target_branch }).html_safe
+ = (s_("CompareRevisions|%{source_branch} and %{target_branch} are the same.") % { source_branch: source_branch, target_branch: target_branch }).html_safe
- else
= _("You'll need to use different branch names to get a valid comparison.")
diff --git a/app/views/projects/confluences/show.html.haml b/app/views/projects/confluences/show.html.haml
index 6fec9b501ea..283408ffa63 100644
--- a/app/views/projects/confluences/show.html.haml
+++ b/app/views/projects/confluences/show.html.haml
@@ -8,6 +8,6 @@
- wiki_confluence_epic_link_url = 'https://gitlab.com/groups/gitlab-org/-/epics/3629'
- wiki_confluence_epic_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: wiki_confluence_epic_link_url }
= html_escape(s_("WikiEmpty|You've enabled the Confluence Workspace integration. Your wiki will be viewable directly within Confluence. We are hard at work integrating Confluence more seamlessly into GitLab. If you'd like to stay up to date, follow our %{wiki_confluence_epic_link_start}Confluence epic%{wiki_confluence_epic_link_end}.")) % { wiki_confluence_epic_link_start: wiki_confluence_epic_link_start, wiki_confluence_epic_link_end: '</a>'.html_safe }
- = link_to @project.confluence_integration.confluence_url, target: '_blank', rel: 'noopener noreferrer', class: 'gl-button btn btn-confirm external-url', title: s_('WikiEmpty|Go to Confluence') do
+ = link_button_to @project.confluence_integration.confluence_url, target: '_blank', rel: 'noopener noreferrer', class: 'external-url', title: s_('WikiEmpty|Go to Confluence'), variant: :confirm do
= s_('WikiEmpty|Go to Confluence')
= sprite_icon('external-link')
diff --git a/app/views/projects/deploy_keys/edit.html.haml b/app/views/projects/deploy_keys/edit.html.haml
index 91444a00334..997443d5fa9 100644
--- a/app/views/projects/deploy_keys/edit.html.haml
+++ b/app/views/projects/deploy_keys/edit.html.haml
@@ -7,4 +7,4 @@
= render partial: 'shared/deploy_keys/form', locals: { form: f, deploy_key: @deploy_key }
.form-actions
= f.submit _('Save changes'), pajamas_button: true
- = link_to _('Cancel'), project_settings_repository_path(@project), class: 'gl-button btn btn-default btn-cancel'
+ = link_button_to _('Cancel'), project_settings_repository_path(@project)
diff --git a/app/views/projects/diffs/_diffs.html.haml b/app/views/projects/diffs/_diffs.html.haml
index 982ecbbae51..9193fc4ef25 100644
--- a/app/views/projects/diffs/_diffs.html.haml
+++ b/app/views/projects/diffs/_diffs.html.haml
@@ -12,7 +12,7 @@
.files-changed-inner
.inline-parallel-buttons.gl-display-none.gl-md-display-flex.gl-relative
- if !diffs_expanded? && diff_files.any?(&:collapsed?)
- = link_to _('Expand all'), url_for(safe_params.merge(expanded: 1, format: nil)), class: 'gl-button btn btn-default'
+ = link_button_to _('Expand all'), url_for(safe_params.merge(expanded: 1, format: nil))
- if show_whitespace_toggle
- if current_controller?(:commit)
= commit_diff_whitespace_link(diffs.project, @commit, class: 'd-none d-sm-inline-block')
diff --git a/app/views/projects/diffs/_file.html.haml b/app/views/projects/diffs/_file.html.haml
index 5ec95c3095d..3db1467df60 100644
--- a/app/views/projects/diffs/_file.html.haml
+++ b/app/views/projects/diffs/_file.html.haml
@@ -18,9 +18,7 @@
#js-diff-stats{ data: diff_file_stats_data(diff_file) }
- if diff_file.blob&.readable_text?
- unless @diff_notes_disabled
- %span.has-tooltip{ title: _("Toggle comments for this file") }
- = link_to '#', class: 'js-toggle-diff-comments btn gl-button btn-default btn-icon selected' do
- = sprite_icon('comment')
+ = link_button_to nil, '#', class: 'js-toggle-diff-comments has-tooltip', icon: 'comment', title: _("Toggle comments for this file")
\
- if editable_diff?(diff_file)
- link_opts = @merge_request.persisted? ? { from_merge_request_iid: @merge_request.iid } : {}
diff --git a/app/views/projects/edit.html.haml b/app/views/projects/edit.html.haml
index a5224db1be9..98e8c2dd61b 100644
--- a/app/views/projects/edit.html.haml
+++ b/app/views/projects/edit.html.haml
@@ -7,12 +7,10 @@
= render_if_exists 'shared/ultimate_feature_removal_banner', project: @project
-- if Feature.enabled?(:show_pages_in_deployments_menu, current_user, type: :experiment)
- = render Pajamas::AlertComponent.new(variant: :info,
- title: _('GitLab Pages has moved'),
- alert_options: { class: 'gl-my-5', data: { feature_id: Users::CalloutsHelper::PAGES_MOVED_CALLOUT, dismiss_endpoint: callouts_path, defer_links: 'true' } }) do |c|
- - c.with_body do
- = _('To go to GitLab Pages, on the left sidebar, select %{pages_link}.').html_safe % {pages_link: link_to('Deployments > Pages', project_pages_path(@project)).html_safe}
+= render Pajamas::AlertComponent.new(title: _('GitLab Pages has moved'),
+ alert_options: { class: 'gl-my-5', data: { feature_id: Users::CalloutsHelper::PAGES_MOVED_CALLOUT, dismiss_endpoint: callouts_path, defer_links: 'true' } }) do |c|
+ - c.with_body do
+ = _('To go to GitLab Pages, on the left sidebar, select %{pages_link}.').html_safe % {pages_link: link_to('Deploy > Pages', project_pages_path(@project)).html_safe}
%section.settings.general-settings.no-animate.expanded#js-general-settings
.settings-header
@@ -79,8 +77,8 @@
%p
= _('Runs a number of housekeeping tasks within the current repository, such as compressing file revisions and removing unreachable objects.')
= link_to _('Learn more.'), help_page_path('administration/housekeeping'), target: '_blank', rel: 'noopener noreferrer'
- = link_to _('Run housekeeping'), housekeeping_project_path(@project),
- method: :post, class: "btn gl-button btn-default"
+ = render Pajamas::ButtonComponent.new(method: :post, href: housekeeping_project_path(@project)) do
+ = _('Run housekeeping')
.gl-display-inline-flex
#js-project-prune-unreachable-objects-button{ data: { prune_objects_path: housekeeping_project_path(@project, prune: true), prune_objects_doc_path: help_page_path('administration/housekeeping', anchor: 'prune-unreachable-objects') } }
diff --git a/app/views/projects/environments/edit.html.haml b/app/views/projects/environments/edit.html.haml
index c7752a45c63..1c107784e08 100644
--- a/app/views/projects/environments/edit.html.haml
+++ b/app/views/projects/environments/edit.html.haml
@@ -2,7 +2,7 @@
- add_page_specific_style 'page_bundles/environments'
#js-edit-environment{ data: { project_environments_path: project_environments_path(@project),
- update_environment_path: project_environment_path(@project, @environment),
protected_environment_settings_path: (project_settings_ci_cd_path(@project, anchor: 'js-protected-environments-settings') if @project.licensed_feature_available?(:protected_environments)),
project_path: @project.full_path,
- environment: environment_data(@environment) } }
+ environment_name: @environment.name,
+ kas_tunnel_url: ::Gitlab::Kas.tunnel_url } }
diff --git a/app/views/projects/environments/empty_metrics.html.haml b/app/views/projects/environments/empty_metrics.html.haml
deleted file mode 100644
index df05909e8ef..00000000000
--- a/app/views/projects/environments/empty_metrics.html.haml
+++ /dev/null
@@ -1,14 +0,0 @@
-- page_title _("Metrics")
-
-.row.empty-state
- .col-sm-12
- .svg-content
- = image_tag 'illustrations/operations_metrics_empty.svg'
- .col-12
- .text-content
- %h4.text-center
- = s_('Environments|No deployed environments')
- %p.state-description
- = s_('Metrics|Check out the CI/CD documentation on deploying to an environment')
- .text-center
- = link_to s_("Environments|Learn about environments"), help_page_path('ci/environments/index.md'), class: 'gl-button btn btn-confirm'
diff --git a/app/views/projects/environments/metrics.html.haml b/app/views/projects/environments/metrics.html.haml
deleted file mode 100644
index 31041d124e4..00000000000
--- a/app/views/projects/environments/metrics.html.haml
+++ /dev/null
@@ -1,6 +0,0 @@
-- add_page_specific_style 'page_bundles/prometheus'
-
-- page_title _("Metrics Dashboard"), @environment.name
-
-.prometheus-container
- #prometheus-graphs{ data: metrics_data(@project, @environment) }
diff --git a/app/views/projects/environments/new.html.haml b/app/views/projects/environments/new.html.haml
index 9e8484b88b9..301c19ee6f0 100644
--- a/app/views/projects/environments/new.html.haml
+++ b/app/views/projects/environments/new.html.haml
@@ -3,4 +3,4 @@
- page_title s_("Environments|New Environment")
- add_page_specific_style 'page_bundles/environments'
-#js-new-environment{ data: { project_environments_path: project_environments_path(@project), project_path: @project.full_path, } }
+#js-new-environment{ data: { project_environments_path: project_environments_path(@project), project_path: @project.full_path, kas_tunnel_url: ::Gitlab::Kas.tunnel_url } }
diff --git a/app/views/projects/environments/terminal.html.haml b/app/views/projects/environments/terminal.html.haml
index 7c837d4ded0..c2ad9191800 100644
--- a/app/views/projects/environments/terminal.html.haml
+++ b/app/views/projects/environments/terminal.html.haml
@@ -13,8 +13,7 @@
.col-sm-6
.nav-controls
- if @environment.external_url.present?
- = link_to @environment.external_url, class: 'gl-button btn btn-default', target: '_blank', rel: 'noopener noreferrer nofollow' do
- = sprite_icon('external-link')
+ = link_button_to nil, @environment.external_url, target: '_blank', rel: 'noopener noreferrer nofollow', icon: 'external-link'
= render 'projects/deployments/actions', deployment: @environment.last_deployment
.terminal-container{ class: container_class }
diff --git a/app/views/projects/find_file/show.html.haml b/app/views/projects/find_file/show.html.haml
index afb49c48146..7e93e44c463 100644
--- a/app/views/projects/find_file/show.html.haml
+++ b/app/views/projects/find_file/show.html.haml
@@ -2,11 +2,11 @@
- add_page_specific_style 'page_bundles/tree'
.file-finder-holder.tree-holder.clearfix.js-file-finder{ 'data-file-find-url': "#{escape_javascript(project_files_path(@project, @ref, format: :json))}", 'data-find-tree-url': escape_javascript(project_tree_path(@project, @ref)), 'data-blob-url-template': escape_javascript(project_blob_path(@project, @ref)) }
- .nav-block
- .tree-ref-holder
+ .nav-block.gl-xs-mr-0
+ .tree-ref-holder.gl-xs-mb-3.gl-xs-w-full
#js-blob-ref-switcher{ data: { project_id: @project.id, ref: @ref, namespace: "/-/find_file" } }
- %ul.breadcrumb.repo-breadcrumb
- %li.breadcrumb-item
+ %ul.breadcrumb.repo-breadcrumb.gl-flex-nowrap
+ %li.breadcrumb-item.gl-white-space-nowrap
= link_to project_tree_path(@project, @ref) do
= @project.path
%li.file-finder.breadcrumb-item
diff --git a/app/views/projects/forks/error.html.haml b/app/views/projects/forks/error.html.haml
index cff5899b960..f589c8f9566 100644
--- a/app/views/projects/forks/error.html.haml
+++ b/app/views/projects/forks/error.html.haml
@@ -18,4 +18,4 @@
= error
- c.with_actions do
- = link_to _('Try to fork again'), new_project_fork_path(@project), title: _("Fork"), class: "btn gl-alert-action btn-info btn-md gl-button"
+ = link_button_to _('Try to fork again'), new_project_fork_path(@project), title: _("Fork"), class: 'gl-alert-action', variant: :confirm
diff --git a/app/views/projects/forks/index.html.haml b/app/views/projects/forks/index.html.haml
index d28ee30b6f9..49047749b71 100644
--- a/app/views/projects/forks/index.html.haml
+++ b/app/views/projects/forks/index.html.haml
@@ -20,12 +20,10 @@
- if current_user && can?(current_user, :fork_project, @project)
- if current_user.already_forked?(@project) && current_user.forkable_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 gl-md-ml-3' do
- = sprite_icon('fork', size: 12)
- %span= _('Fork')
+ = link_button_to namespace_project_path(current_user, current_user.fork_of(@project)), title: _('Go to your fork'), class: 'gl-md-ml-3', variant: :confirm, icon: 'fork' do
+ = _('Fork')
- else
- = 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')
+ = link_button_to new_project_fork_path(@project), title: _("Fork project"), class: 'gl-md-ml-3 gl-mt-3 gl-md-mt-0', variant: :confirm, icon: 'fork' do
+ = _('Fork')
= render 'projects', projects: @forks
diff --git a/app/views/projects/hook_logs/show.html.haml b/app/views/projects/hook_logs/show.html.haml
index 0f4dc4b5e32..30084e3310b 100644
--- a/app/views/projects/hook_logs/show.html.haml
+++ b/app/views/projects/hook_logs/show.html.haml
@@ -9,6 +9,6 @@
- if @hook_log.oversize?
= button_tag _("Resend Request"), class: "btn gl-button btn-default float-right gl-ml-3 has-tooltip", disabled: true, title: _("Request data is too large")
- else
- = link_to _("Resend Request"), @hook_log.present.retry_path, method: :post, class: "btn gl-button btn-default float-right gl-ml-3"
+ = link_button_to _("Resend Request"), @hook_log.present.retry_path, method: :post, class: 'float-right gl-ml-3'
= render partial: 'shared/hook_logs/content', locals: { hook_log: @hook_log }
diff --git a/app/views/projects/hooks/edit.html.haml b/app/views/projects/hooks/edit.html.haml
index b553249c4b8..26ec09c76db 100644
--- a/app/views/projects/hooks/edit.html.haml
+++ b/app/views/projects/hooks/edit.html.haml
@@ -3,17 +3,16 @@
= render 'shared/web_hooks/hook_errors', hook: @hook
-.row.gl-mt-3
- .col-lg-3
- = render 'shared/web_hooks/title_and_docs', hook: @hook
+.gl-mt-5
+ = render 'shared/web_hooks/title_and_docs', hook: @hook
- .col-lg-9.gl-mb-3
- = gitlab_ui_form_for [@project, @hook], as: :hook, url: project_hook_path(@project, @hook), html: { class: 'js-webhook-form' } do |f|
- = render partial: 'shared/web_hooks/form', locals: { form: f, hook: @hook }
+ = gitlab_ui_form_for [@project, @hook], as: :hook, url: project_hook_path(@project, @hook), html: { class: 'js-webhook-form' } do |f|
+ = render partial: 'shared/web_hooks/form', locals: { form: f, hook: @hook }
- = f.submit _('Save changes'), pajamas_button: true
+ %div
+ = f.submit _('Save changes'), pajamas_button: true, class: 'gl-sm-mr-3'
= render 'shared/web_hooks/test_button', hook: @hook
- = link_to _('Delete'), project_hook_path(@project, @hook), method: :delete, class: 'btn gl-button btn-danger float-right', aria: { label: s_('Webhooks|Delete webhook') }, data: { confirm: s_('Webhooks|Are you sure you want to delete this project hook?'), confirm_btn_variant: 'danger' }
+ = link_button_to _('Delete'), project_hook_path(@project, @hook), method: :delete, class: 'gl-float-right', aria: { label: s_('Webhooks|Delete webhook') }, data: { confirm: s_('Webhooks|Are you sure you want to delete this project hook?'), confirm_btn_variant: 'danger' }, variant: :danger
%hr
diff --git a/app/views/projects/hooks/index.html.haml b/app/views/projects/hooks/index.html.haml
index 4d71161c96e..b57adc0ef0d 100644
--- a/app/views/projects/hooks/index.html.haml
+++ b/app/views/projects/hooks/index.html.haml
@@ -2,13 +2,6 @@
- page_title _('Webhooks')
- @force_desktop_expanded_sidebar = true
-.row.gl-mt-3.js-search-settings-section
- .col-lg-4
- = render 'shared/web_hooks/title_and_docs', hook: @hook
-
- .col-lg-8.gl-mb-3
- = gitlab_ui_form_for @hook, as: :hook, url: polymorphic_path([@project, :hooks]), html: { class: 'js-webhook-form' } do |f|
- = render partial: 'shared/web_hooks/form', locals: { form: f, hook: @hook }
- = f.submit _('Add webhook'), pajamas_button: true, data: { qa_selector: "create_webhook_button" }
-
- = render 'shared/web_hooks/index', hooks: @hooks, hook_class: @hook.class
+.gl-mt-3.js-search-settings-section
+ = render 'shared/web_hooks/title_and_docs', hook: @hook
+ = render 'shared/web_hooks/index', hooks: @hooks, hook_class: @hook.class, partial: 'shared/web_hooks/form', url: polymorphic_path([@project, :hooks])
diff --git a/app/views/projects/integrations/shimos/show.html.haml b/app/views/projects/integrations/shimos/show.html.haml
index 92b9e03d5bd..e6cd8c15809 100644
--- a/app/views/projects/integrations/shimos/show.html.haml
+++ b/app/views/projects/integrations/shimos/show.html.haml
@@ -6,5 +6,5 @@
= 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
+ = link_button_to @project.shimo_integration.external_wiki_url, target: '_blank', rel: 'noopener noreferrer', title: s_('Shimo|Go to Shimo Workspace'), variant: :confirm do
= s_('Shimo|Go to Shimo Workspace')
diff --git a/app/views/projects/issues/_related_branches.html.haml b/app/views/projects/issues/_related_branches.html.haml
index 3d6a266dc4d..21f1a4d19fa 100644
--- a/app/views/projects/issues/_related_branches.html.haml
+++ b/app/views/projects/issues/_related_branches.html.haml
@@ -1,24 +1,25 @@
- if @related_branches.any?
- if @related_branches.any?
- = render Pajamas::CardComponent.new(card_options: { class: 'gl-bg-gray-10 gl-mt-5 gl-mb-0' }, header_options: { class: 'gl-bg-white gl-pl-5 gl-pr-4 gl-py-4' } , body_options: { class: 'gl-py-3 gl-px-4' }) do |c|
+ = render Pajamas::CardComponent.new(card_options: { class: 'gl-new-card' }, header_options: { class: 'gl-new-card-header' } , body_options: { class: 'gl-new-card-body' }) do |c|
- c.with_header do
- %h3.card-title.h5.gl-my-0.gl-display-flex.gl-align-items-center.gl-flex-grow-1.gl-relative.gl-line-height-24
- = link_to "", "#related-branches", class: "gl-link anchor position-absolute gl-text-decoration-none", "aria-hidden": true
- = _('Related branches')
- .gl-display-inline-flex.gl-mx-3.gl-text-gray-500
- .gl-display-inline-flex.gl-align-items-center
- = sprite_icon('branch', css_class: "gl-mr-2 gl-text-gray-500 gl-icon")
- = @related_branches.size
+ .gl-new-card-title-wrapper
+ %h3.gl-new-card-title
+ = link_to "", "#related-branches", class: "gl-link anchor position-absolute gl-text-decoration-none", "aria-hidden": true
+ = _('Related branches')
+ .gl-new-card-count
+ = sprite_icon('branch', css_class: "gl-mr-2 gl-text-gray-500 gl-icon")
+ = @related_branches.size
- c.with_body do
- %ul.related-merge-requests.content-list.gl-p-3!
- - @related_branches.each do |branch|
- %li.list-item{ class: "gl-py-0! gl-border-0!" }
- .item-body.gl-display-flex.align-items-center.gl-px-3.gl-pr-2.gl-mx-n2
- .item-contents.gl-display-flex.gl-align-items-center.gl-flex-wrap.gl-flex-grow-1.gl-min-h-7
- .item-title.gl-display-flex.mb-xl-0.gl-min-w-0
- - if branch[:pipeline_status].present?
- %span.related-branch-ci-status
- = render 'ci/status/icon', status: branch[:pipeline_status]
- %span.related-branch-info
- %strong
- = link_to branch[:name], branch[:link], class: "ref-name"
+ .gl-new-card-content
+ %ul.related-merge-requests.content-list
+ - @related_branches.each do |branch|
+ %li.list-item{ class: "gl-py-0! gl-border-0!" }
+ .item-body.gl-display-flex.align-items-center.gl-px-3.gl-pr-2.gl-mx-n2
+ .item-contents.gl-display-flex.gl-align-items-center.gl-flex-wrap.gl-flex-grow-1.gl-min-h-7
+ .item-title.gl-display-flex.mb-xl-0.gl-min-w-0
+ - if branch[:pipeline_status].present?
+ %span.related-branch-ci-status
+ = render 'ci/status/icon', status: branch[:pipeline_status]
+ %span.related-branch-info
+ %strong
+ = link_to branch[:name], branch[:link], class: "ref-name"
diff --git a/app/views/projects/issues/service_desk.html.haml b/app/views/projects/issues/service_desk.html.haml
index 3cc419716e5..9793f21e4a9 100644
--- a/app/views/projects/issues/service_desk.html.haml
+++ b/app/views/projects/issues/service_desk.html.haml
@@ -8,15 +8,26 @@
- support_bot_attrs = { service_desk_enabled: @project.service_desk_enabled?, **UserSerializer.new.represent(User.support_bot) }.to_json
.js-service-desk-issues.service-desk-issues{ data: { support_bot: support_bot_attrs } }
- .top-area
- = render 'shared/issuable/nav', type: :issues
- .nav-controls.d-block.d-sm-none
- = render "projects/issues/service_desk/nav_btns", show_feed_buttons: false, show_import_button: false, show_export_button: false
+ - if ::Feature.enabled?(:service_desk_vue_list, @project)
+ .js-service-desk-list{ data: { project_data: project_issues_list_data(@project, current_user),
+ service_desk_email_address: @project.service_desk_address,
+ can_admin_issues: can?(current_user, :admin_issue, @project).to_s,
+ can_edit_project_settings: can?(current_user, :admin_project, @project).to_s,
+ service_desk_callout_svg_path: image_path('service_desk_callout.svg'),
+ service_desk_settings_path: edit_project_path(@project, anchor: 'js-service-desk'),
+ service_desk_help_path: help_page_path('user/project/service_desk'),
+ is_service_desk_supported: Gitlab::ServiceDesk.supported?.to_s,
+ is_service_desk_enabled: @project.service_desk_enabled?.to_s } }
+ - else
+ .top-area
+ = render 'shared/issuable/nav', type: :issues
+ .nav-controls.gl-display-block.gl-sm-display-none
+ = render "projects/issues/service_desk/nav_btns", show_feed_buttons: false, show_import_button: false, show_export_button: false
- - if @issues.present?
- = render 'shared/issuable/search_bar', type: :issues
- - if Gitlab::ServiceDesk.supported?
- = render 'projects/issues/service_desk/service_desk_info_content'
+ - if @issues.present?
+ = render 'shared/issuable/search_bar', type: :issues
+ - if Gitlab::ServiceDesk.supported?
+ = render 'projects/issues/service_desk/service_desk_info_content'
- .issues-holder
- = render 'projects/issues/issues', empty_state_path: 'projects/issues/service_desk/service_desk_empty_state'
+ .issues-holder
+ = render 'projects/issues/issues', empty_state_path: 'projects/issues/service_desk/service_desk_empty_state'
diff --git a/app/views/projects/issues/service_desk/_issue.html.haml b/app/views/projects/issues/service_desk/_issue.html.haml
index 04ea6103b83..5b98712d3eb 100644
--- a/app/views/projects/issues/service_desk/_issue.html.haml
+++ b/app/views/projects/issues/service_desk/_issue.html.haml
@@ -33,7 +33,7 @@
%span.issuable-due-date.d-none.d-sm-inline-block.has-tooltip{ class: "#{'cred' if issue.overdue? && !issue.closed?}", title: _('Due date') }
&nbsp;
= sprite_icon('calendar')
- = issue.due_date.to_s(:medium)
+ = issue.due_date.to_fs(:medium)
= render_if_exists "projects/issues/issue_weight", issue: issue
= render_if_exists "projects/issues/health_status", issue: issue
diff --git a/app/views/projects/issues/service_desk/_nav_btns.html.haml b/app/views/projects/issues/service_desk/_nav_btns.html.haml
index a0a290f340a..3b7b3f57abd 100644
--- a/app/views/projects/issues/service_desk/_nav_btns.html.haml
+++ b/app/views/projects/issues/service_desk/_nav_btns.html.haml
@@ -7,12 +7,13 @@
.nav-controls.issues-nav-controls.gl-font-size-0
- if @can_bulk_update
- = button_tag _("Bulk edit"), class: "gl-button btn btn-default gl-mr-3 js-bulk-update-toggle"
+ = render Pajamas::ButtonComponent.new(button_options: { class: 'gl-mr-3 js-bulk-update-toggle' }) do
+ = _("Bulk edit")
- if show_new_issue_link?(@project)
- = link_to _("New issue"), new_project_issue_path(@project,
- issue: { milestone_id: finder.milestones.first.try(:id) }),
- class: "gl-button btn btn-confirm gl-mr-3",
- id: "new_issue_link"
+ = render Pajamas::ButtonComponent.new(variant: :confirm,
+ href: new_project_issue_path(@project, issue: { milestone_id: finder.milestones.first.try(:id) }),
+ button_options: { id: 'new_issue_link', class: 'gl-mr-3' }) do
+ = _("New issue")
.dropdown.gl-dropdown
= button_tag type: 'button', class: "btn dropdown-toggle btn-default btn-md gl-button gl-dropdown gl-dropdown-toggle btn-default-tertiary dropdown-icon-only dropdown-toggle-no-caret has-tooltip gl-display-none! gl-md-display-inline-flex!", data: { toggle: 'dropdown', title: _('Actions') } do
diff --git a/app/views/projects/issues/service_desk/_service_desk_empty_state.html.haml b/app/views/projects/issues/service_desk/_service_desk_empty_state.html.haml
index 855625368a9..831bd107961 100644
--- a/app/views/projects/issues/service_desk/_service_desk_empty_state.html.haml
+++ b/app/views/projects/issues/service_desk/_service_desk_empty_state.html.haml
@@ -21,7 +21,7 @@
- if can_edit_project_settings && !service_desk_enabled
.text-center
- = link_to s_("ServiceDesk|Enable Service Desk"), edit_project_path(@project), class: 'gl-button btn btn-confirm'
+ = link_button_to s_("ServiceDesk|Enable Service Desk"), edit_project_path(@project), variant: :confirm
- else
.empty-state
.svg-content
diff --git a/app/views/projects/issues/service_desk/_service_desk_info_content.html.haml b/app/views/projects/issues/service_desk/_service_desk_info_content.html.haml
index 95837748c7f..093a47e63be 100644
--- a/app/views/projects/issues/service_desk/_service_desk_info_content.html.haml
+++ b/app/views/projects/issues/service_desk/_service_desk_info_content.html.haml
@@ -21,4 +21,4 @@
- if can_edit_project_settings && !service_desk_enabled
.gl-mt-3
- = link_to s_("ServiceDesk|Enable Service Desk"), edit_project_path(@project), class: 'gl-button btn btn-confirm'
+ = link_button_to s_("ServiceDesk|Enable Service Desk"), edit_project_path(@project), variant: :confirm
diff --git a/app/views/projects/jobs/_table.html.haml b/app/views/projects/jobs/_table.html.haml
index 954c77a21f3..0bb512b4035 100644
--- a/app/views/projects/jobs/_table.html.haml
+++ b/app/views/projects/jobs/_table.html.haml
@@ -12,7 +12,7 @@
= s_('Jobs|Use jobs to automate your tasks')
%p
= s_('Jobs|Jobs are the building blocks of a GitLab CI/CD pipeline. Each job has a specific task, like testing code. To set up jobs in a CI/CD pipeline, add a CI/CD configuration file to your project.')
- = link_to s_('Jobs|Create CI/CD configuration file'), project_ci_pipeline_editor_path(project), class: 'btn gl-button btn-confirm js-empty-state-button'
+ = link_button_to s_('Jobs|Create CI/CD configuration file'), project_ci_pipeline_editor_path(project), class: 'js-empty-state-button', variant: :confirm
- else
.nothing-here-block= s_('Jobs|No jobs to show')
- else
diff --git a/app/views/projects/jobs/show.html.haml b/app/views/projects/jobs/show.html.haml
index 5f249f693ff..b151c355b3e 100644
--- a/app/views/projects/jobs/show.html.haml
+++ b/app/views/projects/jobs/show.html.haml
@@ -7,4 +7,4 @@
= render_if_exists "shared/shared_runners_minutes_limit_flash_message"
-#js-job-page{ data: jobs_data }
+#js-job-page{ data: jobs_data(@project, @build) }
diff --git a/app/views/projects/labels/index.html.haml b/app/views/projects/labels/index.html.haml
index 7a4ae409ee2..e1c904d000f 100644
--- a/app/views/projects/labels/index.html.haml
+++ b/app/views/projects/labels/index.html.haml
@@ -16,12 +16,13 @@
.labels-container
-# Only show it in the first page
- hide = @available_labels.empty? || (params[:page].present? && params[:page] != '1')
- .prioritized-labels.gl-rounded-base.gl-border.gl-bg-gray-10.gl-mt-4{ class: [('hide' if hide), ('is-not-draggable' unless can_admin_label)] }
- .gl-px-5.gl-py-4.gl-bg-white.gl-rounded-top-base.gl-border-b
- %h3.card-title.h5.gl-m-0.gl-relative.gl-line-height-24
- = _('Prioritized labels')
- .gl-font-sm.gl-font-weight-semibold.gl-text-gray-500
- = _('Drag to reorder prioritized labels and change their relative priority.')
+ .prioritized-labels.gl-new-card{ class: [('hide' if hide), ('is-not-draggable' unless can_admin_label)] }
+ .gl-new-card-header
+ .gl-new-card-title-wrapper.gl-flex-direction-column
+ %h3.gl-new-card-title
+ = _('Prioritized labels')
+ .gl-new-card-description
+ = _('Drag to reorder prioritized labels and change their relative priority.')
.js-prioritized-labels.gl-px-3.gl-rounded-base.manage-labels-list{ data: { url: set_priorities_project_labels_path(@project), sortable: can_admin_label } }
#js-priority-labels-empty-state.priority-labels-empty-state{ class: "#{'hidden' unless @prioritized_labels.empty? && search.blank?}" }
= render 'shared/empty_states/priority_labels'
@@ -32,12 +33,14 @@
= _('No prioritized labels with such name or description')
- if @labels.any?
- .other-labels.gl-rounded-base.gl-border.gl-bg-gray-10.gl-mt-4
- .gl-px-5.gl-py-4.gl-bg-white.gl-rounded-top-base.gl-border-b
- %h3.card-title.h5.gl-m-0.gl-relative.gl-line-height-24{ class: ('hide' if hide) }= _('Other labels')
- .js-other-labels.gl-px-3.gl-rounded-base.manage-labels-list
- = render partial: 'shared/label', collection: @labels, as: :label, locals: { subject: @project }
- = paginate @labels, theme: 'gitlab'
+ .other-labels.gl-new-card
+ .gl-new-card-header
+ .gl-new-card-title-wrapper
+ %h3.gl-new-card-title{ class: ('hide' if hide) }= _('Other labels')
+ .gl-new-card-body
+ .js-other-labels.manage-labels-list.gl-new-card-content
+ = render partial: 'shared/label', collection: @labels, as: :label, locals: { subject: @project }
+ = paginate @labels, theme: 'gitlab'
- elsif search.present?
.other-labels
diff --git a/app/views/projects/mattermosts/_no_teams.html.haml b/app/views/projects/mattermosts/_no_teams.html.haml
index 5886c0565b1..c53e805fae1 100644
--- a/app/views/projects/mattermosts/_no_teams.html.haml
+++ b/app/views/projects/mattermosts/_no_teams.html.haml
@@ -9,4 +9,4 @@
and try again.
%hr
.clearfix
- = link_to 'Go back', edit_project_settings_integration_path(@project, @integration), class: 'gl-button btn btn-lg float-right'
+ = link_button_to 'Go back', edit_project_settings_integration_path(@project, @integration), class: 'float-right'
diff --git a/app/views/projects/merge_requests/_close_reopen_draft_report_toggle.html.haml b/app/views/projects/merge_requests/_close_reopen_draft_report_toggle.html.haml
index a3536ead240..ab841d4f1b2 100644
--- a/app/views/projects/merge_requests/_close_reopen_draft_report_toggle.html.haml
+++ b/app/views/projects/merge_requests/_close_reopen_draft_report_toggle.html.haml
@@ -1,6 +1,7 @@
.js-mr-more-dropdown{ data: {
merge_request: @merge_request.to_json,
project_path: @project.full_path,
+ url: merge_request_url(@merge_request),
edit_url: edit_project_merge_request_path(@project, @merge_request),
is_current_user: issuable_author_is_current_user(@merge_request),
is_logged_in: current_user,
@@ -11,5 +12,4 @@
clipboard_text: @merge_request.to_reference(full: true),
report_abuse_path: add_category_abuse_reports_path,
reported_user_id: @merge_request.author.id,
- reported_from_url: merge_request_url(@merge_request),
} }
diff --git a/app/views/projects/merge_requests/_form.html.haml b/app/views/projects/merge_requests/_form.html.haml
index 5f1c72156eb..6d2e2cfcc54 100644
--- a/app/views/projects/merge_requests/_form.html.haml
+++ b/app/views/projects/merge_requests/_form.html.haml
@@ -1,3 +1,4 @@
= gitlab_ui_form_for [@project, @merge_request],
html: { class: 'merge-request-form common-note-form js-requires-input js-quick-submit' } do |f|
+ = render 'source_and_target', mr: @merge_request
= render 'shared/issuable/form', f: f, issuable: @merge_request, presenter: @mr_presenter
diff --git a/app/views/projects/merge_requests/_mr_box.html.haml b/app/views/projects/merge_requests/_mr_box.html.haml
index 6f662b81dd7..1774401ed78 100644
--- a/app/views/projects/merge_requests/_mr_box.html.haml
+++ b/app/views/projects/merge_requests/_mr_box.html.haml
@@ -1,3 +1,3 @@
-.detail-page-description.gl-pt-2.gl-pb-4.gl-display-flex.gl-align-items-center.gl-flex-wrap{ class: "#{'is-merge-request' if moved_mr_sidebar_enabled? && !fluid_layout}" }
+.detail-page-description.gl-pt-2.gl-pb-4.gl-display-flex.gl-align-items-baseline.gl-flex-wrap{ class: "#{'is-merge-request' if moved_mr_sidebar_enabled? && !fluid_layout}" }
= render 'shared/issuable/status_box', issuable: @merge_request
= merge_request_header(@project, @merge_request)
diff --git a/app/views/projects/merge_requests/_source_and_target.html.haml b/app/views/projects/merge_requests/_source_and_target.html.haml
new file mode 100644
index 00000000000..68cd4fe9372
--- /dev/null
+++ b/app/views/projects/merge_requests/_source_and_target.html.haml
@@ -0,0 +1,10 @@
+%span{
+ id: "js-merge-request-metadata",
+ class: ["js-merge-request-metadata", "gl-display-none"],
+ data: {
+ "source-project-id": mr.source_project_id,
+ "source-branch": mr.source_branch,
+ "target-project-id": mr.target_project_id,
+ "target-branch": mr.target_branch
+ }
+}
diff --git a/app/views/projects/merge_requests/_widget.html.haml b/app/views/projects/merge_requests/_widget.html.haml
index 576fed58609..606d4e06d33 100644
--- a/app/views/projects/merge_requests/_widget.html.haml
+++ b/app/views/projects/merge_requests/_widget.html.haml
@@ -23,4 +23,9 @@
window.gl.mrWidgetData.user_preferences_gitpod_path = '#{profile_preferences_path(anchor: 'user_gitpod_enabled')}';
window.gl.mrWidgetData.user_profile_enable_gitpod_path = '#{profile_path(user: { gitpod_enabled: true })}';
-#js-vue-mr-widget.mr-widget
+%h2#merge-request-widgets-heading.gl-sr-only
+ = _("Merge request reports")
+#js-vue-mr-widget.mr-widget{
+ role: 'region',
+ 'aria-labelledby': 'merge-request-widgets-heading'
+}
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 bec7cb3fd34..a7151421acb 100644
--- a/app/views/projects/merge_requests/creations/_new_submit.html.haml
+++ b/app/views/projects/merge_requests/creations/_new_submit.html.haml
@@ -1,6 +1,7 @@
%h1.page-title.gl-font-size-h-display
= _('New merge request')
= gitlab_ui_form_for [@project, @merge_request], html: { class: 'merge-request-form common-note-form js-requires-input js-quick-submit' } do |f|
+ = render "projects/merge_requests/source_and_target", mr: @merge_request
= render 'shared/issuable/form', f: f, issuable: @merge_request, commits: @commits, presenter: @mr_presenter
= f.hidden_field :source_project_id
= f.hidden_field :source_branch
diff --git a/app/views/projects/milestones/_form.html.haml b/app/views/projects/milestones/_form.html.haml
index be6f9ac83dc..a592062a17d 100644
--- a/app/views/projects/milestones/_form.html.haml
+++ b/app/views/projects/milestones/_form.html.haml
@@ -12,13 +12,16 @@
= render 'shared/milestones/form_dates', f: f
.form-group
= f.label :description, _('Description')
- = render layout: 'shared/md_preview', locals: { url: preview_markdown_path(@project) } do
- = render 'shared/zen', f: f, attr: :description,
- classes: 'note-textarea',
- qa_selector: 'milestone_description_field',
- supports_autocomplete: true,
- placeholder: _('Write milestone description...')
- = render 'shared/notes/hints'
+ - @gfm_form = true
+ .js-markdown-editor{ data: { render_markdown_path: preview_markdown_path(@project),
+ markdown_docs_path: help_page_path('user/markdown'),
+ qa_selector: 'milestone_description_field',
+ form_field_placeholder: _('Write milestone description...'),
+ supports_quick_actions: 'false',
+ enable_autocomplete: 'true',
+ autofocus: 'false',
+ form_field_classes: 'note-textarea js-gfm-input markdown-area' } }
+ = f.hidden_field :description
.clearfix
.error-alert
@@ -26,7 +29,7 @@
- if @milestone.new_record?
= f.submit _('Create milestone'), data: { qa_selector: 'create_milestone_button' }, class: 'gl-mr-2', pajamas_button: true
- = link_to _('Cancel'), project_milestones_path(@project), class: 'gl-button btn btn-default btn-cancel'
+ = link_button_to _('Cancel'), project_milestones_path(@project)
- else
= f.submit _('Save changes'), class: 'gl-mr-2', pajamas_button: true
- = link_to _('Cancel'), project_milestone_path(@project, @milestone), class: 'gl-button btn btn-default btn-cancel'
+ = link_button_to _('Cancel'), project_milestone_path(@project, @milestone)
diff --git a/app/views/projects/milestones/index.html.haml b/app/views/projects/milestones/index.html.haml
index 326a7c4027f..a7a21ef0440 100644
--- a/app/views/projects/milestones/index.html.haml
+++ b/app/views/projects/milestones/index.html.haml
@@ -9,14 +9,14 @@
= render 'shared/milestones/search_form'
= render 'shared/milestones_sort_dropdown'
- if can?(current_user, :admin_milestone, @project)
- = link_to new_project_milestone_path(@project), class: 'gl-button btn btn-confirm gl-ml-3', data: { qa_selector: "new_project_milestone_link" }, title: _('New milestone') do
+ = link_button_to new_project_milestone_path(@project), class: 'gl-ml-3', data: { qa_selector: "new_project_milestone_link" }, title: _('New milestone'), variant: :confirm do
= _('New milestone')
- if @milestones.blank?
= render 'shared/empty_states/milestones_tab' do
- if can?(current_user, :admin_milestone, @project)
.text-center
- = link_to new_project_milestone_path(@project), class: 'gl-button btn btn-confirm', data: { qa_selector: "new_project_milestone_link" }, title: _('New milestone') do
+ = link_button_to new_project_milestone_path(@project), data: { qa_selector: "new_project_milestone_link" }, title: _('New milestone'), variant: :confirm do
= _('New milestone')
- else
@@ -32,5 +32,5 @@
= render 'shared/empty_states/milestones' do
- if can?(current_user, :admin_milestone, @project)
.text-center
- = link_to new_project_milestone_path(@project), class: 'gl-button btn btn-confirm', data: { qa_selector: "new_project_milestone_link" }, title: _('New milestone') do
+ = link_button_to new_project_milestone_path(@project), data: { qa_selector: "new_project_milestone_link" }, title: _('New milestone'), variant: :confirm do
= _('New milestone')
diff --git a/app/views/projects/ml/models/index.html.haml b/app/views/projects/ml/models/index.html.haml
new file mode 100644
index 00000000000..2caba2ae9be
--- /dev/null
+++ b/app/views/projects/ml/models/index.html.haml
@@ -0,0 +1,5 @@
+- breadcrumb_title s_('ModelRegistry|Model registry')
+- page_title s_('ModelRegistry|Model registry')
+- presenter = ::Ml::ModelsIndexPresenter.new(@models)
+
+#js-index-ml-models{ data: { view_model: presenter.present } }
diff --git a/app/views/projects/no_repo.html.haml b/app/views/projects/no_repo.html.haml
index e3f46d601a3..3abec75b971 100644
--- a/app/views/projects/no_repo.html.haml
+++ b/app/views/projects/no_repo.html.haml
@@ -13,14 +13,14 @@
%hr
.no-repo-actions
- = link_to project_repository_path(@project), method: :post, class: 'btn gl-button btn-confirm' do
- #{ _('Create empty repository') }
+ = link_button_to project_repository_path(@project), method: :post, variant: :confirm do
+ = _('Create empty repository')
%strong.gl-ml-3.gl-mr-3 or
- = link_to new_project_import_path(@project), class: 'btn gl-button btn-default' do
- #{ _('Import repository') }
+ = link_button_to new_project_import_path(@project) do
+ = _('Import repository')
- if can? current_user, :remove_project, @project
.prepend-top-20
- = link_to _('Delete project'), project_path(@project), data: { confirm: remove_project_message(@project), confirm_btn_variant: 'danger' }, aria: { label: _('Delete project') }, method: :delete, class: "btn gl-button btn-danger float-right"
+ = link_button_to _('Delete project'), project_path(@project), data: { confirm: remove_project_message(@project), confirm_btn_variant: 'danger' }, aria: { label: _('Delete project') }, method: :delete, class: 'float-right', variant: :danger
diff --git a/app/views/projects/packages/packages/index.html.haml b/app/views/projects/packages/packages/index.html.haml
index 48aaf0884c8..5397828d48e 100644
--- a/app/views/projects/packages/packages/index.html.haml
+++ b/app/views/projects/packages/packages/index.html.haml
@@ -10,4 +10,5 @@
npm_instance_url: package_registry_instance_url(:npm),
project_list_url: project_packages_path(@project),
settings_path: show_package_registry_settings(@project) ? project_settings_packages_and_registries_path(@project) : '',
+ can_delete_packages: can_delete_packages?(@project).to_s,
group_list_url: '' } }
diff --git a/app/views/projects/pages/_access.html.haml b/app/views/projects/pages/_access.html.haml
index 50e48187be3..6eab31075d4 100644
--- a/app/views/projects/pages/_access.html.haml
+++ b/app/views/projects/pages/_access.html.haml
@@ -1,5 +1,5 @@
- if @project.pages_deployed?
- - pages_url = @project.pages_url(with_unique_domain: true)
+ - pages_url = build_pages_url(@project, with_unique_domain: true)
= render Pajamas::CardComponent.new(card_options: { class: 'gl-mb-5', data: { qa_selector: 'access_page_container' } }, footer_options: { class: 'gl-alert-warning' }) do |c|
- c.with_header do
diff --git a/app/views/projects/pages/_list.html.haml b/app/views/projects/pages/_list.html.haml
index 57371aa49f6..38e15d02a39 100644
--- a/app/views/projects/pages/_list.html.haml
+++ b/app/views/projects/pages/_list.html.haml
@@ -26,8 +26,8 @@
- if domain.expired?
= gl_badge_tag s_('GitLabPages|Expired'), variant: :danger
%div
- = link_to s_('GitLabPages|Edit'), project_pages_domain_path(@project, domain), class: "btn gl-button btn-sm btn-grouped btn-confirm btn-inverted"
- = link_to s_('GitLabPages|Remove'), project_pages_domain_path(@project, domain), data: { confirm: s_('GitLabPages|Are you sure?'), 'confirm-btn-variant': 'danger'}, "aria-label": s_("GitLabPages|Remove domain"), method: :delete, class: "btn gl-button btn-danger btn-sm btn-grouped"
+ = link_button_to s_('GitLabPages|Edit'), project_pages_domain_path(@project, domain), class: 'btn-grouped', variant: :confirm, category: :secondary, size: :small
+ = link_button_to s_('GitLabPages|Remove'), project_pages_domain_path(@project, domain), data: { confirm: s_('GitLabPages|Are you sure?'), 'confirm-btn-variant': 'danger'}, "aria-label": s_("GitLabPages|Remove domain"), method: :delete, class: 'btn-grouped', variant: :danger, size: :small
- if domain.needs_verification?
%li.list-group-item.bs-callout-warning
- details_link_start = "<a href='#{project_pages_domain_path(@project, domain)}'>".html_safe
diff --git a/app/views/projects/pages/new.html.haml b/app/views/projects/pages/new.html.haml
index b9d2af9cf19..89f8f62ea83 100644
--- a/app/views/projects/pages/new.html.haml
+++ b/app/views/projects/pages/new.html.haml
@@ -1,9 +1,5 @@
-- if Feature.enabled?(:show_pages_in_deployments_menu, current_user, type: :experiment)
- - @breadcrumb_link = project_pages_path(@project)
- - breadcrumb_title s_('GitLabPages|Pages')
- - page_title s_('GitLabPages|Pages')
-- else
- %section.js-search-settings-section
+- @breadcrumb_link = project_pages_path(@project)
+- page_title s_('GitLabPages|Pages')
- if Feature.enabled?(:use_pipeline_wizard_for_pages, @project.group)
#js-pages{ data: @pipeline_wizard_data }
diff --git a/app/views/projects/pages/show.html.haml b/app/views/projects/pages/show.html.haml
index 01477967394..698ce404be8 100644
--- a/app/views/projects/pages/show.html.haml
+++ b/app/views/projects/pages/show.html.haml
@@ -1,4 +1,4 @@
-- page_title _('Pages')
+- page_title s_('GitLabPages|Pages')
- unless @project.pages_deployed?
= render 'waiting'
@@ -11,7 +11,7 @@
= render 'pages_settings'
%hr.clearfix
- = render 'ssl_limitations_warning' if @project.pages_subdomain.include?(".")
+ = render 'ssl_limitations_warning' if pages_subdomain(@project).include?(".")
= render 'access'
- if Gitlab.config.pages.external_http || Gitlab.config.pages.external_https
= render 'list'
diff --git a/app/views/projects/pages_domains/_dns.html.haml b/app/views/projects/pages_domains/_dns.html.haml
index 3e6a92d8bc0..0edce28bb9d 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} ALIAS #{domain_presenter.project.pages_subdomain}.#{Settings.pages.host}."
+- dns_record = "#{domain_presenter.domain} ALIAS #{pages_subdomain(domain_presenter.project)}.#{Settings.pages.host}."
.form-group.border-section
.row
@@ -21,11 +21,11 @@
.gl-mb-3
- text, status = domain_presenter.unverified? ? [_('Unverified'), :danger] : [_('Verified'), :success]
= gl_badge_tag text, variant: status
- = link_to sprite_icon("redo"), verify_project_pages_domain_path(@project, domain_presenter), method: :post, class: "gl-ml-2 gl-button btn btn-sm btn-default has-tooltip", title: _("Retry verification")
+ = link_button_to sprite_icon("redo"), verify_project_pages_domain_path(@project, domain_presenter), method: :post, class: 'gl-ml-2 has-tooltip', title: _("Retry verification"), size: :small
.input-group
= text_field_tag :domain_verification, domain_presenter.verification_record, class: "monospace js-select-on-focus form-control", readonly: true
.input-group-append
= clipboard_button(target: '#domain_verification', class: 'btn-default d-none d-sm-block')
%p.form-text.text-muted
- link_to_help = link_to(_('verify ownership'), help_page_path('user/project/pages/custom_domains_ssl_tls_certification/index.md', anchor: '4-verify-the-domains-ownership'))
- = _("To %{link_to_help} of your domain, add the above key to a TXT record within your DNS configuration.").html_safe % { link_to_help: link_to_help }
+ = _("To %{link_to_help} of your domain, add the above key to a TXT record within your DNS configuration within seven days.").html_safe % { link_to_help: link_to_help }
diff --git a/app/views/projects/pages_domains/_lets_encrypt_callout.html.haml b/app/views/projects/pages_domains/_lets_encrypt_callout.html.haml
index d6c213571f2..68b6884c4f5 100644
--- a/app/views/projects/pages_domains/_lets_encrypt_callout.html.haml
+++ b/app/views/projects/pages_domains/_lets_encrypt_callout.html.haml
@@ -9,7 +9,7 @@
= sprite_icon('warning-solid', css_class: ' mr-2 gl-text-orange-600')
= _("Something went wrong while obtaining the Let's Encrypt certificate.")
.row.mx-0.mt-3
- = link_to s_('GitLabPagesDomains|Retry'), retry_auto_ssl_project_pages_domain_path(@project, domain_presenter), class: "gl-button btn btn-default btn-sm btn-grouped", method: :post
+ = link_button_to s_('GitLabPagesDomains|Retry'), retry_auto_ssl_project_pages_domain_path(@project, domain_presenter), class: 'btn-grouped', method: :post, size: :small
- elsif !domain_presenter.certificate_gitlab_provided?
.form-group.border-section.js-shown-if-auto-ssl{ class: ("d-none" unless auto_ssl_available_and_enabled) }
.row
diff --git a/app/views/projects/pages_domains/new.html.haml b/app/views/projects/pages_domains/new.html.haml
index c88255e23f9..c58209f8806 100644
--- a/app/views/projects/pages_domains/new.html.haml
+++ b/app/views/projects/pages_domains/new.html.haml
@@ -8,4 +8,4 @@
= render 'form', { f: f }
.form-actions.gl-display-flex
= f.submit _('Create New Domain'), class: 'gl-mr-3', pajamas_button: true
- = link_to _('Cancel'), project_pages_path(@project), class: 'gl-button btn btn-default btn-cancel'
+ = link_button_to _('Cancel'), project_pages_path(@project)
diff --git a/app/views/projects/pages_domains/show.html.haml b/app/views/projects/pages_domains/show.html.haml
index b8de364babc..d34650d3f5a 100644
--- a/app/views/projects/pages_domains/show.html.haml
+++ b/app/views/projects/pages_domains/show.html.haml
@@ -10,4 +10,4 @@
= render 'form', { f: f }
.form-actions.gl-display-flex
= f.submit _('Save Changes'), class: 'gl-mr-3', pajamas_button: true
- = link_to _('Cancel'), project_pages_path(@project), class: 'gl-button btn btn-default btn-inverse'
+ = link_button_to _('Cancel'), project_pages_path(@project)
diff --git a/app/views/projects/pipeline_schedules/_form.html.haml b/app/views/projects/pipeline_schedules/_form.html.haml
index 235b89b8c5b..df85963218d 100644
--- a/app/views/projects/pipeline_schedules/_form.html.haml
+++ b/app/views/projects/pipeline_schedules/_form.html.haml
@@ -40,4 +40,4 @@
= f.gitlab_ui_checkbox_component :active, _('Active'), checkbox_options: { value: @schedule.active, required: false }
.footer-block
= f.submit _('Save pipeline schedule'), pajamas_button: true
- = link_to _('Cancel'), pipeline_schedules_path(@project), class: 'btn gl-button btn-default btn-cancel'
+ = link_button_to _('Cancel'), pipeline_schedules_path(@project)
diff --git a/app/views/projects/pipeline_schedules/_pipeline_schedule.html.haml b/app/views/projects/pipeline_schedules/_pipeline_schedule.html.haml
index 37b2b3ecfde..a050808f13c 100644
--- a/app/views/projects/pipeline_schedules/_pipeline_schedule.html.haml
+++ b/app/views/projects/pipeline_schedules/_pipeline_schedule.html.haml
@@ -35,14 +35,11 @@
%td{ role: 'cell', data: { label: _('Actions') } }
.float-right.btn-group
- if can?(current_user, :play_pipeline_schedule, pipeline_schedule)
- = link_to play_pipeline_schedule_path(pipeline_schedule), method: :post, title: _('Play'), class: 'btn gl-button btn-default btn-icon' do
- = sprite_icon('play')
+ = link_button_to nil, play_pipeline_schedule_path(pipeline_schedule), method: :post, title: _('Play'), icon: 'play'
- if can?(current_user, :admin_pipeline_schedule, pipeline_schedule) && pipeline_schedule.owner != current_user
= render Pajamas::ButtonComponent.new(button_options: { class: 'js-take-ownership-button has-tooltip', title: s_('PipelineSchedule|Take ownership to edit'), data: { url: take_ownership_pipeline_schedule_path(pipeline_schedule) } }) do
= s_('PipelineSchedules|Take ownership')
- if can?(current_user, :update_pipeline_schedule, pipeline_schedule)
- = link_to edit_pipeline_schedule_path(pipeline_schedule), title: _('Edit'), class: 'btn gl-button btn-default btn-icon' do
- = sprite_icon('pencil')
+ = link_button_to nil, edit_pipeline_schedule_path(pipeline_schedule), title: _('Edit'), icon: 'pencil'
- if can?(current_user, :admin_pipeline_schedule, pipeline_schedule)
- = link_to pipeline_schedule_path(pipeline_schedule), title: _('Delete'), method: :delete, class: 'btn gl-button btn-danger btn-icon', aria: { label: _('Delete pipeline schedule') }, data: { confirm: _("Are you sure you want to delete this pipeline schedule?"), confirm_btn_variant: 'danger' } do
- = sprite_icon('remove')
+ = link_button_to nil, pipeline_schedule_path(pipeline_schedule), title: _('Delete'), method: :delete, aria: { label: _('Delete pipeline schedule') }, data: { confirm: _("Are you sure you want to delete this pipeline schedule?"), confirm_btn_variant: 'danger' }, variant: :danger, icon: 'remove'
diff --git a/app/views/projects/pipeline_schedules/edit.html.haml b/app/views/projects/pipeline_schedules/edit.html.haml
index 3f843ce6aec..4e1ae53a101 100644
--- a/app/views/projects/pipeline_schedules/edit.html.haml
+++ b/app/views/projects/pipeline_schedules/edit.html.haml
@@ -5,9 +5,8 @@
%h1.page-title.gl-font-size-h-display
= _("Edit Pipeline Schedule")
-%hr
- if Feature.enabled?(:pipeline_schedules_vue, @project)
- #pipeline-schedules-form-edit{ data: { full_path: @project.full_path } }
+ #pipeline-schedules-form-edit{ data: js_pipeline_schedules_form_data(@project, @schedule) }
- else
= render "form"
diff --git a/app/views/projects/pipeline_schedules/index.html.haml b/app/views/projects/pipeline_schedules/index.html.haml
index ab86d505f0f..88a60b1fb06 100644
--- a/app/views/projects/pipeline_schedules/index.html.haml
+++ b/app/views/projects/pipeline_schedules/index.html.haml
@@ -6,7 +6,7 @@
#pipeline-schedules-callout{ data: { docs_url: help_page_path('ci/pipelines/schedules'), illustration_url: image_path('illustrations/pipeline_schedule_callout.svg') } }
- if Feature.enabled?(:pipeline_schedules_vue, @project)
- #pipeline-schedules-app{ data: { full_path: @project.full_path, pipelines_path: project_pipelines_path(@project) } }
+ #pipeline-schedules-app{ data: { full_path: @project.full_path, pipelines_path: project_pipelines_path(@project), new_schedule_path: new_project_pipeline_schedule_path(@project) } }
- else
.top-area
- schedule_path_proc = ->(scope) { pipeline_schedules_path(@project, scope: scope) }
@@ -14,8 +14,8 @@
- if can?(current_user, :create_pipeline_schedule, @project)
.nav-controls
- = link_to new_project_pipeline_schedule_path(@project), class: 'btn gl-button btn-confirm' do
- %span= _('New schedule')
+ = link_button_to new_project_pipeline_schedule_path(@project), variant: :confirm do
+ = _('New schedule')
- if @schedules.present?
%ul.content-list
diff --git a/app/views/projects/pipeline_schedules/new.html.haml b/app/views/projects/pipeline_schedules/new.html.haml
index 2d4ed5a9872..ef99a79b06f 100644
--- a/app/views/projects/pipeline_schedules/new.html.haml
+++ b/app/views/projects/pipeline_schedules/new.html.haml
@@ -9,6 +9,6 @@
= _("Schedule a new pipeline")
- if Feature.enabled?(:pipeline_schedules_vue, @project)
- #pipeline-schedules-form-new{ data: { full_path: @project.full_path, cron: @schedule.cron, daily_limit: @schedule.daily_limit, timezone_data: timezone_data.to_json, cron_timezone: @schedule.cron_timezone, project_id: @project.id, default_branch: @project.default_branch, settings_link: project_settings_ci_cd_path(@project), } }
+ #pipeline-schedules-form-new{ data: js_pipeline_schedules_form_data(@project, @schedule) }
- else
= render "form"
diff --git a/app/views/projects/pipelines/_info.html.haml b/app/views/projects/pipelines/_info.html.haml
deleted file mode 100644
index 753bb77e755..00000000000
--- a/app/views/projects/pipelines/_info.html.haml
+++ /dev/null
@@ -1,75 +0,0 @@
-- if @pipeline.name
- .gl-border-t.gl-p-5.gl-px-0
- %h3.gl-m-0.gl-text-body
- = @pipeline.name
-- else
- .commit-box
- %h3.commit-title
- = markdown(commit.title, pipeline: :single_line)
- - if commit.description.present?
- %pre.commit-description<
- = preserve(markdown(commit.description, pipeline: :single_line))
-
-.info-well
- .well-segment.pipeline-info{ class: "gl-align-items-baseline! gl-flex-direction-column" }
- %div
- .icon-container
- = sprite_icon('clock', css_class: 'gl-top-0!')
- = n_('%d job', '%d jobs', @pipeline.total_size) % @pipeline.total_size
- = @pipeline.ref_text_legacy
- - if @pipeline.finished_at
- - duration = time_interval_in_words(@pipeline.duration)
- - queued_duration = time_interval_in_words(@pipeline.queued_duration)
- %span.gl-pl-7{ 'data-testid': 'pipeline-stats-text' }
- = render_if_exists 'projects/pipelines/pipeline_stats_text', duration: duration, pipeline: @pipeline, queued_duration: queued_duration
-
- - if has_pipeline_badges?(@pipeline)
- .well-segment
- .icon-container
- = sprite_icon('flag', css_class: 'gl-top-0!')
- - if @pipeline.schedule?
- = gl_badge_tag _('Scheduled'), { variant: :info, size: :sm }, { class: 'js-pipeline-url-scheduled', title: _('This pipeline was triggered by a schedule.') }
- - if @pipeline.child?
- - text = sprintf(s_('Pipelines|Child pipeline (%{link_start}parent%{link_end})'), { link_start: "<a href='#{pipeline_path(@pipeline.triggered_by_pipeline)}' class='text-underline'>", link_end: "</a>"}).html_safe
- = gl_badge_tag text, { variant: :info, size: :sm }, { class: 'js-pipeline-child has-tooltip', title: s_("Pipelines|This is a child pipeline within the parent pipeline") }
- - if @pipeline.latest?
- = gl_badge_tag s_('Pipelines|latest'), { variant: :success, size: :sm }, { class: 'js-pipeline-url-latest has-tooltip', title: _("Latest pipeline for the most recent commit on this branch") }
- - if @pipeline.merge_train_pipeline?
- = gl_badge_tag s_('Pipelines|merge train'), { variant: :info, size: :sm }, { class: 'js-pipeline-url-train has-tooltip', title: s_("Pipelines|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch.") }
- - if @pipeline.has_yaml_errors?
- = gl_badge_tag s_('Pipelines|yaml invalid'), { variant: :danger, size: :sm }, { class: 'js-pipeline-url-yaml has-tooltip', title: @pipeline.yaml_errors }
- - if @pipeline.failure_reason?
- = gl_badge_tag s_('Pipelines|error'), { variant: :danger, size: :sm }, { class: 'js-pipeline-url-failure has-tooltip', title: @pipeline.failure_reason }
- - if @pipeline.auto_devops_source?
- - popover_title_text = html_escape(_('This pipeline makes use of a predefined CI/CD configuration enabled by %{b_open}Auto DevOps.%{b_close}')) % { b_open: '<b>'.html_safe, b_close: '</b>'.html_safe }
- - popover_content_url = help_page_path('topics/autodevops/index.md')
- - popover_content_text = _('Learn more about Auto DevOps')
- = gl_badge_tag s_('Pipelines|Auto DevOps'), { variant: :info, size: :sm }, { class: 'js-pipeline-url-autodevops', href: "#", tabindex: "0", role: "button", data: { container: 'body', toggle: 'popover', placement: 'top', html: 'true', triggers: 'focus', title: "<div class='gl-font-weight-normal gl-line-height-normal'>#{popover_title_text}</div>", content: "<a href='#{popover_content_url}' target='_blank' rel='noopener noreferrer nofollow'>#{popover_content_text}</a>" } }
- - if @pipeline.detached_merge_request_pipeline?
- = gl_badge_tag s_('Pipelines|merge request'), { variant: :info, size: :sm }, { class: 'js-pipeline-url-mergerequest has-tooltip', data: { qa_selector: 'merge_request_badge_tag' }, title: s_("Pipelines|This pipeline ran on the contents of this merge request's source branch, not the target branch.") }
- - if @pipeline.stuck?
- = gl_badge_tag s_('Pipelines|stuck'), { variant: :warning, size: :sm }, { class: 'js-pipeline-url-stuck has-tooltip' }
-
- .well-segment{ 'data-testid': 'commit-row' }
- .icon-container.commit-icon
- = sprite_icon('commit', css_class: 'gl-top-0!')
- - if @pipeline.name
- = markdown(commit.title, pipeline: :single_line)
- = clipboard_button(text: @pipeline.sha, title: _("Copy commit SHA"))
- = link_to commit.short_id, project_commit_path(@project, @pipeline.sha), class: "commit-sha"
- - else
- = link_to commit.short_id, project_commit_path(@project, @pipeline.sha), class: "commit-sha"
- = clipboard_button(text: @pipeline.sha, title: _("Copy commit SHA"))
-
- .well-segment.related-merge-request-info
- .icon-container
- = sprite_icon("git-merge", css_class: 'gl-top-0!')
- %span.related-merge-requests
- %span.js-truncated-mr-list
- = @pipeline.all_related_merge_request_text(limit: 1)
- - if @pipeline.has_many_merge_requests?
- = link_to("#", class: "js-toggle-mr-list") do
- %span.text-expander
- = sprite_icon('ellipsis_h', size: 12)
- %span.js-full-mr-list.hide
- = @pipeline.all_related_merge_request_text
diff --git a/app/views/projects/pipelines/show.html.haml b/app/views/projects/pipelines/show.html.haml
index 46e1cd07a17..bdf09e5356f 100644
--- a/app/views/projects/pipelines/show.html.haml
+++ b/app/views/projects/pipelines/show.html.haml
@@ -9,16 +9,10 @@
- add_page_startup_graphql_call('pipelines/get_pipeline_details', { projectPath: @project.full_path, iid: @pipeline.iid })
.js-pipeline-container{ data: { controller_action: "#{controller.action_name}" } }
- - if Feature.enabled?(:pipeline_details_header_vue, @project)
- #js-pipeline-details-header-vue{ data: js_pipeline_details_header_data(@project, @pipeline) }
- - else
- #js-pipeline-header-vue.pipeline-header-container{ data: { full_path: @project.full_path, graphql_resource_etag: graphql_etag_pipeline_path(@pipeline), pipeline_iid: @pipeline.iid, pipeline_id: @pipeline.id, pipelines_path: project_pipelines_path(@project) } }
+ #js-pipeline-details-header-vue{ data: js_pipeline_details_header_data(@project, @pipeline) }
= render_if_exists 'projects/pipelines/cc_validation_required_alert', pipeline: @pipeline
- - if @pipeline.commit.present? && !Feature.enabled?(:pipeline_details_header_vue, @project)
- = render "projects/pipelines/info", commit: @pipeline.commit
-
- if pipeline_has_errors
= render Pajamas::AlertComponent.new(title: s_('Pipelines|Unable to create pipeline'),
variant: :danger,
diff --git a/app/views/projects/project_templates/_template.html.haml b/app/views/projects/project_templates/_template.html.haml
index 9dde86f77b4..93c53fc99fc 100644
--- a/app/views/projects/project_templates/_template.html.haml
+++ b/app/views/projects/project_templates/_template.html.haml
@@ -8,7 +8,7 @@
.text-muted
= template.description
.controls.d-flex.align-items-center
- %a.btn.gl-button.btn-default.gl-mr-3{ href: template.preview, rel: 'noopener noreferrer', target: '_blank', data: { track_label: "template_preview", track_property: template.name, track_action: "click_button", track_value: "" } }
+ = render Pajamas::ButtonComponent.new(button_options: { class: 'gl-mr-3', data: { track_label: "template_preview", track_property: template.name, track_action: "click_button", track_value: "" }, rel: 'noopener noreferrer' }, href: template.preview, target: '_blank') do
= _("Preview")
%label.btn.gl-button.btn-confirm.template-button.choose-template.gl-mb-0{ for: template.name,
'data-testid': "use_template_#{template.name}" }
diff --git a/app/views/projects/protected_tags/shared/_index.html.haml b/app/views/projects/protected_tags/shared/_index.html.haml
index 11e09d843e0..a016ccf8656 100644
--- a/app/views/projects/protected_tags/shared/_index.html.haml
+++ b/app/views/projects/protected_tags/shared/_index.html.haml
@@ -8,7 +8,7 @@
= expanded ? _('Collapse') : _('Expand')
%p
= s_("ProtectedTag|Limit access to creating and updating tags.")
- = link_to s_("ProtectedTag|What are protected tags?"), help_page_path("user/project/protected_tags")
+ = link_to s_("ProtectedTag|What are protected tags?"), help_page_path("user/project/protected_tags")
.settings-content
%p
= s_("ProtectedTag|By default, protected tags restrict who can modify the tag.")
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 ed5b5b17942..4fe1c8bd3cb 100644
--- a/app/views/projects/protected_tags/shared/_protected_tag.html.haml
+++ b/app/views/projects/protected_tags/shared/_protected_tag.html.haml
@@ -19,4 +19,4 @@
- if can? current_user, :admin_project, @project
%td
- = link_to 'Unprotect', [@project, protected_tag, { update_section: 'js-protected-tags-settings' }], aria: { label: s_('ProtectedTags|Unprotect tag') }, data: { confirm: 'Tag will be writable for developers. Are you sure?', confirm_btn_variant: 'danger' }, method: :delete, class: 'gl-button btn btn-danger-secondary'
+ = link_button_to 'Unprotect', [@project, protected_tag, { update_section: 'js-protected-tags-settings' }], aria: { label: s_('ProtectedTags|Unprotect tag') }, data: { confirm: 'Tag will be writable for developers. Are you sure?', confirm_btn_variant: 'danger' }, method: :delete, variant: :danger, category: :secondary
diff --git a/app/views/projects/runners/_group_runners.html.haml b/app/views/projects/runners/_group_runners.html.haml
index d71bcd12e64..32a2e36c779 100644
--- a/app/views/projects/runners/_group_runners.html.haml
+++ b/app/views/projects/runners/_group_runners.html.haml
@@ -13,10 +13,10 @@
%br
%br
- if @project.group_runners_enabled?
- = link_to toggle_group_runners_project_runners_path(@project), class: 'btn gl-button btn-default', method: :post do
+ = link_button_to toggle_group_runners_project_runners_path(@project), method: :post do
= _('Disable group runners')
- else
- = link_to toggle_group_runners_project_runners_path(@project), class: 'btn gl-button btn-confirm-secondary', method: :post do
+ = link_button_to toggle_group_runners_project_runners_path(@project), method: :post, variant: :confirm, category: :secondary do
= _('Enable group runners')
&nbsp;
= _('for this project')
diff --git a/app/views/projects/runners/_project_runners.html.haml b/app/views/projects/runners/_project_runners.html.haml
index af8f39ce0ad..0f2f0c3f21c 100644
--- a/app/views/projects/runners/_project_runners.html.haml
+++ b/app/views/projects/runners/_project_runners.html.haml
@@ -3,26 +3,14 @@
.bs-callout.help-callout
%p= s_('Runners|These runners are assigned to this project.')
- - if Feature.enabled?(:create_runner_workflow_for_namespace, @project.namespace)
- - if can?(current_user, :create_runner, @project)
- = render Pajamas::ButtonComponent.new(href: new_project_runner_path(@project), variant: :confirm) do
- = s_('Runners|New project runner')
- .gl-display-inline
- #js-project-runner-registration-dropdown{ data: { registration_token: @project.runners_token, project_id: @project.id } }
- - else
- = _('Please contact an admin to create runners.')
- = link_to _('Learn more.'), help_page_path('user/admin_area/settings/continuous_integration', anchor: 'restrict-runner-registration-by-all-users-in-an-instance'), target: '_blank', rel: 'noopener noreferrer'
+ - if can?(current_user, :create_runner, @project)
+ = render Pajamas::ButtonComponent.new(href: new_project_runner_path(@project), variant: :confirm) do
+ = s_('Runners|New project runner')
+ .gl-display-inline
+ #js-project-runner-registration-dropdown{ data: { registration_token: @project.runners_token, project_id: @project.id } }
- else
- - if can?(current_user, :register_project_runners, @project)
- = render partial: 'ci/runner/how_to_setup_runner',
- locals: { registration_token: @project.runners_token,
- type: _('project'),
- reset_token_url: reset_registration_token_namespace_project_settings_ci_cd_path,
- project_path: @project.path_with_namespace,
- group_path: '' }
- - else
- = _('Please contact an admin to register runners.')
- = link_to _('Learn more.'), help_page_path('user/admin_area/settings/continuous_integration', anchor: 'restrict-runner-registration-by-all-users-in-an-instance'), target: '_blank', rel: 'noopener noreferrer'
+ = _('Please contact an admin to create runners.')
+ = link_to _('Learn more.'), help_page_path('administration/settings/continuous_integration', anchor: 'restrict-runner-registration-by-all-users-in-an-instance'), target: '_blank', rel: 'noopener noreferrer'
%hr
diff --git a/app/views/projects/runners/_runner.html.haml b/app/views/projects/runners/_runner.html.haml
index e517b37aae9..12432cd3484 100644
--- a/app/views/projects/runners/_runner.html.haml
+++ b/app/views/projects/runners/_runner.html.haml
@@ -13,19 +13,16 @@
.gl-ml-2
.btn-group.btn-group-sm
- if @project_runners.include?(runner)
- = link_to edit_project_runner_path(@project, runner), class: 'btn gl-button btn-icon', title: _('Edit'), aria: { label: _('Edit') }, data: { testid: 'edit-runner-link', toggle: 'tooltip', placement: 'top', container: 'body' } do
- = sprite_icon('pencil')
+ = link_button_to nil, edit_project_runner_path(@project, runner), title: _('Edit'), aria: { label: _('Edit') }, data: { testid: 'edit-runner-link', toggle: 'tooltip', placement: 'top', container: 'body' }, icon: 'pencil'
- if runner.active?
- = link_to pause_project_runner_path(@project, runner), method: :post, class: 'btn gl-button btn-icon', title: s_('Runners|Pause from accepting jobs'), aria: { label: _('Pause') }, data: { toggle: 'tooltip', container: 'body', confirm: _("Are you sure?") } do
- = sprite_icon('pause')
+ = link_button_to nil, pause_project_runner_path(@project, runner), method: :post, title: s_('Runners|Pause from accepting jobs'), aria: { label: _('Pause') }, data: { toggle: 'tooltip', container: 'body', confirm: _("Are you sure?") }, icon: 'pause'
- else
- = link_to resume_project_runner_path(@project, runner), method: :post, class: 'btn gl-button btn-icon', title: s_('Runners|Resume accepting jobs'), aria: { label: _('Resume') }, data: { toggle: 'tooltip', container: 'body' } do
- = sprite_icon('play')
+ = link_button_to nil, resume_project_runner_path(@project, runner), method: :post, title: s_('Runners|Resume accepting jobs'), aria: { label: _('Resume') }, data: { toggle: 'tooltip', container: 'body' }, icon: 'play'
- if runner.belongs_to_one_project?
- = link_to _('Remove runner'), project_runner_path(@project, runner), aria: { label: _('Remove') }, data: { confirm: _("Are you sure?"), 'confirm-btn-variant': 'danger' }, method: :delete, class: 'btn gl-button btn-danger'
+ = link_button_to _('Remove runner'), project_runner_path(@project, runner), aria: { label: _('Remove') }, data: { confirm: _("Are you sure?"), 'confirm-btn-variant': 'danger' }, method: :delete, variant: :danger
- else
- runner_project = @project.runner_projects.find_by(runner_id: runner) # rubocop: disable CodeReuse/ActiveRecord
- = link_to _('Disable for this project'), project_runner_project_path(@project, runner_project), aria: { label: _('Disable') }, data: { confirm: _("Are you sure?"), 'confirm-btn-variant': 'danger' }, method: :delete, class: 'btn gl-button btn-danger'
+ = link_button_to _('Disable for this project'), project_runner_project_path(@project, runner_project), aria: { label: _('Disable') }, data: { confirm: _("Are you sure?"), 'confirm-btn-variant': 'danger' }, method: :delete, variant: :danger
- elsif runner.project_type?
= form_for [@project, @project.runner_projects.new] do |f|
= f.hidden_field :runner_id, value: runner.id
diff --git a/app/views/projects/settings/_archive.html.haml b/app/views/projects/settings/_archive.html.haml
index 70e14eadaf9..05685c26ac5 100644
--- a/app/views/projects/settings/_archive.html.haml
+++ b/app/views/projects/settings/_archive.html.haml
@@ -9,14 +9,10 @@
- if @project.archived?
- link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: help_page_path('user/project/settings/index', anchor: 'unarchive-a-project') }
%p= _("Unarchiving the project restores its members' ability to make commits, and create issues, comments, and other entities. %{strong_start}After you unarchive the project, it displays in the search and on the dashboard.%{strong_end} %{link_start}Learn more.%{link_end}").html_safe % { strong_start: '<strong>'.html_safe, strong_end: '</strong>'.html_safe, link_start: link_start, link_end: '</a>'.html_safe }
- = link_to _('Unarchive project'), unarchive_project_path(@project),
- aria: { label: _('Unarchive project') },
- data: { confirm: _("Are you sure that you want to unarchive this project?"), qa_selector: 'unarchive_project_link' },
- method: :post, class: "gl-button btn btn-confirm"
+ = render Pajamas::ButtonComponent.new(method: :post, href: unarchive_project_path(@project), variant: :confirm, button_options: { aria: { label: _('Unarchive project') }, data: { confirm: _("Are you sure that you want to unarchive this project?"), qa_selector: 'unarchive_project_link' } }) do
+ = _('Unarchive project')
- else
- link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: help_page_path('user/project/settings/index', anchor: 'archive-a-project') }
%p= _("Archiving the project makes it entirely read-only. It is hidden from the dashboard and doesn't display in searches. %{strong_start}The repository cannot be committed to, and no issues, comments, or other entities can be created.%{strong_end} %{link_start}Learn more.%{link_end}").html_safe % { strong_start: '<strong>'.html_safe, strong_end: '</strong>'.html_safe, link_start: link_start, link_end: '</a>'.html_safe }
- = link_to _('Archive project'), archive_project_path(@project),
- aria: { label: _('Archive project') },
- data: { confirm: _("Are you sure that you want to archive this project?"), qa_selector: 'archive_project_link', 'confirm-btn-variant': 'confirm' },
- method: :post, class: "gl-button btn btn-confirm"
+ = render Pajamas::ButtonComponent.new(method: :post, href: archive_project_path(@project), variant: :confirm, button_options: { aria: { label: _('Archive project') }, data: { confirm: _("Are you sure that you want to archive this project?"), qa_selector: 'archive_project_link', 'confirm-btn-variant': 'confirm' } }) do
+ = _('Archive project')
diff --git a/app/views/projects/settings/_general.html.haml b/app/views/projects/settings/_general.html.haml
index 847f9ad3e2a..f5c275827fc 100644
--- a/app/views/projects/settings/_general.html.haml
+++ b/app/views/projects/settings/_general.html.haml
@@ -35,6 +35,6 @@
= render 'shared/choose_avatar_button', f: f
- if @project.avatar?
%hr
- = link_to _('Remove avatar'), project_avatar_path(@project), aria: { label: _('Remove avatar') }, data: { confirm: _('Avatar will be removed. Are you sure?'), 'confirm-btn-variant': 'danger' }, method: :delete, class: 'gl-button btn btn-danger-secondary'
+ = link_button_to _('Remove avatar'), project_avatar_path(@project), aria: { label: _('Remove avatar') }, data: { confirm: _('Avatar will be removed. Are you sure?'), 'confirm-btn-variant': 'danger' }, method: :delete, variant: :danger, category: :secondary
= f.submit _('Save changes'), pajamas_button: true, class: "gl-mt-6", data: { qa_selector: 'save_naming_topics_avatar_button' }
diff --git a/app/views/projects/settings/access_tokens/index.html.haml b/app/views/projects/settings/access_tokens/index.html.haml
index df517b5d642..e4af6d59cad 100644
--- a/app/views/projects/settings/access_tokens/index.html.haml
+++ b/app/views/projects/settings/access_tokens/index.html.haml
@@ -4,31 +4,28 @@
- type_plural = _('project access tokens')
- @force_desktop_expanded_sidebar = true
-.row.gl-mt-3.js-search-settings-section
- .col-lg-4
- %h4.gl-mt-0
- = page_title
- %p
- - link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: help_page_path('user/project/settings/project_access_tokens') }
+.gl-mt-5.js-search-settings-section
+ %h4.gl-my-0
+ = page_title
+ %p.gl-text-secondary
+ - help_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: help_page_path('user/project/settings/project_access_tokens') }
- if current_user.can?(:create_resource_access_tokens, @project)
= _('Generate project access tokens scoped to this project for your applications that need access to the GitLab API.')
- %p
- = _('You can also use project access tokens with Git to authenticate over HTTP(S). %{link_start}Learn more.%{link_end}').html_safe % { link_start: link_start, link_end: '</a>'.html_safe }
+ = _('You can also use project access tokens with Git to authenticate over HTTP(S). %{link_start}Learn more.%{link_end}').html_safe % { link_start: help_link_start, link_end: '</a>'.html_safe }
- else
- = _('Project access token creation is disabled in this group. You can still use and manage existing tokens. %{link_start}Learn more.%{link_end}').html_safe % { link_start: link_start, link_end: '</a>'.html_safe }
- %p
+ = _('Project access token creation is disabled in this group.')
- root_group = @project.group.root_ancestor
- if current_user.can?(:admin_group, root_group)
- group_settings_link = edit_group_path(root_group)
- link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: group_settings_link }
= _('You can enable project access token creation in %{link_start}group settings%{link_end}.').html_safe % { link_start: link_start, link_end: '</a>'.html_safe }
+ = html_escape(_('You can still use and manage existing tokens. %{link_start}Learn more.%{link_end}')) % { link_start: help_link_start, link_end: '</a>'.html_safe }
- .col-lg-8
- #js-new-access-token-app{ data: { access_token_type: type } }
+ #js-new-access-token-app{ data: { access_token_type: type } }
- - if current_user.can?(:create_resource_access_tokens, @project)
- = render_if_exists 'projects/settings/access_tokens/form',
- type: type
+ - if current_user.can?(:create_resource_access_tokens, @project)
+ = render_if_exists 'projects/settings/access_tokens/form',
+ type: type
- #js-access-token-table-app{ data: { access_token_type: type, access_token_type_plural: type_plural, initial_active_access_tokens: @active_access_tokens.to_json, no_active_tokens_message: _('This project has no active access tokens.'), show_role: true
+ #js-access-token-table-app{ data: { access_token_type: type, access_token_type_plural: type_plural, initial_active_access_tokens: @active_access_tokens.to_json, no_active_tokens_message: _('This project has no active access tokens.'), show_role: true
} }
diff --git a/app/views/projects/settings/ci_cd/_form.html.haml b/app/views/projects/settings/ci_cd/_form.html.haml
index 6f64d3f3f76..6eccbd245af 100644
--- a/app/views/projects/settings/ci_cd/_form.html.haml
+++ b/app/views/projects/settings/ci_cd/_form.html.haml
@@ -75,7 +75,7 @@
= f.number_field :max_artifacts_size, class: 'form-control gl-form-input'
%p.form-text.text-muted
= _("The maximum file size in megabytes for individual job artifacts.")
- = link_to sprite_icon('question-o'), help_page_path('user/admin_area/settings/continuous_integration', anchor: 'maximum-artifacts-size'), target: '_blank', rel: 'noopener noreferrer'
+ = link_to sprite_icon('question-o'), help_page_path('administration/settings/continuous_integration', anchor: 'maximum-artifacts-size'), target: '_blank', rel: 'noopener noreferrer'
= f.submit _('Save changes'), pajamas_button: true
diff --git a/app/views/projects/settings/ci_cd/show.html.haml b/app/views/projects/settings/ci_cd/show.html.haml
index c7bb6a7f5da..007169809c9 100644
--- a/app/views/projects/settings/ci_cd/show.html.haml
+++ b/app/views/projects/settings/ci_cd/show.html.haml
@@ -33,12 +33,13 @@
= render_if_exists 'projects/settings/ci_cd/protected_environments', expanded: expanded
-%section.settings.no-animate#js-runners-settings{ class: ('expanded' if expanded || params[:expand_runners]), data: { qa_selector: 'runners_settings_content' } }
+- expand_runners = expanded || params[:expand_runners]
+%section.settings.no-animate#js-runners-settings{ class: ('expanded' if expand_runners), data: { qa_selector: 'runners_settings_content' } }
.settings-header
%h4.settings-title.js-settings-toggle.js-settings-toggle-trigger-only
= _("Runners")
= render Pajamas::ButtonComponent.new(button_options: { class: 'js-settings-toggle' }) do
- = expanded ? _('Collapse') : _('Expand')
+ = expand_runners ? _('Collapse') : _('Expand')
%p
= _("Runners are processes that pick up and execute CI/CD jobs for GitLab.")
= link_to s_('What is GitLab Runner?'), 'https://docs.gitlab.com/runner/', target: '_blank', rel: 'noopener noreferrer'
diff --git a/app/views/projects/settings/slacks/edit.html.haml b/app/views/projects/settings/slacks/edit.html.haml
index 867b90655e3..537ae767b1d 100644
--- a/app/views/projects/settings/slacks/edit.html.haml
+++ b/app/views/projects/settings/slacks/edit.html.haml
@@ -17,4 +17,4 @@
.footer-block.row-content-block
= form.submit _('Save changes'), pajamas_button: true
&nbsp;
- = link_to _('Cancel'), edit_project_settings_integration_path(@project, @service), class: 'btn gl-button btn-cancel'
+ = link_button_to _('Cancel'), edit_project_settings_integration_path(@project, @service)
diff --git a/app/views/projects/snippets/index.html.haml b/app/views/projects/snippets/index.html.haml
index 7c936c849d0..ae9a8307eb9 100644
--- a/app/views/projects/snippets/index.html.haml
+++ b/app/views/projects/snippets/index.html.haml
@@ -9,7 +9,7 @@
- if new_project_snippet_link.present?
.nav-controls
- = link_to _("New snippet"), new_project_snippet_link, class: "gl-button btn btn-confirm", title: _("New snippet")
+ = link_button_to _("New snippet"), new_project_snippet_link, title: _("New snippet"), variant: :confirm
= render 'shared/snippets/list'
- else
diff --git a/app/views/projects/tags/_edit_release_button.html.haml b/app/views/projects/tags/_edit_release_button.html.haml
index 9a6c18df2ca..42af8d4f59f 100644
--- a/app/views/projects/tags/_edit_release_button.html.haml
+++ b/app/views/projects/tags/_edit_release_button.html.haml
@@ -1,9 +1,8 @@
- release_btn_text = s_('TagsPage|Create release')
- release_btn_path = new_project_release_path(project, tag_name: tag.name)
- option_css_classes = local_assigns.fetch(:option_css_classes, '')
-- css_classes = "btn gl-button btn-default btn-icon btn-edit has-tooltip #{option_css_classes}"
- if release
- release_btn_text = s_('TagsPage|Edit release')
- release_btn_path = edit_project_release_path(project, release)
-= link_to release_btn_path, class: css_classes do
+= render Pajamas::ButtonComponent.new(href: release_btn_path, button_options: { class: option_css_classes }) do
= release_btn_text
diff --git a/app/views/projects/tags/index.html.haml b/app/views/projects/tags/index.html.haml
index fda797f3228..b0be748eb36 100644
--- a/app/views/projects/tags/index.html.haml
+++ b/app/views/projects/tags/index.html.haml
@@ -9,10 +9,9 @@
.nav-controls
#js-tags-sort-dropdown{ data: { filter_tags_path: filter_tags_path(search: @search, sort: @sort), sort_options: tags_sort_options_hash.to_json } }
- = link_to project_tags_path(@project, rss_url_options), title: _("Tags feed"), class: 'btn gl-button btn-default btn-icon has-tooltip gl-ml-auto' do
- = sprite_icon('rss', css_class: 'gl-icon')
+ = link_button_to nil, project_tags_path(@project, rss_url_options), title: _("Tags feed"), class: 'has-tooltip gl-ml-auto', icon: 'rss'
- if can?(current_user, :admin_tag, @project)
- = link_to new_project_tag_path(@project), class: 'btn gl-button btn-confirm', data: { qa_selector: "new_tag_button" } do
+ = link_button_to new_project_tag_path(@project), data: { qa_selector: "new_tag_button" }, variant: :confirm do
= s_('TagsPage|New tag')
= render_if_exists 'projects/commits/mirror_status'
diff --git a/app/views/projects/tags/show.html.haml b/app/views/projects/tags/show.html.haml
index 5127972c406..1649e56043e 100644
--- a/app/views/projects/tags/show.html.haml
+++ b/app/views/projects/tags/show.html.haml
@@ -45,10 +45,8 @@
= render partial: 'projects/commit/signature', object: @tag.signature
- if can?(current_user, :admin_tag, @project)
= render 'edit_release_button', tag: @tag, project: @project, release: @release
- = link_to project_tree_path(@project, @tag.name), class: 'btn btn-icon gl-button btn-default has-tooltip', title: s_('TagsPage|Browse files') do
- = sprite_icon('folder-open', css_class: 'gl-icon')
- = link_to project_commits_path(@project, @tag.name), class: 'btn btn-icon gl-button btn-default has-tooltip', title: s_('TagsPage|Browse commits') do
- = sprite_icon('history', css_class: 'gl-icon')
+ = link_button_to nil, project_tree_path(@project, @tag.name), class: 'has-tooltip', title: s_('TagsPage|Browse files'), icon: 'folder-open'
+ = link_button_to nil, project_commits_path(@project, @tag.name), class: 'has-tooltip', title: s_('TagsPage|Browse commits'), icon: 'history'
= render 'projects/buttons/download', project: @project, ref: @tag.name
- if can?(current_user, :admin_tag, @project)
= render 'projects/buttons/remove_tag', project: @project, tag: @tag
diff --git a/app/views/projects/tracing/index.html.haml b/app/views/projects/tracing/index.html.haml
new file mode 100644
index 00000000000..ae6608cf343
--- /dev/null
+++ b/app/views/projects/tracing/index.html.haml
@@ -0,0 +1,4 @@
+- page_title _('Tracing')
+
+#js-tracing{ data: { view_model: observability_tracing_view_model(@project) } }
+
diff --git a/app/views/protected_branches/shared/_protected_branch.html.haml b/app/views/protected_branches/shared/_protected_branch.html.haml
index c2a5dd8a9b0..69969b7f848 100644
--- a/app/views/protected_branches/shared/_protected_branch.html.haml
+++ b/app/views/protected_branches/shared/_protected_branch.html.haml
@@ -27,4 +27,4 @@
%span.has-tooltip{ data: { container: 'body' }, title: s_('ProtectedBranch|Inherited - This setting can be changed at the group level'), 'aria-hidden': 'true' }
= sprite_icon 'lock'
- else
- = link_to s_('ProtectedBranch|Unprotect'), [protected_branch_entity, protected_branch, { update_section: 'js-protected-branches-settings' }], disabled: local_assigns[:disabled], aria: { label: s_('ProtectedBranch|Unprotect branch') }, data: { confirm: s_('ProtectedBranch|Branch will be writable for developers. Are you sure?'), confirm_btn_variant: 'danger' }, method: :delete, class: "btn gl-button btn-danger btn-sm"
+ = link_button_to s_('ProtectedBranch|Unprotect'), [protected_branch_entity, protected_branch, { update_section: 'js-protected-branches-settings' }], disabled: local_assigns[:disabled], aria: { label: s_('ProtectedBranch|Unprotect branch') }, data: { confirm: s_('ProtectedBranch|Branch will be writable for developers. Are you sure?'), confirm_btn_variant: 'danger' }, method: :delete, variant: :danger, size: :small
diff --git a/app/views/registrations/welcome/show.html.haml b/app/views/registrations/welcome/show.html.haml
index 986bc53fd81..caaa209a702 100644
--- a/app/views/registrations/welcome/show.html.haml
+++ b/app/views/registrations/welcome/show.html.haml
@@ -8,6 +8,7 @@
= render "layouts/one_trust"
= render "layouts/bizible"
= render "layouts/google_tag_manager_body"
+
.row.gl-flex-grow-1
.d-flex.gl-flex-direction-column.gl-align-items-center.gl-w-full.gl-px-5.gl-pb-5
.edit-profile.login-page.d-flex.flex-column.gl-align-items-center
diff --git a/app/views/search/results/_issuable.html.haml b/app/views/search/results/_issuable.html.haml
index 188ead4008e..a896cbc5cba 100644
--- a/app/views/search/results/_issuable.html.haml
+++ b/app/views/search/results/_issuable.html.haml
@@ -1,4 +1,4 @@
-%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!' }
+%div{ class: 'search-result-row gl-display-flex gl-sm-flex-direction-row gl-flex-direction-column gl-align-items-center gl-pb-5! gl-mt-5 gl-mb-0!' }
.col-sm-9
%span.gl-display-flex.gl-align-items-center
= gl_badge_tag issuable_state_text(issuable), variant: issuable_state_to_badge_class(issuable), size: :sm
@@ -11,6 +11,11 @@
= sprintf(s_('created %{issuable_created} by %{author}'), { issuable_created: time_ago_with_tooltip(issuable.created_at, placement: 'bottom'), author: link_to_member(@project, issuable.author, avatar: false) }).html_safe
.description.term.gl-px-0
= highlight_and_truncate_issuable(issuable, @search_term, @search_highlight)
+ - if issuable.labels.any?
+ .gl-mt-3
+ - presented_labels_sorted_by_title(issuable.labels, issuable.project).each do |label|
+ = link_to_label(label, small: true)
+
.col-sm-3.gl-mt-3.gl-sm-mt-0.gl-text-right
- if issuable.respond_to?(:upvotes_count) && issuable.upvotes_count > 0
%li.gl-list-style-none
diff --git a/app/views/search/results/_wiki_blob.html.haml b/app/views/search/results/_wiki_blob.html.haml
index d6900c397a0..08d8ffcf250 100644
--- a/app/views/search/results/_wiki_blob.html.haml
+++ b/app/views/search/results/_wiki_blob.html.haml
@@ -1,9 +1,6 @@
-- project = wiki_blob.project
-- wiki_blob_link = project_wiki_path(project, wiki_blob.basename)
-
%div{ class: 'search-result-row gl-pb-3! gl-mt-5 gl-mb-0!' }
%span.gl-display-flex.gl-align-items-center
- = link_to wiki_blob_link, data: { track_action: 'click_text', track_label: "wiki_title", track_property: 'search_result' }, class: 'gl-w-full' do
+ = link_to wiki_blob_link(wiki_blob), data: { track_action: 'click_text', track_label: "wiki_title", track_property: 'search_result' }, class: 'gl-w-full' do
%span.term.str-truncated.gl-font-weight-bold= ::Wiki.canonicalize_filename(wiki_blob.path)
.description.term.col-sm-10.gl-px-0
= simple_search_highlight_and_truncate(wiki_blob.data, @search_term)
diff --git a/app/views/sent_notifications/unsubscribe.html.haml b/app/views/sent_notifications/unsubscribe.html.haml
index 03b030eb257..16e4ff4d17f 100644
--- a/app/views/sent_notifications/unsubscribe.html.haml
+++ b/app/views/sent_notifications/unsubscribe.html.haml
@@ -16,4 +16,4 @@
%p
= link_to _('Unsubscribe'), unsubscribe_sent_notification_path(@sent_notification, force: true),
class: 'gl-button btn btn-confirm gl-mr-3'
- = link_to _('Cancel'), new_user_session_path, class: 'gl-button btn gl-mr-3'
+ = link_button_to _('Cancel'), new_user_session_path, class: 'gl-mr-3'
diff --git a/app/views/shared/_auto_devops_implicitly_enabled_banner.html.haml b/app/views/shared/_auto_devops_implicitly_enabled_banner.html.haml
index f4af3ea70d4..79a9bafc4f0 100644
--- a/app/views/shared/_auto_devops_implicitly_enabled_banner.html.haml
+++ b/app/views/shared/_auto_devops_implicitly_enabled_banner.html.haml
@@ -8,5 +8,5 @@
%div
= _('Container registry is not enabled on this GitLab instance. Ask an administrator to enable it in order for Auto DevOps to work.')
- c.with_actions do
- = link_to _('Settings'), project_settings_ci_cd_path(project), class: 'alert-link btn gl-button btn-confirm'
- = link_to _('More information'), help_page_path('topics/autodevops/index.md'), target: '_blank', class: 'alert-link btn gl-button btn-default gl-ml-3'
+ = link_button_to _('Settings'), project_settings_ci_cd_path(project), class: 'alert-link', variant: :confirm
+ = link_button_to _('More information'), help_page_path('topics/autodevops/index.md'), target: '_blank', class: 'alert-link gl-ml-3'
diff --git a/app/views/shared/_md_preview.html.haml b/app/views/shared/_md_preview.html.haml
index dd3a31f5a59..1fd430527a1 100644
--- a/app/views/shared/_md_preview.html.haml
+++ b/app/views/shared/_md_preview.html.haml
@@ -1,4 +1,5 @@
- referenced_users = local_assigns.fetch(:referenced_users, nil)
+- supports_quick_actions = local_assigns.fetch(:supports_quick_actions, false)
- if @merge_request&.discussion_locked?
.issuable-note-warning
@@ -8,14 +9,14 @@
= _('Only project members can comment.')
.md-area.position-relative
- .md-header.gl-bg-gray-50.gl-px-2.gl-rounded-base.gl-mx-2.gl-mt-2
+ .md-header.gl-px-3.gl-rounded-top-base.gl-border-b.gl-border-gray-100
.gl-display-flex.gl-align-items-center.gl-flex-wrap.gl-justify-content-space-between
- .md-header-toolbar.gl-display-flex.gl-py-2.gl-flex-wrap
- = render 'shared/blob/markdown_buttons'
- .switch-preview.gl-py-2.gl-display-flex.gl-align-items-center.gl-ml-auto
+ .md-header-toolbar.gl-display-flex.gl-py-3.gl-flex-wrap.gl-row-gap-3
= render Pajamas::ButtonComponent.new(category: :tertiary, size: :small, button_options: { class: 'js-md-preview-button', value: 'preview' }) do
= _('Preview')
- = render Pajamas::ButtonComponent.new(icon: 'maximize', category: :tertiary, size: :small, button_options: { 'tabindex': -1, 'aria-label': _("Go full screen"), class: 'has-tooltip js-zen-enter gl-ml-2', data: { container: 'body' } })
+ = render 'shared/blob/markdown_buttons', supports_quick_actions: supports_quick_actions
+ .full-screen
+ = render Pajamas::ButtonComponent.new(icon: 'maximize', category: :tertiary, size: :small, button_options: { 'tabindex': -1, 'aria-label': _("Go full screen"), class: 'has-tooltip js-zen-enter', data: { container: 'body' } })
.md-write-holder
= yield
diff --git a/app/views/shared/_new_merge_request_checkbox.html.haml b/app/views/shared/_new_merge_request_checkbox.html.haml
index fb3dfba2691..b84efd2d577 100644
--- a/app/views/shared/_new_merge_request_checkbox.html.haml
+++ b/app/views/shared/_new_merge_request_checkbox.html.haml
@@ -2,7 +2,8 @@
- nonce = SecureRandom.hex
= render Pajamas::CheckboxTagComponent.new(name: 'create_merge_request',
checked: true,
- checkbox_options: { class: 'js-create-merge-request', id: "create_merge_request-#{nonce}" }) do |c|
+ checkbox_options: { class: 'js-create-merge-request', id: "create_merge_request-#{nonce}" },
+ label_options: { for: "create_merge_request-#{nonce}" }) do |c|
- c.with_label do
- translation_variables = { new_merge_request: "<strong>#{_('new merge request')}</strong>" }
- translation = _('Start a %{new_merge_request} with these changes') % translation_variables
diff --git a/app/views/shared/_no_ssh.html.haml b/app/views/shared/_no_ssh.html.haml
index e9c0858e090..a3f24da5d7c 100644
--- a/app/views/shared/_no_ssh.html.haml
+++ b/app/views/shared/_no_ssh.html.haml
@@ -5,5 +5,5 @@
- c.with_body do
= s_("MissingSSHKeyWarningLink|You can't push or pull repositories using SSH until you add an SSH key to your profile.")
- c.with_actions do
- = link_to s_('MissingSSHKeyWarningLink|Add SSH key'), profile_keys_path, class: "gl-alert-action btn btn-confirm btn-md gl-button"
- = link_to s_("MissingSSHKeyWarningLink|Don't show again"), profile_path(user: { hide_no_ssh_key: true }), method: :put, role: 'button', class: 'gl-alert-action btn btn-default btn-md gl-button'
+ = link_button_to s_('MissingSSHKeyWarningLink|Add SSH key'), profile_keys_path, class: 'gl-alert-action', variant: :confirm
+ = link_button_to s_("MissingSSHKeyWarningLink|Don't show again"), profile_path(user: { hide_no_ssh_key: true }), method: :put, role: 'button', class: 'gl-alert-action'
diff --git a/app/views/shared/_project_limit.html.haml b/app/views/shared/_project_limit.html.haml
index ce49193e27b..a99db32c40e 100644
--- a/app/views/shared/_project_limit.html.haml
+++ b/app/views/shared/_project_limit.html.haml
@@ -5,5 +5,5 @@
- c.with_body do
= _("You won't be able to create new projects because you have reached your project limit.")
- c.with_actions do
- = link_to _('Remind later'), '#', class: 'alert-link hide-project-limit-message btn gl-button btn-confirm'
- = link_to _("Don't show again"), profile_path(user: {hide_project_limit: true}), method: :put, class: 'alert-link btn gl-button btn-default gl-ml-3'
+ = link_button_to _('Remind later'), '#', class: 'alert-link hide-project-limit-message', variant: :confirm
+ = link_button_to _("Don't show again"), profile_path(user: {hide_project_limit: true}), method: :put, class: 'alert-link gl-ml-3'
diff --git a/app/views/shared/_prometheus_configuration_banner.html.haml b/app/views/shared/_prometheus_configuration_banner.html.haml
index 2d948cf28a6..7469260a997 100644
--- a/app/views/shared/_prometheus_configuration_banner.html.haml
+++ b/app/views/shared/_prometheus_configuration_banner.html.haml
@@ -17,11 +17,11 @@
.col-sm-10
%p.text-success.gl-mt-3
= s_('PrometheusService|You have a cluster with the Prometheus integration enabled.')
- = link_to s_('PrometheusService|Manage clusters'), project_clusters_path(project), class: 'btn gl-button btn-default'
+ = link_button_to s_('PrometheusService|Manage clusters'), project_clusters_path(project)
- else
.col-sm-2
= image_tag 'illustrations/monitoring/loading.svg'
.col-sm-10
%p.gl-mt-3
= s_('PrometheusService|Configure GitLab to query a Prometheus installed in one of your clusters.')
- = link_to s_('PrometheusService|Manage clusters'), project_clusters_path(project), class: 'btn gl-button btn-confirm'
+ = link_button_to s_('PrometheusService|Manage clusters'), project_clusters_path(project), variant: :confirm
diff --git a/app/views/shared/_registration_features_discovery_message.html.haml b/app/views/shared/_registration_features_discovery_message.html.haml
index 053c511830c..6e386866dfb 100644
--- a/app/views/shared/_registration_features_discovery_message.html.haml
+++ b/app/views/shared/_registration_features_discovery_message.html.haml
@@ -1,5 +1,5 @@
- feature_title = local_assigns.fetch(:feature_title, s_('RegistrationFeatures|use this feature'))
-- registration_features_docs_path = help_page_path('user/admin_area/settings/usage_statistics.md', anchor: 'registration-features-program')
+- registration_features_docs_path = help_page_path('administration/settings/usage_statistics.md', anchor: 'registration-features-program')
- registration_features_link_start = '<a href="%{url}" target="_blank">'.html_safe % { url: registration_features_docs_path }
%div
diff --git a/app/views/shared/_remote_mirror_update_button.html.haml b/app/views/shared/_remote_mirror_update_button.html.haml
index bc80ebe3950..fa5c862b768 100644
--- a/app/views/shared/_remote_mirror_update_button.html.haml
+++ b/app/views/shared/_remote_mirror_update_button.html.haml
@@ -3,5 +3,4 @@
button_options: { class: 'disabled', title: _('Updating'), data: { toggle: 'tooltip', container: 'body' } },
icon_classes: 'spin')
- elsif remote_mirror.enabled?
- = link_to update_now_project_mirror_path(@project, sync_remote: true), method: :post, class: "btn btn-icon gl-button rspec-update-now-button", data: { toggle: 'tooltip', container: 'body', qa_selector: 'update_now_button' }, title: _('Update now') do
- = sprite_icon("retry")
+ = link_button_to nil, update_now_project_mirror_path(@project, sync_remote: true), method: :post, class: 'rspec-update-now-button', data: { toggle: 'tooltip', container: 'body', qa_selector: 'update_now_button' }, title: _('Update now'), icon: 'retry'
diff --git a/app/views/shared/_service_ping_consent.html.haml b/app/views/shared/_service_ping_consent.html.haml
index 108d846e3ee..e0313710736 100644
--- a/app/views/shared/_service_ping_consent.html.haml
+++ b/app/views/shared/_service_ping_consent.html.haml
@@ -1,11 +1,14 @@
- if session[:ask_for_usage_stats_consent]
= render Pajamas::AlertComponent.new(alert_options: { class: 'service-ping-consent-message' }) do |c|
- c.with_body do
- - docs_link = link_to _('collect usage information'), help_page_path('user/admin_area/settings/usage_statistics.md'), class: 'gl-link'
- - settings_link = link_to _('your settings'), metrics_and_profiling_admin_application_settings_path(anchor: 'js-usage-settings'), class: 'gl-link'
- = s_('To help improve GitLab, we would like to periodically %{docs_link}. This can be changed at any time in %{settings_link}.').html_safe % { docs_link: docs_link, settings_link: settings_link }
+ - docs_link = link_to '', help_page_path('user/admin_area/settings/usage_statistics.md'), class: 'gl-link'
+ - settings_link = link_to '', metrics_and_profiling_admin_application_settings_path(anchor: 'js-usage-settings'), class: 'gl-link'
+ = safe_format s_('ServicePing|To help improve GitLab, we would like to periodically %{link_start}collect usage information%{link_end}.'), tag_pair(docs_link, :link_start, :link_end)
+ = safe_format s_('ServicePing|This can be changed at any time in %{link_start}your settings%{link_end}.'), tag_pair(settings_link, :link_start, :link_end)
- c.with_actions do
- send_service_data_path = admin_application_settings_path(application_setting: { version_check_enabled: 1, usage_ping_enabled: 1 })
- not_now_path = admin_application_settings_path(application_setting: { version_check_enabled: 0, usage_ping_enabled: 0 })
- = link_to _("Send service data"), send_service_data_path, 'data-url' => admin_application_settings_path, method: :put, 'data-check-enabled': true, 'data-service-ping-enabled': true, class: 'js-service-ping-consent-action alert-link btn gl-button btn-confirm'
- = link_to _("Don't send service data"), not_now_path, 'data-url' => admin_application_settings_path, method: :put, 'data-check-enabled': false, 'data-service-ping-enabled': false, class: 'js-service-ping-consent-action alert-link btn gl-button btn-default gl-ml-3'
+ = render Pajamas::ButtonComponent.new(href: send_service_data_path, method: :put, variant: :confirm, button_options: { 'data-url' => admin_application_settings_path, 'data-check-enabled': true, 'data-service-ping-enabled': true, class: 'js-service-ping-consent-action alert-link' }) do
+ = _('Send service data')
+ = render Pajamas::ButtonComponent.new(href: not_now_path, method: :put, button_options: { 'data-url' => admin_application_settings_path, 'data-check-enabled': false, 'data-service-ping-enabled': false, class: 'js-service-ping-consent-action alert-link gl-ml-3' }) do
+ = _("Don't send service data")
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 290152d5803..e372dbd983c 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
@@ -8,5 +8,5 @@
= s_('Profiles|Ensure you have two-factor authentication recovery codes stored in a safe place.')
= link_to _('Learn more.'), help_page_path('user/profile/account/two_factor_authentication', anchor: 'recovery-codes'), target: '_blank', rel: 'noopener noreferrer'
- c.with_actions do
- = link_to profile_two_factor_auth_path, class: 'deferred-link btn gl-alert-action btn-confirm btn-md gl-button' do
+ = link_button_to profile_two_factor_auth_path, class: 'deferred-link gl-alert-action', variant: :confirm do
= s_('Profiles|Manage two-factor authentication')
diff --git a/app/views/shared/access_tokens/_form.html.haml b/app/views/shared/access_tokens/_form.html.haml
index ac359d37c49..54af364aca3 100644
--- a/app/views/shared/access_tokens/_form.html.haml
+++ b/app/views/shared/access_tokens/_form.html.haml
@@ -7,36 +7,27 @@
- access_levels = local_assigns.fetch(:access_levels, false)
- default_access_level = local_assigns.fetch(:default_access_level, false)
-%h5.gl-mt-0
+%h5.gl-font-lg.gl-mt-0
= title
-%p.profile-settings-content
- = s_("AccessTokens|Enter the name of your application, and we'll return a unique %{type}.") % { type: type }
= gitlab_ui_form_for token, as: prefix, url: path, method: :post, html: { id: 'js-new-access-token-form', class: 'js-requires-input' }, remote: ajax do |f|
-
= form_errors(token)
- .row
- .form-group.col
- .row
- = f.label :name, s_('AccessTokens|Token name'), class: 'label-bold col-md-12'
- .col-md-6
- - resource_type = resource.is_a?(Group) ? "group" : "project"
- = f.text_field :name, class: 'form-control gl-form-input', required: true, data: { qa_selector: 'access_token_name_field' }, :'aria-describedby' => 'access_token_help_text'
- %span.form-text.text-muted.col-md-12#access_token_help_text= s_("AccessTokens|For example, the application using the token or the purpose of the token. Do not give sensitive information for the name of the token, as it will be visible to all %{resource_type} members.") % { resource_type: resource_type }
+ .form-group
+ = f.label :name, s_('AccessTokens|Token name'), class: 'label-bold'
+ - resource_type = resource.is_a?(Group) ? "group" : "project"
+ = f.text_field :name, class: 'form-control gl-form-input gl-max-w-80', required: true, data: { qa_selector: 'access_token_name_field' }, :'aria-describedby' => 'access_token_help_text'
+ %span.form-text.text-muted#access_token_help_text= s_("AccessTokens|For example, the application using the token or the purpose of the token. Do not give sensitive information for the name of the token, as it will be visible to all %{resource_type} members.") % { resource_type: resource_type }
- .row
- .col
- .js-access-tokens-expires-at{ data: expires_at_field_data }
- = f.text_field :expires_at, class: 'gl-datepicker-input form-control gl-form-input', placeholder: 'YYYY-MM-DD', autocomplete: 'off', data: { js_name: 'expiresAt' }
+ .js-access-tokens-expires-at{ data: expires_at_field_data }
+ = f.text_field :expires_at, class: 'gl-datepicker-input form-control gl-form-input', placeholder: 'YYYY-MM-DD', autocomplete: 'off', data: { js_name: 'expiresAt' }
- if resource
- .row
- .form-group.col-md-6
- = label_tag :access_level, s_("AccessTokens|Select a role"), class: "label-bold"
- .select-wrapper
- = select_tag :"#{prefix}[access_level]", options_for_select(access_levels, default_access_level), class: "form-control select-control", data: { qa_selector: 'access_token_access_level' }
- = sprite_icon('chevron-down', css_class: "gl-icon gl-absolute gl-top-3 gl-right-3 gl-text-gray-200")
+ .form-group
+ = label_tag :access_level, s_("AccessTokens|Select a role"), class: "label-bold"
+ .select-wrapper.gl-form-input-md
+ = select_tag :"#{prefix}[access_level]", options_for_select(access_levels, default_access_level), class: "form-control select-control", data: { qa_selector: 'access_token_access_level' }
+ = sprite_icon('chevron-down', css_class: "gl-icon gl-absolute gl-top-3 gl-right-3 gl-text-gray-200")
.form-group
%b{ :'aria-describedby' => 'select_scope_help_text' }
diff --git a/app/views/shared/blob/_markdown_buttons.html.haml b/app/views/shared/blob/_markdown_buttons.html.haml
index a3d3c1c8231..16bffaca810 100644
--- a/app/views/shared/blob/_markdown_buttons.html.haml
+++ b/app/views/shared/blob/_markdown_buttons.html.haml
@@ -1,32 +1,33 @@
- modifier_key = client_js_flags[:isMac] ? 'āŒ˜' : s_('KeyboardKey|Ctrl+')
- supports_file_upload = local_assigns.fetch(:supports_file_upload, true)
+- supports_quick_actions = local_assigns.fetch(:supports_quick_actions, false)
= markdown_toolbar_button({ icon: "bold",
- css_class: 'gl-mr-3',
+ css_class: 'haml-markdown-button gl-mr-3',
data: { "md-tag" => "**", "md-shortcuts": '["mod+b"]' },
title: sprintf(s_("MarkdownEditor|Add bold text (%{modifier_key}B)") % { modifier_key: modifier_key }) })
= markdown_toolbar_button({ icon: "italic",
- css_class: 'gl-mr-3',
+ css_class: 'haml-markdown-button gl-mr-3',
data: { "md-tag" => "_", "md-shortcuts": '["mod+i"]' },
title: sprintf(s_("MarkdownEditor|Add italic text (%{modifier_key}I)") % { modifier_key: modifier_key }) })
= markdown_toolbar_button({ icon: "strikethrough",
- css_class: 'gl-mr-3',
+ css_class: 'haml-markdown-button gl-mr-3',
data: { "md-tag" => "~~", "md-shortcuts": '["mod+shift+x"]' },
title: sprintf(s_("MarkdownEditor|Add strikethrough text (%{modifier_key}ā‡§X)") % { modifier_key: modifier_key }) })
-= markdown_toolbar_button({ icon: "quote", css_class: 'gl-mr-3', data: { "md-tag" => "> ", "md-prepend" => true }, title: _("Insert a quote") })
-= markdown_toolbar_button({ icon: "code", css_class: 'gl-mr-3', data: { "md-tag" => "`", "md-block" => "```" }, title: _("Insert code") })
+= markdown_toolbar_button({ icon: "quote", css_class: 'haml-markdown-button gl-mr-3', data: { "md-tag" => "> ", "md-prepend" => true }, title: _("Insert a quote") })
+= markdown_toolbar_button({ icon: "code", css_class: 'haml-markdown-button gl-mr-3', data: { "md-tag" => "`", "md-block" => "```" }, title: _("Insert code") })
= markdown_toolbar_button({ icon: "link",
- css_class: 'gl-mr-3',
+ css_class: 'haml-markdown-button gl-mr-3',
data: { "md-tag" => "[{text}](url)", "md-select" => "url", "md-shortcuts": '["mod+k"]' },
title: sprintf(s_("MarkdownEditor|Add a link (%{modifier_key}K)") % { modifier_key: modifier_key }) })
-= markdown_toolbar_button({ icon: "list-bulleted", css_class: 'gl-mr-3', data: { "md-tag" => "- ", "md-prepend" => true }, title: _("Add a bullet list") })
-= markdown_toolbar_button({ icon: "list-numbered", css_class: 'gl-mr-3', data: { "md-tag" => "1. ", "md-prepend" => true }, title: _("Add a numbered list") })
-= markdown_toolbar_button({ icon: "list-task", css_class: 'gl-mr-3', data: { "md-tag" => "- [ ] ", "md-prepend" => true }, title: _("Add a checklist") })
+= markdown_toolbar_button({ icon: "list-bulleted", css_class: 'haml-markdown-button gl-mr-3', data: { "md-tag" => "- ", "md-prepend" => true }, title: _("Add a bullet list") })
+= markdown_toolbar_button({ icon: "list-numbered", css_class: 'haml-markdown-button gl-mr-3', data: { "md-tag" => "1. ", "md-prepend" => true }, title: _("Add a numbered list") })
+= markdown_toolbar_button({ icon: "list-task", css_class: 'haml-markdown-button gl-mr-3', data: { "md-tag" => "- [ ] ", "md-prepend" => true }, title: _("Add a checklist") })
= markdown_toolbar_button({ icon: "list-indent",
css_class: 'gl-display-none gl-mr-3',
data: { "md-command" => 'indentLines', "md-shortcuts": '["mod+]"]' },
@@ -36,9 +37,11 @@
data: { "md-command" => 'outdentLines', "md-shortcuts": '["mod+["]' },
title: sprintf(s_("MarkdownEditor|Outdent line (%{modifier_key}[)") % { modifier_key: modifier_key }) })
= markdown_toolbar_button({ icon: "details-block",
- css_class: 'gl-mr-3',
+ css_class: 'haml-markdown-button gl-mr-3',
data: { "md-tag" => "<details><summary>Click to expand</summary>\n{text}\n</details>", "md-prepend" => true, "md-select" => "Click to expand" },
title: _("Add a collapsible section") })
-= markdown_toolbar_button({ icon: "table", css_class: 'gl-mr-3', data: { "md-tag" => "| header | header |\n| ------ | ------ |\n| | |\n| | |", "md-prepend" => true }, title: _("Add a table") })
+= markdown_toolbar_button({ icon: "table", css_class: 'haml-markdown-button gl-mr-3', data: { "md-tag" => "| header | header |\n| ------ | ------ |\n| | |\n| | |", "md-prepend" => true }, title: _("Add a table") })
- if supports_file_upload
- = render Pajamas::ButtonComponent.new(icon: 'paperclip', category: :tertiary, size: :small, button_options: { 'aria-label': _("Attach a file or image"), class: 'has-tooltip js-attach-file-button gl-mr-3', data: { testid: 'button-attach-file', container: 'body' } })
+ = render Pajamas::ButtonComponent.new(icon: 'paperclip', category: :tertiary, size: :small, button_options: { 'aria-label': _("Attach a file or image"), class: 'has-tooltip js-attach-file-button haml-markdown-button gl-mr-3', data: { testid: 'button-attach-file', container: 'body' } })
+- if supports_quick_actions
+ = markdown_toolbar_button({ icon: "quick-actions", css_class: 'haml-markdown-button gl-mr-3', data: { "md-tag" => "/", "md-prepend" => true }, title: _("Add a quick action") })
diff --git a/app/views/shared/deploy_tokens/_form.html.haml b/app/views/shared/deploy_tokens/_form.html.haml
index 0f290f34a95..8821804ce6b 100644
--- a/app/views/shared/deploy_tokens/_form.html.haml
+++ b/app/views/shared/deploy_tokens/_form.html.haml
@@ -1,4 +1,4 @@
-%p.profile-settings-content
+%p
- group_deploy_tokens_help_link_url = help_page_path('user/project/deploy_tokens/index.md')
- group_deploy_tokens_help_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: group_deploy_tokens_help_link_url }
= s_('DeployTokens|Create a new deploy token for all projects in this group. %{link_start}What are deploy tokens?%{link_end}').html_safe % { link_start: group_deploy_tokens_help_link_start, link_end: '</a>'.html_safe }
diff --git a/app/views/shared/deploy_tokens/_table.html.haml b/app/views/shared/deploy_tokens/_table.html.haml
index a7bf3bfb81e..3827ecf73a4 100644
--- a/app/views/shared/deploy_tokens/_table.html.haml
+++ b/app/views/shared/deploy_tokens/_table.html.haml
@@ -16,7 +16,7 @@
%tr
%td= token.name
%td= token.username
- %td= token.created_at.to_date.to_s(:medium)
+ %td= token.created_at.to_date.to_fs(:medium)
%td
- if token.expires?
%span{ class: ('text-warning' if token.expires_soon?) }
diff --git a/app/views/shared/doorkeeper/applications/_form.html.haml b/app/views/shared/doorkeeper/applications/_form.html.haml
index 628a34e1278..ae539c46cf1 100644
--- a/app/views/shared/doorkeeper/applications/_form.html.haml
+++ b/app/views/shared/doorkeeper/applications/_form.html.haml
@@ -1,4 +1,4 @@
-= gitlab_ui_form_for @application, url: url, html: { role: 'form', class: 'doorkeeper-app-form' } do |f|
+= gitlab_ui_form_for @application, url: url, html: { role: 'form', class: 'doorkeeper-app-form gl-max-w-80' } do |f|
= form_errors(@application)
.form-group
diff --git a/app/views/shared/doorkeeper/applications/_index.html.haml b/app/views/shared/doorkeeper/applications/_index.html.haml
index abfe3baf8b4..bf78f275d65 100644
--- a/app/views/shared/doorkeeper/applications/_index.html.haml
+++ b/app/views/shared/doorkeeper/applications/_index.html.haml
@@ -1,88 +1,86 @@
- @force_desktop_expanded_sidebar = true
-.row.gl-mt-3.js-search-settings-section
- .col-lg-4.profile-settings-sidebar
- %h4.gl-mt-0
- = page_title
- %p
- - if oauth_applications_enabled
- - 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 use GitLab as an OAuth provider.")
- - else
- = _("Manage applications that you've authorized to use your account.")
- .col-lg-8
+.settings-section.js-search-settings-section
+ .settings-sticky-header
+ .settings-sticky-header-inner
+ %h4.gl-my-0
+ = page_title
+ %p.gl-text-secondary
- if oauth_applications_enabled
- %h5.gl-mt-0
- = _('Add new application')
- = render 'shared/doorkeeper/applications/form', url: form_url
- %hr
+ - 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 use GitLab as an OAuth provider.")
- else
- .bs-callout.bs-callout-disabled
- = _('Adding new applications is disabled in your GitLab instance. Please contact your GitLab administrator to get the permission')
- - if oauth_applications_enabled
- .oauth-applications
- %h5
- = _("Your applications (%{size})") % { size: @applications.size }
- - if @applications.any?
- .table-responsive
- %table.table
- %thead
- %tr
- %th= _('Name')
- %th= _('Callback URL')
- %th= _('Clients')
- %th.last-heading
- %tbody
- - @applications.each do |application|
- %tr{ id: "application_#{application.id}" }
- %td= link_to application.name, application_url.call(application)
- %td
- - application.redirect_uri.split.each do |uri|
- %div= uri
- %td= application.access_tokens.count
- %td.gl-display-flex
- = link_to edit_application_url.call(application), class: "gl-button btn btn-default btn-icon gl-mr-3" do
- %span.sr-only
- = _('Edit')
- = sprite_icon('pencil')
- = render 'shared/doorkeeper/applications/delete_form', path: application_url.call(application), small: true
- - else
- .settings-message.text-center
- = _("You don't have any applications")
- - if oauth_authorized_applications_enabled
- .oauth-authorized-applications.prepend-top-20.gl-mb-3
- - if oauth_applications_enabled
- %h5
- = _("Authorized applications (%{size})") % { size: @authorized_tokens.size }
+ = _("Manage applications that you've authorized to use your account.")
+ - if oauth_applications_enabled
+ %h5.gl-mt-0
+ = _('Add new application')
+ .gl-border-b.gl-pb-6
+ = render 'shared/doorkeeper/applications/form', url: form_url
+
+ - else
+ .bs-callout.bs-callout-disabled
+ = _('Adding new applications is disabled in your GitLab instance. Please contact your GitLab administrator to get the permission')
+ - if oauth_applications_enabled
+ .oauth-applications.gl-pt-6
+ %h5.gl-mt-0
+ = _("Your applications (%{size})") % { size: @applications.size }
+ - if @applications.any?
+ .table-responsive
+ %table.table
+ %thead
+ %tr
+ %th= _('Name')
+ %th= _('Callback URL')
+ %th= _('Clients')
+ %th.last-heading
+ %tbody
+ - @applications.each do |application|
+ %tr{ id: "application_#{application.id}" }
+ %td= link_to application.name, application_url.call(application)
+ %td
+ - application.redirect_uri.split.each do |uri|
+ %div= uri
+ %td= application.access_tokens.count
+ %td.gl-display-flex
+ = link_button_to nil, edit_application_url.call(application), class: 'gl-mr-3', icon: 'pencil', 'aria-label': _('Edit')
+ = render 'shared/doorkeeper/applications/delete_form', path: application_url.call(application), small: true
+ - else
+ .settings-message
+ = _("You don't have any applications")
+ - if oauth_authorized_applications_enabled
+ .oauth-authorized-applications.gl-mt-4
+ - if oauth_applications_enabled
+ %h5.gl-mt-0
+ = _("Authorized applications (%{size})") % { size: @authorized_tokens.size }
- - if @authorized_tokens.any?
- .table-responsive
- %table.table.table-striped
- %thead
- %tr
- %th= _('Name')
- %th= _('Authorized At')
- %th= _('Scope')
- %th
- %tbody
- - @authorized_tokens.each do |token|
- %tr{ id: ("application_#{token.application.id}" if token.application) }
- %td
- - if token.application
- = token.application.name
- - else
- = _('Anonymous')
- .form-text.text-muted
- %em= _("Authorization was granted by entering your username and password in the application.")
- %td= token.created_at
- %td= token.scopes
- %td
- - if token.application
- = render 'doorkeeper/authorized_applications/delete_form', application: token.application
- - else
- = render 'doorkeeper/authorized_applications/delete_form', token: token
- - else
- .settings-message.text-center
- = _("You don't have any authorized applications")
+ - if @authorized_tokens.any?
+ .table-responsive
+ %table.table.table-striped
+ %thead
+ %tr
+ %th= _('Name')
+ %th= _('Authorized At')
+ %th= _('Scope')
+ %th
+ %tbody
+ - @authorized_tokens.each do |token|
+ %tr{ id: ("application_#{token.application.id}" if token.application) }
+ %td
+ - if token.application
+ = token.application.name
+ - else
+ = _('Anonymous')
+ .form-text.text-muted
+ %em= _("Authorization was granted by entering your username and password in the application.")
+ %td= token.created_at
+ %td= token.scopes
+ %td
+ - if token.application
+ = render 'doorkeeper/authorized_applications/delete_form', application: token.application
+ - else
+ = render 'doorkeeper/authorized_applications/delete_form', token: token
+ - else
+ .settings-message
+ = _("You don't have any authorized applications")
diff --git a/app/views/shared/doorkeeper/applications/_show.html.haml b/app/views/shared/doorkeeper/applications/_show.html.haml
index b9095e2a1a1..b075cece877 100644
--- a/app/views/shared/doorkeeper/applications/_show.html.haml
+++ b/app/views/shared/doorkeeper/applications/_show.html.haml
@@ -43,8 +43,8 @@
.form-actions.gl-display-flex.gl-justify-content-space-between
%div
- if @created
- = link_to _('Continue'), index_path, class: 'btn btn-confirm btn-md gl-button gl-mr-3'
- = link_to _('Edit'), edit_path, class: 'btn btn-default btn-md gl-button'
+ = link_button_to _('Continue'), index_path, class: 'gl-mr-3', variant: :confirm
+ = link_button_to _('Edit'), edit_path
= render 'shared/doorkeeper/applications/delete_form', path: delete_path
-# Create a hidden field to save the ID of application created
diff --git a/app/views/shared/empty_states/_issues.html.haml b/app/views/shared/empty_states/_issues.html.haml
index 387a83873b5..a4ea98a0fb7 100644
--- a/app/views/shared/empty_states/_issues.html.haml
+++ b/app/views/shared/empty_states/_issues.html.haml
@@ -19,7 +19,7 @@
= _("To widen your search, change or remove filters above")
- if show_new_issue_link?(@project)
.text-center
- = link_to _("New issue"), new_project_issue_path(@project), class: "gl-button btn btn-confirm"
+ = link_button_to _("New issue"), new_project_issue_path(@project), variant: :confirm
- elsif is_opened_state && opened_issues_count == 0 && closed_issues_count > 0
%h4.text-center
= _("There are no open issues")
@@ -27,7 +27,7 @@
= _("To keep this project going, create a new issue")
- if show_new_issue_link?(@project)
.text-center
- = link_to _("New issue"), new_project_issue_path(@project), class: "gl-button btn btn-confirm"
+ = link_button_to _("New issue"), new_project_issue_path(@project), variant: :confirm
- elsif is_closed_state && opened_issues_count > 0 && closed_issues_count == 0
%h4.text-center
= _("There are no closed issues")
@@ -39,7 +39,7 @@
- if button_path
.text-center
- if show_new_issue_link?(@project)
- = link_to _('New issue'), button_path, class: 'gl-button btn btn-confirm', id: 'new_issue_link'
+ = link_button_to _('New issue'), button_path, id: 'new_issue_link', variant: :confirm
- if show_import_button
.js-csv-import-export-buttons{ data: { show_import_button: 'true', issuable_type: 'issue', import_csv_issues_path: import_csv_namespace_project_issues_path, can_edit: can_edit.to_s, project_import_jira_path: project_import_jira_path(@project), max_attachment_size: number_to_human_size(Gitlab::CurrentSettings.max_attachment_size.megabytes) } }
@@ -59,4 +59,4 @@
%p
= _("The Issue Tracker is the place to add things that need to be improved or solved in a project. You can register or sign in to create issues for this project.")
.text-center
- = link_to _('Register / Sign In'), new_user_session_path, class: 'gl-button btn btn-confirm'
+ = link_button_to _('Register / Sign In'), new_user_session_path, variant: :confirm
diff --git a/app/views/shared/empty_states/_labels.html.haml b/app/views/shared/empty_states/_labels.html.haml
index da88c139a6e..4d2127c0161 100644
--- a/app/views/shared/empty_states/_labels.html.haml
+++ b/app/views/shared/empty_states/_labels.html.haml
@@ -8,7 +8,7 @@
%p= _("You can also star a label to make it a priority label.")
.text-center
- if can?(current_user, :admin_label, @project)
- = link_to _('New label'), new_project_label_path(@project), class: 'btn gl-button btn-confirm', title: _('New label'), id: 'new_label_link'
- = link_to _('Generate a default set of labels'), generate_project_labels_path(@project), method: :post, class: 'btn gl-button btn-confirm-secondary', title: _('Generate a default set of labels'), id: 'generate_labels_link'
+ = link_button_to _('New label'), new_project_label_path(@project), title: _('New label'), id: 'new_label_link', variant: :confirm
+ = link_button_to _('Generate a default set of labels'), generate_project_labels_path(@project), method: :post, title: _('Generate a default set of labels'), id: 'generate_labels_link', variant: :confirm, category: :secondary
- if can?(current_user, :admin_label, @group)
- = link_to _('New label'), new_group_label_path(@group), class: 'btn gl-button btn-confirm', title: _('New label'), id: 'new_label_link'
+ = link_button_to _('New label'), new_group_label_path(@group), title: _('New label'), id: 'new_label_link', variant: :confirm
diff --git a/app/views/shared/empty_states/_merge_requests.html.haml b/app/views/shared/empty_states/_merge_requests.html.haml
index 94589996c3a..5b377818c6e 100644
--- a/app/views/shared/empty_states/_merge_requests.html.haml
+++ b/app/views/shared/empty_states/_merge_requests.html.haml
@@ -18,7 +18,7 @@
= _("To widen your search, change or remove filters above")
.text-center
- if can_create_merge_request
- = link_to _("New merge request"), button_path || project_new_merge_request_path(@project), class: "gl-button btn btn-confirm", title: _("New merge request")
+ = link_button_to _("New merge request"), button_path || project_new_merge_request_path(@project), title: _("New merge request"), variant: :confirm
- elsif is_opened_state && opened_merged_count == 0 && closed_merged_count > 0
%h4.text-center
= _("There are no open merge requests")
@@ -26,7 +26,7 @@
= _("To keep this project going, create a new merge request")
.text-center
- if can_create_merge_request
- = link_to _("New merge request"), button_path || project_new_merge_request_path(@project), class: "gl-button btn btn-confirm", title: _("New merge request")
+ = link_button_to _("New merge request"), button_path || project_new_merge_request_path(@project), title: _("New merge request"), variant: :confirm
- elsif is_closed_state && opened_merged_count > 0 && closed_merged_count == 0
%h4.text-center
= _("There are no closed merge requests")
@@ -37,4 +37,4 @@
= _("Interested parties can even contribute by pushing commits if they want to.")
- if button_path
.text-center
- = link_to _('New merge request'), button_path, class: 'gl-button btn btn-confirm', title: _('New merge request'), id: 'new_merge_request_link', data: { qa_selector: "new_merge_request_button" }
+ = link_button_to _('New merge request'), button_path, title: _('New merge request'), id: 'new_merge_request_link', data: { qa_selector: "new_merge_request_button" }, variant: :confirm
diff --git a/app/views/shared/empty_states/_priority_labels.html.haml b/app/views/shared/empty_states/_priority_labels.html.haml
index b24fa0b3bdb..688df1705aa 100644
--- a/app/views/shared/empty_states/_priority_labels.html.haml
+++ b/app/views/shared/empty_states/_priority_labels.html.haml
@@ -1,8 +1,8 @@
-.text-center.gl-mt-1.gl-mb-6
+.text-center.gl-mt-1.gl-mb-5
.svg-content{ data: { qa_selector: 'label_svg_content' } }
= image_tag 'illustrations/empty-state/empty-labels-starred-md.svg'
- if can?(current_user, :admin_label, @project)
- %div
+ %h5.gl-my-0
= _("No prioritized labels yet!")
- %div
+ %p.gl-text-secondary
= _("Star labels to start sorting by priority.")
diff --git a/app/views/shared/empty_states/_profile_tabs.html.haml b/app/views/shared/empty_states/_profile_tabs.html.haml
index c813fd691f1..ba5fbd90528 100644
--- a/app/views/shared/empty_states/_profile_tabs.html.haml
+++ b/app/views/shared/empty_states/_profile_tabs.html.haml
@@ -13,9 +13,9 @@
%p= current_user_empty_message_description
- if secondary_button_link.present?
- = link_to secondary_button_label, secondary_button_link, class: 'gl-button btn btn-confirm btn-inverted'
+ = link_button_to secondary_button_label, secondary_button_link, variant: :confirm, category: :secondary
- if primary_button_link.present?
- = link_to primary_button_label, primary_button_link, class: 'gl-button btn btn-confirm'
+ = link_button_to primary_button_label, primary_button_link, variant: :confirm
- else
%h5= visitor_empty_message
diff --git a/app/views/shared/empty_states/_snippets.html.haml b/app/views/shared/empty_states/_snippets.html.haml
index 87de756093d..6fe36d75453 100644
--- a/app/views/shared/empty_states/_snippets.html.haml
+++ b/app/views/shared/empty_states/_snippets.html.haml
@@ -12,7 +12,7 @@
= s_('SnippetsEmptyState|Store, share, and embed small pieces of code and text.')
.gl-mt-3<
- if button_path
- = link_to s_('SnippetsEmptyState|New snippet'), button_path, class: 'btn gl-button btn-confirm', title: s_('SnippetsEmptyState|New snippet'), id: 'new_snippet_link', data: { qa_selector: 'create_first_snippet_link' }
- = link_to s_('SnippetsEmptyState|Documentation'), help_page_path('user/snippets.md'), class: 'btn gl-button btn-default', title: s_('SnippetsEmptyState|Documentation')
+ = link_button_to s_('SnippetsEmptyState|New snippet'), button_path, title: s_('SnippetsEmptyState|New snippet'), id: 'new_snippet_link', data: { qa_selector: 'create_first_snippet_link' }, variant: :confirm
+ = link_button_to s_('SnippetsEmptyState|Documentation'), help_page_path('user/snippets.md'), title: s_('SnippetsEmptyState|Documentation')
- else
%h4.gl-text-center= s_('SnippetsEmptyState|There are no snippets to show.')
diff --git a/app/views/shared/empty_states/_wikis.html.haml b/app/views/shared/empty_states/_wikis.html.haml
index 57f1c9d381e..9e628a1f409 100644
--- a/app/views/shared/empty_states/_wikis.html.haml
+++ b/app/views/shared/empty_states/_wikis.html.haml
@@ -4,7 +4,7 @@
- if !hide_create && can?(current_user, :create_wiki, @wiki.container)
- create_path = wiki_page_path(@wiki, params[:id], view: 'create')
- - create_link = link_to s_('WikiEmpty|Create your first page'), create_path, class: 'btn gl-button btn-confirm', title: s_('WikiEmpty|Create your first page'), data: { qa_selector: 'create_first_page_link' }
+ - create_link = link_button_to s_('WikiEmpty|Create your first page'), create_path, title: s_('WikiEmpty|Create your first page'), data: { qa_selector: 'create_first_page_link' }, variant: :confirm
= render layout: layout_path, locals: { image_path: 'illustrations/wiki_login_empty.svg' } do
%h4.text-left
@@ -26,7 +26,7 @@
%p.text-left
= messages.dig(:issuable, :body).html_safe % { issues_link: issues_link }
- if show_new_issue_link?(@project)
- = link_to s_('WikiEmpty|Suggest wiki improvement'), new_project_issue_path(@project), class: 'btn gl-button btn-confirm', title: s_('WikiEmptyIssueMessage|Suggest wiki improvement')
+ = link_button_to s_('WikiEmpty|Suggest wiki improvement'), new_project_issue_path(@project), title: s_('WikiEmptyIssueMessage|Suggest wiki improvement'), variant: :confirm
- else
= render layout: layout_path, locals: { image_path: 'illustrations/wiki_logout_empty.svg' } do
diff --git a/app/views/shared/file_hooks/_index.html.haml b/app/views/shared/file_hooks/_index.html.haml
index ba968c6b2d2..9f1b11d6ab5 100644
--- a/app/views/shared/file_hooks/_index.html.haml
+++ b/app/views/shared/file_hooks/_index.html.haml
@@ -1,26 +1,30 @@
- file_hooks = Gitlab::FileHook.files
-.row.gl-mt-3
- .col-lg-4
- %h4.gl-mt-0
- = _('File Hooks')
- %p
- = _('File hooks are similar to system hooks but are executed as files instead of sending data to a URL.')
- = link_to _('For more information, see the File Hooks documentation.'), help_page_path('administration/file_hooks')
+.settings-section
+ .settings-sticky-header
+ .settings-sticky-header-inner
+ %h4.gl-my-0
+ = _('File Hooks')
+ %p.gl-text-secondary
+ = _('File hooks are similar to system hooks but are executed as files instead of sending data to a URL.')
+ = link_to _('For more information, see the File Hooks documentation.'), help_page_path('administration/file_hooks')
-
- .col-lg-8.gl-mb-3
- - if file_hooks.any?
- = render Pajamas::CardComponent.new do |c|
- - c.with_header do
- = _('File Hooks (%{count})') % { count: file_hooks.count }
- - c.with_body do
- %ul.content-list
- - file_hooks.each do |file|
- %li
- .monospace
- = File.basename(file)
- - else
- = render Pajamas::CardComponent.new do |c|
- - c.with_body do
- .nothing-here-block= _('No file hooks found.')
+ .gl-mb-3
+ = render Pajamas::CardComponent.new(card_options: { class: 'gl-new-card' }, header_options: { class: 'gl-new-card-header'}, body_options: { class: 'gl-new-card-body'}) do |c|
+ - c.with_header do
+ .gl-new-card-title-wrapper
+ %h3.gl-new-card-title
+ = _('File Hooks')
+ %span.gl-new-card-count
+ = sprite_icon('hook', css_class: 'gl-mr-2')
+ #{file_hooks.count}
+ - c.with_body do
+ .gl-new-card-content
+ - if file_hooks.any?
+ %ul.content-list{ class: 'gl-my-n3!' }
+ - file_hooks.each do |file|
+ %li.label-list-item
+ .monospace
+ = File.basename(file)
+ - else
+ .gl-new-card-empty.gl-text-center= _('No file hooks found.')
diff --git a/app/views/shared/form_elements/_apply_generated_description_warning.haml b/app/views/shared/form_elements/_apply_generated_description_warning.haml
new file mode 100644
index 00000000000..906f60d01e6
--- /dev/null
+++ b/app/views/shared/form_elements/_apply_generated_description_warning.haml
@@ -0,0 +1,13 @@
+.form-group.row.js-ai-description-warning.hidden.js-issuable-ai-description-warning
+ .col-sm-12
+ .warning_message.mb-0{ role: 'alert' }
+ %btn.js-close-btn.js-dismiss-btn.close{ type: "button", "aria-hidden": "true", "aria-label": _("Close") }
+ = sprite_icon("close")
+
+ %p
+ = s_("AI|Replace the existing description with an AI-generated description? Any changes you have made will be lost.")
+
+ = render Pajamas::ButtonComponent.new(variant: :confirm, button_options: { class: 'gl-mr-3 js-ai-override-description' }) do
+ = s_("AI|Apply AI-generated description")
+ = render Pajamas::ButtonComponent.new(button_options: { class: 'js-cancel-btn' }) do
+ = _("Cancel")
diff --git a/app/views/shared/form_elements/_description.html.haml b/app/views/shared/form_elements/_description.html.haml
index 415849672b6..75f678dea5c 100644
--- a/app/views/shared/form_elements/_description.html.haml
+++ b/app/views/shared/form_elements/_description.html.haml
@@ -15,12 +15,15 @@
= render 'shared/issuable/form/template_selector', issuable: model
= render 'shared/form_elements/apply_template_warning', issuable: model
+ - if model.is_a?(MergeRequest)
+ = render 'shared/form_elements/apply_generated_description_warning', issuable: model
.js-markdown-editor{ data: { render_markdown_path: preview_url,
markdown_docs_path: help_page_path('user/markdown'),
quick_actions_docs_path: help_page_path('user/project/quick_actions'),
qa_selector: 'issuable_form_description_field',
form_field_placeholder: placeholder,
+ autofocus: 'false',
form_field_classes: 'js-gfm-input markdown-area note-textarea rspec-issuable-form-description' } }
= form.hidden_field :description
diff --git a/app/views/shared/hook_logs/_index.html.haml b/app/views/shared/hook_logs/_index.html.haml
index 7dab14b95c1..ee7d5b79560 100644
--- a/app/views/shared/hook_logs/_index.html.haml
+++ b/app/views/shared/hook_logs/_index.html.haml
@@ -2,10 +2,9 @@
- link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: docs_link_url }
- link_end = '</a>'.html_safe
-.row.gl-mt-3.gl-mb-3
- .col-lg-3
- %h4.gl-mt-0
- = _('Recent events')
- %p= _('GitLab events trigger webhooks. Use the request details of a webhook to help troubleshoot problems. %{link_start}How do I troubleshoot?%{link_end}').html_safe % { link_start: link_start, link_end: link_end }
- .col-lg-9
- = render partial: 'shared/hook_logs/recent_deliveries_table', locals: { hook: hook, hook_logs: hook_logs }
+.settings-section
+ .settings-sticky-header
+ .settings-sticky-header-inner
+ %h4.gl-my-0= _('Recent events')
+ %p.gl-text-secondary= _('GitLab events trigger webhooks. Use the request details of a webhook to help troubleshoot problems. %{link_start}How do I troubleshoot?%{link_end}').html_safe % { link_start: link_start, link_end: link_end }
+ = render partial: 'shared/hook_logs/recent_deliveries_table', locals: { hook: hook, hook_logs: hook_logs }
diff --git a/app/views/shared/integrations/gitlab_slack_application/_slack_button.html.haml b/app/views/shared/integrations/gitlab_slack_application/_slack_button.html.haml
deleted file mode 100644
index b22a6eeca90..00000000000
--- a/app/views/shared/integrations/gitlab_slack_application/_slack_button.html.haml
+++ /dev/null
@@ -1,4 +0,0 @@
-= link_to add_to_slack_link(project, slack_app_id), class: 'btn btn-default gl-button gl-pr-6!' do
- = image_tag 'illustrations/slack_logo.svg', class: 'gl-icon gl-button-icon gl-w-9! gl-h-9! gl-my-n3! gl-mr-0!'
- %strong.gl-button-text
- = label
diff --git a/app/views/shared/integrations/gitlab_slack_application/_slack_integration_form.html.haml b/app/views/shared/integrations/gitlab_slack_application/_slack_integration_form.html.haml
index 5c9f77f8c12..e5d05a8a83d 100644
--- a/app/views/shared/integrations/gitlab_slack_application/_slack_integration_form.html.haml
+++ b/app/views/shared/integrations/gitlab_slack_application/_slack_integration_form.html.haml
@@ -20,13 +20,16 @@
%td{ class: 'gl-py-3!' }
= time_ago_with_tooltip(slack_integration.created_at)
%td{ class: 'gl-py-3!' }
- .controls
+ .controls.gl-display-flex.gl-gap-3
- project = integration.project
- = link_to _('Edit'), edit_project_settings_slack_path(project), class: 'btn gl-button btn-default'
- = link_to sprite_icon('remove', css_class: 'gl-icon'), project_settings_slack_path(project), method: :delete, class: 'btn gl-button btn-danger btn-danger-secondary', aria: { label: s_('SlackIntegration|Remove project') }, data: { confirm_btn_variant: "danger", confirm: s_('SlackIntegration|Are you sure you want to remove this project from the GitLab for Slack app?') }
+ = render Pajamas::ButtonComponent.new(href: edit_project_settings_slack_path(project)) do
+ = _('Edit')
+ = render Pajamas::ButtonComponent.new(method: :delete, category: 'secondary', variant: "danger", href: project_settings_slack_path(project), icon: 'remove', button_options: { aria: { label: s_('SlackIntegration|Remove project') }, data: { confirm_btn_variant: "danger", confirm: s_('SlackIntegration|Are you sure you want to remove this project from the GitLab for Slack app?') }})
.gl-my-5
- = render 'shared/integrations/gitlab_slack_application/slack_button', project: @project, label: s_('SlackIntegration|Reinstall GitLab for Slack app')
+ = render Pajamas::ButtonComponent.new(href: add_to_slack_link(@project, slack_app_id)) do
+ = s_('SlackIntegration|Reinstall GitLab for Slack appā€¦')
%p
= html_escape(s_('SlackIntegration|You may need to reinstall the GitLab for Slack app when we %{linkStart}make updates or change permissions%{linkEnd}.')) % { linkStart: %(<a href="#{help_page_path('user/project/integrations/gitlab_slack_application.md', anchor: 'update-the-gitlab-for-slack-app')}">).html_safe, linkEnd: '</a>'.html_safe}
- else
- = render 'shared/integrations/gitlab_slack_application/slack_button', project: @project, label: s_('SlackIntegration|Install GitLab for Slack app')
+ = render Pajamas::ButtonComponent.new(href: add_to_slack_link(@project, slack_app_id)) do
+ = s_('SlackIntegration|Install GitLab for Slack appā€¦')
diff --git a/app/views/shared/integrations/prometheus/_custom_metrics.html.haml b/app/views/shared/integrations/prometheus/_custom_metrics.html.haml
index 0264196f60c..a7a650aa95d 100644
--- a/app/views/shared/integrations/prometheus/_custom_metrics.html.haml
+++ b/app/views/shared/integrations/prometheus/_custom_metrics.html.haml
@@ -11,7 +11,7 @@
%strong
= s_('PrometheusService|Custom metrics')
= gl_badge_tag 0, nil, class: 'gl-ml-2 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'
+ = link_button_to s_('PrometheusService|New metric'), new_project_prometheus_metric_path(project), class: 'gl-ml-auto js-new-metric-button hidden', variant: :confirm
- c.with_body do
.flash-container.hidden
.flash-warning
diff --git a/app/views/shared/integrations/slack_slash_commands/_help.html.haml b/app/views/shared/integrations/slack_slash_commands/_help.html.haml
index fee0ca15808..43a240fa6fe 100644
--- a/app/views/shared/integrations/slack_slash_commands/_help.html.haml
+++ b/app/views/shared/integrations/slack_slash_commands/_help.html.haml
@@ -57,7 +57,7 @@
= label_tag nil, _('Customize icon'), class: 'col-12 col-form-label label-bold'
.col-12
= image_tag(asset_url('slash-command-logo.png', skip_pipeline: true), width: 36, height: 36, class: 'mr-3')
- = link_to(_('Download image'), asset_url('gitlab_logo.png'), class: 'gl-button btn btn-default btn-sm', target: '_blank', rel: 'noopener noreferrer')
+ = link_button_to _('Download image'), asset_url('gitlab_logo.png'), target: '_blank', rel: 'noopener noreferrer', size: :small
.form-group
= label_tag nil, _('Autocomplete'), class: 'col-12 col-form-label label-bold'
diff --git a/app/views/shared/issuable/_form.html.haml b/app/views/shared/issuable/_form.html.haml
index b6bd691213c..42f035b99aa 100644
--- a/app/views/shared/issuable/_form.html.haml
+++ b/app/views/shared/issuable/_form.html.haml
@@ -61,14 +61,14 @@
= form.submit _('Save changes'), pajamas_button: true, class: 'gl-mr-2 js-issuable-submit-button js-reset-autosave', data: { track_action: 'click_button', track_label: 'submit_mr', track_value: 0 }
- if issuable.new_record?
- = link_to _('Cancel'), polymorphic_path([@project, issuable.class]), class: 'btn gl-button btn-default js-reset-autosave'
+ = link_button_to _('Cancel'), polymorphic_path([@project, issuable.class]), class: 'js-reset-autosave'
- else
- = link_to _('Cancel'), polymorphic_path([@project, issuable]), class: 'gl-button btn btn-default js-reset-autosave'
+ = link_button_to _('Cancel'), polymorphic_path([@project, issuable]), class: 'js-reset-autosave'
- if can?(current_user, :"destroy_#{issuable.to_ability_name}", @project)
- confirm_title = _('Delete %{issuableType}?') % { issuableType: issuable.human_class_name }
- confirm_body = _('Youā€™re about to permanently delete the %{issuableType} ā€˜%{strongOpen}%{issuableTitle}%{strongClose}ā€™. To avoid data loss, consider %{strongOpen}closing this %{issuableType}%{strongClose} instead. Once deleted, it cannot be undone or recovered.') % { issuableType: issuable.human_class_name, issuableTitle: issuable.title, strongOpen: '<strong>', strongClose: '</strong>' }
- confirm_primary_btn_text = _('Delete %{issuableType}') % { issuableType: issuable.human_class_name }
- = link_to _('Delete'), polymorphic_path([@project, issuable], params: { destroy_confirm: true }), data: { title: confirm_title, confirm: confirm_body, is_html_message: true, confirm_btn_variant: 'danger'}, method: :delete, class: 'btn gl-button btn-danger btn-danger-secondary gl-float-right js-reset-autosave', "aria-label": confirm_primary_btn_text
+ = link_button_to _('Delete'), polymorphic_path([@project, issuable], params: { destroy_confirm: true }), data: { title: confirm_title, confirm: confirm_body, is_html_message: true, confirm_btn_variant: 'danger'}, method: :delete, class: 'gl-float-right js-reset-autosave', "aria-label": confirm_primary_btn_text, variant: :danger, category: :secondary
- if issuable.respond_to?(:issue_type)
= form.hidden_field :issue_type
diff --git a/app/views/shared/issuable/_search_bar.html.haml b/app/views/shared/issuable/_search_bar.html.haml
index b8f98c28574..d590c859945 100644
--- a/app/views/shared/issuable/_search_bar.html.haml
+++ b/app/views/shared/issuable/_search_bar.html.haml
@@ -34,7 +34,7 @@
#js-dropdown-hint.filtered-search-input-dropdown-menu.dropdown-menu.hint-dropdown
%ul.filter-dropdown{ data: { dynamic: true, dropdown: true } }
%li.filter-dropdown-item{ data: {hint: "#{'{{hint}}'}", tag: "#{'{{tag}}'}", action: "#{'{{hint === \'search\' ? \'submit\' : \'\' }}'}" } }
- %button.gl-button.btn.btn-link{ type: 'button' }
+ %button.btn.btn-link{ type: 'button' }
-# Encapsulate static class name `{{icon}}` inside #{} to bypass
-# haml lint's ClassAttributeWithStaticValue
%svg
@@ -44,7 +44,7 @@
#js-dropdown-operator.filtered-search-input-dropdown-menu.dropdown-menu
%ul.filter-dropdown{ data: { dropdown: true, dynamic: true } }
%li.filter-dropdown-item{ data: { value: "{{ title }}" } }
- %button.gl-button.btn.btn-link{ type: 'button' }
+ %button.btn.btn-link{ type: 'button' }
{{ title }}
%span.btn-helptext
{{ help }}
@@ -60,10 +60,10 @@
#js-dropdown-assignee.filtered-search-input-dropdown-menu.dropdown-menu
%ul{ data: { dropdown: true } }
%li.filter-dropdown-item{ data: { value: 'None' } }
- %button.gl-button.btn.btn-link{ type: 'button' }
+ %button.btn.btn-link{ type: 'button' }
= _('None')
%li.filter-dropdown-item{ data: { value: 'Any' } }
- %button.gl-button.btn.btn-link{ type: 'button' }
+ %button.btn.btn-link{ type: 'button' }
= _('Any')
%li.divider.droplab-item-ignore
- if current_user
@@ -76,10 +76,10 @@
#js-dropdown-reviewer.filtered-search-input-dropdown-menu.dropdown-menu
%ul{ data: { dropdown: true } }
%li.filter-dropdown-item{ data: { value: 'None' } }
- %button.gl-button.btn.btn-link{ type: 'button' }
+ %button.btn.btn-link{ type: 'button' }
= _('None')
%li.filter-dropdown-item{ data: { value: 'Any' } }
- %button.gl-button.btn.btn-link{ type: 'button' }
+ %button.btn.btn-link{ type: 'button' }
= _('Any')
%li.divider.droplab-item-ignore
- if current_user
@@ -94,101 +94,101 @@
#js-dropdown-milestone.filtered-search-input-dropdown-menu.dropdown-menu
%ul{ data: { dropdown: true } }
%li.filter-dropdown-item{ data: { value: 'None' } }
- %button.gl-button.btn.btn-link{ type: 'button' }
+ %button.btn.btn-link{ type: 'button' }
= _('None')
%li.filter-dropdown-item{ data: { value: 'Any' } }
- %button.gl-button.btn.btn-link{ type: 'button' }
+ %button.btn.btn-link{ type: 'button' }
= _('Any')
%li.filter-dropdown-item{ data: { value: 'Upcoming' } }
- %button.gl-button.btn.btn-link{ type: 'button' }
+ %button.btn.btn-link{ type: 'button' }
= _('Upcoming')
%li.filter-dropdown-item{ data: { value: 'Started' } }
- %button.gl-button.btn.btn-link{ type: 'button' }
+ %button.btn.btn-link{ type: 'button' }
= _('Started')
%li.divider.droplab-item-ignore
%ul.filter-dropdown{ data: { dynamic: true, dropdown: true } }
%li.filter-dropdown-item
- %button.gl-button.btn.btn-link.js-data-value{ type: 'button' }
+ %button.btn.btn-link.js-data-value{ type: 'button' }
{{title}}
= render_if_exists 'shared/issuable/filter_iteration', type: type
#js-dropdown-release.filtered-search-input-dropdown-menu.dropdown-menu
%ul{ data: { dropdown: true } }
%li.filter-dropdown-item{ data: { value: 'None' } }
- %button.gl-button.btn.btn-link{ type: 'button' }
+ %button.btn.btn-link{ type: 'button' }
= _('None')
%li.filter-dropdown-item{ data: { value: 'Any' } }
- %button.gl-button.btn.btn-link{ type: 'button' }
+ %button.btn.btn-link{ type: 'button' }
= _('Any')
%li.divider.droplab-item-ignore
%ul.filter-dropdown{ data: { dynamic: true, dropdown: true } }
%li.filter-dropdown-item
- %button.gl-button.btn.btn-link.js-data-value{ type: 'button' }
+ %button.btn.btn-link.js-data-value{ type: 'button' }
{{title}}
#js-dropdown-label.filtered-search-input-dropdown-menu.dropdown-menu
%ul{ data: { dropdown: true } }
%li.filter-dropdown-item{ data: { value: 'None' } }
- %button.gl-button.btn.btn-link{ type: 'button' }
+ %button.btn.btn-link{ type: 'button' }
= _('None')
%li.filter-dropdown-item{ data: { value: 'Any' } }
- %button.gl-button.btn.btn-link{ type: 'button' }
+ %button.btn.btn-link{ type: 'button' }
= _('Any')
%li.divider.droplab-item-ignore
%ul.filter-dropdown{ data: { dynamic: true, dropdown: true } }
%li.filter-dropdown-item
- %button.gl-button.btn.btn-link{ type: 'button' }
+ %button.btn.btn-link{ type: 'button' }
%span.dropdown-label-box{ style: 'background: {{color}}' }
%span.label-title.js-data-value
{{title}}
#js-dropdown-my-reaction.filtered-search-input-dropdown-menu.dropdown-menu
%ul{ data: { dropdown: true } }
%li.filter-dropdown-item{ data: { value: 'None' } }
- %button.gl-button.btn.btn-link{ type: 'button' }
+ %button.btn.btn-link{ type: 'button' }
= _('None')
%li.filter-dropdown-item{ data: { value: 'Any' } }
- %button.gl-button.btn.btn-link{ type: 'button' }
+ %button.btn.btn-link{ type: 'button' }
= _('Any')
%li.divider.droplab-item-ignore
%ul.filter-dropdown{ data: { dynamic: true, dropdown: true } }
%li.filter-dropdown-item
- %button.gl-button.btn.btn-link{ type: 'button' }
+ %button.btn.btn-link{ type: 'button' }
%gl-emoji
%span.js-data-value.gl-ml-3
{{name}}
#js-dropdown-wip.filtered-search-input-dropdown-menu.dropdown-menu
%ul.filter-dropdown{ data: { dropdown: true } }
%li.filter-dropdown-item{ data: { value: 'yes', capitalize: true } }
- %button.gl-button.btn.btn-link{ type: 'button' }
+ %button.btn.btn-link{ type: 'button' }
= _('Yes')
%li.filter-dropdown-item{ data: { value: 'no', capitalize: true } }
- %button.gl-button.btn.btn-link{ type: 'button' }
+ %button.btn.btn-link{ type: 'button' }
= _('No')
- if ::Feature.enabled?(:mr_approved_filter, type: :ops)
#js-dropdown-approved.filtered-search-input-dropdown-menu.dropdown-menu
%ul.filter-dropdown{ data: { dropdown: true } }
%li.filter-dropdown-item{ data: { value: 'yes', capitalize: true } }
- %button.gl-button.btn.btn-link{ type: 'button' }
+ %button.btn.btn-link{ type: 'button' }
= _('Yes')
%li.filter-dropdown-item{ data: { value: 'no', capitalize: true } }
- %button.gl-button.btn.btn-link{ type: 'button' }
+ %button.btn.btn-link{ type: 'button' }
= _('No')
#js-dropdown-confidential.filtered-search-input-dropdown-menu.dropdown-menu
%ul.filter-dropdown{ data: { dropdown: true } }
%li.filter-dropdown-item{ data: { value: 'yes', capitalize: true } }
- %button.gl-button.btn.btn-link{ type: 'button' }
+ %button.btn.btn-link{ type: 'button' }
= _('Yes')
%li.filter-dropdown-item{ data: { value: 'no', capitalize: true } }
- %button.gl-button.btn.btn-link{ type: 'button' }
+ %button.btn.btn-link{ type: 'button' }
= _('No')
- unless disable_target_branch
#js-dropdown-target-branch.filtered-search-input-dropdown-menu.dropdown-menu
%ul.filter-dropdown{ data: { dynamic: true, dropdown: true } }
%li.filter-dropdown-item
- %button.gl-button.btn.btn-link.js-data-value.monospace
+ %button.btn.btn-link.js-data-value.monospace
{{title}}
#js-dropdown-environment.filtered-search-input-dropdown-menu.dropdown-menu
%ul.filter-dropdown{ data: { dynamic: true, dropdown: true } }
%li.filter-dropdown-item
- %button.gl-button.btn.btn-link.js-data-value{ type: 'button' }
+ %button.btn.btn-link.js-data-value{ type: 'button' }
{{title}}
= render_if_exists 'shared/issuable/filter_weight', type: type
diff --git a/app/views/shared/issuable/_sidebar.html.haml b/app/views/shared/issuable/_sidebar.html.haml
index ee1ca364b07..fadaeafeaf6 100644
--- a/app/views/shared/issuable/_sidebar.html.haml
+++ b/app/views/shared/issuable/_sidebar.html.haml
@@ -12,10 +12,10 @@
- moved_sidebar_enabled = moved_mr_sidebar_enabled?
- is_merge_request_with_flag = is_merge_request && moved_sidebar_enabled
-%aside.right-sidebar.js-right-sidebar.js-issuable-sidebar{ data: { signed: { in: signed_in }, issuable_type: issuable_type }, class: "#{sidebar_gutter_collapsed_class(is_merge_request_with_flag)} #{'right-sidebar-merge-requests' if is_merge_request_with_flag}", 'aria-live' => 'polite', 'aria-label': issuable_type }
+%aside.right-sidebar.js-right-sidebar.js-issuable-sidebar{ data: { always_show_toggle: true, signed: { in: signed_in }, issuable_type: issuable_type }, class: "#{sidebar_gutter_collapsed_class(is_merge_request_with_flag)} #{'right-sidebar-merge-requests' if is_merge_request_with_flag}", 'aria-live' => 'polite', 'aria-label': issuable_type }
.issuable-sidebar{ class: "#{'is-merge-request' if is_merge_request_with_flag}" }
.issuable-sidebar-header{ class: "#{'gl-pb-2! gl-md-display-flex gl-justify-content-end gl-lg-display-none!' if is_merge_request_with_flag}" }
- %button.btn.gl-button.gutter-toggle.float-right.js-sidebar-toggle.has-tooltip{ type: "reset", class: "gl-shadow-none! #{'gl-display-block' if moved_sidebar_enabled}", "aria-label" => _('Toggle sidebar'), title: sidebar_gutter_tooltip_text, data: { container: 'body', placement: 'left', boundary: 'viewport' } }
+ = render Pajamas::ButtonComponent.new(button_options: { class: "gutter-toggle float-right js-sidebar-toggle has-tooltip gl-shadow-none! #{'gl-display-block' if moved_sidebar_enabled}", type: 'button', 'aria-label' => _('Toggle sidebar'), title: sidebar_gutter_tooltip_text, data: { container: 'body', placement: 'left', boundary: 'viewport' } }) do
= sidebar_gutter_toggle_icon
- if signed_in && !is_merge_request_with_flag
.js-sidebar-todo-widget-root{ data: { project_path: issuable_sidebar[:project_full_path], iid: issuable_sidebar[:iid], id: issuable_sidebar[:id] } }
diff --git a/app/views/shared/issuable/_sidebar_assignees.html.haml b/app/views/shared/issuable/_sidebar_assignees.html.haml
index c6f3e4d97a8..a27bb506c87 100644
--- a/app/views/shared/issuable/_sidebar_assignees.html.haml
+++ b/app/views/shared/issuable/_sidebar_assignees.html.haml
@@ -2,7 +2,6 @@
- dropdown_options = assignees_dropdown_options(issuable_type)
.js-sidebar-assignees-root{ data: { field: issuable_type,
- signed_in: signed_in,
max_assignees: dropdown_options[:data][:"max-select"],
directly_invite_members: can_admin_project_member?(@project) } }
.title.hide-collapsed
diff --git a/app/views/shared/issuable/_status_box.html.haml b/app/views/shared/issuable/_status_box.html.haml
index 125ef921cfa..cca51b48322 100644
--- a/app/views/shared/issuable/_status_box.html.haml
+++ b/app/views/shared/issuable/_status_box.html.haml
@@ -2,7 +2,7 @@
- badge_icon = state_name_with_icon(issuable)[1]
- badge_variant = issuable.open? ? :success : issuable.merged? ? :info : :danger
- badge_status_class = issuable.open? ? 'issuable-status-badge-open' : issuable.merged? ? 'issuable-status-badge-merged' : 'issuable-status-badge-closed'
-- badge_classes = "js-mr-status-box issuable-status-badge gl-mr-3 #{badge_status_class} #{'gl-vertical-align-bottom' if issuable.is_a?(MergeRequest)}"
+- badge_classes = "js-mr-status-box issuable-status-badge gl-mr-3 gl-align-self-center #{badge_status_class} #{'gl-vertical-align-bottom' if issuable.is_a?(MergeRequest)}"
= gl_badge_tag({ variant: badge_variant, icon: badge_icon, icon_classes: 'gl-mr-0!' }, { class: badge_classes, data: { project_path: issuable.project.path_with_namespace, iid: issuable.iid, issuable_type: 'merge_request', state: issuable.state } }) do
%span.gl-display-none.gl-sm-display-block.gl-ml-2
diff --git a/app/views/shared/issue_type/_details_header.html.haml b/app/views/shared/issue_type/_details_header.html.haml
index b6c0b73a83d..4997d429587 100644
--- a/app/views/shared/issue_type/_details_header.html.haml
+++ b/app/views/shared/issue_type/_details_header.html.haml
@@ -16,7 +16,6 @@
#js-issuable-header-warnings{ data: { hidden: issue_hidden?(issuable).to_s } }
= issuable_meta(issuable, @project)
- %a.btn.gl-button.btn-default.btn-icon.float-right.gl-display-block.d-sm-none.gutter-toggle.issuable-gutter-toggle.js-sidebar-toggle{ href: "#" }
- = sprite_icon('chevron-double-lg-left')
+ = render Pajamas::ButtonComponent.new(href: '#', icon: 'chevron-double-lg-left', button_options: { class: 'gl-float-right gl-display-block gl-sm-display-none! gutter-toggle issuable-gutter-toggle js-sidebar-toggle' })
.js-issue-header-actions{ data: issue_header_actions_data(@project, issuable, current_user, @issuable_sidebar) }
diff --git a/app/views/shared/members/_manage_access_button.html.haml b/app/views/shared/members/_manage_access_button.html.haml
index c88198ec380..910d62d4dc4 100644
--- a/app/views/shared/members/_manage_access_button.html.haml
+++ b/app/views/shared/members/_manage_access_button.html.haml
@@ -1,7 +1,5 @@
- path = local_assigns.fetch(:path, nil)
.gl-float-right
- = link_to path, class: 'btn btn-default btn-sm gl-button' do
- = sprite_icon('pencil', css_class: 'gl-icon gl-button-icon')
- %span.gl-button-text
- = _('Manage access')
+ = link_button_to path, size: :small, icon: 'pencil' do
+ = _('Manage access')
diff --git a/app/views/shared/members/_member.html.haml b/app/views/shared/members/_member.html.haml
index 376e51a6b15..c86993f5b77 100644
--- a/app/views/shared/members/_member.html.haml
+++ b/app/views/shared/members/_member.html.haml
@@ -43,7 +43,7 @@
= _("Given access %{time_ago}").html_safe % { time_ago: time_ago_with_tooltip(member.created_at) }
%span.js-expires-in{ class: ('gl-display-none' unless member.expires?) }
&middot;
- %span.js-expires-in-text{ class: "has-tooltip#{' text-warning' if member.expires_soon?}", title: (member.expires_at.to_time.in_time_zone.to_s(:medium) if member.expires?) }
+ %span.js-expires-in-text{ class: "has-tooltip#{' text-warning' if member.expires_soon?}", title: (member.expires_at.to_time.in_time_zone.to_fs(:medium) if member.expires?) }
- if member.expires?
- preposition = current_user.time_display_relative ? '' : 'on'
= _("Expires %{preposition} %{expires_at}").html_safe % { expires_at: time_ago_with_tooltip(member.expires_at), preposition: preposition }
diff --git a/app/views/shared/milestones/_labels_tab.html.haml b/app/views/shared/milestones/_labels_tab.html.haml
index d2bee57992d..1e856bf4355 100644
--- a/app/views/shared/milestones/_labels_tab.html.haml
+++ b/app/views/shared/milestones/_labels_tab.html.haml
@@ -8,7 +8,7 @@
= markdown_field(label, :description)
.float-right.d-none.d-lg-block
- = link_to milestones_issues_path(options.merge(state: 'opened')), class: 'btn gl-button btn-default-tertiary' do
- - pluralize milestone_issues_by_label_count(@milestone, label, state: :opened), _('open issue')
- = link_to milestones_issues_path(options.merge(state: 'closed')), class: 'btn gl-button btn-default-tertiary' do
- - pluralize milestone_issues_by_label_count(@milestone, label, state: :closed), _('closed issue')
+ = link_button_to milestones_issues_path(options.merge(state: 'opened')), category: :tertiary do
+ = n_('open issue', 'open issues', milestone_issues_by_label_count(@milestone, label, state: :opened))
+ = link_button_to milestones_issues_path(options.merge(state: 'closed')), category: :tertiary do
+ = n_('closed issue', 'closed issues', milestone_issues_by_label_count(@milestone, label, state: :closed))
diff --git a/app/views/shared/milestones/_milestone.html.haml b/app/views/shared/milestones/_milestone.html.haml
index 01548325c83..c36d3a8b92b 100644
--- a/app/views/shared/milestones/_milestone.html.haml
+++ b/app/views/shared/milestones/_milestone.html.haml
@@ -52,6 +52,6 @@
= render Pajamas::ButtonComponent.new(icon: 'level-up', category: :tertiary, size: :small, button_options: { class: 'js-promote-project-milestone-button', title: s_('Milestones|Promote to Group Milestone'), disabled: true, data: { toggle: 'tooltip', container: 'body', url: promote_project_milestone_path(milestone.project, milestone), milestone_title: milestone.title, group_name: @project.group.name } })
- if can?(current_user, :admin_milestone, milestone)
- if milestone.closed?
- = link_to s_('Milestones|Reopen Milestone'), milestone_path(milestone, milestone: { state_event: :activate }), method: :put, class: "btn gl-button btn-sm gl-ml-3"
+ = link_button_to s_('Milestones|Reopen Milestone'), milestone_path(milestone, milestone: { state_event: :activate }), method: :put, class: 'gl-ml-3', size: :small
- else
- = link_to s_('Milestones|Close Milestone'), milestone_path(milestone, milestone: { state_event: :close }), method: :put, class: "btn gl-button btn-default btn-default-secondary btn-sm gl-ml-3"
+ = link_button_to s_('Milestones|Close Milestone'), milestone_path(milestone, milestone: { state_event: :close }), method: :put, class: 'gl-ml-3', category: :secondary, size: :small
diff --git a/app/views/shared/milestones/_sidebar.html.haml b/app/views/shared/milestones/_sidebar.html.haml
index 5477b9395ea..1b0eeb424c2 100644
--- a/app/views/shared/milestones/_sidebar.html.haml
+++ b/app/views/shared/milestones/_sidebar.html.haml
@@ -26,7 +26,7 @@
.value
%span.value-content{ data: { qa_selector: 'start_date_content' } }
- if milestone.start_date
- %span.bold= milestone.start_date.to_s(:medium)
+ %span.bold= milestone.start_date.to_fs(:medium)
- else
%span.no-value= s_('MilestoneSidebar|No start date')
@@ -63,7 +63,7 @@
.value.hide-collapsed
%span.value-content{ data: { qa_selector: 'due_date_content' } }
- if milestone.due_date
- %span.bold= milestone.due_date.to_s(:medium)
+ %span.bold= milestone.due_date.to_fs(:medium)
- else
%span.no-value= s_('MilestoneSidebar|No due date')
- remaining_days = remaining_days_in_words(milestone.due_date, milestone.start_date)
diff --git a/app/views/shared/nav/_sidebar.html.haml b/app/views/shared/nav/_sidebar.html.haml
index 915352996d9..91b0582e04a 100644
--- a/app/views/shared/nav/_sidebar.html.haml
+++ b/app/views/shared/nav/_sidebar.html.haml
@@ -1,6 +1,6 @@
%aside.nav-sidebar{ class: ('sidebar-collapsed-desktop' if collapsed_sidebar?), **sidebar_tracking_attributes_by_object(sidebar.container), 'aria-label': sidebar.aria_label }
.nav-sidebar-inner-scroll
- %ul.sidebar-top-level-items{ data: { qa_selector: sidebar_qa_selector(sidebar.container) } }
+ %ul.sidebar-top-level-items{ data: { testid: sidebar_qa_selector(sidebar.container) } }
- if sidebar.render_raw_scope_menu_partial
= render sidebar.render_raw_scope_menu_partial
- elsif sidebar.scope_menu
diff --git a/app/views/shared/nav/_sidebar_menu.html.haml b/app/views/shared/nav/_sidebar_menu.html.haml
index bc0648c14e0..27f77ed4813 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.link_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: { testid: '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 eea36127745..ef488d06e87 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.link_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: { testid: 'sidebar_menu_item_link', qa_menu_item: sidebar_menu_item.title } do
%span.gl-flex-grow-1
= sidebar_menu_item.title
- if sidebar_menu_item.sprite_icon
diff --git a/app/views/shared/notes/_form.html.haml b/app/views/shared/notes/_form.html.haml
index 98008fede90..9a5e9b2179f 100644
--- a/app/views/shared/notes/_form.html.haml
+++ b/app/views/shared/notes/_form.html.haml
@@ -5,7 +5,7 @@
- else
- preview_url = preview_markdown_path(@project)
-= form_for form_resources, url: new_form_url, remote: true, html: { :'data-type' => 'json', multipart: true, id: nil, class: "new-note js-new-note-form js-quick-submit common-note-form discussion-reply-holder", "data-noteable-iid" => @note.noteable.try(:iid), }, authenticity_token: true do |f|
+= form_for form_resources, url: new_form_url, remote: true, html: { :'data-type' => 'json', multipart: true, id: nil, class: "new-note js-new-note-form js-quick-submit common-note-form discussion-reply-holder gl-border-top-0!", "data-noteable-iid" => @note.noteable.try(:iid), }, authenticity_token: true do |f|
= hidden_field_tag :view, diff_view
= hidden_field_tag :line_type
= hidden_field_tag :merge_request_diff_head_sha, @note.noteable.try(:diff_head_sha)
@@ -25,14 +25,14 @@
= f.hidden_field :position
.discussion-form-container.discussion-with-resolve-btn.flex-column.p-0
- = render layout: 'shared/md_preview', locals: { url: preview_url, referenced_users: true } do
+ = render layout: 'shared/md_preview', locals: { url: preview_url, referenced_users: true, supports_quick_actions: supports_quick_actions } do
= render 'shared/zen', f: f, qa_selector: 'note_field',
attr: :note,
classes: 'note-textarea js-note-text',
placeholder: _("Write a comment or drag your files hereā€¦"),
supports_quick_actions: supports_quick_actions,
supports_autocomplete: supports_autocomplete
- = render 'shared/notes/hints', supports_quick_actions: supports_quick_actions
+ = render 'shared/notes/hints'
.error-alert
.note-form-actions.clearfix.gl-display-flex.gl-flex-wrap
diff --git a/app/views/shared/notes/_hints.html.haml b/app/views/shared/notes/_hints.html.haml
index d7d6e477ab1..23ce38d50e0 100644
--- a/app/views/shared/notes/_hints.html.haml
+++ b/app/views/shared/notes/_hints.html.haml
@@ -1,13 +1,7 @@
-- supports_quick_actions = local_assigns.fetch(:supports_quick_actions, false)
- supports_file_upload = local_assigns.fetch(:supports_file_upload, true)
-.comment-toolbar.gl-mx-2.gl-mb-2.gl-px-4.gl-bg-gray-10.gl-rounded-bottom-left-base.gl-rounded-bottom-right-base.clearfix
- .toolbar-text.gl-font-sm
- - markdownLinkStart = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: help_page_path('user/markdown') }
- - quickActionsLinkStart = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: help_page_path('user/project/quick_actions') }
- - if supports_quick_actions
- = html_escape(s_('NoteToolbar|Supports %{markdownDocsLinkStart}Markdown%{markdownDocsLinkEnd}. For %{quickActionsDocsLinkStart}quick actions%{quickActionsDocsLinkEnd}, type %{keyboardStart}/%{keyboardEnd}.')) % { markdownDocsLinkStart: markdownLinkStart, markdownDocsLinkEnd: '</a>'.html_safe, quickActionsDocsLinkStart: quickActionsLinkStart, quickActionsDocsLinkEnd: '</a>'.html_safe, keyboardStart: '<kbd>'.html_safe, keyboardEnd: '</kbd>'.html_safe }
- - else
- = html_escape(s_('MarkdownToolbar|Supports %{markdownDocsLinkStart}Markdown%{markdownDocsLinkEnd}')) % { markdownDocsLinkStart: markdownLinkStart, markdownDocsLinkEnd: '</a>'.html_safe }
+.comment-toolbar.gl-px-2.gl-display-flex.gl-justify-content-end.gl-rounded-bottom-left-base.gl-rounded-bottom-right-base.clearfix
+ .content-editor-switcher.gl-display-inline-flex.gl-align-items-center
+ = render Pajamas::ButtonComponent.new(category: :tertiary, icon: 'markdown-mark', size: :small, href: help_page_path('user/markdown'), target: '_blank', button_options: { class: 'gl-px-3!' })
- if supports_file_upload
%span.uploading-container.gl-line-height-32.gl-font-sm
%span.uploading-progress-container.hide
diff --git a/app/views/shared/projects/_search_form.html.haml b/app/views/shared/projects/_search_form.html.haml
index 72709b3ed2f..2388bf2f0be 100644
--- a/app/views/shared/projects/_search_form.html.haml
+++ b/app/views/shared/projects/_search_form.html.haml
@@ -51,5 +51,5 @@
.gl-display-flex.gl-w-full.gl-md-w-auto{ class: 'gl-m-0!' }
.js-namespace-select{ data: { field_name: 'namespace_id', selected_id: namespace&.id, selected_text: selected_text, update_location: 'true' } }
- = link_to new_project_path, class: 'gl-button btn btn-confirm gl-display-inline gl-mb-0!' do
+ = link_button_to new_project_path, class: 'gl-display-inline gl-mb-0!', variant: :confirm do
= _('New Project')
diff --git a/app/views/shared/web_hooks/_form.html.haml b/app/views/shared/web_hooks/_form.html.haml
index 7eafd6ae092..a0e55cd5723 100644
--- a/app/views/shared/web_hooks/_form.html.haml
+++ b/app/views/shared/web_hooks/_form.html.haml
@@ -3,7 +3,7 @@
.js-vue-webhook-form{ data: webhook_form_data(hook) }
.form-group
= form.label :token, s_('Webhooks|Secret token'), class: 'label-bold'
- = form.password_field :token, value: hook.masked_token, autocomplete: 'new-password', class: 'form-control gl-form-input'
+ = form.password_field :token, value: hook.masked_token, autocomplete: 'new-password', class: 'form-control gl-form-input gl-max-w-48'
%p.form-text.text-muted
- code_start = '<code>'.html_safe
- code_end = '</code>'.html_safe
@@ -11,59 +11,66 @@
.form-group
= form.label :url, s_('Webhooks|Trigger'), class: 'label-bold'
%ul.list-unstyled
- %li.gl-pb-5
+ %li.gl-pb-3
.js-vue-push-events{ data: { push_events: hook.push_events.to_s, strategy: hook.branch_filter_strategy, is_new_hook: hook.new_record?.to_s, push_events_branch_filter: hook.push_events_branch_filter } }
- %li.gl-pb-5
+ %li.gl-pb-3
= form.gitlab_ui_checkbox_component :tag_push_events,
integration_webhook_event_human_name(:tag_push_events),
help_text: s_('Webhooks|A new tag is pushed to the repository.')
- %li.gl-pb-5
+ %li.gl-pb-3
= form.gitlab_ui_checkbox_component :note_events,
integration_webhook_event_human_name(:note_events),
help_text: s_('Webhooks|A comment is added to an issue or merge request.')
- %li.gl-pb-5
+ %li.gl-pb-3
= form.gitlab_ui_checkbox_component :confidential_note_events,
integration_webhook_event_human_name(:confidential_note_events),
help_text: s_('Webhooks|A comment is added to a confidential issue.')
- %li.gl-pb-5
+ %li.gl-pb-3
= form.gitlab_ui_checkbox_component :issues_events,
integration_webhook_event_human_name(:issues_events),
help_text: s_('Webhooks|An issue is created, updated, closed, or reopened.')
- %li.gl-pb-5
+ %li.gl-pb-3
= form.gitlab_ui_checkbox_component :confidential_issues_events,
integration_webhook_event_human_name(:confidential_issues_events),
help_text: s_('Webhooks|A confidential issue is created, updated, closed, or reopened.')
- if @group
= render_if_exists 'groups/hooks/member_events', form: form
= render_if_exists 'groups/hooks/subgroup_events', form: form
- %li.gl-pb-5
+ %li.gl-pb-3
= form.gitlab_ui_checkbox_component :merge_requests_events,
integration_webhook_event_human_name(:merge_requests_events),
help_text: s_('Webhooks|A merge request is created, updated, or merged.')
- %li.gl-pb-5
+ %li.gl-pb-3
= form.gitlab_ui_checkbox_component :job_events,
integration_webhook_event_human_name(:job_events),
help_text: s_("Webhooks|A job's status changes.")
- %li.gl-pb-5
+ %li.gl-pb-3
= form.gitlab_ui_checkbox_component :pipeline_events,
integration_webhook_event_human_name(:pipeline_events),
help_text: s_("Webhooks|A pipeline's status changes.")
- %li.gl-pb-5
+ %li.gl-pb-3
= form.gitlab_ui_checkbox_component :wiki_page_events,
integration_webhook_event_human_name(:wiki_page_events),
help_text: s_('Webhooks|A wiki page is created or updated.')
- %li.gl-pb-5
+ %li.gl-pb-3
= form.gitlab_ui_checkbox_component :deployment_events,
integration_webhook_event_human_name(:deployment_events),
help_text: s_('Webhooks|A deployment starts, finishes, fails, or is canceled.')
- %li.gl-pb-5
+ %li.gl-pb-3
= form.gitlab_ui_checkbox_component :feature_flag_events,
integration_webhook_event_human_name(:feature_flag_events),
help_text: s_('Webhooks|A feature flag is turned on or off.')
- %li.gl-pb-5
+ %li.gl-pb-3
= form.gitlab_ui_checkbox_component :releases_events,
integration_webhook_event_human_name(:releases_events),
help_text: s_('Webhooks|A release is created or updated.')
+ - if Feature.enabled?(:emoji_webhooks, hook.parent)
+ %li.gl-pb-5
+ - emoji_help_link = link_to s_('Which emoji events trigger webhooks'), help_page_path('user/project/integrations/webhook_events.md', anchor: 'emoji-events')
+ = form.gitlab_ui_checkbox_component :emoji_events,
+ integration_webhook_event_human_name(:emoji_events),
+ help_text: s_('Webhooks|An emoji is awarded or revoked. %{help_link}?').html_safe % { help_link: emoji_help_link }
+
.form-group
= form.label :enable_ssl_verification, s_('Webhooks|SSL verification'), class: 'label-bold checkbox'
%ul.list-unstyled
diff --git a/app/views/shared/web_hooks/_hook.html.haml b/app/views/shared/web_hooks/_hook.html.haml
index 155a7b1827f..50ce6552616 100644
--- a/app/views/shared/web_hooks/_hook.html.haml
+++ b/app/views/shared/web_hooks/_hook.html.haml
@@ -1,10 +1,10 @@
- sslStatus = hook.enable_ssl_verification ? _('enabled') : _('disabled')
- sslBadgeText = _('SSL Verification:') + ' ' + sslStatus
-%li
- .row
- .col-md-8.col-lg-7
- %strong.light-header
+%li.label-list-item
+ .gl-display-flex.lgl-align-items-center.row.gl-mx-n1
+ .col-md-8.col-lg-7.gl-px-3
+ .light-header.gl-mb-2
= hook.url
- if hook.rate_limited?
= gl_badge_tag(_('Disabled'), variant: :danger, size: :sm)
@@ -19,7 +19,7 @@
= gl_badge_tag(integration_webhook_event_human_name(trigger), size: :sm)
= gl_badge_tag(sslBadgeText, size: :sm)
- .col-md-4.col-lg-5.gl-mt-2.gl-display-flex.gl-md-justify-content-end.gl-align-items-baseline.gl-gap-3
+ .col-md-4.col-lg-5.gl-mt-2.gl-px-3.gl-gap-3.gl-display-flex.gl-md-justify-content-end.gl-align-items-baseline
= render 'shared/web_hooks/test_button', hook: hook, size: 'small'
= render Pajamas::ButtonComponent.new(href: edit_hook_path(hook), size: :small) do
= _('Edit')
diff --git a/app/views/shared/web_hooks/_index.html.haml b/app/views/shared/web_hooks/_index.html.haml
index 8a81e697a59..0ea6a0307ba 100644
--- a/app/views/shared/web_hooks/_index.html.haml
+++ b/app/views/shared/web_hooks/_index.html.haml
@@ -1,13 +1,24 @@
-%hr
-= render Pajamas::CardComponent.new(card_options: { id: 'webhooks-index' }, body_options: { class: 'gl-py-0'}) do |c|
+= render Pajamas::CardComponent.new(card_options: { id: 'webhooks-index', class: 'gl-new-card js-toggle-container' }, header_options: { class: 'gl-new-card-header'}, body_options: { class: 'gl-new-card-body'}) do |c|
- c.with_header do
- = hook_class.underscore.humanize.titleize.pluralize
- (#{hooks.size})
+ .gl-new-card-title-wrapper
+ %h3.gl-new-card-title
+ = hook_class.underscore.humanize.titleize.pluralize
+ %span.gl-new-card-count
+ = sprite_icon('hook', css_class: 'gl-mr-2')
+ #{hooks.size}
+ = render Pajamas::ButtonComponent.new(size: :small, button_options: { class: 'js-toggle-button js-toggle-content' }) do
+ = _('Add new webhook')
- c.with_body do
- - if hooks.any?
- %ul.content-list
- - hooks.each do |hook|
- = render 'shared/web_hooks/hook', hook: hook
- - else
- %p.text-center.gl-mt-3.gl-mb-3
- = _('No webhooks enabled. Select trigger events above.')
+ .gl-new-card-content
+ = gitlab_ui_form_for @hook, as: :hook, url: url, html: { class: 'js-webhook-form gl-new-card-add-form gl-mb-3 gl-display-none js-toggle-content' } do |f|
+ = render partial: partial, locals: { form: f, hook: @hook }
+ = f.submit _('Add webhook'), pajamas_button: true, data: { qa_selector: "create_webhook_button" }
+ = render Pajamas::ButtonComponent.new(button_options: { type: 'reset', class: 'js-webhook-edit-close gl-ml-2 js-toggle-button' }) do
+ = _('Cancel')
+ - if hooks.any?
+ %ul.content-list{ class: 'gl-my-n3!' }
+ - hooks.each do |hook|
+ = render 'shared/web_hooks/hook', hook: hook
+ - else
+ %p.gl-new-card-empty.gl-text-center
+ = _('No webhooks enabled. Select trigger events above.')
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 c220b46f70f..ae32dcea7cb 100644
--- a/app/views/shared/web_hooks/_title_and_docs.html.haml
+++ b/app/views/shared/web_hooks/_title_and_docs.html.haml
@@ -1,10 +1,12 @@
- webhooks_link_start = '<a href="%{url}">'.html_safe % { url: help_page_path(hook.help_path) }
-%h4.gl-mt-0
- = page_title
+.settings-sticky-header
+ .settings-sticky-header-inner
+ %h4.gl-my-0
+ = page_title
- if @project
- 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 }
+ %p.gl-text-secondary= _("%{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 }
+ %p.gl-text-secondary= _("%{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/web_hooks/_web_hook_disabled_alert.html.haml b/app/views/shared/web_hooks/_web_hook_disabled_alert.html.haml
index cbbb2f51fd5..1580fc0bd6d 100644
--- a/app/views/shared/web_hooks/_web_hook_disabled_alert.html.haml
+++ b/app/views/shared/web_hooks/_web_hook_disabled_alert.html.haml
@@ -10,4 +10,4 @@
= succeed '.' do
= link_to _('Learn more'), help_page_path('user/project/integrations/webhooks', anchor: 'troubleshooting'), target: '_blank', rel: 'noopener noreferrer'
- c.with_actions do
- = link_to s_('Webhooks|Go to webhooks'), project_hooks_path(@project, anchor: 'webhooks-index'), class: 'btn gl-alert-action btn-confirm gl-button'
+ = link_button_to s_('Webhooks|Go to webhooks'), project_hooks_path(@project, anchor: 'webhooks-index'), class: 'gl-alert-action', variant: :confirm
diff --git a/app/views/shared/wikis/_main_links.html.haml b/app/views/shared/wikis/_main_links.html.haml
index c1fd8c48c60..41831c95198 100644
--- a/app/views/shared/wikis/_main_links.html.haml
+++ b/app/views/shared/wikis/_main_links.html.haml
@@ -1,6 +1,6 @@
- if @page&.persisted?
- = link_to wiki_page_path(@wiki, @page, action: :history), class: "btn gl-button btn-default", role: "button", data: { qa_selector: 'page_history_button' } do
+ = link_button_to wiki_page_path(@wiki, @page, action: :history), role: "button", data: { qa_selector: 'page_history_button' } do
= s_("Wiki|Page history")
- if can?(current_user, :create_wiki, @wiki.container)
- = link_to wiki_path(@wiki, action: :new), class: "btn gl-button btn-confirm-secondary", role: "button", data: { qa_selector: 'new_page_button' } do
+ = link_button_to wiki_path(@wiki, action: :new), role: "button", data: { qa_selector: 'new_page_button' }, variant: :confirm, category: :secondary do
= s_("Wiki|New page")
diff --git a/app/views/shared/wikis/_sidebar.html.haml b/app/views/shared/wikis/_sidebar.html.haml
index 8b8c981da96..a34827602ab 100644
--- a/app/views/shared/wikis/_sidebar.html.haml
+++ b/app/views/shared/wikis/_sidebar.html.haml
@@ -32,5 +32,5 @@
= render partial: entry.to_partial_path, object: entry, locals: { context: 'sidebar' }
.block.w-100
- if @sidebar_limited
- = link_to wiki_path(@wiki, action: :pages), class: 'btn gl-button btn-block', data: { qa_selector: 'view_all_pages_button' } do
+ = link_button_to wiki_path(@wiki, action: :pages), data: { qa_selector: 'view_all_pages_button' }, block: true do
= s_("Wiki|View All Pages")
diff --git a/app/views/shared/wikis/diff.html.haml b/app/views/shared/wikis/diff.html.haml
index ee6c7f307a7..67772ec40c1 100644
--- a/app/views/shared/wikis/diff.html.haml
+++ b/app/views/shared/wikis/diff.html.haml
@@ -12,7 +12,7 @@
= _('Changes')
.nav-controls.pb-md-3.pb-lg-0
- = link_to wiki_page_path(@wiki, @page, action: :history), class: 'btn gl-button', role: 'button', data: { qa_selector: 'page_history_button' } do
+ = link_button_to wiki_page_path(@wiki, @page, action: :history), role: 'button', data: { qa_selector: 'page_history_button' } do
= s_('Wiki|Page history')
.page-content-header
diff --git a/app/views/shared/wikis/pages.html.haml b/app/views/shared/wikis/pages.html.haml
index f35649d031c..4656bb8d453 100644
--- a/app/views/shared/wikis/pages.html.haml
+++ b/app/views/shared/wikis/pages.html.haml
@@ -8,8 +8,7 @@
= s_("Wiki|Wiki Pages")
.nav-controls.pb-md-3.pb-lg-0
- = link_to wiki_path(@wiki, action: :git_access), class: 'btn gl-button' do
- = sprite_icon('download')
+ = link_button_to wiki_path(@wiki, action: :git_access), icon: 'download' do
= _("Clone repository")
.dropdown.inline.wiki-sort-dropdown
diff --git a/app/views/shared/wikis/show.html.haml b/app/views/shared/wikis/show.html.haml
index 3841113231c..28699ca27f3 100644
--- a/app/views/shared/wikis/show.html.haml
+++ b/app/views/shared/wikis/show.html.haml
@@ -14,18 +14,23 @@
= render 'shared/wikis/main_links'
- if @page.historical?
- .warning_message
- = s_("WikiHistoricalPage|This is an old version of this page.")
- - most_recent_link = link_to s_("WikiHistoricalPage|most recent version"), wiki_page_path(@wiki, @page)
- - history_link = link_to s_("WikiHistoricalPage|history"), wiki_page_path(@wiki, @page, action: :history)
- = (s_("WikiHistoricalPage|You can view the %{most_recent_link} or browse the %{history_link}.") % { most_recent_link: most_recent_link, history_link: history_link }).html_safe
+ = render Pajamas::AlertComponent.new(variant: :warning,
+ dismissible: false) do |c|
+ - c.with_body do
+ = s_("WikiHistoricalPage|This is an old version of this page.")
+ - c.with_actions do
+ .gl-display-flex.gl-gap-3
+ = render Pajamas::ButtonComponent.new(category: :primary, variant: :confirm, href: wiki_page_path(@wiki, @page)) do
+ = s_('WikiHistoricalPage|Go to most recent version')
+ = render Pajamas::ButtonComponent.new(href: wiki_page_path(@wiki, @page, action: :history)) do
+ = s_('WikiHistoricalPage|Browse history')
.gl-mt-5.gl-mb-3
.gl-display-flex.gl-justify-content-space-between
%h2.gl-mt-0.gl-mb-5{ data: { qa_selector: 'wiki_page_title', testid: 'wiki_page_title' } }= @page.human_title
%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' }
+ = render Pajamas::ButtonComponent.new(href: wiki_page_path(@wiki, @page, action: :edit), icon: 'pencil', button_options: { class: 'js-wiki-edit', title: "Edit", data: { qa_selector: 'edit_page_button', testid: 'wiki_edit_button' }})
.js-async-wiki-page-content.md.gl-pt-2{ data: { qa_selector: 'wiki_page_content', testid: 'wiki-page-content', tracking_context: wiki_page_tracking_context(@page).to_json, get_wiki_content_url: wiki_page_render_api_endpoint(@page) } }
diff --git a/app/views/users/_follow_user.html.haml b/app/views/users/_follow_user.html.haml
new file mode 100644
index 00000000000..3ee8c81496c
--- /dev/null
+++ b/app/views/users/_follow_user.html.haml
@@ -0,0 +1,11 @@
+- link_classes = "flex-grow-1 gl-display-inline-block"
+
+- if current_user&.following_users_allowed?(@user)
+ - if current_user.following?(@user)
+ = form_tag user_unfollow_path(@user, :json), class: link_classes do
+ = render Pajamas::ButtonComponent.new(type: :submit, button_options: { class: 'gl-w-full', data: { track_action: 'click_button', track_label: 'unfollow_from_profile' } }) do
+ = _('Unfollow')
+ - else
+ = form_tag user_follow_path(@user, :json), class: link_classes do
+ = render Pajamas::ButtonComponent.new(variant: :confirm, type: :submit, button_options: { class: 'gl-w-full', data: { qa_selector: 'follow_user_link', track_action: 'click_button', track_label: 'follow_from_profile' } }) do
+ = _('Follow')
diff --git a/app/views/users/_overview.html.haml b/app/views/users/_overview.html.haml
index ce82a5e1614..0b76ed6c086 100644
--- a/app/views/users/_overview.html.haml
+++ b/app/views/users/_overview.html.haml
@@ -13,12 +13,10 @@
.col-12.col-md-10.col-lg-8.gl-my-6
.gl-display-flex
%ol.breadcrumb.gl-breadcrumb-list.gl-mb-4
- %li.breadcrumb-item.gl-breadcrumb-item
+ %li.gl-breadcrumb-item
= link_to project_path(@user.user_project) do
= @user.username
- %span.gl-breadcrumb-separator
- = sprite_icon("chevron-right", size: 16)
- %li.breadcrumb-item.gl-breadcrumb-item
+ %li.gl-breadcrumb-item
= link_to @user.user_readme.path, @user.user_project.readme_url
- if current_user == @user
.gl-ml-auto
diff --git a/app/views/users/_profile_basic_info.html.haml b/app/views/users/_profile_basic_info.html.haml
index 7c50031598c..6de9e80008e 100644
--- a/app/views/users/_profile_basic_info.html.haml
+++ b/app/views/users/_profile_basic_info.html.haml
@@ -2,8 +2,9 @@
= render 'middle_dot_divider', stacking: true do
@#{@user.username}
- if can?(current_user, :read_user_profile, @user)
- = render 'middle_dot_divider', stacking: true do
- = s_('UserProfile|User ID: %{id}') % { id: @user.id }
- = clipboard_button(title: s_('UserProfile|Copy user ID'), text: @user.id)
+ - unless Feature.enabled?(:user_profile_overflow_menu_vue)
+ = render 'middle_dot_divider', stacking: true do
+ = s_('UserProfile|User ID: %{id}') % { id: @user.id }
+ = clipboard_button(title: s_('UserProfile|Copy user ID'), text: @user.id)
= render 'middle_dot_divider', stacking: true do
= s_('Member since %{date}') % { date: l(@user.created_at.to_date, format: :long) }
diff --git a/app/views/users/_view_gpg_keys.html.haml b/app/views/users/_view_gpg_keys.html.haml
new file mode 100644
index 00000000000..aa0f69ffe3c
--- /dev/null
+++ b/app/views/users/_view_gpg_keys.html.haml
@@ -0,0 +1,5 @@
+- verified_gpg_keys = @user.gpg_keys.select(&:verified?)
+- if verified_gpg_keys.any?
+ = render Pajamas::ButtonComponent.new(href: user_gpg_keys_path,
+ icon: 'key',
+ button_options: { class: 'gl-flex-grow-1 gl-mx-1 has-tooltip', title: n_('View public GPG key', 'View public GPG keys', verified_gpg_keys.length), data: { toggle: 'tooltip', placement: 'bottom', container: 'body' }})
diff --git a/app/views/users/_view_user_in_admin_area.html.haml b/app/views/users/_view_user_in_admin_area.html.haml
new file mode 100644
index 00000000000..b13f22956f6
--- /dev/null
+++ b/app/views/users/_view_user_in_admin_area.html.haml
@@ -0,0 +1,4 @@
+- if current_user && current_user.admin?
+ = render Pajamas::ButtonComponent.new(href: [:admin, @user],
+ icon: 'user',
+ button_options: { class: 'gl-flex-grow-1 gl-mx-1 has-tooltip', title: s_('UserProfile|View user in admin area'), data: { toggle: 'tooltip', placement: 'bottom', container: 'body' } })
diff --git a/app/views/users/calendar_activities.html.haml b/app/views/users/calendar_activities.html.haml
index 3571031fbfa..e98dd87a307 100644
--- a/app/views/users/calendar_activities.html.haml
+++ b/app/views/users/calendar_activities.html.haml
@@ -1,5 +1,5 @@
%h4.prepend-top-20
- = html_escape(_("Contributions for %{calendar_date}")) % { calendar_date: tag.strong(@calendar_date.to_s(:medium)) }
+ = html_escape(_("Contributions for %{calendar_date}")) % { calendar_date: tag.strong(@calendar_date.to_fs(:medium)) }
- if @events.any?
%ul.bordered-list
diff --git a/app/views/users/show.html.haml b/app/views/users/show.html.haml
index 4113a276416..380d6aacb84 100644
--- a/app/views/users/show.html.haml
+++ b/app/views/users/show.html.haml
@@ -5,7 +5,6 @@
- page_description @user.bio unless @user.blocked? || !@user.confirmed?
- page_itemtype 'http://schema.org/Person'
- add_page_specific_style 'page_bundles/profile'
-- link_classes = "flex-grow-1 mx-1 "
- if show_super_sidebar?
- @left_sidebar = true
- @force_desktop_expanded_sidebar = true
@@ -17,35 +16,32 @@
.user-profile
.cover-block.user-cover-block.gl-border-t.gl-border-b.gl-mt-n1
%div{ class: container_class }
- = render layout: 'users/cover_controls' do
- - if @user == current_user
- = render Pajamas::ButtonComponent.new(href: profile_path,
- icon: 'pencil',
- button_options: { class: 'gl-flex-grow-1 gl-mx-1 has-tooltip', title: s_('UserProfile|Edit profile'), 'aria-label': 'Edit profile', data: { toggle: 'tooltip', placement: 'bottom', container: 'body' }})
- - elsif current_user
- #js-report-abuse{ data: { report_abuse_path: add_category_abuse_reports_path, reported_user_id: @user.id, reported_from_url: user_url(@user) } }
- - verified_gpg_keys = @user.gpg_keys.select(&:verified?)
- - if verified_gpg_keys.any?
- = render Pajamas::ButtonComponent.new(href: user_gpg_keys_path,
- icon: 'key',
- button_options: { class: 'gl-flex-grow-1 gl-mx-1 has-tooltip', title: n_('View public GPG key', 'View public GPG keys', verified_gpg_keys.length), data: { toggle: 'tooltip', placement: 'bottom', container: 'body' }})
- - if can?(current_user, :read_user_profile, @user)
- = render Pajamas::ButtonComponent.new(href: user_path(@user, rss_url_options),
- icon: 'rss',
- button_options: { class: 'gl-flex-grow-1 gl-mx-1 has-tooltip', title: s_('UserProfile|Subscribe'), data: { toggle: 'tooltip', placement: 'bottom', container: 'body' }})
- - if current_user && current_user.admin?
- = render Pajamas::ButtonComponent.new(href: [:admin, @user],
- icon: 'user',
- button_options: { class: 'gl-flex-grow-1 gl-mx-1 has-tooltip', title: s_('UserProfile|View user in admin area'), data: {toggle: 'tooltip', placement: 'bottom', container: 'body'}})
- - if current_user && current_user.following_users_allowed?(@user)
- - if current_user.following?(@user)
- = form_tag user_unfollow_path(@user, :json), class: link_classes + 'gl-display-inline-block' do
- = render Pajamas::ButtonComponent.new(type: :submit, button_options: { class: 'gl-w-full', data: { track_action: 'click_button', track_label: 'unfollow_from_profile' } }) do
- = _('Unfollow')
- - else
- = form_tag user_follow_path(@user, :json), class: link_classes + 'gl-display-inline-block' do
- = render Pajamas::ButtonComponent.new(variant: :confirm, type: :submit, button_options: { class: 'gl-w-full', data: { qa_selector: 'follow_user_link', track_action: 'click_button', track_label: 'follow_from_profile' } }) do
- = _('Follow')
+ - if Feature.enabled?(:user_profile_overflow_menu_vue)
+ .cover-controls.d-flex.px-2.pb-4.d-sm-block.p-sm-0
+ = render 'users/follow_user'
+ -# The following edit button is mutually exclusive to the follow user button, they won't be shown together
+ - if @user == current_user
+ = render Pajamas::ButtonComponent.new(href: profile_path,
+ button_options: { class: 'gl-flex-grow-1', title: s_('UserProfile|Edit profile') }) do
+ = s_("UserProfile|Edit profile")
+ = render 'users/view_gpg_keys'
+ = render 'users/view_user_in_admin_area'
+ .js-user-profile-actions{ data: { user_id: @user.id } }
+ - else
+ = render layout: 'users/cover_controls' do
+ - if @user == current_user
+ = render Pajamas::ButtonComponent.new(href: profile_path,
+ icon: 'pencil',
+ button_options: { class: 'gl-flex-grow-1 gl-mx-1 has-tooltip', title: s_('UserProfile|Edit profile'), 'aria-label': 'Edit profile', data: { toggle: 'tooltip', placement: 'bottom', container: 'body' }})
+ - elsif current_user
+ #js-report-abuse{ data: { report_abuse_path: add_category_abuse_reports_path, reported_user_id: @user.id, reported_from_url: user_url(@user) } }
+ = render 'users/view_gpg_keys'
+ - if can?(current_user, :read_user_profile, @user)
+ = render Pajamas::ButtonComponent.new(href: user_path(@user, rss_url_options),
+ icon: 'rss',
+ button_options: { class: 'gl-flex-grow-1 gl-mx-1 has-tooltip', title: s_('UserProfile|Subscribe'), data: { toggle: 'tooltip', placement: 'bottom', container: 'body' }})
+ = render 'users/view_user_in_admin_area'
+ = render 'users/follow_user'
.profile-header{ class: [('with-no-profile-tabs' if profile_tabs.empty?), ('gl-mb-4!' if show_super_sidebar?)] }
.gl-display-inline-block.gl-mx-8.gl-vertical-align-top