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

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/app/views
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2020-11-19 11:27:35 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2020-11-19 11:27:35 +0300
commit7e9c479f7de77702622631cff2628a9c8dcbc627 (patch)
treec8f718a08e110ad7e1894510980d2155a6549197 /app/views
parente852b0ae16db4052c1c567d9efa4facc81146e88 (diff)
Add latest changes from gitlab-org/gitlab@13-6-stable-eev13.6.0-rc42
Diffstat (limited to 'app/views')
-rw-r--r--app/views/admin/application_settings/_eks.html.haml2
-rw-r--r--app/views/admin/application_settings/_gitpod.html.haml4
-rw-r--r--app/views/admin/application_settings/_outbound.html.haml4
-rw-r--r--app/views/admin/application_settings/_package_registry.html.haml2
-rw-r--r--app/views/admin/application_settings/_plantuml.html.haml2
-rw-r--r--app/views/admin/application_settings/_signin.html.haml4
-rw-r--r--app/views/admin/application_settings/_signup.html.haml54
-rw-r--r--app/views/admin/application_settings/_snowplow.html.haml2
-rw-r--r--app/views/admin/application_settings/_third_party_offers.html.haml2
-rw-r--r--app/views/admin/application_settings/ci/_header.html.haml2
-rw-r--r--app/views/admin/application_settings/ci_cd.html.haml4
-rw-r--r--app/views/admin/application_settings/general.html.haml18
-rw-r--r--app/views/admin/application_settings/network.html.haml16
-rw-r--r--app/views/admin/dashboard/index.html.haml24
-rw-r--r--app/views/admin/dev_ops_report/_report.html.haml30
-rw-r--r--app/views/admin/dev_ops_report/show.html.haml32
-rw-r--r--app/views/admin/groups/show.html.haml10
-rw-r--r--app/views/admin/health_check/show.html.haml2
-rw-r--r--app/views/admin/identities/_identity.html.haml2
-rw-r--r--app/views/admin/jobs/index.html.haml6
-rw-r--r--app/views/admin/projects/show.html.haml19
-rw-r--r--app/views/admin/runners/index.html.haml4
-rw-r--r--app/views/admin/serverless/domains/_form.html.haml2
-rw-r--r--app/views/admin/system_info/show.html.haml4
-rw-r--r--app/views/admin/users/_block_user.html.haml7
-rw-r--r--app/views/admin/users/_modals.html.haml5
-rw-r--r--app/views/admin/users/_user.html.haml12
-rw-r--r--app/views/admin/users/_user_block_effects.html.haml11
-rw-r--r--app/views/admin/users/index.html.haml9
-rw-r--r--app/views/ci/runner/_how_to_setup_runner.html.haml4
-rw-r--r--app/views/ci/runner/_how_to_setup_runner_automatically.html.haml2
-rw-r--r--app/views/ci/variables/_index.html.haml48
-rw-r--r--app/views/clusters/clusters/_details.html.haml2
-rw-r--r--app/views/clusters/clusters/_empty_state.html.haml2
-rw-r--r--app/views/clusters/clusters/_provider_details_form.html.haml2
-rw-r--r--app/views/clusters/clusters/aws/_new.html.haml2
-rw-r--r--app/views/clusters/clusters/gcp/_form.html.haml4
-rw-r--r--app/views/clusters/clusters/user/_form.html.haml2
-rw-r--r--app/views/dashboard/_groups_head.html.haml2
-rw-r--r--app/views/dashboard/_projects_head.html.haml2
-rw-r--r--app/views/dashboard/_snippets_head.html.haml2
-rw-r--r--app/views/dashboard/groups/index.html.haml3
-rw-r--r--app/views/dashboard/todos/_todo.html.haml6
-rw-r--r--app/views/dashboard/todos/index.html.haml6
-rw-r--r--app/views/devise/confirmations/new.html.haml2
-rw-r--r--app/views/devise/mailer/user_admin_approval.html.haml8
-rw-r--r--app/views/devise/mailer/user_admin_approval.text.erb7
-rw-r--r--app/views/devise/passwords/edit.html.haml2
-rw-r--r--app/views/devise/registrations/new.html.haml25
-rw-r--r--app/views/devise/sessions/_new_base.html.haml2
-rw-r--r--app/views/devise/sessions/new.html.haml17
-rw-r--r--app/views/devise/sessions/two_factor.html.haml2
-rw-r--r--app/views/devise/shared/_experimental_separate_sign_up_flow_box.html.haml39
-rw-r--r--app/views/devise/shared/_omniauth_box.html.haml2
-rw-r--r--app/views/devise/shared/_signin_box.html.haml5
-rw-r--r--app/views/devise/shared/_signup_box.html.haml68
-rw-r--r--app/views/devise/shared/_signup_omniauth_providers.haml (renamed from app/views/devise/shared/_experimental_separate_sign_up_flow_omniauth_box.haml)2
-rw-r--r--app/views/devise/shared/_tabs_ldap.html.haml8
-rw-r--r--app/views/devise/unlocks/new.html.haml2
-rw-r--r--app/views/discussions/_discussion.html.haml8
-rw-r--r--app/views/doorkeeper/applications/_delete_form.html.haml2
-rw-r--r--app/views/doorkeeper/applications/_form.html.haml2
-rw-r--r--app/views/doorkeeper/applications/index.html.haml2
-rw-r--r--app/views/doorkeeper/applications/show.html.haml6
-rw-r--r--app/views/doorkeeper/authorizations/new.html.haml4
-rw-r--r--app/views/errors/access_denied.html.haml2
-rw-r--r--app/views/errors/not_found.html.haml2
-rw-r--r--app/views/errors/omniauth_error.html.haml4
-rw-r--r--app/views/events/event/_note.html.haml2
-rw-r--r--app/views/explore/projects/_projects.html.haml3
-rw-r--r--app/views/explore/projects/index.html.haml1
-rw-r--r--app/views/explore/projects/page_out_of_bounds.html.haml2
-rw-r--r--app/views/explore/projects/trending.html.haml2
-rw-r--r--app/views/groups/_home_panel.html.haml39
-rw-r--r--app/views/groups/_invite_members_modal.html.haml5
-rw-r--r--app/views/groups/_invite_members_side_nav_link.html.haml2
-rw-r--r--app/views/groups/dependency_proxies/_url.html.haml12
-rw-r--r--app/views/groups/dependency_proxies/show.html.haml28
-rw-r--r--app/views/groups/group_members/index.html.haml29
-rw-r--r--app/views/groups/issues.html.haml3
-rw-r--r--app/views/groups/labels/index.html.haml2
-rw-r--r--app/views/groups/milestones/_form.html.haml8
-rw-r--r--app/views/groups/milestones/index.html.haml2
-rw-r--r--app/views/groups/runners/_group_runners.html.haml4
-rw-r--r--app/views/groups/settings/repository/_initial_branch_name.html.haml22
-rw-r--r--app/views/groups/settings/repository/show.html.haml1
-rw-r--r--app/views/groups/show.html.haml4
-rw-r--r--app/views/groups/sidebar/_packages.html.haml6
-rw-r--r--app/views/ide/_show.html.haml1
-rw-r--r--app/views/import/_project_status.html.haml11
-rw-r--r--app/views/import/google_code/status.html.haml2
-rw-r--r--app/views/import/shared/_new_project_form.html.haml4
-rw-r--r--app/views/invites/show.html.haml2
-rw-r--r--app/views/jira_connect/subscriptions/index.html.haml9
-rw-r--r--app/views/layouts/_flash.html.haml2
-rw-r--r--app/views/layouts/_google_tag_manager_body.html.haml4
-rw-r--r--app/views/layouts/_google_tag_manager_head.html.haml8
-rw-r--r--app/views/layouts/_head.html.haml13
-rw-r--r--app/views/layouts/_mailer.html.haml8
-rw-r--r--app/views/layouts/_page.html.haml5
-rw-r--r--app/views/layouts/_search.html.haml3
-rw-r--r--app/views/layouts/_startup_js.html.haml2
-rw-r--r--app/views/layouts/devise_experimental_onboarding_issues.html.haml2
-rw-r--r--app/views/layouts/devise_experimental_separate_sign_up_flow.html.haml20
-rw-r--r--app/views/layouts/experiment_mailer.html.haml48
-rw-r--r--app/views/layouts/header/_current_user_dropdown.html.haml9
-rw-r--r--app/views/layouts/header/_default.html.haml3
-rw-r--r--app/views/layouts/header/_registration_enabled_callout.html.haml15
-rw-r--r--app/views/layouts/mailer.html.haml9
-rw-r--r--app/views/layouts/nav/_breadcrumbs.html.haml4
-rw-r--r--app/views/layouts/nav/_dashboard.html.haml10
-rw-r--r--app/views/layouts/nav/sidebar/_admin.html.haml2
-rw-r--r--app/views/layouts/nav/sidebar/_project.html.haml21
-rw-r--r--app/views/layouts/project.html.haml1
-rw-r--r--app/views/layouts/unknown_user_mailer.html.haml8
-rw-r--r--app/views/layouts/unknown_user_mailer.text.erb9
-rw-r--r--app/views/layouts/welcome.html.haml8
-rw-r--r--app/views/notify/_issuable_csv_export.html.haml2
-rw-r--r--app/views/notify/_note_email.html.haml2
-rw-r--r--app/views/notify/instance_access_request_email.html.haml10
-rw-r--r--app/views/notify/instance_access_request_email.text.erb8
-rw-r--r--app/views/notify/member_invited_email.html.haml20
-rw-r--r--app/views/notify/member_invited_email.text.erb11
-rw-r--r--app/views/notify/member_invited_email_experiment.html.haml12
-rw-r--r--app/views/notify/member_invited_email_experiment.text.erb10
-rw-r--r--app/views/notify/prometheus_alert_fired_email.html.haml6
-rw-r--r--app/views/notify/prometheus_alert_fired_email.text.erb5
-rw-r--r--app/views/profiles/_event_table.html.haml2
-rw-r--r--app/views/profiles/preferences/_gitpod.html.haml9
-rw-r--r--app/views/profiles/preferences/_integrations.html.haml18
-rw-r--r--app/views/profiles/preferences/_sourcegraph.html.haml10
-rw-r--r--app/views/profiles/preferences/show.html.haml255
-rw-r--r--app/views/profiles/show.html.haml10
-rw-r--r--app/views/projects/_find_file_link.html.haml2
-rw-r--r--app/views/projects/_home_panel.html.haml16
-rw-r--r--app/views/projects/_invite_members_modal.html.haml7
-rw-r--r--app/views/projects/_invite_members_side_nav_link.html.haml3
-rw-r--r--app/views/projects/_merge_request_merge_options_settings.html.haml1
-rw-r--r--app/views/projects/_remove.html.haml3
-rw-r--r--app/views/projects/_remove_fork.html.haml10
-rw-r--r--app/views/projects/_service_desk_settings.html.haml2
-rw-r--r--app/views/projects/_stat_anchor_list.html.haml2
-rw-r--r--app/views/projects/_transfer.html.haml16
-rw-r--r--app/views/projects/alert_management/details.html.haml1
-rw-r--r--app/views/projects/artifacts/_artifact.html.haml4
-rw-r--r--app/views/projects/artifacts/_tree_file.html.haml2
-rw-r--r--app/views/projects/artifacts/browse.html.haml2
-rw-r--r--app/views/projects/blob/_breadcrumb.html.haml8
-rw-r--r--app/views/projects/blob/_header.html.haml4
-rw-r--r--app/views/projects/blob/_header_content.html.haml2
-rw-r--r--app/views/projects/blob/_pipeline_tour_success.html.haml2
-rw-r--r--app/views/projects/blob/_upload.html.haml2
-rw-r--r--app/views/projects/blob/viewers/_gitlab_ci_yml.html.haml4
-rw-r--r--app/views/projects/blob/viewers/_metrics_dashboard_yml.html.haml4
-rw-r--r--app/views/projects/blob/viewers/_route_map.html.haml4
-rw-r--r--app/views/projects/branches/_branch.html.haml4
-rw-r--r--app/views/projects/branches/_delete_protected_modal.html.haml2
-rw-r--r--app/views/projects/branches/index.html.haml4
-rw-r--r--app/views/projects/branches/new.html.haml6
-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/_xcode_link.html.haml2
-rw-r--r--app/views/projects/ci/lints/_create.html.haml51
-rw-r--r--app/views/projects/ci/lints/_lint_warnings.html.haml10
-rw-r--r--app/views/projects/ci/lints/show.html.haml30
-rw-r--r--app/views/projects/ci/pipeline_editor/show.html.haml6
-rw-r--r--app/views/projects/cleanup/_show.html.haml2
-rw-r--r--app/views/projects/commit/_change.html.haml4
-rw-r--r--app/views/projects/commit/diff_files.html.haml4
-rw-r--r--app/views/projects/commits/_commit.html.haml6
-rw-r--r--app/views/projects/commits/show.html.haml3
-rw-r--r--app/views/projects/confluences/show.html.haml2
-rw-r--r--app/views/projects/cycle_analytics/show.html.haml2
-rw-r--r--app/views/projects/default_branch/_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.haml7
-rw-r--r--app/views/projects/diffs/_file_header.html.haml17
-rw-r--r--app/views/projects/diffs/_line.html.haml29
-rw-r--r--app/views/projects/diffs/_stats.html.haml2
-rw-r--r--app/views/projects/edit.html.haml28
-rw-r--r--app/views/projects/environments/_external_url.html.haml2
-rw-r--r--app/views/projects/environments/_form.html.haml4
-rw-r--r--app/views/projects/environments/_metrics_button.html.haml2
-rw-r--r--app/views/projects/environments/_pin_button.html.haml2
-rw-r--r--app/views/projects/environments/_terminal_button.html.haml2
-rw-r--r--app/views/projects/environments/empty_metrics.html.haml2
-rw-r--r--app/views/projects/environments/show.html.haml11
-rw-r--r--app/views/projects/environments/terminal.html.haml2
-rw-r--r--app/views/projects/generic_commit_statuses/_generic_commit_status.html.haml5
-rw-r--r--app/views/projects/hooks/index.html.haml2
-rw-r--r--app/views/projects/imports/new.html.haml2
-rw-r--r--app/views/projects/incidents/show.html.haml7
-rw-r--r--app/views/projects/issuable/_show.html.haml10
-rw-r--r--app/views/projects/issues/_design_management.html.haml2
-rw-r--r--app/views/projects/issues/_discussion.html.haml4
-rw-r--r--app/views/projects/issues/_issue.html.haml5
-rw-r--r--app/views/projects/issues/_issues.html.haml3
-rw-r--r--app/views/projects/issues/_nav_btns.html.haml8
-rw-r--r--app/views/projects/issues/_new_branch.html.haml4
-rw-r--r--app/views/projects/issues/_service_desk_empty_state.html.haml2
-rw-r--r--app/views/projects/issues/_service_desk_info_content.html.haml2
-rw-r--r--app/views/projects/issues/export_csv/_modal.html.haml22
-rw-r--r--app/views/projects/issues/import_csv/_modal.html.haml2
-rw-r--r--app/views/projects/issues/show.html.haml101
-rw-r--r--app/views/projects/jobs/index.html.haml1
-rw-r--r--app/views/projects/jobs/show.html.haml2
-rw-r--r--app/views/projects/labels/index.html.haml4
-rw-r--r--app/views/projects/logs/empty_logs.html.haml2
-rw-r--r--app/views/projects/mattermosts/_no_teams.html.haml4
-rw-r--r--app/views/projects/mattermosts/_team_selection.html.haml8
-rw-r--r--app/views/projects/merge_requests/_mr_title.html.haml8
-rw-r--r--app/views/projects/merge_requests/_nav_btns.html.haml9
-rw-r--r--app/views/projects/merge_requests/conflicts/_submit_form.html.haml2
-rw-r--r--app/views/projects/merge_requests/conflicts/components/_diff_file_editor.html.haml5
-rw-r--r--app/views/projects/merge_requests/conflicts/show.html.haml2
-rw-r--r--app/views/projects/merge_requests/creations/_new_compare.html.haml3
-rw-r--r--app/views/projects/merge_requests/creations/new.html.haml1
-rw-r--r--app/views/projects/merge_requests/show.html.haml1
-rw-r--r--app/views/projects/milestones/_form.html.haml4
-rw-r--r--app/views/projects/milestones/index.html.haml2
-rw-r--r--app/views/projects/mirrors/_authentication_method.html.haml2
-rw-r--r--app/views/projects/mirrors/_mirror_repos.html.haml6
-rw-r--r--app/views/projects/mirrors/_mirror_repos_form.html.haml2
-rw-r--r--app/views/projects/mirrors/_ssh_host_keys.html.haml2
-rw-r--r--app/views/projects/new.html.haml2
-rw-r--r--app/views/projects/no_repo.html.haml9
-rw-r--r--app/views/projects/pages/_ssl_limitations_warning.html.haml2
-rw-r--r--app/views/projects/pages_domains/_dns.html.haml2
-rw-r--r--app/views/projects/pages_domains/_lets_encrypt_callout.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/edit.html.haml1
-rw-r--r--app/views/projects/pipeline_schedules/index.html.haml4
-rw-r--r--app/views/projects/pipeline_schedules/new.html.haml1
-rw-r--r--app/views/projects/pipelines/_info.html.haml9
-rw-r--r--app/views/projects/pipelines/_with_tabs.html.haml4
-rw-r--r--app/views/projects/pipelines/index.html.haml1
-rw-r--r--app/views/projects/pipelines/new.html.haml4
-rw-r--r--app/views/projects/pipelines/show.html.haml3
-rw-r--r--app/views/projects/project_members/_team.html.haml10
-rw-r--r--app/views/projects/project_members/index.html.haml5
-rw-r--r--app/views/projects/runners/_runner.html.haml4
-rw-r--r--app/views/projects/runners/_specific_runners.html.haml7
-rw-r--r--app/views/projects/services/prometheus/_metrics.html.haml3
-rw-r--r--app/views/projects/settings/ci_cd/_form.html.haml5
-rw-r--r--app/views/projects/settings/ci_cd/show.html.haml4
-rw-r--r--app/views/projects/settings/operations/_alert_management.html.haml1
-rw-r--r--app/views/projects/settings/operations/_error_tracking.html.haml2
-rw-r--r--app/views/projects/show.html.haml1
-rw-r--r--app/views/projects/tags/_tag.html.haml7
-rw-r--r--app/views/projects/terraform/index.html.haml4
-rw-r--r--app/views/projects/tree/_tree_header.html.haml2
-rw-r--r--app/views/projects/tree/show.html.haml4
-rw-r--r--app/views/registrations/welcome/show.html.haml (renamed from app/views/registrations/welcome.html.haml)4
-rw-r--r--app/views/search/_filter.html.haml19
-rw-r--r--app/views/search/_form.html.haml2
-rw-r--r--app/views/search/_results.html.haml75
-rw-r--r--app/views/search/_sort_dropdown.html.haml16
-rw-r--r--app/views/search/results/_blob_data.html.haml2
-rw-r--r--app/views/search/results/_empty.html.haml4
-rw-r--r--app/views/search/results/_filters.html.haml7
-rw-r--r--app/views/search/results/_issuable.html.haml10
-rw-r--r--app/views/search/results/_issue.html.haml14
-rw-r--r--app/views/search/results/_merge_request.html.haml15
-rw-r--r--app/views/search/results/_wiki_blob.html.haml7
-rw-r--r--app/views/sent_notifications/unsubscribe.html.haml4
-rw-r--r--app/views/shared/_broadcast_message.html.haml4
-rw-r--r--app/views/shared/_file_highlight.html.haml5
-rw-r--r--app/views/shared/_issuable_meta_data.html.haml2
-rw-r--r--app/views/shared/_label.html.haml5
-rw-r--r--app/views/shared/_label_row.html.haml6
-rw-r--r--app/views/shared/_ping_consent.html.haml20
-rw-r--r--app/views/shared/_remote_mirror_update_button.html.haml8
-rw-r--r--app/views/shared/access_tokens/_form.html.haml5
-rw-r--r--app/views/shared/boards/_show.html.haml5
-rw-r--r--app/views/shared/boards/components/sidebar/_assignee.html.haml2
-rw-r--r--app/views/shared/boards/components/sidebar/_due_date.html.haml2
-rw-r--r--app/views/shared/boards/components/sidebar/_labels.html.haml2
-rw-r--r--app/views/shared/boards/components/sidebar/_milestone.html.haml2
-rw-r--r--app/views/shared/form_elements/_apply_template_warning.html.haml5
-rw-r--r--app/views/shared/form_elements/_description.html.haml3
-rw-r--r--app/views/shared/groups/_empty_state.html.haml11
-rw-r--r--app/views/shared/groups/_search_form.html.haml2
-rw-r--r--app/views/shared/issuable/_close_reopen_button.html.haml5
-rw-r--r--app/views/shared/issuable/_close_reopen_report_toggle.html.haml4
-rw-r--r--app/views/shared/issuable/_form.html.haml2
-rw-r--r--app/views/shared/issuable/_label_dropdown.html.haml2
-rw-r--r--app/views/shared/issuable/_search_bar.html.haml3
-rw-r--r--app/views/shared/issuable/_sidebar.html.haml14
-rw-r--r--app/views/shared/issuable/_sort_dropdown.html.haml2
-rw-r--r--app/views/shared/issuable/csv_export/_button.html.haml (renamed from app/views/projects/issues/export_csv/_button.html.haml)2
-rw-r--r--app/views/shared/issuable/csv_export/_modal.html.haml29
-rw-r--r--app/views/shared/issuable/form/_type_selector.html.haml2
-rw-r--r--app/views/shared/issue_type/_details_content.html.haml31
-rw-r--r--app/views/shared/issue_type/_details_header.html.haml55
-rw-r--r--app/views/shared/issue_type/_emoji_block.html.haml9
-rw-r--r--app/views/shared/issue_type/_sentry_stack_trace.html.haml4
-rw-r--r--app/views/shared/members/_filter_2fa_dropdown.html.haml4
-rw-r--r--app/views/shared/members/_invite_group.html.haml2
-rw-r--r--app/views/shared/members/_invite_member.html.haml4
-rw-r--r--app/views/shared/members/_member.html.haml20
-rw-r--r--app/views/shared/members/_requests.html.haml9
-rw-r--r--app/views/shared/members/_search_field.html.haml2
-rw-r--r--app/views/shared/members/_sort_dropdown.html.haml10
-rw-r--r--app/views/shared/milestones/_delete_button.html.haml2
-rw-r--r--app/views/shared/milestones/_header.html.haml10
-rw-r--r--app/views/shared/milestones/_labels_tab.html.haml6
-rw-r--r--app/views/shared/milestones/_milestone.html.haml6
-rw-r--r--app/views/shared/notes/_comment_button.html.haml4
-rw-r--r--app/views/shared/notes/_hints.html.haml19
-rw-r--r--app/views/shared/notes/_note.html.haml2
-rw-r--r--app/views/shared/notes/_notes_with_form.html.haml2
-rw-r--r--app/views/shared/notifications/_custom_notifications.html.haml3
-rw-r--r--app/views/shared/notifications/_new_button.html.haml5
-rw-r--r--app/views/shared/projects/_search_form.html.haml1
-rw-r--r--app/views/shared/web_hooks/_form.html.haml12
-rw-r--r--app/views/shared/wikis/_sidebar.html.haml2
-rw-r--r--app/views/sherlock/transactions/_file_samples.html.haml2
-rw-r--r--app/views/sherlock/transactions/_queries.html.haml2
-rw-r--r--app/views/sherlock/transactions/index.html.haml4
-rw-r--r--app/views/snippets/notes/_actions.html.haml2
-rw-r--r--app/views/snippets/show.html.haml6
-rw-r--r--app/views/users/_groups.html.haml5
-rw-r--r--app/views/users/_overview.html.haml16
-rw-r--r--app/views/users/show.html.haml19
-rw-r--r--app/views/users/terms/index.html.haml6
328 files changed, 1396 insertions, 1359 deletions
diff --git a/app/views/admin/application_settings/_eks.html.haml b/app/views/admin/application_settings/_eks.html.haml
index 68324425ef9..5c0e544eaad 100644
--- a/app/views/admin/application_settings/_eks.html.haml
+++ b/app/views/admin/application_settings/_eks.html.haml
@@ -3,7 +3,7 @@
.settings-header
%h4
= _('Amazon EKS')
- %button.btn.js-settings-toggle{ type: 'button' }
+ %button.btn.gl-button.js-settings-toggle{ type: 'button' }
= expanded ? 'Collapse' : 'Expand'
%p
= _('Amazon EKS integration allows you to provision EKS clusters from GitLab.')
diff --git a/app/views/admin/application_settings/_gitpod.html.haml b/app/views/admin/application_settings/_gitpod.html.haml
index f0a1fd5e763..1baec07fa25 100644
--- a/app/views/admin/application_settings/_gitpod.html.haml
+++ b/app/views/admin/application_settings/_gitpod.html.haml
@@ -5,10 +5,10 @@
.settings-header
%h4
= _('Gitpod')
- %button.btn.btn-default.js-settings-toggle{ type: 'button' }
+ %button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' }
= expanded ? _('Collapse') : _('Expand')
%p
- = gitpod_enable_description
+ %integration-help-text{ "id" => "js-gitpod-settings-help-text", "message" => gitpod_enable_description, "message-url" => "https://gitpod.io/" }
= link_to sprite_icon('question-o'), help_page_path('integration/gitpod.md'), target: '_blank', class: 'has-tooltip', title: _('More information')
diff --git a/app/views/admin/application_settings/_outbound.html.haml b/app/views/admin/application_settings/_outbound.html.haml
index 4f38ab3ab7a..db0a87c366e 100644
--- a/app/views/admin/application_settings/_outbound.html.haml
+++ b/app/views/admin/application_settings/_outbound.html.haml
@@ -13,9 +13,9 @@
= _('Allow requests to the local network from system hooks')
.form-group
- = f.label :outbound_local_requests_whitelist_raw, class: 'label-bold' do
+ = f.label :outbound_local_requests_allowlist_raw, class: 'label-bold' do
= _('Local IP addresses and domain names that hooks and services may access.')
- = f.text_area :outbound_local_requests_whitelist_raw, placeholder: "example.com, 192.168.1.1", class: 'form-control', rows: 8
+ = f.text_area :outbound_local_requests_allowlist_raw, placeholder: "example.com, 192.168.1.1", class: 'form-control', rows: 8
%span.form-text.text-muted
= _('Requests to these domain(s)/address(es) on the local network will be allowed when local requests from hooks and services are not allowed. IP ranges such as 1:0:0:0:0:0:0:0/124 or 127.0.0.0/28 are supported. Domain wildcards are not supported currently. Use comma, semicolon, or newline to separate multiple entries. The allowlist can hold a maximum of 1000 entries. Domains should use IDNA encoding. Ex: example.com, 192.168.1.1, 127.0.0.0/28, xn--itlab-j1a.com.')
diff --git a/app/views/admin/application_settings/_package_registry.html.haml b/app/views/admin/application_settings/_package_registry.html.haml
index 257a90252cc..8c956a43e22 100644
--- a/app/views/admin/application_settings/_package_registry.html.haml
+++ b/app/views/admin/application_settings/_package_registry.html.haml
@@ -3,7 +3,7 @@
.settings-header
%h4
= _('Package Registry')
- %button.btn.btn-default.js-settings-toggle{ type: 'button' }
+ %button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' }
= expanded_by_default? ? _('Collapse') : _('Expand')
%p
= _("Settings related to the use and experience of using GitLab's Package Registry.")
diff --git a/app/views/admin/application_settings/_plantuml.html.haml b/app/views/admin/application_settings/_plantuml.html.haml
index 324f544a108..30acb773424 100644
--- a/app/views/admin/application_settings/_plantuml.html.haml
+++ b/app/views/admin/application_settings/_plantuml.html.haml
@@ -3,7 +3,7 @@
.settings-header
%h4
= _('PlantUML')
- %button.btn.btn-default.js-settings-toggle{ type: 'button' }
+ %button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' }
= expanded ? _('Collapse') : _('Expand')
%p
= _('Allow rendering of PlantUML diagrams in Asciidoc documents.')
diff --git a/app/views/admin/application_settings/_signin.html.haml b/app/views/admin/application_settings/_signin.html.haml
index 4a8616beff6..66fd0087c3e 100644
--- a/app/views/admin/application_settings/_signin.html.haml
+++ b/app/views/admin/application_settings/_signin.html.haml
@@ -50,11 +50,11 @@
= f.text_field :home_page_url, class: 'form-control', placeholder: 'http://company.example.com', :'aria-describedby' => 'home_help_block'
%span.form-text.text-muted#home_help_block We will redirect non-logged in users to this page
.form-group
- = f.label :after_sign_out_path, class: 'label-bold'
+ = f.label :after_sign_out_path, _('After sign-out path'), class: 'label-bold'
= f.text_field :after_sign_out_path, class: 'form-control', placeholder: 'http://company.example.com', :'aria-describedby' => 'after_sign_out_path_help_block'
%span.form-text.text-muted#after_sign_out_path_help_block We will redirect users to this page after they sign out
.form-group
- = f.label :sign_in_text, class: 'label-bold'
+ = f.label :sign_in_text, _('Sign-in text'), class: 'label-bold'
= f.text_area :sign_in_text, class: 'form-control', rows: 4
.form-text.text-muted Markdown enabled
= f.submit 'Save changes', class: "gl-button btn btn-success"
diff --git a/app/views/admin/application_settings/_signup.html.haml b/app/views/admin/application_settings/_signup.html.haml
index 98b49a236a3..c3deb8af99e 100644
--- a/app/views/admin/application_settings/_signup.html.haml
+++ b/app/views/admin/application_settings/_signup.html.haml
@@ -9,19 +9,21 @@
Sign-up enabled
.form-text.text-muted
= _("When enabled, any user visiting %{host} will be able to create an account.") % { host: "#{new_user_session_url(host: Gitlab.config.gitlab.host)}" }
- - if Feature.enabled?(:admin_approval_for_new_user_signups, default_enabled: true)
- .form-group
- .form-check
- = f.check_box :require_admin_approval_after_user_signup, class: 'form-check-input'
- = f.label :require_admin_approval_after_user_signup, class: 'form-check-label' do
- = _('Require admin approval for new sign-ups')
- .form-text.text-muted
- = _("When enabled, any user visiting %{host} and creating an account will have to be explicitly approved by an admin before they can sign in. This setting is effective only if sign-ups are enabled.") % { host: "#{new_user_session_url(host: Gitlab.config.gitlab.host)}" }
+ .form-group
+ .form-check
+ = f.check_box :require_admin_approval_after_user_signup, class: 'form-check-input'
+ = f.label :require_admin_approval_after_user_signup, class: 'form-check-label' do
+ = _('Require admin approval for new sign-ups')
+ .form-text.text-muted
+ = _("When enabled, any user visiting %{host} and creating an account will have to be explicitly approved by an admin before they can sign in. This setting is effective only if sign-ups are enabled.") % { host: "#{new_user_session_url(host: Gitlab.config.gitlab.host)}" }
.form-group
.form-check
= f.check_box :send_user_confirmation_email, class: 'form-check-input'
= f.label :send_user_confirmation_email, class: 'form-check-label' do
Send confirmation email on sign-up
+
+ = render_if_exists 'admin/application_settings/new_user_signups_cap', form: f
+
.form-group
= f.label :minimum_password_length, _('Minimum password length (number of characters)'), class: 'label-bold'
= f.number_field :minimum_password_length, class: 'form-control', rows: 4, min: ApplicationSetting::DEFAULT_MINIMUM_PASSWORD_LENGTH, max: Devise.password_length.max
@@ -29,33 +31,33 @@
.form-text.text-muted
= _("See GitLab's %{password_policy_guidelines}").html_safe % { password_policy_guidelines: password_policy_guidelines_link }
.form-group
- = f.label :domain_whitelist, 'Whitelisted domains for sign-ups', class: 'label-bold'
- = f.text_area :domain_whitelist_raw, placeholder: 'domain.com', class: 'form-control', rows: 8
+ = f.label :domain_allowlist, _('Allowed domains for sign-ups'), class: 'label-bold'
+ = f.text_area :domain_allowlist_raw, placeholder: 'domain.com', class: 'form-control', rows: 8
.form-text.text-muted ONLY users with e-mail addresses that match these domain(s) will be able to sign-up. Wildcards allowed. Use separate lines for multiple entries. Ex: domain.com, *.domain.com
.form-group
- = f.label :domain_blacklist_enabled, 'Domain Blacklist', class: 'label-bold'
+ = f.label :domain_denylist_enabled, _('Domain denylist'), class: 'label-bold'
.form-check
- = f.check_box :domain_blacklist_enabled, class: 'form-check-input'
- = f.label :domain_blacklist_enabled, class: 'form-check-label' do
- Enable domain blacklist for sign ups
+ = f.check_box :domain_denylist_enabled, class: 'form-check-input'
+ = f.label :domain_denylist_enabled, class: 'form-check-label' do
+ Enable domain denylist for sign ups
.form-group
.form-check
- = radio_button_tag :blacklist_type, :file, false, class: 'form-check-input'
- = label_tag :blacklist_type_file, class: 'form-check-label' do
+ = radio_button_tag :denylist_type, :file, false, class: 'form-check-input'
+ = label_tag :denylist_type_file, class: 'form-check-label' do
.option-title
- Upload blacklist file
+ Upload denylist file
.form-check
- = radio_button_tag :blacklist_type, :raw, @application_setting.domain_blacklist.present? || @application_setting.domain_blacklist.blank?, class: 'form-check-input'
- = label_tag :blacklist_type_raw, class: 'form-check-label' do
+ = radio_button_tag :denylist_type, :raw, @application_setting.domain_denylist.present? || @application_setting.domain_denylist.blank?, class: 'form-check-input'
+ = label_tag :denylist_type_raw, class: 'form-check-label' do
.option-title
- Enter blacklist manually
- .form-group.blacklist-file
- = f.label :domain_blacklist_file, 'Blacklist file', class: 'label-bold'
- = f.file_field :domain_blacklist_file, class: 'form-control', accept: '.txt,.conf'
+ Enter denylist manually
+ .form-group.js-denylist-file
+ = f.label :domain_denylist_file, _('Denylist file'), class: 'label-bold'
+ = f.file_field :domain_denylist_file, class: 'form-control', accept: '.txt,.conf'
.form-text.text-muted Users with e-mail addresses that match these domain(s) will NOT be able to sign-up. Wildcards allowed. Use separate lines or commas for multiple entries.
- .form-group.blacklist-raw
- = f.label :domain_blacklist, 'Blacklisted domains for sign-ups', class: 'label-bold'
- = f.text_area :domain_blacklist_raw, placeholder: 'domain.com', class: 'form-control', rows: 8
+ .form-group.js-denylist-raw
+ = f.label :domain_denylist, _('Denied domains for sign-ups'), class: 'label-bold'
+ = f.text_area :domain_denylist_raw, placeholder: 'domain.com', class: 'form-control', rows: 8
.form-text.text-muted Users with e-mail addresses that match these domain(s) will NOT be able to sign-up. Wildcards allowed. Use separate lines for multiple entries. Ex: domain.com, *.domain.com
.form-group
= f.label :email_restrictions_enabled, _('Email restrictions'), class: 'label-bold'
diff --git a/app/views/admin/application_settings/_snowplow.html.haml b/app/views/admin/application_settings/_snowplow.html.haml
index 7c2c5e0b3dc..c1edaf9ff29 100644
--- a/app/views/admin/application_settings/_snowplow.html.haml
+++ b/app/views/admin/application_settings/_snowplow.html.haml
@@ -3,7 +3,7 @@
.settings-header
%h4
= _('Snowplow')
- %button.btn.btn-default.js-settings-toggle{ type: 'button' }
+ %button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' }
= expanded ? _('Collapse') : _('Expand')
%p
= _('Configure the %{link} integration.').html_safe % { link: link_to('Snowplow', 'https://snowplowanalytics.com/', target: '_blank') }
diff --git a/app/views/admin/application_settings/_third_party_offers.html.haml b/app/views/admin/application_settings/_third_party_offers.html.haml
index 7e3e063118e..32023b11993 100644
--- a/app/views/admin/application_settings/_third_party_offers.html.haml
+++ b/app/views/admin/application_settings/_third_party_offers.html.haml
@@ -3,7 +3,7 @@
.settings-header
%h4
= _('Third party offers')
- %button.btn.btn-default.js-settings-toggle{ type: 'button' }
+ %button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' }
= expanded ? _('Collapse') : _('Expand')
%p
= _('Control the display of third party offers.')
diff --git a/app/views/admin/application_settings/ci/_header.html.haml b/app/views/admin/application_settings/ci/_header.html.haml
index 6ff35a42efd..0a0f8aaf032 100644
--- a/app/views/admin/application_settings/ci/_header.html.haml
+++ b/app/views/admin/application_settings/ci/_header.html.haml
@@ -4,7 +4,7 @@
= _('Variables')
= link_to sprite_icon('question-o', css_class: 'gl-vertical-align-baseline!'), help_page_path('ci/variables/README', anchor: 'custom-environment-variables'), target: '_blank', rel: 'noopener noreferrer'
-%button.btn.btn-default.js-settings-toggle{ type: 'button' }
+%button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' }
= expanded ? _('Collapse') : _('Expand')
%p
diff --git a/app/views/admin/application_settings/ci_cd.html.haml b/app/views/admin/application_settings/ci_cd.html.haml
index cdb69d33b12..b05e8621d07 100644
--- a/app/views/admin/application_settings/ci_cd.html.haml
+++ b/app/views/admin/application_settings/ci_cd.html.haml
@@ -17,7 +17,7 @@
.settings-header
%h4
= _('Continuous Integration and Deployment')
- %button.btn.btn-default.js-settings-toggle{ type: 'button' }
+ %button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' }
= expanded_by_default? ? _('Collapse') : _('Expand')
%p
= _('Auto DevOps, runners and job artifacts')
@@ -33,7 +33,7 @@
.settings-header
%h4
= _('Container Registry')
- %button.btn.btn-default.js-settings-toggle{ type: 'button' }
+ %button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' }
= expanded_by_default? ? _('Collapse') : _('Expand')
%p
= _('Various container registry settings.')
diff --git a/app/views/admin/application_settings/general.html.haml b/app/views/admin/application_settings/general.html.haml
index 2d336bebc8d..5c3f68843a2 100644
--- a/app/views/admin/application_settings/general.html.haml
+++ b/app/views/admin/application_settings/general.html.haml
@@ -6,7 +6,7 @@
.settings-header
%h4
= _('Visibility and access controls')
- %button.btn.js-settings-toggle{ type: 'button' }
+ %button.btn.gl-button.js-settings-toggle{ type: 'button' }
= expanded_by_default? ? _('Collapse') : _('Expand')
%p
= _('Set default and restrict visibility levels. Configure import sources and git access protocol.')
@@ -17,7 +17,7 @@
.settings-header
%h4
= _('Account and limit')
- %button.btn.js-settings-toggle{ type: 'button' }
+ %button.btn.gl-button.js-settings-toggle{ type: 'button' }
= expanded_by_default? ? _('Collapse') : _('Expand')
%p
= _('Set projects and maximum size limits, session duration, user options, and check feature availability for namespace plan.')
@@ -28,7 +28,7 @@
.settings-header
%h4
= _('Diff limits')
- %button.btn.js-settings-toggle{ type: 'button' }
+ %button.btn.gl-button.js-settings-toggle{ type: 'button' }
= expanded_by_default? ? _('Collapse') : _('Expand')
%p
= _('Diff content limits')
@@ -39,7 +39,7 @@
.settings-header
%h4
= _('Sign-up restrictions')
- %button.btn.js-settings-toggle{ type: 'button' }
+ %button.btn.gl-button.js-settings-toggle{ type: 'button' }
= expanded_by_default? ? _('Collapse') : _('Expand')
%p
= _('Configure the way a user creates a new account.')
@@ -50,7 +50,7 @@
.settings-header
%h4
= _('Sign-in restrictions')
- %button.btn.js-settings-toggle{ type: 'button' }
+ %button.btn.gl-button.js-settings-toggle{ type: 'button' }
= expanded_by_default? ? _('Collapse') : _('Expand')
%p
= _('Set requirements for a user to sign-in. Enable mandatory two-factor authentication.')
@@ -61,7 +61,7 @@
.settings-header
%h4
= _('Terms of Service and Privacy Policy')
- %button.btn.btn-default.js-settings-toggle{ type: 'button' }
+ %button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' }
= expanded_by_default? ? _('Collapse') : _('Expand')
%p
= _('Include a Terms of Service agreement and Privacy Policy that all users must accept.')
@@ -74,7 +74,7 @@
.settings-header
%h4
= _('Web terminal')
- %button.btn.btn-default.js-settings-toggle{ type: 'button' }
+ %button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' }
= expanded_by_default? ? _('Collapse') : _('Expand')
%p
= _('Set max session time for web terminal.')
@@ -85,7 +85,7 @@
.settings-header
%h4
= _('Web IDE')
- %button.btn.btn-default.js-settings-toggle{ type: 'button' }
+ %button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' }
= expanded_by_default? ? _('Collapse') : _('Expand')
%p
= _('Manage Web IDE features')
@@ -108,7 +108,7 @@
.settings-header
%h4
= _('Maintenance mode')
- %button.btn.btn-default.js-settings-toggle{ type: 'button' }
+ %button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' }
= expanded_by_default? ? _('Collapse') : _('Expand')
%p
= _('Prevent users from performing write operations on GitLab while performing maintenance.')
diff --git a/app/views/admin/application_settings/network.html.haml b/app/views/admin/application_settings/network.html.haml
index 40fa86d8ea3..f977a8c93fa 100644
--- a/app/views/admin/application_settings/network.html.haml
+++ b/app/views/admin/application_settings/network.html.haml
@@ -6,7 +6,7 @@
.settings-header
%h4
= _('Performance optimization')
- %button.btn.btn-default.js-settings-toggle{ type: 'button' }
+ %button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' }
= expanded_by_default? ? _('Collapse') : _('Expand')
%p
= _('Various settings that affect GitLab performance.')
@@ -17,7 +17,7 @@
.settings-header
%h4
= _('User and IP Rate Limits')
- %button.btn.btn-default.js-settings-toggle{ type: 'button' }
+ %button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' }
= expanded_by_default? ? _('Collapse') : _('Expand')
%p
= _('Configure limits for web and API requests.')
@@ -28,7 +28,7 @@
.settings-header
%h4
= _('Outbound requests')
- %button.btn.btn-default.js-settings-toggle{ type: 'button' }
+ %button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' }
= expanded_by_default? ? _('Collapse') : _('Expand')
%p
= _('Allow requests to the local network from hooks and services.')
@@ -39,10 +39,14 @@
.settings-header
%h4
= _('Protected Paths')
- %button.btn.btn-default.js-settings-toggle{ type: 'button' }
+ %button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' }
= expanded_by_default? ? _('Collapse') : _('Expand')
%p
= _('Configure paths to be protected by Rack Attack.')
+ .help-block
+ = _('These paths are protected for POST requests.')
+ = link_to _('More information'), help_page_path('security/rack_attack', anchor: 'protected-paths-throttle'), target: '_blank'
+
.settings-content
= render 'protected_paths'
@@ -50,7 +54,7 @@
.settings-header
%h4
= _('Issues Rate Limits')
- %button.btn.btn-default.js-settings-toggle{ type: 'button' }
+ %button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' }
= expanded_by_default? ? _('Collapse') : _('Expand')
%p
= _('Configure limit for issues created per minute by web and API requests.')
@@ -61,7 +65,7 @@
.settings-header
%h4
= _('Import/Export Rate Limits')
- %button.btn.btn-default.js-settings-toggle{ type: 'button' }
+ %button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' }
= expanded_by_default? ? _('Collapse') : _('Expand')
%p
= _('Configure limits for Project/Group Import/Export.')
diff --git a/app/views/admin/dashboard/index.html.haml b/app/views/admin/dashboard/index.html.haml
index b0d4a3fd8f5..220a211cca6 100644
--- a/app/views/admin/dashboard/index.html.haml
+++ b/app/views/admin/dashboard/index.html.haml
@@ -1,5 +1,7 @@
- breadcrumb_title _("Dashboard")
- page_title _("Dashboard")
+- billable_users_url = help_page_path('subscriptions/self_managed/index', anchor: 'billable-users')
+- billable_users_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer nofollow">'.html_safe % { url: billable_users_url }
- if @notices
- @notices.each do |notice|
@@ -8,7 +10,9 @@
= notice[:message].html_safe
- if @license.present? && show_license_breakdown?
- = render_if_exists 'admin/licenses/breakdown'
+ .license-panel.gl-mt-5
+ = render_if_exists 'admin/licenses/summary'
+ = render_if_exists 'admin/licenses/breakdown'
.admin-dashboard.gl-mt-3
.row
@@ -22,10 +26,20 @@
= link_to(s_('AdminArea|New project'), new_project_path, class: "btn gl-button btn-success gl-w-full")
.col-sm-4
.info-well.dark-well
- .well-segment.well-centered
+ .well-segment.well-centered.gl-text-center
= link_to admin_users_path do
- %h3.text-center
+ %h3.gl-display-inline-block.gl-mb-0
= s_('AdminArea|Users: %{number_of_users}') % { number_of_users: approximate_count_with_delimiters(@counts, User) }
+
+ %span.gl-outline-0.gl-ml-2{ href: "#", tabindex: "0", data: { container: "body",
+ toggle: "popover",
+ placement: "top",
+ html: "true",
+ trigger: "focus",
+ content: s_("AdminArea|All users created in the instance, including users who are not %{billable_users_link_start}billable users%{billable_users_link_end}.").html_safe % { billable_users_link_start: billable_users_link_start, billable_users_link_end: '</a>'.html_safe },
+ } }
+ = sprite_icon('question', size: 16, css_class: 'gl-text-gray-700 gl-mb-1')
+
%hr
.btn-group.d-flex{ role: 'group' }
= link_to s_('AdminArea|New user'), new_admin_user_path, class: "btn gl-button btn-success gl-w-full"
@@ -126,6 +140,10 @@
%span.float-right
= Gitlab::Database.version
%p
+ = _('Redis')
+ %span.float-right
+ = @redis_versions&.join(", ")
+ %p
= link_to _("Gitaly Servers"), admin_gitaly_servers_path
.row
.col-md-4
diff --git a/app/views/admin/dev_ops_report/_report.html.haml b/app/views/admin/dev_ops_report/_report.html.haml
new file mode 100644
index 00000000000..24c805d273a
--- /dev/null
+++ b/app/views/admin/dev_ops_report/_report.html.haml
@@ -0,0 +1,30 @@
+- usage_ping_enabled = Gitlab::CurrentSettings.usage_ping_enabled
+
+- if usage_ping_enabled && show_callout?('dev_ops_report_intro_callout_dismissed')
+ = render 'callout'
+
+- if !usage_ping_enabled
+ #js-devops-empty-state{ data: { is_admin: current_user&.admin.to_s, empty_state_svg_path: image_path('illustrations/convdev/convdev_no_index.svg'), enable_usage_ping_link: metrics_and_profiling_admin_application_settings_path(anchor: 'js-usage-settings'), docs_link: help_page_path('development/product_analytics/usage_ping') } }
+- elsif @metric.blank?
+ = render 'no_data'
+- else
+ .devops
+ .devops-header
+ %h2.devops-header-title{ class: "devops-#{score_level(@metric.average_percentage_score)}-score" }
+ = number_to_percentage(@metric.average_percentage_score, precision: 1)
+ .devops-header-subtitle
+ = s_('DevopsReport|DevOps')
+ %br
+ = s_('DevopsReport|Score')
+ = link_to sprite_icon('question-o', css_class: 'devops-header-icon'), help_page_path('user/admin_area/analytics/dev_ops_report')
+
+ .devops-cards.board-card-container
+ - @metric.cards.each do |card|
+ = render 'card', card: card
+
+ .devops-steps.d-none.d-lg-block
+ - @metric.idea_to_production_steps.each_with_index do |step, index|
+ .devops-step{ class: "devops-#{score_level(step.percentage_score)}-score" }
+ = custom_icon("i2p_step_#{index + 1}")
+ %h4.devops-step-title
+ = step.title
diff --git a/app/views/admin/dev_ops_report/show.html.haml b/app/views/admin/dev_ops_report/show.html.haml
index 88105be70fb..dc3bda3a994 100644
--- a/app/views/admin/dev_ops_report/show.html.haml
+++ b/app/views/admin/dev_ops_report/show.html.haml
@@ -1,34 +1,10 @@
- page_title _('DevOps Report')
-- usage_ping_enabled = Gitlab::CurrentSettings.usage_ping_enabled
- add_page_specific_style 'page_bundles/dev_ops_report'
.container
- - if usage_ping_enabled && show_callout?('dev_ops_report_intro_callout_dismissed')
- = render 'callout'
-
.gl-mt-3
- - if !usage_ping_enabled
- #js-devops-empty-state{ data: { is_admin: current_user&.admin.to_s, empty_state_svg_path: image_path('illustrations/convdev/convdev_no_index.svg'), enable_usage_ping_link: metrics_and_profiling_admin_application_settings_path(anchor: 'js-usage-settings'), docs_link: help_page_path('development/product_analytics/usage_ping') } }
- - elsif @metric.blank?
- = render 'no_data'
- - else
- .devops
- .devops-header
- %h2.devops-header-title{ class: "devops-#{score_level(@metric.average_percentage_score)}-score" }
- = number_to_percentage(@metric.average_percentage_score, precision: 1)
- .devops-header-subtitle
- = _('DevOps')
- %br
- = _('Score')
- = link_to sprite_icon('question-o', css_class: 'devops-header-icon'), help_page_path('user/admin_area/analytics/dev_ops_report')
-
- .devops-cards.board-card-container
- - @metric.cards.each do |card|
- = render 'card', card: card
+ - if Gitlab.ee? && Feature.enabled?(:devops_adoption_feature) && License.feature_available?(:devops_adoption)
+ = render_if_exists 'admin/dev_ops_report/devops_tabs'
+ - else
+ = render 'report'
- .devops-steps.d-none.d-lg-block
- - @metric.idea_to_production_steps.each_with_index do |step, index|
- .devops-step{ class: "devops-#{score_level(step.percentage_score)}-score" }
- = custom_icon("i2p_step_#{index + 1}")
- %h4.devops-step-title
- = step.title
diff --git a/app/views/admin/groups/show.html.haml b/app/views/admin/groups/show.html.haml
index 424251f543e..386df99717b 100644
--- a/app/views/admin/groups/show.html.haml
+++ b/app/views/admin/groups/show.html.haml
@@ -1,6 +1,7 @@
- add_to_breadcrumbs _("Groups"), admin_groups_path
- breadcrumb_title @group.name
- page_title @group.name, _("Groups")
+- current_user_is_group_owner = @group && @group.has_owner?(current_user)
.js-remove-member-modal
%h3.page-title
@@ -116,7 +117,7 @@
= select_tag :access_level, options_for_select(@group.access_level_roles), class: "project-access-select select2"
%hr
= button_tag _('Add users to group'), class: "gl-button btn btn-success"
- = render 'shared/members/requests', membership_source: @group, requesters: @requesters, force_mobile_view: true
+ = render 'shared/members/requests', membership_source: @group, group: @group, requesters: @requesters, force_mobile_view: true
.card
.card-header
@@ -127,6 +128,11 @@
= sprite_icon('pencil-square', css_class: 'gl-icon')
= _('Manage access')
%ul.content-list.group-users-list.content-list.members-list
- = render partial: 'shared/members/member', collection: @members, as: :member, locals: { show_controls: false }
+ = render partial: 'shared/members/member',
+ collection: @members, as: :member,
+ locals: { membership_source: @group,
+ group: @group,
+ show_controls: false,
+ current_user_is_group_owner: current_user_is_group_owner }
.card-footer
= paginate @members, param_name: 'members_page', theme: 'gitlab'
diff --git a/app/views/admin/health_check/show.html.haml b/app/views/admin/health_check/show.html.haml
index 76e4fa971a3..78f0fd325fb 100644
--- a/app/views/admin/health_check/show.html.haml
+++ b/app/views/admin/health_check/show.html.haml
@@ -30,7 +30,7 @@
= sprite_icon('check', css_class: 'cgreen')
#{ s_('HealthCheck|Healthy') }
- else
- = icon('warning', class: 'cred')
+ = sprite_icon('warning-solid', css_class: 'cred')
#{ s_('HealthCheck|Unhealthy') }
.card-body
- if no_errors
diff --git a/app/views/admin/identities/_identity.html.haml b/app/views/admin/identities/_identity.html.haml
index d8facbb780a..d852e4a2463 100644
--- a/app/views/admin/identities/_identity.html.haml
+++ b/app/views/admin/identities/_identity.html.haml
@@ -1,6 +1,6 @@
%tr
%td
- #{Gitlab::Auth::OAuth::Provider.label_for(identity.provider)} (#{identity.provider})
+ #{Gitlab::Auth::OAuth::Provider.label_for(identity.provider)} (#{identity.provider}) #{identity.saml_provider_id.present? ? "for #{link_to identity.saml_provider.group.path, identity.saml_provider.group} ID: #{identity.saml_provider_id}".html_safe : ""}
%td
= identity.extern_uid
%td
diff --git a/app/views/admin/jobs/index.html.haml b/app/views/admin/jobs/index.html.haml
index d482ae04c08..8eaf84c8df9 100644
--- a/app/views/admin/jobs/index.html.haml
+++ b/app/views/admin/jobs/index.html.haml
@@ -6,11 +6,9 @@
= render "shared/builds/tabs", build_path_proc: build_path_proc, all_builds: @all_builds, scope: @scope
- if @all_builds.running_or_pending.any?
- #stop-jobs-modal
+ #js-stop-jobs-modal
.nav-controls
- %button#stop-jobs-button.btn.gl-button.btn-danger{ data: { toggle: 'modal',
- target: '#stop-jobs-modal',
- url: cancel_all_admin_jobs_path } }
+ %button#js-stop-jobs-button.btn.gl-button.btn-danger{ data: { url: cancel_all_admin_jobs_path } }
= s_('AdminArea|Stop all jobs')
.row-content-block.second-block
diff --git a/app/views/admin/projects/show.html.haml b/app/views/admin/projects/show.html.haml
index 417fd1d60eb..aae1d5b6a4e 100644
--- a/app/views/admin/projects/show.html.haml
+++ b/app/views/admin/projects/show.html.haml
@@ -2,6 +2,7 @@
- breadcrumb_title @project.full_name
- page_title @project.full_name, _("Projects")
- @content_class = "admin-projects"
+- current_user_is_group_owner = @group && @group.has_owner?(current_user)
.js-remove-member-modal
%h3.page-title
@@ -13,7 +14,7 @@
- if @project.last_repository_check_failed?
.row
.col-md-12
- .gl-alert.gl-alert-danger.gl-mb-5
+ .gl-alert.gl-alert-danger.gl-mb-5{ data: { testid: 'last-repository-check-failed-alert' } }
= sprite_icon('error', size: 16, css_class: 'gl-icon gl-alert-icon gl-alert-icon-no-title')
.gl-alert-body
- last_check_message = _("Last repository check (%{last_check_timestamp}) failed. See the 'repocheck.log' file for error messages.")
@@ -183,11 +184,16 @@
= sprite_icon('pencil-square', css_class: 'gl-icon')
= _('Manage access')
%ul.content-list.members-list
- = render partial: 'shared/members/member', collection: @group_members, as: :member, locals: { show_controls: false }
+ = render partial: 'shared/members/member',
+ collection: @group_members, as: :member,
+ locals: { membership_source: @project,
+ group: @group,
+ show_controls: false,
+ current_user_is_group_owner: current_user_is_group_owner }
.card-footer
= paginate @group_members, param_name: 'group_members_page', theme: 'gitlab'
- = render 'shared/members/requests', membership_source: @project, requesters: @requesters, force_mobile_view: true
+ = render 'shared/members/requests', membership_source: @project, group: @group, requesters: @requesters, force_mobile_view: true
.card
.card-header
@@ -199,6 +205,11 @@
= sprite_icon('pencil-square', css_class: 'gl-icon')
= _('Manage access')
%ul.content-list.project_members.members-list
- = render partial: 'shared/members/member', collection: @project_members, as: :member, locals: { show_controls: false }
+ = render partial: 'shared/members/member',
+ collection: @project_members, as: :member,
+ locals: { membership_source: @project,
+ group: @group,
+ show_controls: false,
+ current_user_is_group_owner: current_user_is_group_owner }
.card-footer
= paginate @project_members, param_name: 'project_members_page', theme: 'gitlab'
diff --git a/app/views/admin/runners/index.html.haml b/app/views/admin/runners/index.html.haml
index 3d3b8c28a17..c2d7b63f1f9 100644
--- a/app/views/admin/runners/index.html.haml
+++ b/app/views/admin/runners/index.html.haml
@@ -39,7 +39,9 @@
= render partial: 'ci/runner/how_to_setup_runner',
locals: { registration_token: Gitlab::CurrentSettings.runners_registration_token,
type: 'shared',
- reset_token_url: reset_registration_token_admin_application_settings_path }
+ reset_token_url: reset_registration_token_admin_application_settings_path,
+ project_path: '',
+ group_path: '' }
.row
.col-sm-9
diff --git a/app/views/admin/serverless/domains/_form.html.haml b/app/views/admin/serverless/domains/_form.html.haml
index 8f0dd0cab8e..e4b054c7480 100644
--- a/app/views/admin/serverless/domains/_form.html.haml
+++ b/app/views/admin/serverless/domains/_form.html.haml
@@ -36,7 +36,7 @@
= clipboard_button(target: '#serverless_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 to 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.").html_safe % { link_to_help: link_to_help }
- else
.form-group
diff --git a/app/views/admin/system_info/show.html.haml b/app/views/admin/system_info/show.html.haml
index 312ca62cfdf..ca6efe9b095 100644
--- a/app/views/admin/system_info/show.html.haml
+++ b/app/views/admin/system_info/show.html.haml
@@ -9,7 +9,7 @@
- if @cpus
%h2= _('%{cores} cores') % { cores: @cpus.length }
- else
- = icon('warning', class: 'text-warning')
+ = sprite_icon('warning-solid', css_class: 'text-warning')
= _('Unable to collect CPU info')
.bg-light.light-well.gl-mt-3
%h4= _('Memory Usage')
@@ -17,7 +17,7 @@
- if @memory
%h2 #{number_to_human_size(@memory.active_bytes)} / #{number_to_human_size(@memory.total_bytes)}
- else
- = icon('warning', class: 'text-warning')
+ = sprite_icon('warning-solid', css_class: 'text-warning')
= _('Unable to collect memory info')
.bg-light.light-well.gl-mt-3
%h4= _('Uptime')
diff --git a/app/views/admin/users/_block_user.html.haml b/app/views/admin/users/_block_user.html.haml
index b07a72c3e28..29029986345 100644
--- a/app/views/admin/users/_block_user.html.haml
+++ b/app/views/admin/users/_block_user.html.haml
@@ -2,10 +2,7 @@
.card-header.bg-warning.text-white
= s_('AdminUsers|Block this user')
.card-body
- = render partial: 'admin/users/user_block_effects'
+ = user_block_effects
%br
- %button.btn.gl-button.btn-warning{ data: { 'gl-modal-action': 'block',
- content: s_('AdminUsers|You can always unblock their account, their data will remain intact.'),
- url: block_admin_user_path(user),
- username: sanitize_name(user.name) } }
+ %button.btn.gl-button.btn-warning.js-confirm-modal-button{ data: user_block_data(user, s_('AdminUsers|You can always unblock their account, their data will remain intact.')) }
= s_('AdminUsers|Block user')
diff --git a/app/views/admin/users/_modals.html.haml b/app/views/admin/users/_modals.html.haml
index a8e5d962e5b..e56bbd06575 100644
--- a/app/views/admin/users/_modals.html.haml
+++ b/app/views/admin/users/_modals.html.haml
@@ -5,11 +5,6 @@
action: s_("AdminUsers|Deactivate") } }
= render partial: 'admin/users/user_deactivation_effects'
- %div{ data: { modal: "block",
- title: s_("AdminUsers|Block user %{username}?"),
- action: s_("AdminUsers|Block") } }
- = render partial: 'admin/users/user_block_effects'
-
%div{ data: { modal: "delete",
title: s_("AdminUsers|Delete User %{username}?"),
action: s_('AdminUsers|Delete user'),
diff --git a/app/views/admin/users/_user.html.haml b/app/views/admin/users/_user.html.haml
index 70ab95bfa61..679c4805280 100644
--- a/app/views/admin/users/_user.html.haml
+++ b/app/views/admin/users/_user.html.haml
@@ -24,10 +24,10 @@
.table-action-buttons
= link_to _('Edit'), edit_admin_user_path(user), id: "edit_#{dom_id(user)}", class: 'btn gl-button btn-default'
- unless user == current_user
- %button.dropdown-new.btn.gl-button.btn-default{ type: 'button', data: { toggle: 'dropdown' } }
+ %button.dropdown-new.btn.gl-button.btn-default{ type: 'button', data: { testid: "user-action-button-#{user.id}", toggle: 'dropdown' } }
= sprite_icon('settings')
= sprite_icon('chevron-down')
- %ul.dropdown-menu.dropdown-menu-right
+ %ul.dropdown-menu.dropdown-menu-right{ data: { testid: "user-action-dropdown-#{user.id}" } }
%li.dropdown-header
= _('Settings')
%li
@@ -37,16 +37,12 @@
- elsif user.blocked?
- if user.blocked_pending_approval?
= link_to s_('AdminUsers|Approve'), approve_admin_user_path(user), method: :put
- %button.btn.btn-default-tertiary{ data: { 'gl-modal-action': 'block',
- url: block_admin_user_path(user),
- username: sanitize_name(user.name) } }
+ %button.btn.btn-default-tertiary.js-confirm-modal-button{ data: user_block_data(user, user_block_effects) }
= s_('AdminUsers|Block')
- else
= link_to _('Unblock'), unblock_admin_user_path(user), method: :put
- else
- %button.btn.btn-default-tertiary{ data: { 'gl-modal-action': 'block',
- url: block_admin_user_path(user),
- username: sanitize_name(user.name) } }
+ %button.btn.btn-default-tertiary.js-confirm-modal-button{ data: user_block_data(user, user_block_effects) }
= s_('AdminUsers|Block')
- if user.can_be_deactivated?
%li
diff --git a/app/views/admin/users/_user_block_effects.html.haml b/app/views/admin/users/_user_block_effects.html.haml
deleted file mode 100644
index 8ffbe145169..00000000000
--- a/app/views/admin/users/_user_block_effects.html.haml
+++ /dev/null
@@ -1,11 +0,0 @@
-%p
- = s_('AdminUsers|Blocking user has the following effects:')
-%ul
- %li
- = s_('AdminUsers|User will not be able to login')
- %li
- = s_('AdminUsers|User will not be able to access git repositories')
- %li
- = s_('AdminUsers|Personal projects will be left')
- %li
- = s_('AdminUsers|Owned groups will be left')
diff --git a/app/views/admin/users/index.html.haml b/app/views/admin/users/index.html.haml
index 33faef92646..2e179d2d845 100644
--- a/app/views/admin/users/index.html.haml
+++ b/app/views/admin/users/index.html.haml
@@ -30,11 +30,10 @@
= link_to admin_users_path(filter: "blocked") do
= s_('AdminUsers|Blocked')
%small.badge.badge-pill= limited_counter_with_delimiter(User.blocked)
- - if Feature.enabled?(:admin_approval_for_new_user_signups, default_enabled: true)
- = nav_link(html_options: { class: "#{active_when(params[:filter] == 'blocked_pending_approval')} filter-blocked-pending-approval" }) do
- = link_to admin_users_path(filter: "blocked_pending_approval") do
- = s_('AdminUsers|Pending approval')
- %small.badge.badge-pill= limited_counter_with_delimiter(User.blocked_pending_approval)
+ = nav_link(html_options: { class: "#{active_when(params[:filter] == 'blocked_pending_approval')} filter-blocked-pending-approval" }) do
+ = link_to admin_users_path(filter: "blocked_pending_approval") do
+ = s_('AdminUsers|Pending approval')
+ %small.badge.badge-pill= limited_counter_with_delimiter(User.blocked_pending_approval)
= nav_link(html_options: { class: active_when(params[:filter] == 'deactivated') }) do
= link_to admin_users_path(filter: "deactivated") do
= s_('AdminUsers|Deactivated')
diff --git a/app/views/ci/runner/_how_to_setup_runner.html.haml b/app/views/ci/runner/_how_to_setup_runner.html.haml
index 6c2bd2a5d2f..0ff6fdc6354 100644
--- a/app/views/ci/runner/_how_to_setup_runner.html.haml
+++ b/app/views/ci/runner/_how_to_setup_runner.html.haml
@@ -15,7 +15,9 @@
= clipboard_button(target: '#registration_token', title: _("Copy token"), class: "btn-transparent btn-clipboard")
.gl-mt-3.gl-mb-3
= button_to _("Reset runners registration token"), reset_token_url,
- method: :put, class: 'btn btn-default',
+ method: :put, class: 'gl-button btn btn-default',
data: { confirm: _("Are you sure you want to reset registration token?") }
%li
= _("Start the Runner!")
+
+#js-install-runner{ data: { project_path: project_path, group_path: group_path } }
diff --git a/app/views/ci/runner/_how_to_setup_runner_automatically.html.haml b/app/views/ci/runner/_how_to_setup_runner_automatically.html.haml
index 42710039757..343abf6099e 100644
--- a/app/views/ci/runner/_how_to_setup_runner_automatically.html.haml
+++ b/app/views/ci/runner/_how_to_setup_runner_automatically.html.haml
@@ -19,4 +19,4 @@
= link_to _('Install Runner on Kubernetes'),
clusters_path,
- class: 'btn btn-info'
+ class: 'gl-button btn btn-info'
diff --git a/app/views/ci/variables/_index.html.haml b/app/views/ci/variables/_index.html.haml
index b90e672cca9..660fd1a48a7 100644
--- a/app/views/ci/variables/_index.html.haml
+++ b/app/views/ci/variables/_index.html.haml
@@ -5,42 +5,20 @@
- link_start = '<a href="%{url}">'.html_safe % { url: help_page_path('ci/variables/README', anchor: 'protect-a-custom-variable') }
= s_('Environment variables are configured by your administrator to be %{link_start}protected%{link_end} by default').html_safe % { link_start: link_start, link_end: '</a>'.html_safe }
-- if Feature.enabled?(:new_variables_ui, @project || @group, default_enabled: true)
- - is_group = !@group.nil?
+- is_group = !@group.nil?
- #js-ci-project-variables{ data: { endpoint: save_endpoint,
- project_id: @project&.id || '',
- group: is_group.to_s,
- maskable_regex: ci_variable_maskable_regex,
- protected_by_default: ci_variable_protected_by_default?.to_s,
- aws_logo_svg_path: image_path('aws_logo.svg'),
- aws_tip_deploy_link: help_page_path('ci/cloud_deployment/index.md', anchor: 'deploy-your-application-to-the-aws-elastic-container-service-ecs'),
- aws_tip_commands_link: help_page_path('ci/cloud_deployment/index.md', anchor: 'run-aws-commands-from-gitlab-cicd'),
- aws_tip_learn_link: help_page_path('ci/cloud_deployment/index.md', anchor: 'aws'),
- protected_environment_variables_link: help_page_path('ci/variables/README', anchor: 'protect-a-custom-variable'),
- masked_environment_variables_link: help_page_path('ci/variables/README', anchor: 'mask-a-custom-variable'),
- } }
-
-- else
- .row
- .col-lg-12.js-ci-variable-list-section{ data: { save_endpoint: save_endpoint, maskable_regex: ci_variable_maskable_regex } }
- .hide.gl-alert.gl-alert-danger.js-ci-variable-error-box
-
- %ul.ci-variable-list
- = render 'ci/variables/variable_header'
- - @variables.each.each do |variable|
- = render 'ci/variables/variable_row', form_field: 'variables', variable: variable
- = render 'ci/variables/variable_row', form_field: 'variables'
- .prepend-top-20
- %button.btn.btn-success.js-ci-variables-save-button{ type: 'button' }
- %span.hide.js-ci-variables-save-loading-icon
- .spinner.spinner-light.mr-1
- = _('Save variables')
- %button.btn.btn-info.btn-inverted.gl-ml-3.js-secret-value-reveal-button{ type: 'button', data: { secret_reveal_status: "#{@variables.size == 0}" } }
- - if @variables.size == 0
- = n_('Hide value', 'Hide values', @variables.size)
- - else
- = n_('Reveal value', 'Reveal values', @variables.size)
+#js-ci-project-variables{ data: { endpoint: save_endpoint,
+ project_id: @project&.id || '',
+ group: is_group.to_s,
+ maskable_regex: ci_variable_maskable_regex,
+ protected_by_default: ci_variable_protected_by_default?.to_s,
+ aws_logo_svg_path: image_path('aws_logo.svg'),
+ aws_tip_deploy_link: help_page_path('ci/cloud_deployment/index.md', anchor: 'deploy-your-application-to-the-aws-elastic-container-service-ecs'),
+ aws_tip_commands_link: help_page_path('ci/cloud_deployment/index.md', anchor: 'run-aws-commands-from-gitlab-cicd'),
+ aws_tip_learn_link: help_page_path('ci/cloud_deployment/index.md', anchor: 'aws'),
+ protected_environment_variables_link: help_page_path('ci/variables/README', anchor: 'protect-a-custom-variable'),
+ masked_environment_variables_link: help_page_path('ci/variables/README', anchor: 'mask-a-custom-variable'),
+} }
- if !@group && @project.group
.settings-header.border-top.prepend-top-20
diff --git a/app/views/clusters/clusters/_details.html.haml b/app/views/clusters/clusters/_details.html.haml
index fb0a1aaebc4..3079e024369 100644
--- a/app/views/clusters/clusters/_details.html.haml
+++ b/app/views/clusters/clusters/_details.html.haml
@@ -4,7 +4,7 @@
%section.settings.no-animate{ class: ('expanded' if expanded) }
.settings-header
%h4= s_('ClusterIntegration|Provider details')
- %button.btn.js-settings-toggle{ type: 'button' }
+ %button.btn.gl-button.js-settings-toggle{ type: 'button' }
= expanded ? _('Collapse') : _('Expand')
%p= s_('ClusterIntegration|See and edit the details for your Kubernetes cluster')
.settings-content
diff --git a/app/views/clusters/clusters/_empty_state.html.haml b/app/views/clusters/clusters/_empty_state.html.haml
index 1798ba81075..676a8a8111a 100644
--- a/app/views/clusters/clusters/_empty_state.html.haml
+++ b/app/views/clusters/clusters/_empty_state.html.haml
@@ -11,4 +11,4 @@
- if clusterable.can_add_cluster?
.gl-text-center
- = link_to s_('ClusterIntegration|Integrate with a cluster certificate'), clusterable.new_path, class: 'btn btn-success'
+ = link_to s_('ClusterIntegration|Integrate with a cluster certificate'), clusterable.new_path, class: 'gl-button btn btn-success'
diff --git a/app/views/clusters/clusters/_provider_details_form.html.haml b/app/views/clusters/clusters/_provider_details_form.html.haml
index 16891c7fc21..7fc803e9579 100644
--- a/app/views/clusters/clusters/_provider_details_form.html.haml
+++ b/app/views/clusters/clusters/_provider_details_form.html.haml
@@ -55,4 +55,4 @@
= render('clusters/clusters/namespace', platform_field: platform_field, field: field)
.form-group
- = field.submit s_('ClusterIntegration|Save changes'), class: 'btn btn-success'
+ = field.submit s_('ClusterIntegration|Save changes'), class: 'gl-button btn btn-success'
diff --git a/app/views/clusters/clusters/aws/_new.html.haml b/app/views/clusters/clusters/aws/_new.html.haml
index b1a277faae9..4407b27df1e 100644
--- a/app/views/clusters/clusters/aws/_new.html.haml
+++ b/app/views/clusters/clusters/aws/_new.html.haml
@@ -14,4 +14,4 @@
'kubernetes-integration-help-path' => help_page_path('user/project/clusters/index'),
'account-and-external-ids-help-path' => help_page_path('user/project/clusters/add_remove_clusters.md', anchor: 'new-eks-cluster'),
'create-role-arn-help-path' => help_page_path('user/project/clusters/add_remove_clusters.md', anchor: 'new-eks-cluster'),
- 'external-link-icon' => icon('external-link') } }
+ 'external-link-icon' => sprite_icon('external-link') } }
diff --git a/app/views/clusters/clusters/gcp/_form.html.haml b/app/views/clusters/clusters/gcp/_form.html.haml
index ceb6e1d46b0..d1ea7fec49d 100644
--- a/app/views/clusters/clusters/gcp/_form.html.haml
+++ b/app/views/clusters/clusters/gcp/_form.html.haml
@@ -1,5 +1,5 @@
= javascript_include_tag 'https://apis.google.com/js/api.js'
-- external_link_icon = icon('external-link')
+- external_link_icon = sprite_icon('external-link')
- zones_link_url = 'https://cloud.google.com/compute/docs/regions-zones/regions-zones'
- machine_type_link_url = 'https://cloud.google.com/compute/docs/machine-types'
- pricing_link_url = 'https://cloud.google.com/compute/pricing#machinetype'
@@ -86,4 +86,4 @@
.form-group.js-gke-cluster-creation-submit-container
= field.submit s_('ClusterIntegration|Create Kubernetes cluster'),
- class: 'js-gke-cluster-creation-submit btn btn-success', disabled: true
+ class: 'js-gke-cluster-creation-submit gl-button btn btn-success', disabled: true
diff --git a/app/views/clusters/clusters/user/_form.html.haml b/app/views/clusters/clusters/user/_form.html.haml
index a6097038b2e..e2779d1b683 100644
--- a/app/views/clusters/clusters/user/_form.html.haml
+++ b/app/views/clusters/clusters/user/_form.html.haml
@@ -60,4 +60,4 @@
= render('clusters/clusters/namespace', platform_field: platform_kubernetes_field)
.form-group
- = field.submit s_('ClusterIntegration|Add Kubernetes cluster'), class: 'btn btn-success', data: { qa_selector: 'add_kubernetes_cluster_button' }
+ = field.submit s_('ClusterIntegration|Add Kubernetes cluster'), class: 'gl-button btn btn-success', data: { qa_selector: 'add_kubernetes_cluster_button' }
diff --git a/app/views/dashboard/_groups_head.html.haml b/app/views/dashboard/_groups_head.html.haml
index b2fadb77418..c24fe5c6307 100644
--- a/app/views/dashboard/_groups_head.html.haml
+++ b/app/views/dashboard/_groups_head.html.haml
@@ -3,7 +3,7 @@
- if current_user.can_create_group?
.page-title-controls
- = link_to _("New group"), new_group_path, class: "btn btn-success"
+ = link_to _("New group"), new_group_path, class: "gl-button btn btn-success"
.top-area
%ul.nav-links.mobile-separator.nav.nav-tabs
diff --git a/app/views/dashboard/_projects_head.html.haml b/app/views/dashboard/_projects_head.html.haml
index fe91f9859f9..6c994f3b230 100644
--- a/app/views/dashboard/_projects_head.html.haml
+++ b/app/views/dashboard/_projects_head.html.haml
@@ -9,7 +9,7 @@
- if current_user.can_create_project?
.page-title-controls
- = link_to _("New project"), new_project_path, class: "btn btn-success"
+ = link_to _("New project"), new_project_path, class: "gl-button btn btn-success"
.top-area.scrolling-tabs-container.inner-page-scroll-tabs
.fade-left= sprite_icon('chevron-lg-left', size: 12)
diff --git a/app/views/dashboard/_snippets_head.html.haml b/app/views/dashboard/_snippets_head.html.haml
index d2fb4a3cd43..2640d483615 100644
--- a/app/views/dashboard/_snippets_head.html.haml
+++ b/app/views/dashboard/_snippets_head.html.haml
@@ -4,7 +4,7 @@
- if current_user && current_user.snippets.any? || @snippets.any?
.page-title-controls
- if can?(current_user, :create_snippet)
- = link_to _("New snippet"), new_snippet_path, class: "btn btn-success", title: _("New snippet")
+ = link_to _("New snippet"), new_snippet_path, class: "gl-button btn btn-success", title: _("New snippet")
.top-area
%ul.nav-links.nav.nav-tabs
diff --git a/app/views/dashboard/groups/index.html.haml b/app/views/dashboard/groups/index.html.haml
index 9536ff940f5..afe4f1b84c2 100644
--- a/app/views/dashboard/groups/index.html.haml
+++ b/app/views/dashboard/groups/index.html.haml
@@ -6,6 +6,7 @@
= render 'dashboard/groups_head'
- if params[:filter].blank? && @groups.empty?
- = render 'shared/groups/empty_state'
+ .empty-state
+ = render 'shared/groups/empty_state'
- else
= render 'groups'
diff --git a/app/views/dashboard/todos/_todo.html.haml b/app/views/dashboard/todos/_todo.html.haml
index 6fb387ecca3..8e038baf14d 100644
--- a/app/views/dashboard/todos/_todo.html.haml
+++ b/app/views/dashboard/todos/_todo.html.haml
@@ -48,14 +48,14 @@
- if todo.pending?
.todo-actions
- = link_to dashboard_todo_path(todo), method: :delete, class: 'btn btn-loading d-flex align-items-center js-done-todo', data: { href: dashboard_todo_path(todo) } do
+ = link_to dashboard_todo_path(todo), method: :delete, class: 'gl-button btn btn-loading d-flex align-items-center js-done-todo', data: { href: dashboard_todo_path(todo) } do
Done
%span.spinner.ml-1
- = link_to restore_dashboard_todo_path(todo), method: :patch, class: 'btn btn-loading d-flex align-items-center js-undo-todo hidden', data: { href: restore_dashboard_todo_path(todo) } do
+ = link_to restore_dashboard_todo_path(todo), method: :patch, class: 'gl-button btn btn-loading d-flex align-items-center js-undo-todo hidden', data: { href: restore_dashboard_todo_path(todo) } do
Undo
%span.spinner.ml-1
- else
.todo-actions
- = link_to restore_dashboard_todo_path(todo), method: :patch, class: 'btn btn-loading d-flex align-items-center js-add-todo', data: { href: restore_dashboard_todo_path(todo) } do
+ = link_to restore_dashboard_todo_path(todo), method: :patch, class: 'gl-button btn btn-loading d-flex align-items-center js-add-todo', data: { href: restore_dashboard_todo_path(todo) } do
Add a to do
%span.spinner.ml-1
diff --git a/app/views/dashboard/todos/index.html.haml b/app/views/dashboard/todos/index.html.haml
index 56506370ee0..9a9fbfc1ee8 100644
--- a/app/views/dashboard/todos/index.html.haml
+++ b/app/views/dashboard/todos/index.html.haml
@@ -27,10 +27,10 @@
.nav-controls
- if @todos.any?(&:pending?)
.gl-mr-3
- = link_to destroy_all_dashboard_todos_path(todos_filter_params), class: 'btn btn-loading align-items-center js-todos-mark-all', method: :delete, data: { href: destroy_all_dashboard_todos_path(todos_filter_params) } do
+ = link_to destroy_all_dashboard_todos_path(todos_filter_params), class: 'gl-button btn btn-loading align-items-center js-todos-mark-all', method: :delete, data: { href: destroy_all_dashboard_todos_path(todos_filter_params) } do
Mark all as done
%span.spinner.ml-1
- = link_to bulk_restore_dashboard_todos_path, class: 'btn btn-loading align-items-center js-todos-undo-all hidden', method: :patch , data: { href: bulk_restore_dashboard_todos_path(todos_filter_params) } do
+ = link_to bulk_restore_dashboard_todos_path, class: 'gl-button btn btn-loading align-items-center js-todos-undo-all hidden', method: :patch , data: { href: bulk_restore_dashboard_todos_path(todos_filter_params) } do
Undo mark all as done
%span.spinner.ml-1
@@ -114,7 +114,7 @@
.todos-empty
.todos-empty-hero.svg-content
= image_tag 'illustrations/todos_empty.svg'
- .todos-empty-content
+ .todos-empty-content.gl-mx-5
%h4
Your To-Do List shows what to work on next
%p
diff --git a/app/views/devise/confirmations/new.html.haml b/app/views/devise/confirmations/new.html.haml
index f8aa3cf98dc..49112ed6cd5 100644
--- a/app/views/devise/confirmations/new.html.haml
+++ b/app/views/devise/confirmations/new.html.haml
@@ -8,7 +8,7 @@
= f.label :email
= f.email_field :email, class: "form-control", required: true, title: 'Please provide a valid email address.'
.clearfix
- = f.submit "Resend", class: 'btn btn-success'
+ = f.submit "Resend", class: 'gl-button btn btn-success'
.clearfix.prepend-top-20
= render 'devise/shared/sign_in_link'
diff --git a/app/views/devise/mailer/user_admin_approval.html.haml b/app/views/devise/mailer/user_admin_approval.html.haml
new file mode 100644
index 00000000000..199a143ba63
--- /dev/null
+++ b/app/views/devise/mailer/user_admin_approval.html.haml
@@ -0,0 +1,8 @@
+= email_default_heading(say_hi(@resource))
+
+%p
+ = _('Your GitLab account request has been approved!')
+%p
+ = _('Your username is %{username}.') % { username: @resource.username }
+%p
+ = _('Your sign-in page is %{url}.').html_safe % { url: link_to(Gitlab.config.gitlab.url, Gitlab.config.gitlab.url) }
diff --git a/app/views/devise/mailer/user_admin_approval.text.erb b/app/views/devise/mailer/user_admin_approval.text.erb
new file mode 100644
index 00000000000..5242981e514
--- /dev/null
+++ b/app/views/devise/mailer/user_admin_approval.text.erb
@@ -0,0 +1,7 @@
+<%= say_hi(@resource) %>
+
+<%= _('Your GitLab account request has been approved!') %>
+
+<%= _('Your username is %{username}.' % { username: @resource.username }) %>
+
+<%= _('Your sign-in page is %{url}.' % { url: Gitlab.config.gitlab.url }) %>
diff --git a/app/views/devise/passwords/edit.html.haml b/app/views/devise/passwords/edit.html.haml
index fee87c6324c..42e301d88ae 100644
--- a/app/views/devise/passwords/edit.html.haml
+++ b/app/views/devise/passwords/edit.html.haml
@@ -12,7 +12,7 @@
= f.label 'Confirm new password', for: "user_password_confirmation"
= f.password_field :password_confirmation, class: "form-control bottom", title: 'This field is required', data: { qa_selector: 'password_confirmation_field' }, required: true
.clearfix
- = f.submit "Change your password", class: "btn btn-primary", data: { qa_selector: 'change_password_button' }
+ = f.submit "Change your password", class: "gl-button btn btn-primary", data: { qa_selector: 'change_password_button' }
.clearfix.prepend-top-20
%p
diff --git a/app/views/devise/registrations/new.html.haml b/app/views/devise/registrations/new.html.haml
index 2f75203ac62..00429f1acbc 100644
--- a/app/views/devise/registrations/new.html.haml
+++ b/app/views/devise/registrations/new.html.haml
@@ -1,16 +1,13 @@
- page_title _("Sign up")
-- if experiment_enabled?(:signup_flow)
- .row
- .col-lg-7
- %h1.mb-3.font-weight-bold.text-6.mt-0
- = html_escape(_("Speed up your DevOps%{br_tag}with GitLab")) % { br_tag: '<br/>'.html_safe }
- %p.text-3
- = _("GitLab is a single application for the entire software development lifecycle. From project planning and source code management to CI/CD, monitoring, and security.")
- .col-lg-5.order-12
- .text-center.mb-3
- %h2.font-weight-bold= _('Register for GitLab')
- = render 'devise/shared/experimental_separate_sign_up_flow_box'
- = render 'devise/shared/sign_in_link'
-- else
- = render 'devise/shared/signup_box'
+- add_page_specific_style 'page_bundles/signup'
+- content_for :page_specific_javascripts do
+ = render "layouts/google_tag_manager_head"
+= render "layouts/google_tag_manager_body"
+
+.signup-page
+ = render 'devise/shared/signup_box',
+ url: registration_path(resource_name),
+ button_text: _('Register'),
+ show_omniauth_providers: omniauth_enabled? && button_based_providers_enabled?,
+ suggestion_path: nil
= render 'devise/shared/sign_in_link'
diff --git a/app/views/devise/sessions/_new_base.html.haml b/app/views/devise/sessions/_new_base.html.haml
index 8c0ca6d4345..a1a1a767847 100644
--- a/app/views/devise/sessions/_new_base.html.haml
+++ b/app/views/devise/sessions/_new_base.html.haml
@@ -20,4 +20,4 @@
= recaptcha_tags
.submit-container.move-submit-down
- = f.submit _('Sign in'), class: 'btn btn-success', data: { qa_selector: 'sign_in_button' }
+ = f.submit _('Sign in'), class: 'gl-button btn btn-success', data: { qa_selector: 'sign_in_button' }
diff --git a/app/views/devise/sessions/new.html.haml b/app/views/devise/sessions/new.html.haml
index c466d2ce936..cce0a3b926e 100644
--- a/app/views/devise/sessions/new.html.haml
+++ b/app/views/devise/sessions/new.html.haml
@@ -1,24 +1,25 @@
- page_title _("Sign in")
+- content_for :page_specific_javascripts do
+ = render "layouts/google_tag_manager_head"
+= render "layouts/google_tag_manager_body"
#signin-container
- if any_form_based_providers_enabled?
- = render 'devise/shared/tabs_ldap'
- - else
- - unless experiment_enabled?(:signup_flow)
- = render 'devise/shared/tabs_normal'
+ = render 'devise/shared/tabs_ldap', render_signup_link: false
.tab-content
- if password_authentication_enabled_for_web? || ldap_sign_in_enabled? || crowd_enabled?
= render 'devise/shared/signin_box'
- -# Signup only makes sense if you can also sign-in
- - if allow_signup?
- = render 'devise/shared/signup_box'
-
-# Show a message if none of the mechanisms above are enabled
- if !password_authentication_enabled_for_web? && !ldap_sign_in_enabled? && !(omniauth_enabled? && devise_mapping.omniauthable?)
%div
No authentication methods configured.
+ - if allow_signup?
+ %p.gl-mt-3
+ = _("Don't have an account yet?")
+ = link_to _("Register now"), new_registration_path(:user, invite_email: @invite_email), data: { qa_selector: 'register_link' }
+
- if omniauth_enabled? && devise_mapping.omniauthable? && button_based_providers_enabled?
.clearfix
= render 'devise/shared/omniauth_box'
diff --git a/app/views/devise/sessions/two_factor.html.haml b/app/views/devise/sessions/two_factor.html.haml
index 8e05488c091..f5f76eb92b1 100644
--- a/app/views/devise/sessions/two_factor.html.haml
+++ b/app/views/devise/sessions/two_factor.html.haml
@@ -11,6 +11,6 @@
= f.text_field :otp_attempt, class: 'form-control', required: true, autofocus: true, autocomplete: 'off', title: 'This field is required.', data: { qa_selector: 'two_fa_code_field' }
%p.form-text.text-muted.hint Enter the code from the two-factor app on your mobile device. If you've lost your device, you may enter one of your recovery codes.
.prepend-top-20
- = f.submit "Verify code", class: "btn btn-success", data: { qa_selector: 'verify_code_button' }
+ = f.submit "Verify code", class: "gl-button btn btn-success", data: { qa_selector: 'verify_code_button' }
- if @user.two_factor_webauthn_u2f_enabled?
= render "authentication/authenticate", params: params, resource: resource, resource_name: resource_name, render_remember_me: true, target_path: new_user_session_path
diff --git a/app/views/devise/shared/_experimental_separate_sign_up_flow_box.html.haml b/app/views/devise/shared/_experimental_separate_sign_up_flow_box.html.haml
deleted file mode 100644
index 621bbb32a13..00000000000
--- a/app/views/devise/shared/_experimental_separate_sign_up_flow_box.html.haml
+++ /dev/null
@@ -1,39 +0,0 @@
-- max_first_name_length = max_last_name_length = 127
-- max_username_length = 255
-- min_username_length = 2
-.signup-box.p-3.mb-2
- .signup-body
- = form_for(resource, as: "new_#{resource_name}", url: registration_path(resource_name), html: { class: "new_new_user gl-show-field-errors", "aria-live" => "assertive" }) do |f|
- .devise-errors.mt-0
- = render "devise/shared/error_messages", resource: resource
- - if Feature.enabled?(:invisible_captcha)
- = invisible_captcha
- .name.form-row
- .col.form-group
- = f.label :first_name, _('First name'), for: 'new_user_first_name', class: 'label-bold'
- = f.text_field :first_name, class: 'form-control top js-block-emoji js-validate-length', :data => { :max_length => max_first_name_length, :max_length_message => _("First name is too long (maximum is %{max_length} characters).") % { max_length: max_first_name_length }, :qa_selector => 'new_user_firstname_field' }, required: true, title: _("This field is required.")
- .col.form-group
- = f.label :last_name, _('Last name'), for: 'new_user_last_name', class: 'label-bold'
- = f.text_field :last_name, class: "form-control top js-block-emoji js-validate-length", :data => { :max_length => max_last_name_length, :max_length_message => _("Last name is too long (maximum is %{max_length} characters).") % { max_length: max_last_name_length }, :qa_selector => 'new_user_lastname_field' }, required: true, title: _("This field is required.")
- .username.form-group
- = f.label :username, class: 'label-bold'
- = f.text_field :username, class: "form-control middle js-block-emoji js-validate-length js-validate-username", :data => { :min_length => min_username_length, :min_length_message => s_("SignUp|Username is too short (minimum is %{min_length} characters).") % { min_length: min_username_length }, :max_length => max_username_length, :max_length_message => _("Username is too long (maximum is %{max_length} characters).") % { max_length: max_username_length }, :qa_selector => 'new_user_username_field' }, pattern: Gitlab::PathRegex::NAMESPACE_FORMAT_REGEX_JS, required: true, title: _("Please create a username with only alphanumeric characters.")
- %p.validation-error.gl-field-error-ignore.field-validation.mt-1.hide.cred= _('Username is already taken.')
- %p.validation-success.gl-field-error-ignore.field-validation.mt-1.hide.cgreen= _('Username is available.')
- %p.validation-pending.gl-field-error-ignore.field-validation.mt-1.hide= _('Checking username availability...')
- .form-group
- = f.label :email, class: 'label-bold'
- = f.email_field :email, class: "form-control middle", data: { qa_selector: 'new_user_email_field' }, required: true, title: _("Please provide a valid email address.")
- .form-group.append-bottom-20#password-strength
- = f.label :password, class: 'label-bold'
- = f.password_field :password, class: "form-control bottom", data: { qa_selector: 'new_user_password_field' }, required: true, pattern: ".{#{@minimum_password_length},}", title: _("Minimum length is %{minimum_password_length} characters.") % { minimum_password_length: @minimum_password_length }
- %p.gl-field-hint.text-secondary= _('Minimum length is %{minimum_password_length} characters') % { minimum_password_length: @minimum_password_length }
- = render_if_exists 'devise/shared/email_opted_in', f: f
- %div
- - if show_recaptcha_sign_up?
- = recaptcha_tags
- .submit-container.mt-3
- = f.submit _("Register"), class: "btn-register btn btn-block btn-success mb-0 p-2", data: { qa_selector: 'new_user_register_button' }
- = render 'devise/shared/terms_of_service_notice'
- - if omniauth_enabled? && button_based_providers_enabled?
- = render 'devise/shared/experimental_separate_sign_up_flow_omniauth_box'
diff --git a/app/views/devise/shared/_omniauth_box.html.haml b/app/views/devise/shared/_omniauth_box.html.haml
index 6cf48f89876..67e6e510923 100644
--- a/app/views/devise/shared/_omniauth_box.html.haml
+++ b/app/views/devise/shared/_omniauth_box.html.haml
@@ -7,7 +7,7 @@
.d-flex.justify-content-between.flex-wrap
- providers.each do |provider|
- has_icon = provider_has_icon?(provider)
- = button_to omniauth_authorize_path(:user, provider), id: "oauth-login-#{provider}", class: "btn d-flex align-items-center omniauth-btn text-left oauth-login #{qa_class_for_provider(provider)}" do
+ = button_to omniauth_authorize_path(:user, provider), id: "oauth-login-#{provider}", class: "gl-button btn d-flex align-items-center omniauth-btn text-left oauth-login #{qa_class_for_provider(provider)}" do
- if has_icon
= provider_image_tag(provider)
%span
diff --git a/app/views/devise/shared/_signin_box.html.haml b/app/views/devise/shared/_signin_box.html.haml
index d217b47527a..ff93449194a 100644
--- a/app/views/devise/shared/_signin_box.html.haml
+++ b/app/views/devise/shared/_signin_box.html.haml
@@ -22,8 +22,3 @@
.login-box.tab-pane.active{ id: 'login-pane', role: 'tabpanel' }
.login-body
= render 'devise/sessions/new_base'
-
-- if experiment_enabled?(:signup_flow)
- %p.light.mt-2
- = _("Don't have an account yet?")
- = link_to _("Register now"), new_registration_path(:user)
diff --git a/app/views/devise/shared/_signup_box.html.haml b/app/views/devise/shared/_signup_box.html.haml
index f4ac9ad696b..0dc98001881 100644
--- a/app/views/devise/shared/_signup_box.html.haml
+++ b/app/views/devise/shared/_signup_box.html.haml
@@ -1,37 +1,37 @@
- max_first_name_length = max_last_name_length = 127
- max_username_length = 255
- min_username_length = 2
-#register-pane.tab-pane.login-box{ role: 'tabpanel' }
- .login-body
- = form_for(resource, as: "new_#{resource_name}", url: registration_path(resource_name), html: { class: "new_new_user gl-show-field-errors", "aria-live" => "assertive" }) do |f|
- .devise-errors
- = render "devise/shared/error_messages", resource: resource
- - if Feature.enabled?(:invisible_captcha)
- = invisible_captcha
- .name.form-row
- .col.form-group
- = f.label :first_name, _('First name'), for: 'new_user_first_name', class: 'label-bold'
- = f.text_field :first_name, class: 'form-control top js-block-emoji js-validate-length', :data => { :max_length => max_first_name_length, :max_length_message => _("First name is too long (maximum is %{max_length} characters).") % { max_length: max_first_name_length }, :qa_selector => 'new_user_first_name_field' }, required: true, title: _("This field is required.")
- .col.form-group
- = f.label :last_name, _('Last name'), for: 'new_user_last_name', class: 'label-bold'
- = f.text_field :last_name, class: "form-control top js-block-emoji js-validate-length", :data => { :max_length => max_last_name_length, :max_length_message => _("Last name is too long (maximum is %{max_length} characters).") % { max_length: max_last_name_length }, :qa_selector => 'new_user_last_name_field' }, required: true, title: _("This field is required.")
- .username.form-group
- = f.label :username, class: 'label-bold'
- = f.text_field :username, class: "form-control middle js-block-emoji js-validate-length js-validate-username", :data => { :min_length => min_username_length, :min_length_message => s_("SignUp|Username is too short (minimum is %{min_length} characters).") % { min_length: min_username_length }, :max_length => max_username_length, :max_length_message => s_("SignUp|Username is too long (maximum is %{max_length} characters).") % { max_length: max_username_length }, :qa_selector => 'new_user_username_field' }, pattern: Gitlab::PathRegex::NAMESPACE_FORMAT_REGEX_JS, required: true, title: _("Please create a username with only alphanumeric characters.")
- %p.validation-error.gl-field-error-ignore.field-validation.hide= _('Username is already taken.')
- %p.validation-success.gl-field-error-ignore.field-validation.hide= _('Username is available.')
- %p.validation-pending.gl-field-error-ignore.field-validation.hide= _('Checking username availability...')
- .form-group
- = f.label :email, class: 'label-bold'
- = f.email_field :email, value: @invite_email, class: "form-control middle", data: { qa_selector: 'new_user_email_field' }, required: true, title: _("Please provide a valid email address.")
- .form-group.append-bottom-20#password-strength
- = f.label :password, class: 'label-bold'
- = f.password_field :password, class: "form-control bottom", data: { qa_selector: 'new_user_password_field' }, required: true, pattern: ".{#{@minimum_password_length},}", title: _("Minimum length is %{minimum_password_length} characters.") % { minimum_password_length: @minimum_password_length }
- %p.gl-field-hint.text-secondary= _('Minimum length is %{minimum_password_length} characters') % { minimum_password_length: @minimum_password_length }
- = render_if_exists 'devise/shared/email_opted_in', f: f
- %div
- - if show_recaptcha_sign_up?
- = recaptcha_tags
- .submit-container
- = f.submit _("Register"), class: "btn-register btn", data: { qa_selector: 'new_user_register_button' }
- = render 'devise/shared/terms_of_service_notice'
+.gl-mb-3.gl-p-4.gl-border-gray-100.gl-border-1.gl-border-solid.gl-rounded-base
+ = form_for(resource, as: "new_#{resource_name}", url: url, html: { class: 'new_user gl-show-field-errors', 'aria-live' => 'assertive' }) do |f|
+ .devise-errors
+ = render 'devise/shared/error_messages', resource: resource
+ - if Feature.enabled?(:invisible_captcha)
+ = invisible_captcha
+ .name.form-row
+ .col.form-group
+ = f.label :first_name, _('First name'), for: 'new_user_first_name', class: 'label-bold'
+ = f.text_field :first_name, class: 'form-control top js-block-emoji js-validate-length', :data => { :max_length => max_first_name_length, :max_length_message => s_('SignUp|First name is too long (maximum is %{max_length} characters).') % { max_length: max_first_name_length }, :qa_selector => 'new_user_first_name_field' }, required: true, title: _('This field is required.')
+ .col.form-group
+ = f.label :last_name, _('Last name'), for: 'new_user_last_name', class: 'label-bold'
+ = f.text_field :last_name, class: 'form-control top js-block-emoji js-validate-length', :data => { :max_length => max_last_name_length, :max_length_message => s_('SignUp|Last name is too long (maximum is %{max_length} characters).') % { max_length: max_last_name_length }, :qa_selector => 'new_user_last_name_field' }, required: true, title: _('This field is required.')
+ .username.form-group
+ = f.label :username, class: 'label-bold'
+ = f.text_field :username, class: 'form-control middle js-block-emoji js-validate-length js-validate-username', :data => { :api_path => suggestion_path, :min_length => min_username_length, :min_length_message => s_('SignUp|Username is too short (minimum is %{min_length} characters).') % { min_length: min_username_length }, :max_length => max_username_length, :max_length_message => s_('SignUp|Username is too long (maximum is %{max_length} characters).') % { max_length: max_username_length }, :qa_selector => 'new_user_username_field' }, pattern: Gitlab::PathRegex::NAMESPACE_FORMAT_REGEX_JS, required: true, title: _('Please create a username with only alphanumeric characters.')
+ %p.validation-error.gl-text-red-500.gl-field-error-ignore.gl-mt-2.field-validation.hide= _('Username is already taken.')
+ %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'
+ = f.email_field :email, value: @invite_email, class: 'form-control middle', data: { qa_selector: 'new_user_email_field' }, required: true, title: _('Please provide a valid email address.')
+ .form-group.append-bottom-20#password-strength
+ = f.label :password, class: 'label-bold'
+ = f.password_field :password, class: 'form-control bottom', data: { qa_selector: 'new_user_password_field' }, required: true, pattern: ".{#{@minimum_password_length},}", title: s_('SignUp|Minimum length is %{minimum_password_length} characters.') % { minimum_password_length: @minimum_password_length }
+ %p.gl-field-hint.text-secondary= s_('SignUp|Minimum length is %{minimum_password_length} characters.') % { minimum_password_length: @minimum_password_length }
+ %div
+ - if show_recaptcha_sign_up?
+ = recaptcha_tags
+ .submit-container
+ = f.submit button_text, class: 'btn gl-button btn-success', data: { qa_selector: 'new_user_register_button' }
+ = render 'devise/shared/terms_of_service_notice'
+ - if show_omniauth_providers
+ = render 'devise/shared/signup_omniauth_providers'
diff --git a/app/views/devise/shared/_experimental_separate_sign_up_flow_omniauth_box.haml b/app/views/devise/shared/_signup_omniauth_providers.haml
index d9143d90430..68098f1865b 100644
--- a/app/views/devise/shared/_experimental_separate_sign_up_flow_omniauth_box.haml
+++ b/app/views/devise/shared/_signup_omniauth_providers.haml
@@ -6,7 +6,7 @@
.d-flex.justify-content-between.flex-wrap
- providers.each do |provider|
- has_icon = provider_has_icon?(provider)
- = link_to omniauth_authorize_path(:user, provider), method: :post, class: "btn d-flex align-items-center omniauth-btn text-left oauth-login mb-2 p-2 #{qa_class_for_provider(provider)}", id: "oauth-login-#{provider}" do
+ = link_to omniauth_authorize_path(:user, provider), method: :post, class: "gl-button btn d-flex align-items-center omniauth-btn text-left oauth-login mb-2 p-2 #{qa_class_for_provider(provider)}", id: "oauth-login-#{provider}" do
- if has_icon
= provider_image_tag(provider)
%span.ml-2
diff --git a/app/views/devise/shared/_tabs_ldap.html.haml b/app/views/devise/shared/_tabs_ldap.html.haml
index acd41fb011a..27057d023b1 100644
--- a/app/views/devise/shared/_tabs_ldap.html.haml
+++ b/app/views/devise/shared/_tabs_ldap.html.haml
@@ -4,17 +4,17 @@
%ul.nav-links.new-session-tabs.nav-tabs.nav{ class: ('custom-provider-tabs' if any_form_based_providers_enabled?) }
- if crowd_enabled?
%li.nav-item
- = link_to "Crowd", "#crowd", class: "nav-link #{active_when(form_based_auth_provider_has_active_class?(:crowd))}", 'data-toggle' => 'tab'
+ = link_to "Crowd", "#crowd", class: "nav-link #{active_when(form_based_auth_provider_has_active_class?(:crowd))}", 'data-toggle' => 'tab', role: 'tab'
= render_if_exists "devise/shared/kerberos_tab"
- ldap_servers.each_with_index do |server, i|
%li.nav-item
- = link_to server['label'], "##{server['provider_name']}", class: "nav-link #{active_when(i == 0 && form_based_auth_provider_has_active_class?(:ldapmain))}", data: { toggle: 'tab', qa_selector: 'ldap_tab' }
+ = link_to server['label'], "##{server['provider_name']}", class: "nav-link #{active_when(i == 0 && form_based_auth_provider_has_active_class?(:ldapmain))}", data: { toggle: 'tab', qa_selector: 'ldap_tab' }, role: 'tab'
= render_if_exists 'devise/shared/tab_smartcard'
- if show_password_form
%li.nav-item
- = link_to _('Standard'), '#login-pane', class: 'nav-link', data: { toggle: 'tab', qa_selector: 'standard_tab' }
+ = link_to _('Standard'), '#login-pane', class: 'nav-link', data: { toggle: 'tab', qa_selector: 'standard_tab' }, role: 'tab'
- if render_signup_link && allow_signup?
%li.nav-item
- = link_to 'Register', '#register-pane', class: 'nav-link', data: { toggle: 'tab', qa_selector: 'register_tab' }
+ = link_to 'Register', '#register-pane', class: 'nav-link', data: { toggle: 'tab', qa_selector: 'register_tab' }, role: 'tab'
diff --git a/app/views/devise/unlocks/new.html.haml b/app/views/devise/unlocks/new.html.haml
index 1167f1718d6..96f4f07176e 100644
--- a/app/views/devise/unlocks/new.html.haml
+++ b/app/views/devise/unlocks/new.html.haml
@@ -8,7 +8,7 @@
= 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', class: 'btn btn-success'
+ = f.submit 'Resend unlock instructions', class: 'gl-button btn btn-success'
.clearfix.prepend-top-20
= render 'devise/shared/sign_in_link'
diff --git a/app/views/discussions/_discussion.html.haml b/app/views/discussions/_discussion.html.haml
index 4a27284cbae..075eb99fc36 100644
--- a/app/views/discussions/_discussion.html.haml
+++ b/app/views/discussions/_discussion.html.haml
@@ -2,17 +2,15 @@
%li.note.note-discussion.timeline-entry.unstyled-comments
.timeline-entry-inner
.timeline-content
- .discussion.js-toggle-container{ data: { discussion_id: discussion.id } }
+ .discussion.js-toggle-container{ data: { discussion_id: discussion.id, is_expanded: expanded.to_s } }
.discussion-header
.timeline-icon
= link_to user_path(discussion.author) do
= image_tag avatar_icon_for_user(discussion.author), class: "avatar s40"
.discussion-actions
%button.note-action-button.discussion-toggle-button.js-toggle-button{ type: "button", class: ("js-toggle-lazy-diff" unless expanded) }
- - if expanded
- = icon("chevron-up")
- - else
- = icon("chevron-down")
+ = sprite_icon('chevron-up', css_class: "js-sidebar-collapse #{'hidden' unless expanded}")
+ = sprite_icon('chevron-down', css_class: "js-sidebar-expand #{'hidden' if expanded}")
= _('Toggle thread')
= link_to_member(@project, discussion.author, avatar: false)
diff --git a/app/views/doorkeeper/applications/_delete_form.html.haml b/app/views/doorkeeper/applications/_delete_form.html.haml
index 64b872b5610..3d6361a90ca 100644
--- a/app/views/doorkeeper/applications/_delete_form.html.haml
+++ b/app/views/doorkeeper/applications/_delete_form.html.haml
@@ -2,7 +2,7 @@
= form_tag oauth_application_path(application) do
%input{ :name => "_method", :type => "hidden", :value => "delete" }/
- if defined? small
- = button_tag type: "submit", class: "btn btn-transparent", data: { confirm: _("Are you sure?") } do
+ = button_tag type: "submit", class: "gl-button btn btn-transparent", data: { confirm: _("Are you sure?") } do
%span.sr-only
= _('Destroy')
= sprite_icon('remove')
diff --git a/app/views/doorkeeper/applications/_form.html.haml b/app/views/doorkeeper/applications/_form.html.haml
index f99db696fd6..fbae24410bb 100644
--- a/app/views/doorkeeper/applications/_form.html.haml
+++ b/app/views/doorkeeper/applications/_form.html.haml
@@ -23,4 +23,4 @@
= render 'shared/tokens/scopes_form', prefix: 'doorkeeper_application', token: application, scopes: @scopes
.gl-mt-3
- = f.submit _('Save application'), class: "btn btn-success"
+ = f.submit _('Save application'), class: "gl-button btn btn-success"
diff --git a/app/views/doorkeeper/applications/index.html.haml b/app/views/doorkeeper/applications/index.html.haml
index 6f781a635ba..2daba4586e1 100644
--- a/app/views/doorkeeper/applications/index.html.haml
+++ b/app/views/doorkeeper/applications/index.html.haml
@@ -41,7 +41,7 @@
%div= uri
%td= application.access_tokens.count
%td
- = link_to edit_oauth_application_path(application), class: "btn btn-transparent gl-mr-2" do
+ = link_to edit_oauth_application_path(application), class: "gl-button btn btn-transparent gl-mr-2" do
%span.sr-only
= _('Edit')
= sprite_icon('pencil')
diff --git a/app/views/doorkeeper/applications/show.html.haml b/app/views/doorkeeper/applications/show.html.haml
index 280b5d90793..0a091aa7586 100644
--- a/app/views/doorkeeper/applications/show.html.haml
+++ b/app/views/doorkeeper/applications/show.html.haml
@@ -16,7 +16,7 @@
.input-group
%input.label.label-monospace.monospace{ id: "application_id", type: "text", autocomplete: 'off', value: @application.uid, readonly: true }
.input-group-append
- = clipboard_button(target: '#application_id', title: _("Copy ID"), class: "btn btn btn-default")
+ = clipboard_button(target: '#application_id', title: _("Copy ID"), class: "gl-button btn btn-default")
%tr
%td
= _('Secret')
@@ -25,7 +25,7 @@
.input-group
%input.label.label-monospace.monospace{ id: "secret", type: "text", autocomplete: 'off', value: @application.secret, readonly: true }
.input-group-append
- = clipboard_button(target: '#secret', title: _("Copy secret"), class: "btn btn btn-default")
+ = clipboard_button(target: '#secret', title: _("Copy secret"), class: "gl-button btn btn-default")
%tr
%td
= _('Callback URL')
@@ -43,5 +43,5 @@
= render "shared/tokens/scopes_list", token: @application
.form-actions
- = link_to _('Edit'), edit_oauth_application_path(@application), class: 'btn btn-primary wide float-left'
+ = link_to _('Edit'), edit_oauth_application_path(@application), class: 'gl-button btn btn-primary wide float-left'
= render 'delete_form', application: @application, submit_btn_css: 'btn btn-danger gl-ml-3'
diff --git a/app/views/doorkeeper/authorizations/new.html.haml b/app/views/doorkeeper/authorizations/new.html.haml
index 62e66486a3e..bf17eb4fe3e 100644
--- a/app/views/doorkeeper/authorizations/new.html.haml
+++ b/app/views/doorkeeper/authorizations/new.html.haml
@@ -38,7 +38,7 @@
= hidden_field_tag :response_type, @pre_auth.response_type
= hidden_field_tag :scope, @pre_auth.scope
= hidden_field_tag :nonce, @pre_auth.nonce
- = submit_tag _("Deny"), class: "btn btn-danger"
+ = submit_tag _("Deny"), class: "gl-button btn btn-danger"
= form_tag oauth_authorization_path, method: :post, class: 'inline' do
= hidden_field_tag :client_id, @pre_auth.client.uid
= hidden_field_tag :redirect_uri, @pre_auth.redirect_uri
@@ -46,4 +46,4 @@
= hidden_field_tag :response_type, @pre_auth.response_type
= hidden_field_tag :scope, @pre_auth.scope
= hidden_field_tag :nonce, @pre_auth.nonce
- = submit_tag _("Authorize"), class: "btn btn-success gl-ml-3", data: { qa_selector: 'authorization_button' }
+ = submit_tag _("Authorize"), class: "gl-button btn btn-success gl-ml-3", data: { qa_selector: 'authorization_button' }
diff --git a/app/views/errors/access_denied.html.haml b/app/views/errors/access_denied.html.haml
index 1ed7b56db1d..ce921060cab 100644
--- a/app/views/errors/access_denied.html.haml
+++ b/app/views/errors/access_denied.html.haml
@@ -11,6 +11,6 @@
%p
= s_('403|Please contact your GitLab administrator to get permission.')
.action-container.js-go-back{ hidden: true }
- %button{ type: 'button', class: 'btn btn-success' }
+ %button{ type: 'button', class: 'gl-button btn btn-success' }
= s_('Go Back')
= render "errors/footer"
diff --git a/app/views/errors/not_found.html.haml b/app/views/errors/not_found.html.haml
index 13f07e2f5d5..291adbc0ae8 100644
--- a/app/views/errors/not_found.html.haml
+++ b/app/views/errors/not_found.html.haml
@@ -11,5 +11,5 @@
= form_tag search_path, method: :get, class: 'form-inline-flex' do |f|
.field
= search_field_tag :search, '', placeholder: _('Search for projects, issues, etc.'), class: 'form-control'
- = button_tag _('Search'), class: 'btn btn-sm btn-success', name: nil, type: 'submit'
+ = button_tag _('Search'), class: 'gl-button btn btn-sm btn-success', name: nil, type: 'submit'
= render 'errors/footer'
diff --git a/app/views/errors/omniauth_error.html.haml b/app/views/errors/omniauth_error.html.haml
index a2a4c75daad..0e9041d07ea 100644
--- a/app/views/errors/omniauth_error.html.haml
+++ b/app/views/errors/omniauth_error.html.haml
@@ -8,8 +8,8 @@
%p Try logging in using your username or email. If you have forgotten your password, try recovering it
- = link_to "Sign in", new_session_path(:user), class: 'btn primary'
- = link_to "Recover password", new_password_path(:user), class: 'btn secondary'
+ = link_to "Sign in", new_session_path(:user), class: 'gl-button btn primary'
+ = link_to "Recover password", new_password_path(:user), class: 'gl-button btn secondary'
%hr
%p.light If none of the options work, try contacting a GitLab administrator.
diff --git a/app/views/events/event/_note.html.haml b/app/views/events/event/_note.html.haml
index 4e936025c74..2fa595503e5 100644
--- a/app/views/events/event/_note.html.haml
+++ b/app/views/events/event/_note.html.haml
@@ -25,5 +25,5 @@
= image_tag note.attachment.url, class: 'note-image-attach'
- else
= link_to note.attachment.url, target: '_blank', class: 'note-file-attach' do
- %i.fa.fa-paperclip
+ = sprite_icon("paperclip")
= note.attachment_identifier
diff --git a/app/views/explore/projects/_projects.html.haml b/app/views/explore/projects/_projects.html.haml
index d819c4ea554..4275f76c046 100644
--- a/app/views/explore/projects/_projects.html.haml
+++ b/app/views/explore/projects/_projects.html.haml
@@ -1,2 +1 @@
-- is_explore_page = defined?(explore_page) && explore_page
-= render 'shared/projects/list', projects: projects, user: current_user, explore_page: is_explore_page, pipeline_status: Feature.enabled?(:dashboard_pipeline_status, default_enabled: true)
+= render 'shared/projects/list', projects: projects, user: current_user, explore_page: true, pipeline_status: Feature.enabled?(:dashboard_pipeline_status, default_enabled: true)
diff --git a/app/views/explore/projects/index.html.haml b/app/views/explore/projects/index.html.haml
index 341ad681c7c..44456b6c015 100644
--- a/app/views/explore/projects/index.html.haml
+++ b/app/views/explore/projects/index.html.haml
@@ -1,6 +1,7 @@
- @hide_top_links = true
- page_title _("Projects")
- header_title _("Projects"), dashboard_projects_path
+- page_canonical_link explore_projects_url
= render_dashboard_gold_trial(current_user)
diff --git a/app/views/explore/projects/page_out_of_bounds.html.haml b/app/views/explore/projects/page_out_of_bounds.html.haml
index 57114dd0752..0ee77ffd7d7 100644
--- a/app/views/explore/projects/page_out_of_bounds.html.haml
+++ b/app/views/explore/projects/page_out_of_bounds.html.haml
@@ -18,4 +18,4 @@
%h5= _("Maximum page reached")
%p= _("Sorry, you have exceeded the maximum browsable page number. Please use the API to explore further.")
- = link_to _("Back to page %{number}") % { number: @max_page_number }, request.params.merge(page: @max_page_number), class: 'btn btn-inverted'
+ = link_to _("Back to page %{number}") % { number: @max_page_number }, request.params.merge(page: @max_page_number), class: 'gl-button btn btn-inverted'
diff --git a/app/views/explore/projects/trending.html.haml b/app/views/explore/projects/trending.html.haml
index 153c90e534e..ed508fa2506 100644
--- a/app/views/explore/projects/trending.html.haml
+++ b/app/views/explore/projects/trending.html.haml
@@ -10,4 +10,4 @@
= render 'explore/head'
= render 'explore/projects/nav' unless Feature.enabled?(:project_list_filter_bar) && current_user
-= render 'projects', projects: @projects, explore_page: true
+= render 'projects', projects: @projects
diff --git a/app/views/groups/_home_panel.html.haml b/app/views/groups/_home_panel.html.haml
index 97e48cdec8c..ee08829d990 100644
--- a/app/views/groups/_home_panel.html.haml
+++ b/app/views/groups/_home_panel.html.haml
@@ -20,37 +20,16 @@
%span.access-request-links.gl-ml-3
= render 'shared/members/access_request_links', source: @group
- .home-panel-buttons.col-md-12.col-lg-6.d-inline-flex.flex-wrap.justify-content-lg-end
+ .home-panel-buttons.col-md-12.col-lg-6
- if current_user
- .group-buttons
- = render 'shared/notifications/new_button', notification_setting: @notification_setting, btn_class: 'btn', emails_disabled: emails_disabled
- - new_project_label = _("New project")
- - new_subgroup_label = _("New subgroup")
- - if can_create_projects and can_create_subgroups
- .btn-group.new-project-subgroup.droplab-dropdown.home-panel-action-button.gl-mt-3.js-new-project-subgroup.qa-new-project-or-subgroup-dropdown{ data: { project_path: new_project_path(namespace_id: @group.id), subgroup_path: new_group_path(parent_id: @group.id) } }
- %input.btn.btn-success.dropdown-primary.js-new-group-child.qa-new-in-group-button{ type: "button", value: new_project_label, data: { action: "new-project" } }
- %button.btn.btn-success.dropdown-toggle.js-dropdown-toggle.qa-new-project-or-subgroup-dropdown-toggle{ type: "button", data: { "dropdown-trigger" => "#new-project-or-subgroup-dropdown", 'display' => 'static' } }
- = sprite_icon("chevron-down", css_class: "icon dropdown-btn-icon")
- %ul#new-project-or-subgroup-dropdown.dropdown-menu.dropdown-menu-right{ data: { dropdown: true } }
- %li.droplab-item-selected.qa-new-project-option{ role: "button", data: { value: "new-project", text: new_project_label } }
- .menu-item
- .icon-container
- = icon("check", class: "list-item-checkmark")
- .description
- %strong= new_project_label
- %span= s_("GroupsTree|Create a project in this group.")
- %li.divider.droplap-item-ignore
- %li.qa-new-subgroup-option{ role: "button", data: { value: "new-subgroup", text: new_subgroup_label } }
- .menu-item
- .icon-container
- = icon("check", class: "list-item-checkmark")
- .description
- %strong= new_subgroup_label
- %span= s_("GroupsTree|Create a subgroup in this group.")
- - elsif can_create_projects
- = link_to new_project_label, new_project_path(namespace_id: @group.id), class: "btn btn-success gl-mt-3"
- - elsif can_create_subgroups
- = link_to new_subgroup_label, new_group_path(parent_id: @group.id), class: "btn btn-success gl-mt-3"
+ .gl-display-flex.gl-flex-wrap.gl-lg-justify-content-end.gl-mx-n2{ data: { testid: 'group-buttons' } }
+ = render 'shared/notifications/new_button', notification_setting: @notification_setting, btn_class: 'btn gl-button gl-sm-w-auto gl-w-full', dropdown_container_class: 'gl-mr-0 gl-px-2 gl-sm-w-auto gl-w-full', emails_disabled: emails_disabled
+ - if can_create_subgroups
+ .gl-px-2.gl-sm-w-auto.gl-w-full
+ = link_to _("New subgroup"), new_group_path(parent_id: @group.id), class: "btn btn-success btn-md gl-button btn-success-secondary gl-mt-3 gl-sm-w-auto gl-w-full", data: { qa_selector: 'new_subgroup_button' }
+ - if can_create_projects
+ .gl-px-2.gl-sm-w-auto.gl-w-full
+ = link_to _("New project"), new_project_path(namespace_id: @group.id), class: "btn btn-success btn-md gl-button gl-mt-3 gl-sm-w-auto gl-w-full", data: { qa_selector: 'new_project_button' }
- if @group.description.present?
.group-home-desc.mt-1
diff --git a/app/views/groups/_invite_members_modal.html.haml b/app/views/groups/_invite_members_modal.html.haml
index 51f41d58029..3aae81cef8d 100644
--- a/app/views/groups/_invite_members_modal.html.haml
+++ b/app/views/groups/_invite_members_modal.html.haml
@@ -1,6 +1,7 @@
- if invite_members_allowed?(group)
- .js-invite-members-modal{ data: { group_id: group.id,
- group_name: group.name,
+ .js-invite-members-modal{ data: { id: group.id,
+ name: group.name,
+ is_project: false,
access_levels: GroupMember.access_level_roles.to_json,
default_access_level: Gitlab::Access::GUEST,
help_link: help_page_url('user/permissions') } }
diff --git a/app/views/groups/_invite_members_side_nav_link.html.haml b/app/views/groups/_invite_members_side_nav_link.html.haml
index 1c90eaee992..4f1c06d9fe3 100644
--- a/app/views/groups/_invite_members_side_nav_link.html.haml
+++ b/app/views/groups/_invite_members_side_nav_link.html.haml
@@ -1,3 +1,3 @@
- if invite_members_allowed?(group) && body_data_page == 'groups:show'
%li
- .js-invite-members-trigger{ data: { icon: 'plus', display_text: 'Invite team members' } }
+ .js-invite-members-trigger{ data: { icon: 'plus', display_text: _('Invite team members') } }
diff --git a/app/views/groups/dependency_proxies/_url.html.haml b/app/views/groups/dependency_proxies/_url.html.haml
new file mode 100644
index 00000000000..9242954b684
--- /dev/null
+++ b/app/views/groups/dependency_proxies/_url.html.haml
@@ -0,0 +1,12 @@
+- proxy_url = "#{group_url(@group)}/dependency_proxy/containers"
+
+%h5.prepend-top-20= _('Dependency proxy URL')
+
+.row
+ .col-lg-8.col-md-12.input-group
+ = text_field_tag :url, "#{proxy_url}", class: 'js-dependency-proxy-url form-control', readonly: true
+ = clipboard_button(text: "#{proxy_url}", title: _("Copy %{proxy_url}") % { proxy_url: proxy_url })
+
+.row
+ .col-12.help-block.gl-mt-3
+ = _('Contains %{count} blobs of images (%{size})') % { count: @blobs_count, size: number_to_human_size(@blobs_total_size) }
diff --git a/app/views/groups/dependency_proxies/show.html.haml b/app/views/groups/dependency_proxies/show.html.haml
new file mode 100644
index 00000000000..ff1312eb763
--- /dev/null
+++ b/app/views/groups/dependency_proxies/show.html.haml
@@ -0,0 +1,28 @@
+- page_title _("Dependency Proxy")
+
+.settings-header
+ %h4= _('Dependency proxy')
+
+ %p
+ - link_start = '<a href="%{url}">'.html_safe % { url: help_page_path('user/packages/dependency_proxy/index') }
+ = _('Create a local proxy for storing frequently used upstream images. %{link_start}Learn more%{link_end} about dependency proxies.').html_safe % { link_start: link_start, link_end: '</a>'.html_safe }
+
+- if @group.public?
+ - if can?(current_user, :admin_dependency_proxy, @group)
+ = form_for(@dependency_proxy, method: :put, url: group_dependency_proxy_path(@group)) do |f|
+ .form-group
+ %h5.prepend-top-20= _('Enable proxy')
+ .js-dependency-proxy-toggle-area
+ = render "shared/buttons/project_feature_toggle", is_checked: @dependency_proxy.enabled?, label: s_("DependencyProxy|Toggle Dependency Proxy") do
+ = f.hidden_field :enabled, { class: 'js-project-feature-toggle-input'}
+
+ - if @dependency_proxy.enabled
+ = render 'groups/dependency_proxies/url'
+
+ - else
+ - if @dependency_proxy.enabled
+ = render 'groups/dependency_proxies/url'
+- else
+ .gl-alert.gl-alert-info
+ = sprite_icon('information-o', size: 16, css_class: 'gl-icon gl-alert-icon gl-alert-icon-no-title')
+ = _('Dependency proxy feature is limited to public groups for now.')
diff --git a/app/views/groups/group_members/index.html.haml b/app/views/groups/group_members/index.html.haml
index d999f20ef91..2a87b42ef13 100644
--- a/app/views/groups/group_members/index.html.haml
+++ b/app/views/groups/group_members/index.html.haml
@@ -3,7 +3,8 @@
- show_invited_members = can_manage_members && @invited_members.exists?
- show_access_requests = can_manage_members && @requesters.exists?
- invited_active = params[:search_invited].present? || params[:invited_members_page].present?
-- vue_members_list_enabled = Feature.enabled?(:vue_group_members_list, @group)
+- vue_members_list_enabled = Feature.enabled?(:vue_group_members_list, @group, default_enabled: true)
+- current_user_is_group_owner = @group && @group.has_owner?(current_user)
- form_item_label_css_class = 'label-bold gl-mr-2 gl-mb-0 gl-py-2 align-self-md-center'
@@ -69,9 +70,15 @@
= render 'shared/members/sort_dropdown'
- if vue_members_list_enabled
.js-group-members-list{ data: group_members_list_data_attributes(@group, @members) }
+ .loading
+ .spinner.spinner-md
- else
%ul.content-list.members-list{ data: { qa_selector: 'members_list' } }
- = render partial: 'shared/members/member', collection: @members, as: :member
+ = render partial: 'shared/members/member',
+ collection: @members, as: :member,
+ locals: { membership_source: @group,
+ group: @group,
+ current_user_is_group_owner: current_user_is_group_owner }
= paginate @members, theme: 'gitlab', params: { invited_members_page: nil, search_invited: nil }
- if @group.shared_with_group_links.any?
#tab-groups.tab-pane
@@ -81,6 +88,8 @@
= html_escape(_('Groups with access to %{strong_start}%{group_name}%{strong_end}')) % { group_name: @group.name, strong_start: '<strong>'.html_safe, strong_end: '</strong>'.html_safe }
- if vue_members_list_enabled
.js-group-linked-list{ data: linked_groups_list_data_attributes(@group) }
+ .loading
+ .spinner.spinner-md
- else
%ul.content-list.members-list{ data: { qa_selector: 'groups_list' } }
- @group.shared_with_group_links.each do |group_link|
@@ -95,9 +104,15 @@
= render 'shared/members/search_field', name: 'search_invited'
- if vue_members_list_enabled
.js-group-invited-members-list{ data: group_members_list_data_attributes(@group, @invited_members) }
+ .loading
+ .spinner.spinner-md
- else
%ul.content-list.members-list
- = render partial: 'shared/members/member', collection: @invited_members, as: :member
+ = render partial: 'shared/members/member',
+ collection: @invited_members, as: :member,
+ locals: { membership_source: @group,
+ group: @group,
+ current_user_is_group_owner: current_user_is_group_owner }
= paginate @invited_members, param_name: 'invited_members_page', theme: 'gitlab', params: { page: nil }
- if show_access_requests
#tab-access-requests.tab-pane
@@ -107,6 +122,12 @@
= html_escape(_('Users requesting access to %{strong_start}%{group_name}%{strong_end}')) % { group_name: @group.name, strong_start: '<strong>'.html_safe, strong_end: '</strong>'.html_safe }
- if vue_members_list_enabled
.js-group-access-requests-list{ data: group_members_list_data_attributes(@group, @requesters) }
+ .loading
+ .spinner.spinner-md
- else
%ul.content-list.members-list
- = render partial: 'shared/members/member', collection: @requesters, as: :member
+ = render partial: 'shared/members/member',
+ collection: @requesters, as: :member,
+ locals: { membership_source: @group,
+ group: @group,
+ current_user_is_group_owner: current_user_is_group_owner }
diff --git a/app/views/groups/issues.html.haml b/app/views/groups/issues.html.haml
index 33a9f423da6..ef7e3efdc68 100644
--- a/app/views/groups/issues.html.haml
+++ b/app/views/groups/issues.html.haml
@@ -30,6 +30,7 @@
'can-bulk-edit': @can_bulk_update.to_json,
'empty-state-meta': { svg_path: image_path('illustrations/issues.svg') },
'sort-key': @sort,
- type: 'issues' } }
+ type: 'issues',
+ 'scoped-labels-available': scoped_labels_available?(@group).to_json } }
- else
= render 'shared/issues'
diff --git a/app/views/groups/labels/index.html.haml b/app/views/groups/labels/index.html.haml
index debbe95d2aa..804d2da2c4b 100644
--- a/app/views/groups/labels/index.html.haml
+++ b/app/views/groups/labels/index.html.haml
@@ -5,7 +5,7 @@
- labels_or_filters = @labels.exists? || search.present? || subscribed.present?
- if labels_or_filters
- #promote-label-modal
+ #js-promote-label-modal
= render 'shared/labels/nav', labels_or_filters: labels_or_filters, can_admin_label: can_admin_label
.labels-container.gl-mt-2
diff --git a/app/views/groups/milestones/_form.html.haml b/app/views/groups/milestones/_form.html.haml
index df82b264f9a..ffb0ade4f73 100644
--- a/app/views/groups/milestones/_form.html.haml
+++ b/app/views/groups/milestones/_form.html.haml
@@ -19,8 +19,8 @@
.form-actions
- if @milestone.new_record?
- = f.submit 'Create milestone', class: "btn-success btn", data: { qa_selector: "create_milestone_button" }
- = link_to "Cancel", group_milestones_path(@group), class: "btn btn-cancel"
+ = f.submit 'Create milestone', class: "btn-success gl-button btn", data: { qa_selector: "create_milestone_button" }
+ = link_to "Cancel", group_milestones_path(@group), class: "btn gl-button btn-cancel"
- else
- = f.submit 'Update milestone', class: "btn-success btn"
- = link_to "Cancel", group_milestone_path(@group, @milestone), class: "btn btn-cancel"
+ = f.submit 'Update milestone', class: "btn-success gl-button btn"
+ = link_to "Cancel", group_milestone_path(@group, @milestone), class: "btn gl-button btn-cancel"
diff --git a/app/views/groups/milestones/index.html.haml b/app/views/groups/milestones/index.html.haml
index d20fa938a68..c93b24d14f0 100644
--- a/app/views/groups/milestones/index.html.haml
+++ b/app/views/groups/milestones/index.html.haml
@@ -8,7 +8,7 @@
= render 'shared/milestones/search_form'
= render 'shared/milestones_sort_dropdown'
- if can?(current_user, :admin_milestone, @group)
- = link_to "New milestone", new_group_milestone_path(@group), class: "btn btn-success", data: { qa_selector: "new_group_milestone_link" }
+ = link_to "New milestone", new_group_milestone_path(@group), class: "btn gl-button btn-success", data: { qa_selector: "new_group_milestone_link" }
.milestones
%ul.content-list
diff --git a/app/views/groups/runners/_group_runners.html.haml b/app/views/groups/runners/_group_runners.html.haml
index 554240b7aef..087c38c7b86 100644
--- a/app/views/groups/runners/_group_runners.html.haml
+++ b/app/views/groups/runners/_group_runners.html.haml
@@ -17,4 +17,6 @@
= render partial: 'ci/runner/how_to_setup_runner',
locals: { registration_token: @group.runners_token,
type: 'group',
- reset_token_url: reset_registration_token_group_settings_ci_cd_path }
+ reset_token_url: reset_registration_token_group_settings_ci_cd_path,
+ project_path: '',
+ group_path: @group.path }
diff --git a/app/views/groups/settings/repository/_initial_branch_name.html.haml b/app/views/groups/settings/repository/_initial_branch_name.html.haml
new file mode 100644
index 00000000000..3ef8dccae08
--- /dev/null
+++ b/app/views/groups/settings/repository/_initial_branch_name.html.haml
@@ -0,0 +1,22 @@
+%section.settings.as-default-branch-name.no-animate#js-default-branch-name{ class: ('expanded' if expanded_by_default?) }
+ .settings-header
+ %h4
+ = _('Default initial branch name')
+ %button.gl-button.js-settings-toggle{ type: 'button' }
+ = expanded_by_default? ? _('Collapse') : _('Expand')
+ %p
+ = _('Set the default name of the initial branch when creating new repositories through the user interface.')
+ .settings-content
+ = form_for @group, url: group_path(@group, anchor: 'js-default-branch-name'), html: { class: 'fieldset-form' } do |f|
+ = form_errors(@group)
+ - fallback_branch_name = '<code>master</code>'
+
+ %fieldset
+ .form-group
+ = f.label :default_branch_name, _('Default initial branch name'), class: 'label-light'
+ = f.text_field :default_branch_name, value: group.namespace_settings&.default_branch_name, placeholder: 'master', class: 'form-control'
+ %span.form-text.text-muted
+ = (_("Changes affect new repositories only. If not specified, either the configured application-wide default or Git's default name %{branch_name_default} will be used.") % { branch_name_default: fallback_branch_name }).html_safe
+
+ = f.hidden_field :redirect_target, value: "repository_settings"
+ = f.submit _('Save changes'), class: 'gl-button btn-success'
diff --git a/app/views/groups/settings/repository/show.html.haml b/app/views/groups/settings/repository/show.html.haml
index ff0c9de4fef..a5819320405 100644
--- a/app/views/groups/settings/repository/show.html.haml
+++ b/app/views/groups/settings/repository/show.html.haml
@@ -4,3 +4,4 @@
- deploy_token_description = s_('DeployTokens|Group deploy tokens allow access to the packages, repositories, and registry images within the group.')
= render "shared/deploy_tokens/index", group_or_project: @group, description: deploy_token_description
+= render "initial_branch_name", group: @group
diff --git a/app/views/groups/show.html.haml b/app/views/groups/show.html.haml
index fa560942c5d..9d5ec5008dc 100644
--- a/app/views/groups/show.html.haml
+++ b/app/views/groups/show.html.haml
@@ -1,7 +1,9 @@
- breadcrumb_title _("Details")
-- page_title _("Groups")
- @content_class = "limit-container-width" unless fluid_layout
+- if show_thanks_for_purchase_banner?
+ = render_if_exists 'shared/thanks_for_purchase_banner', plan_title: plan_title, quantity: params[:purchased_quantity].to_i
+
- if show_invite_banner?(@group)
= content_for :group_invite_members_banner do
.container-fluid.container-limited{ class: "gl-pb-2! gl-pt-6! #{@content_class}" }
diff --git a/app/views/groups/sidebar/_packages.html.haml b/app/views/groups/sidebar/_packages.html.haml
index 54510d5df0c..7e0ee032aeb 100644
--- a/app/views/groups/sidebar/_packages.html.haml
+++ b/app/views/groups/sidebar/_packages.html.haml
@@ -1,7 +1,7 @@
- packages_link = group_packages_list_nav? ? group_packages_path(@group) : group_container_registries_path(@group)
- if group_packages_nav?
- = nav_link(controller: ['groups/packages', 'groups/registry/repositories']) do
+ = nav_link(controller: ['groups/packages', 'groups/registry/repositories', 'groups/dependency_proxies']) do
= link_to packages_link, title: _('Packages') do
.nav-icon-container
= sprite_icon('package')
@@ -21,3 +21,7 @@
= nav_link(controller: 'groups/registry/repositories') do
= link_to group_container_registries_path(@group), title: _('Container Registry') do
%span= _('Container Registry')
+ - if group_dependency_proxy_nav?
+ = nav_link(controller: 'groups/dependency_proxies') do
+ = link_to group_dependency_proxy_path(@group), title: _('Dependency Proxy') do
+ %span= _('Dependency Proxy')
diff --git a/app/views/ide/_show.html.haml b/app/views/ide/_show.html.haml
index 79cba2a54b0..70ac532e69f 100644
--- a/app/views/ide/_show.html.haml
+++ b/app/views/ide/_show.html.haml
@@ -1,6 +1,7 @@
- @body_class = 'ide-layout'
- page_title _('IDE')
+- add_page_specific_style 'page_bundles/build'
- add_page_specific_style 'page_bundles/ide'
#ide.ide-loading{ data: ide_data }
diff --git a/app/views/import/_project_status.html.haml b/app/views/import/_project_status.html.haml
deleted file mode 100644
index b968db58d38..00000000000
--- a/app/views/import/_project_status.html.haml
+++ /dev/null
@@ -1,11 +0,0 @@
-- case project.import_status
-- when 'finished'
- = icon('check')
- = _('Done')
-- when 'started'
- = loading_icon
- = _('Started')
-- when 'failed'
- = _('Failed')
-- else
- = project.human_import_status_name
diff --git a/app/views/import/google_code/status.html.haml b/app/views/import/google_code/status.html.haml
index 72112c128cb..0004f0de69f 100644
--- a/app/views/import/google_code/status.html.haml
+++ b/app/views/import/google_code/status.html.haml
@@ -43,7 +43,7 @@
- case project.import_status
- when 'finished'
%span
- %i.fa.fa-check
+ = sprite_icon('check')
= _("done")
- when 'started'
= loading_icon
diff --git a/app/views/import/shared/_new_project_form.html.haml b/app/views/import/shared/_new_project_form.html.haml
index a558b21b461..b053d14a851 100644
--- a/app/views/import/shared/_new_project_form.html.haml
+++ b/app/views/import/shared/_new_project_form.html.haml
@@ -10,7 +10,7 @@
.input-group-prepend.flex-shrink-0.has-tooltip{ title: root_url }
.input-group-text
= root_url
- = select_tag :namespace_id, namespaces_options(namespace_id_from(params) || :current_user, display_path: true, extra_group: namespace_id_from(params)), class: 'select2 js-select-namespace block-truncated', tabindex: 1
+ = select_tag :namespace_id, namespaces_options(namespace_id_from(params) || :current_user, display_path: true, extra_group: namespace_id_from(params)), class: 'select2 js-select-namespace block-truncated'
- else
.input-group-prepend.static-namespace.has-tooltip{ title: user_url(current_user.username) + '/' }
.input-group-text.border-0
@@ -18,4 +18,4 @@
= hidden_field_tag :namespace_id, current_user.namespace_id
.form-group.col-12.col-sm-6.project-path
= label_tag :path, _('Project slug'), class: 'label-bold'
- = text_field_tag :path, @path, placeholder: "my-awesome-project", class: "js-path-name form-control", tabindex: 2, required: true
+ = text_field_tag :path, @path, placeholder: "my-awesome-project", class: "js-path-name form-control", required: true
diff --git a/app/views/invites/show.html.haml b/app/views/invites/show.html.haml
index 37143799132..1492fea7fb2 100644
--- a/app/views/invites/show.html.haml
+++ b/app/views/invites/show.html.haml
@@ -25,5 +25,5 @@
- if !member?
.actions
- = link_to _("Accept invitation"), accept_invite_url(@token, new_user_invite: params[:new_user_invite]), method: :post, class: "btn gl-button btn-success"
+ = link_to _("Accept invitation"), accept_invite_url(@token), method: :post, class: "btn gl-button btn-success"
= link_to _("Decline"), decline_invite_url(@token), method: :post, class: "btn gl-button btn-danger gl-ml-3"
diff --git a/app/views/jira_connect/subscriptions/index.html.haml b/app/views/jira_connect/subscriptions/index.html.haml
index 655c413f2a6..355ffabd7ec 100644
--- a/app/views/jira_connect/subscriptions/index.html.haml
+++ b/app/views/jira_connect/subscriptions/index.html.haml
@@ -21,6 +21,8 @@
.gl-mt-5
%p Note: this integration only works with accounts on GitLab.com (SaaS).
- else
+ .js-jira-connect-app
+
%form#add-subscription-form.subscription-form{ action: jira_connect_subscriptions_path }
.ak-field-group
%label
@@ -50,12 +52,15 @@
%p.browser-limitations-notice
%strong Browser limitations:
- Adding a namespace currently works only in browsers that allow cross site cookies. Please make sure to use
+ Adding a namespace currently works only in browsers that allow cross‑site cookies. Please make sure to use
%a{ href: 'https://www.mozilla.org/en-US/firefox/', target: '_blank', rel: 'noopener noreferrer' } Firefox
or
%a{ href: 'https://www.google.com/chrome/index.html', target: '_blank', rel: 'noopener noreferrer' } Google Chrome
- or enable cross-site cookies in your browser when adding a namespace.
+ or enable cross‑site cookies in your browser when adding a namespace.
%a{ href: 'https://gitlab.com/gitlab-org/gitlab/-/issues/263509', target: '_blank', rel: 'noopener noreferrer' } Learn more
+= webpack_bundle_tag 'performance_bar' if performance_bar_enabled?
+= webpack_bundle_tag 'jira_connect_app'
+
= page_specific_javascript_tag('jira_connect.js')
- add_page_specific_style 'page_bundles/jira_connect'
diff --git a/app/views/layouts/_flash.html.haml b/app/views/layouts/_flash.html.haml
index a0b57f8dd52..35fefe40d39 100644
--- a/app/views/layouts/_flash.html.haml
+++ b/app/views/layouts/_flash.html.haml
@@ -1,6 +1,6 @@
-# We currently only support `alert`, `notice`, `success`, 'toast'
- icons = {'alert' => 'error', 'notice' => 'information-o', 'success' => 'check-circle'};
-.flash-container.flash-container-page.sticky
+.flash-container.flash-container-page.sticky{ data: { qa_selector: 'flash_container' } }
- flash.each do |key, value|
- if key == 'toast' && value
.js-toast-message{ data: { message: value } }
diff --git a/app/views/layouts/_google_tag_manager_body.html.haml b/app/views/layouts/_google_tag_manager_body.html.haml
new file mode 100644
index 00000000000..d62e52dc91b
--- /dev/null
+++ b/app/views/layouts/_google_tag_manager_body.html.haml
@@ -0,0 +1,4 @@
+- return unless google_tag_manager_enabled?
+
+<noscript><iframe src="https://www.googletagmanager.com/ns.html?id=#{extra_config.google_tag_manager_id}"
+height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
diff --git a/app/views/layouts/_google_tag_manager_head.html.haml b/app/views/layouts/_google_tag_manager_head.html.haml
new file mode 100644
index 00000000000..ab03f1e7670
--- /dev/null
+++ b/app/views/layouts/_google_tag_manager_head.html.haml
@@ -0,0 +1,8 @@
+- if google_tag_manager_enabled?
+ = javascript_tag nonce: true do
+ :plain
+ (function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
+ new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
+ j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
+ 'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
+ })(window,document,'script','dataLayer','#{extra_config.google_tag_manager_id}');
diff --git a/app/views/layouts/_head.html.haml b/app/views/layouts/_head.html.haml
index 9d0c3ad5787..1d12b30c58c 100644
--- a/app/views/layouts/_head.html.haml
+++ b/app/views/layouts/_head.html.haml
@@ -1,17 +1,4 @@
- page_description brand_title unless page_description
-
--# Needs a redirect on the client side since it's using an anchor to distinguish
--# between sign in and registration. We need to inline the JS to not render
--# anything from this page beforehand.
--# Part of an experiment to build a new sign up flow. Will be removed again with
--# https://gitlab.com/gitlab-org/growth/engineering/issues/64
-- if experiment_enabled?(:signup_flow) && current_path?("sessions#new")
- = javascript_tag nonce: true do
- :plain
- if (window.location.hash === '#register-pane') {
- window.location.replace("/users/sign_up")
- }
-
- site_name = "GitLab"
%head{ prefix: "og: http://ogp.me/ns#" }
%meta{ charset: "utf-8" }
diff --git a/app/views/layouts/_mailer.html.haml b/app/views/layouts/_mailer.html.haml
index 24b8138078d..74d05be7f95 100644
--- a/app/views/layouts/_mailer.html.haml
+++ b/app/views/layouts/_mailer.html.haml
@@ -34,13 +34,7 @@
= render_if_exists 'layouts/mailer/additional_text'
- %tr.footer
- %td
- %img{ alt: "GitLab", height: "33", width: "90", src: image_url('mailers/gitlab_footer_logo.gif') }
- %div
- - manage_notifications_link = link_to(_("Manage all notifications"), profile_notifications_url, class: 'mng-notif-link')
- - help_link = link_to(_("Help"), help_url, class: 'help-link')
- = _("You're receiving this email because of your account on %{host}. %{manage_notifications_link} &middot; %{help_link}").html_safe % { host: Gitlab.config.gitlab.host, manage_notifications_link: manage_notifications_link, help_link: help_link }
+ = yield :footer
= yield :additional_footer
%tr
diff --git a/app/views/layouts/_page.html.haml b/app/views/layouts/_page.html.haml
index 9b925369660..f6fc49393d8 100644
--- a/app/views/layouts/_page.html.haml
+++ b/app/views/layouts/_page.html.haml
@@ -4,12 +4,13 @@
.content-wrapper{ class: "#{@content_wrapper_class}" }
.mobile-overlay
= yield :group_invite_members_banner
- .alert-wrapper
+ .alert-wrapper.gl-force-block-formatting-context
= render 'shared/outdated_browser'
= render_if_exists "layouts/header/licensed_user_count_threshold"
= render_if_exists "layouts/header/token_expiry_notification"
= render "layouts/broadcast"
= render "layouts/header/read_only_banner"
+ = render "layouts/header/registration_enabled_callout"
= render "layouts/nav/classification_level_banner"
= yield :flash_message
= render "shared/ping_consent"
@@ -20,6 +21,6 @@
- unless @hide_breadcrumbs
= render "layouts/nav/breadcrumbs"
%div{ class: "#{(container_class unless @no_container)} #{@content_class}" }
- .content{ id: "content-body" }
+ .content{ id: "content-body", **page_itemtype }
= render "layouts/flash", extra_flash_class: 'limit-container-width'
= yield
diff --git a/app/views/layouts/_search.html.haml b/app/views/layouts/_search.html.haml
index 0c6932e59a9..c902c687378 100644
--- a/app/views/layouts/_search.html.haml
+++ b/app/views/layouts/_search.html.haml
@@ -6,14 +6,13 @@
= search_field_tag 'search', nil, placeholder: _('Search or jump to…'),
class: 'search-input dropdown-menu-toggle no-outline js-search-dashboard-options',
spellcheck: false,
- tabindex: '1',
autocomplete: 'off',
data: { issues_path: issues_dashboard_path,
mr_path: merge_requests_dashboard_path,
qa_selector: 'search_term_field' },
aria: { label: _('Search or jump to…') }
%button.hidden.js-dropdown-search-toggle{ type: 'button', data: { toggle: 'dropdown' } }
- .dropdown-menu.dropdown-select.js-dashboard-search-options
+ .dropdown-menu.dropdown-select{ data: { testid: 'dashboard-search-options' } }
= dropdown_content do
%ul
%li.dropdown-menu-empty-item
diff --git a/app/views/layouts/_startup_js.html.haml b/app/views/layouts/_startup_js.html.haml
index f312e00c394..9c488e4f40d 100644
--- a/app/views/layouts/_startup_js.html.haml
+++ b/app/views/layouts/_startup_js.html.haml
@@ -25,7 +25,7 @@
};
gl.startup_graphql_calls = gl.startup_graphql_calls.map(call => ({
- operationName: call.query.match(/^query (.+)\(/)[1],
+ ...call,
fetchCall: fetch(url, {
...opts,
credentials: 'same-origin',
diff --git a/app/views/layouts/devise_experimental_onboarding_issues.html.haml b/app/views/layouts/devise_experimental_onboarding_issues.html.haml
index ec9867f9e1f..f768fba84ca 100644
--- a/app/views/layouts/devise_experimental_onboarding_issues.html.haml
+++ b/app/views/layouts/devise_experimental_onboarding_issues.html.haml
@@ -1,6 +1,6 @@
!!! 5
%html.devise-layout-html.navless{ class: system_message_class }
- - add_page_specific_style 'page_bundles/experimental_separate_sign_up'
+ - add_page_specific_style 'page_bundles/signup'
= render "layouts/head"
%body.ui-indigo.signup-page{ class: "#{client_class_list}", data: { page: body_data_page, qa_selector: 'signup_page' } }
= render "layouts/header/logo_with_title"
diff --git a/app/views/layouts/devise_experimental_separate_sign_up_flow.html.haml b/app/views/layouts/devise_experimental_separate_sign_up_flow.html.haml
deleted file mode 100644
index 6be62645768..00000000000
--- a/app/views/layouts/devise_experimental_separate_sign_up_flow.html.haml
+++ /dev/null
@@ -1,20 +0,0 @@
-!!! 5
-%html.devise-layout-html.navless{ class: system_message_class }
- - add_page_specific_style 'page_bundles/experimental_separate_sign_up'
- = render "layouts/head"
- %body.ui-indigo.signup-page{ class: "#{client_class_list}", data: { page: body_data_page, qa_selector: 'signup_page' } }
- = render "layouts/header/logo_with_title"
- = render "layouts/init_client_detection_flags"
- .page-wrap
- .container.signup-box-container.navless-container
- = render "layouts/broadcast"
- .content
- = render "layouts/flash"
- = yield
- %hr.footer-fixed
- .footer-container
- .container
- .footer-links
- = link_to _("Help"), help_path
- = link_to _("About GitLab"), "https://about.gitlab.com/"
- = footer_message
diff --git a/app/views/layouts/experiment_mailer.html.haml b/app/views/layouts/experiment_mailer.html.haml
deleted file mode 100644
index 5a342c400d6..00000000000
--- a/app/views/layouts/experiment_mailer.html.haml
+++ /dev/null
@@ -1,48 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-%html{ lang: "en" }
- %head
- %meta{ content: "text/html; charset=UTF-8", "http-equiv" => "Content-Type" }/
- %meta{ content: "width=device-width, initial-scale=1", name: "viewport" }/
- %meta{ content: "IE=edge", "http-equiv" => "X-UA-Compatible" }/
- %title= message.subject
-
- -# Avoid premailer processing of client-specific styles (@media tag not supported)
- -# We need to inline the contents here because mail clients (e.g. iOS Mail, Outlook)
- -# do not support linked stylesheets.
- %style{ type: 'text/css', 'data-premailer': 'ignore' }
- = asset_to_string('mailer_client_specific.css').html_safe
-
- = stylesheet_link_tag 'mailer.css'
- %body
- %table#body{ border: "0", cellpadding: "0", cellspacing: "0" }
- %tbody
- %tr.line
- %td
- %tr.header
- %td
- = html_header_message
- = header_logo
- %tr
- %td
- %table.wrapper{ border: "0", cellpadding: "0", cellspacing: "0" }
- %tbody
- %tr
- %td.wrapper-cell{ style: "padding: 0" }
- %table.content{ border: "0", cellpadding: "0", cellspacing: "0" }
- %tbody
- = yield
-
- = render_if_exists 'layouts/mailer/additional_text'
-
- %tr.footer
- %td{ style: "padding: 24px 0" }
- %img{ alt: "GitLab", height: "33", width: "90", src: image_url('mailers/gitlab_footer_logo.gif') }
- %p{ style: "color: #949ba5; max-width: 640px; margin: 0 auto; text-align: left; font-size: 12px;" }
- GitLab is a complete DevOps platform, delivered as a single application, fundamentally changing the way
- %br
- Development, Security, and Ops teams collaborate.
-
- = yield :additional_footer
- %tr
- %td.footer-message
- = html_footer_message
diff --git a/app/views/layouts/header/_current_user_dropdown.html.haml b/app/views/layouts/header/_current_user_dropdown.html.haml
index 4c6bfc0b33c..addf2375222 100644
--- a/app/views/layouts/header/_current_user_dropdown.html.haml
+++ b/app/views/layouts/header/_current_user_dropdown.html.haml
@@ -2,13 +2,16 @@
%ul
%li.current-user
- .user-name.bold
+ .user-name.gl-font-weight-bold
= current_user.name
+ - if current_user&.status && user_status_set_to_busy?(current_user.status)
+ %span.gl-font-weight-normal.gl-text-gray-500= s_("UserProfile|(Busy)")
= current_user.to_reference
- if current_user.status
.user-status.d-flex.align-items-center.gl-mt-2.has-tooltip{ title: current_user.status.message_html, data: { html: 'true', placement: 'bottom' } }
- %span.user-status-emoji.d-flex.align-items-center
- = emoji_icon current_user.status.emoji
+ - if show_status_emoji?(current_user.status)
+ .user-status-emoji.d-flex.align-items-center
+ = emoji_icon current_user.status.emoji
%span.user-status-message.str-truncated
= current_user.status.message_html.html_safe
%li.divider
diff --git a/app/views/layouts/header/_default.html.haml b/app/views/layouts/header/_default.html.haml
index f6dc808aa55..794d1589172 100644
--- a/app/views/layouts/header/_default.html.haml
+++ b/app/views/layouts/header/_default.html.haml
@@ -1,4 +1,5 @@
- 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' } }
%a.sr-only.gl-accessibility{ href: "#content-body", tabindex: "1" } Skip to content
@@ -103,4 +104,4 @@
#whats-new-app{ data: { storage_key: whats_new_storage_key } }
- if can?(current_user, :update_user_status, current_user)
- .js-set-status-modal-wrapper{ data: { current_emoji: current_user.status.present? ? current_user.status.emoji : '', current_message: current_user.status.present? ? current_user.status.message : '' } }
+ .js-set-status-modal-wrapper{ data: user_status_data }
diff --git a/app/views/layouts/header/_registration_enabled_callout.html.haml b/app/views/layouts/header/_registration_enabled_callout.html.haml
new file mode 100644
index 00000000000..1b1804edcc7
--- /dev/null
+++ b/app/views/layouts/header/_registration_enabled_callout.html.haml
@@ -0,0 +1,15 @@
+- return unless show_registration_enabled_user_callout?
+
+%div{ class: [container_class, @content_class, 'gl-pt-5!'] }
+ .gl-alert.gl-alert-warning.js-registration-enabled-callout{ role: 'alert', data: { feature_id: UserCalloutsHelper::REGISTRATION_ENABLED_CALLOUT, dismiss_endpoint: user_callouts_path } }
+ = sprite_icon('warning', size: 16, css_class: 'gl-alert-icon')
+ %button.gl-alert-dismiss.js-close{ type: 'button', aria: { label: _('Close') }, data: { testid: 'close-registration-enabled-callout' } }
+ = sprite_icon('close', size: 16)
+ .gl-alert-title
+ = _('Open registration is enabled on your instance.')
+ .gl-alert-body
+ = html_escape(_('%{anchorOpen}Learn more%{anchorClose} about how you can customize / disable registration on your instance.')) % { anchorOpen: "<a href=\"#{help_page_path('user/admin_area/settings/sign_up_restrictions')}\">".html_safe, anchorClose: '</a>'.html_safe }
+ .gl-alert-actions
+ = link_to general_admin_application_settings_path(anchor: 'js-signup-settings'), class: 'btn gl-alert-action btn-info btn-md gl-button' do
+ %span.gl-button-text
+ = _('View setting')
diff --git a/app/views/layouts/mailer.html.haml b/app/views/layouts/mailer.html.haml
index 28dcbce7183..c2eb6b68024 100644
--- a/app/views/layouts/mailer.html.haml
+++ b/app/views/layouts/mailer.html.haml
@@ -1 +1,10 @@
+= content_for :footer do
+ %tr.footer
+ %td
+ %img.footer-logo{ alt: "GitLab", src: image_url('mailers/gitlab_footer_logo.gif') }
+ %div
+ - manage_notifications_link = link_to(_("Manage all notifications"), profile_notifications_url, class: 'mng-notif-link')
+ - help_link = link_to(_("Help"), help_url, class: 'help-link')
+ = _("You're receiving this email because of your account on %{host}. %{manage_notifications_link} &middot; %{help_link}").html_safe % { host: Gitlab.config.gitlab.host, manage_notifications_link: manage_notifications_link, help_link: help_link }
+
= render 'layouts/mailer'
diff --git a/app/views/layouts/nav/_breadcrumbs.html.haml b/app/views/layouts/nav/_breadcrumbs.html.haml
index 547d005a93e..f0cdb3d1a51 100644
--- a/app/views/layouts/nav/_breadcrumbs.html.haml
+++ b/app/views/layouts/nav/_breadcrumbs.html.haml
@@ -1,5 +1,6 @@
- container = @no_breadcrumb_container ? 'container-fluid' : container_class
- hide_top_links = @hide_top_links || false
+- push_to_schema_breadcrumb(@breadcrumb_title, breadcrumb_title_link)
%nav.breadcrumbs{ role: "navigation", class: [container, @content_class] }
.breadcrumbs-container{ class: ("border-bottom-0" if @no_breadcrumb_border) }
@@ -17,4 +18,7 @@
= render "layouts/nav/breadcrumbs/collapsed_dropdown", location: :after
%li
%h2.breadcrumbs-sub-title= link_to @breadcrumb_title, breadcrumb_title_link
+ %script{ type:'application/ld+json' }
+ :plain
+ #{schema_breadcrumb_json}
= yield :header_content
diff --git a/app/views/layouts/nav/_dashboard.html.haml b/app/views/layouts/nav/_dashboard.html.haml
index abaadc89a9e..7cbef6b00b1 100644
--- a/app/views/layouts/nav/_dashboard.html.haml
+++ b/app/views/layouts/nav/_dashboard.html.haml
@@ -2,7 +2,7 @@
-# https://gitlab.com/gitlab-org/gitlab-foss/issues/49713 for more information.
%ul.list-unstyled.navbar-sub-nav
- if dashboard_nav_link?(:projects)
- = nav_link(path: ['root#index', 'projects#trending', 'projects#starred', 'dashboard/projects#index'], html_options: { id: 'nav-projects-dropdown', class: "home dropdown header-projects qa-projects-dropdown", data: { track_label: "projects_dropdown", track_event: "click_dropdown", track_value: "" } }) do
+ = nav_link(path: ['root#index', 'projects#trending', 'projects#starred', 'dashboard/projects#index'], html_options: { id: 'nav-projects-dropdown', class: "home dropdown header-projects qa-projects-dropdown", data: { track_label: "projects_dropdown", track_event: "click_dropdown" } }) do
%button{ type: 'button', data: { toggle: "dropdown" } }
= _('Projects')
= sprite_icon('chevron-down', css_class: 'caret-down')
@@ -10,7 +10,7 @@
= render "layouts/nav/projects_dropdown/show"
- if dashboard_nav_link?(:groups)
- = nav_link(controller: ['dashboard/groups', 'explore/groups'], html_options: { id: 'nav-groups-dropdown', class: "d-none d-md-block home dropdown header-groups qa-groups-dropdown", data: { track_label: "groups_dropdown", track_event: "click_dropdown", track_value: "" } }) do
+ = nav_link(controller: ['dashboard/groups', 'explore/groups'], html_options: { id: 'nav-groups-dropdown', class: "d-none d-md-block home dropdown header-groups qa-groups-dropdown", data: { track_label: "groups_dropdown", track_event: "click_dropdown" } }) do
%button{ type: 'button', data: { toggle: "dropdown" } }
= _('Groups')
= sprite_icon('chevron-down', css_class: 'caret-down')
@@ -18,7 +18,7 @@
= render "layouts/nav/groups_dropdown/show"
- if any_dashboard_nav_link?([:groups, :milestones, :activity, :snippets])
- %li.header-more.dropdown{ **tracking_attrs('main_navigation', 'click_more_link', 'navigation') }
+ = nav_link(html_options: { id: 'nav-more-dropdown', class: "header-more dropdown", data: { track_label: "more_dropdown", track_event: "click_more_link" } }) do
%a{ href: "#", data: { toggle: "dropdown", qa_selector: 'more_dropdown' } }
= _('More')
= sprite_icon('chevron-down', css_class: 'caret-down')
@@ -71,11 +71,11 @@
- if Feature.enabled?(:user_mode_in_session)
- if header_link?(:admin_mode)
- = nav_link(controller: 'admin/sessions', html_options: { class: "d-none d-lg-block d-xl-block"}) do
+ = nav_link(controller: 'admin/sessions', html_options: { class: "d-none d-lg-block"}) do
= link_to destroy_admin_session_path, method: :post, title: _('Leave Admin Mode'), aria: { label: _('Leave Admin Mode') }, data: { toggle: 'tooltip', placement: 'bottom', container: 'body' } do
= sprite_icon('lock-open', size: 18)
- elsif current_user.admin?
- = nav_link(controller: 'admin/sessions', html_options: { class: "d-none d-lg-block d-xl-block"}) do
+ = nav_link(controller: 'admin/sessions', html_options: { class: "d-none d-lg-block"}) do
= link_to new_admin_session_path, title: _('Enter Admin Mode'), aria: { label: _('Enter Admin Mode') }, data: { toggle: 'tooltip', placement: 'bottom', container: 'body' } do
= sprite_icon('lock', size: 18)
diff --git a/app/views/layouts/nav/sidebar/_admin.html.haml b/app/views/layouts/nav/sidebar/_admin.html.haml
index 0da4d4f7ddd..1e0e9628c89 100644
--- a/app/views/layouts/nav/sidebar/_admin.html.haml
+++ b/app/views/layouts/nav/sidebar/_admin.html.haml
@@ -69,7 +69,7 @@
= link_to admin_cohorts_path, title: _('Cohorts') do
%span
= _('Cohorts')
- - if Feature.enabled?(:instance_statistics)
+ - if Feature.enabled?(:instance_statistics, default_enabled: true)
= nav_link(controller: :instance_statistics) do
= link_to admin_instance_statistics_path, title: _('Instance Statistics') do
%span
diff --git a/app/views/layouts/nav/sidebar/_project.html.haml b/app/views/layouts/nav/sidebar/_project.html.haml
index d3d71f91176..5ff774d5d9c 100644
--- a/app/views/layouts/nav/sidebar/_project.html.haml
+++ b/app/views/layouts/nav/sidebar/_project.html.haml
@@ -167,7 +167,7 @@
= render_if_exists "layouts/nav/requirements_link", project: @project
- if project_nav_tab? :pipelines
- = nav_link(controller: [:pipelines, :builds, :jobs, :pipeline_schedules, :artifacts, :test_cases], unless: -> { current_path?('projects/pipelines#charts') }) do
+ = nav_link(controller: [:pipelines, :builds, :jobs, :pipeline_schedules, :artifacts, :test_cases, :pipeline_editor], unless: -> { current_path?('projects/pipelines#charts') }) do
= link_to project_pipelines_path(@project), class: 'shortcuts-pipelines qa-link-pipelines rspec-link-pipelines', data: { qa_selector: 'ci_cd_link' } do
.nav-icon-container
= sprite_icon('rocket')
@@ -175,7 +175,7 @@
= _('CI / CD')
%ul.sidebar-sub-level-items
- = nav_link(controller: [:pipelines, :builds, :jobs, :pipeline_schedules, :artifacts, :test_cases], html_options: { class: "fly-out-top-item" }) do
+ = nav_link(controller: [:pipelines, :builds, :jobs, :pipeline_schedules, :artifacts, :test_cases, :pipeline_editor], html_options: { class: "fly-out-top-item" }) do
= link_to project_pipelines_path(@project) do
%strong.fly-out-top-item-name
= _('CI / CD')
@@ -186,6 +186,12 @@
%span
= _('Pipelines')
+ - if can_view_pipeline_editor?(@project)
+ = nav_link(controller: :pipeline_editor, action: :show) do
+ = link_to project_ci_pipeline_editor_path(@project), title: s_('Pipelines|Editor') do
+ %span
+ = s_('Pipelines|Editor')
+
- if project_nav_tab? :builds
= nav_link(controller: :jobs) do
= link_to project_jobs_path(@project), title: _('Jobs'), class: 'shortcuts-builds' do
@@ -262,6 +268,12 @@
%span
= _('Serverless')
+ - if project_nav_tab? :terraform
+ = nav_link(controller: :terraform) do
+ = link_to project_terraform_index_path(@project), title: _('Terraform') do
+ %span
+ = _('Terraform')
+
- if project_nav_tab? :clusters
- show_cluster_hint = show_gke_cluster_integration_callout?(@project)
= nav_link(controller: [:clusters, :user, :gcp]) do
@@ -272,7 +284,6 @@
.feature-highlight.js-feature-highlight{ disabled: true,
data: { trigger: 'manual',
container: 'body',
- toggle: 'popover',
placement: 'right',
highlight: UserCalloutsHelper::GKE_CLUSTER_INTEGRATION,
highlight_priority: UserCallout.feature_names[:GKE_CLUSTER_INTEGRATION],
@@ -369,6 +380,8 @@
%strong.fly-out-top-item-name
= _('Members')
+ = render_if_exists 'projects/invite_members_side_nav_link', project: @project
+
- if project_nav_tab? :settings
= nav_link(path: sidebar_settings_paths) do
= link_to edit_project_path(@project) do
@@ -412,7 +425,7 @@
= link_to project_settings_ci_cd_path(@project), title: _('CI / CD') do
%span
= _('CI / CD')
- - if !@project.archived? && settings_operations_available?
+ - if settings_operations_available?
= nav_link(controller: [:operations]) do
= link_to project_settings_operations_path(@project), title: _('Operations'), data: { qa_selector: 'operations_settings_link' } do
= _('Operations')
diff --git a/app/views/layouts/project.html.haml b/app/views/layouts/project.html.haml
index a0c82380023..62e5431e290 100644
--- a/app/views/layouts/project.html.haml
+++ b/app/views/layouts/project.html.haml
@@ -2,6 +2,7 @@
- page_description @project.description_html unless page_description
- header_title project_title(@project) unless header_title
- nav "project"
+- page_itemtype 'http://schema.org/SoftwareSourceCode'
- display_subscription_banner!
- display_namespace_storage_limit_alert!
- @left_sidebar = true
diff --git a/app/views/layouts/unknown_user_mailer.html.haml b/app/views/layouts/unknown_user_mailer.html.haml
new file mode 100644
index 00000000000..2eb7b400604
--- /dev/null
+++ b/app/views/layouts/unknown_user_mailer.html.haml
@@ -0,0 +1,8 @@
+= content_for :footer do
+ %tr.footer
+ %td.gitlab-info
+ %img.footer-logo{ alt: "GitLab", src: image_url('mailers/gitlab_footer_logo.gif') }
+ %p.gitlab-info-text
+ = html_escape(_("GitLab is a complete DevOps platform, delivered as a single application, fundamentally changing the way%{br_tag}Development, Security, and Ops teams collaborate")) % { br_tag: '<br/>'.html_safe }
+
+= render 'layouts/mailer'
diff --git a/app/views/layouts/unknown_user_mailer.text.erb b/app/views/layouts/unknown_user_mailer.text.erb
new file mode 100644
index 00000000000..f3d8f13b7bf
--- /dev/null
+++ b/app/views/layouts/unknown_user_mailer.text.erb
@@ -0,0 +1,9 @@
+<%= text_header_message %>
+
+<%= yield -%>
+
+-- <%# signature marker %>
+<%= _("GitLab is a complete DevOps platform, delivered as a single application, fundamentally changing the way Development, Security, and Ops teams collaborate") %>
+<%= render_if_exists 'layouts/mailer/additional_text' %>
+
+<%= text_footer_message %>
diff --git a/app/views/layouts/welcome.html.haml b/app/views/layouts/welcome.html.haml
new file mode 100644
index 00000000000..48921e9ff89
--- /dev/null
+++ b/app/views/layouts/welcome.html.haml
@@ -0,0 +1,8 @@
+!!! 5
+%html.subscriptions-layout-html{ lang: 'en' }
+ = render 'layouts/head'
+ %body.ui-indigo.d-flex.vh-100.gl-bg-gray-10
+ = render "layouts/header/logo_with_title"
+ = render "layouts/broadcast"
+ .container.d-flex.flex-grow-1.m-0
+ = yield
diff --git a/app/views/notify/_issuable_csv_export.html.haml b/app/views/notify/_issuable_csv_export.html.haml
index 239b5b14966..5a581811179 100644
--- a/app/views/notify/_issuable_csv_export.html.haml
+++ b/app/views/notify/_issuable_csv_export.html.haml
@@ -1,6 +1,6 @@
%p{ style: 'font-size:18px; text-align:center; line-height:30px;' }
- project_link = link_to(@project.full_name, project_url(@project), style: "color:#3777b0; text-decoration:none; display:block;")
- = _('Your CSV export of %{count} from project %{project_link} has been added to this email as an attachment.').html_safe % { count: pluralize(@written_count, type.to_s), project_link: project_link }
+ = _('Your CSV export of %{count} from project %{project_link} has been added to this email as an attachment.').html_safe % { count: pluralize(@written_count, type.to_s.titleize.downcase), project_link: project_link }
- if @truncated
%p
= _('This attachment has been truncated to avoid exceeding the maximum allowed attachment size of 15MB. %{written_count} of %{count} issues have been included. Consider re-exporting with a narrower selection of issues.') % { written_count: @written_count, count: @count }
diff --git a/app/views/notify/_note_email.html.haml b/app/views/notify/_note_email.html.haml
index c558358725c..2cef6f97d48 100644
--- a/app/views/notify/_note_email.html.haml
+++ b/app/views/notify/_note_email.html.haml
@@ -9,7 +9,7 @@
= succeed ':' do
= link_to note.author_name, user_url(note.author)
- if discussion.nil?
- commented
+ = link_to 'commented', target_url
- else
- if note.start_of_discussion?
started a new
diff --git a/app/views/notify/instance_access_request_email.html.haml b/app/views/notify/instance_access_request_email.html.haml
new file mode 100644
index 00000000000..87bc655164b
--- /dev/null
+++ b/app/views/notify/instance_access_request_email.html.haml
@@ -0,0 +1,10 @@
+#content
+ = email_default_heading(say_hello(@recipient))
+ %p
+ = instance_access_request_text(@user, format: :html)
+ %p
+ = _("Username: %{username}") % { username: @user.username }
+ %p
+ = _("Email: %{email}") % { email: @user.email }
+ %p
+ = instance_access_request_link(@user, format: :html)
diff --git a/app/views/notify/instance_access_request_email.text.erb b/app/views/notify/instance_access_request_email.text.erb
new file mode 100644
index 00000000000..317f962a29c
--- /dev/null
+++ b/app/views/notify/instance_access_request_email.text.erb
@@ -0,0 +1,8 @@
+<%= say_hello(@recipient) %>
+
+<%= instance_access_request_text(@user) %>
+
+<%= _("Username: %{username}") % { username: @user.username } %>
+<%= _("Email: %{email}") % { email: @user.email } %>
+
+<%= instance_access_request_link(@user) %>
diff --git a/app/views/notify/member_invited_email.html.haml b/app/views/notify/member_invited_email.html.haml
index 4fcd2936d25..5ff1e2393c9 100644
--- a/app/views/notify/member_invited_email.html.haml
+++ b/app/views/notify/member_invited_email.html.haml
@@ -1,16 +1,12 @@
+- placeholders = { strong_start: '<strong>'.html_safe, strong_end: '</strong>'.html_safe, project_or_group_name: member_source.human_name, project_or_group: member_source.model_name.singular, br_tag: '<br/>'.html_safe, role: member.human_access.downcase }
%tr
%td.text-content
+ %h2.invite-header
+ = s_('InviteEmail|You are invited!')
%p
- You have been invited
- if member.created_by
- by
- = link_to member.created_by.name, user_url(member.created_by)
- to join the
- = link_to member_source.human_name, member_source.public? ? member_source.web_url : invite_url(@token), class: :highlight
- #{member_source.model_name.singular} as #{content_tag :span, member.human_access, class: :highlight}.
-
- %p
- = link_to 'Accept invitation', invite_url(@token, @invite_url_params)
- or
- = link_to 'decline', decline_invite_url(@token)
-
+ = html_escape(s_("InviteEmail|%{inviter} invited you to join the %{strong_start}%{project_or_group_name}%{strong_end}%{br_tag}%{project_or_group} as a %{role}")) % placeholders.merge({ inviter: (link_to member.created_by.name, user_url(member.created_by)).html_safe })
+ - else
+ = html_escape(s_("InviteEmail|You are invited to join the %{strong_start}%{project_or_group_name}%{strong_end}%{br_tag}%{project_or_group} as a %{role}")) % placeholders
+ %p.invite-actions
+ = link_to s_('InviteEmail|Join now'), invite_url(@token), class: 'invite-btn-join'
diff --git a/app/views/notify/member_invited_email.text.erb b/app/views/notify/member_invited_email.text.erb
index e6e6a685f92..e58dfc10810 100644
--- a/app/views/notify/member_invited_email.text.erb
+++ b/app/views/notify/member_invited_email.text.erb
@@ -1,4 +1,9 @@
-You have been invited <%= "by #{sanitize_name(member.created_by.name)} " if member.created_by %>to join the <%= member_source.human_name %> <%= member_source.model_name.singular %> as <%= member.human_access %>.
+<% placeholders = { project_or_group_name: member_source.human_name, project_or_group: member_source.model_name.singular, role: member.human_access.downcase } %>
-Accept invitation: <%= invite_url(@token, @invite_url_params) %>
-Decline invitation: <%= decline_invite_url(@token) %>
+<% if member.created_by %>
+<%= s_('InviteEmail|%{inviter} invited you to join the %{project_or_group_name} %{project_or_group} as a %{role}') % placeholders.merge({ inviter: sanitize_name(member.created_by.name) }) %>
+<% else %>
+<%= s_('InviteEmail|You have been invited to join the %{project_or_group_name} %{project_or_group} as a %{role}') % placeholders %>
+<% end %>
+
+<%= s_('InviteEmail|Join now') %>: <%= invite_url(@token) %>
diff --git a/app/views/notify/member_invited_email_experiment.html.haml b/app/views/notify/member_invited_email_experiment.html.haml
deleted file mode 100644
index 5cfb6acee05..00000000000
--- a/app/views/notify/member_invited_email_experiment.html.haml
+++ /dev/null
@@ -1,12 +0,0 @@
-%tr
- %td.text-content
- %h2.invite-header
- = s_('InviteEmail|You are invited!')
- %p
- - if member.created_by
- = html_escape(s_("InviteEmail|%{inviter} invited you")) % { inviter: (link_to member.created_by.name, user_url(member.created_by)).html_safe }
- = html_escape(s_("InviteEmail|to join the %{strong_start}%{project_or_group_name}%{strong_end}")) % { strong_start: '<strong>'.html_safe, strong_end: '</strong>'.html_safe, project_or_group_name: member_source.human_name }
- %br
- = s_("InviteEmail|%{project_or_group} as a %{role}") % { project_or_group: member_source.model_name.singular, role: member.human_access.downcase }
- %p.invite-actions
- = link_to s_('InviteEmail|Join now'), invite_url(@token, @invite_url_params), class: 'invite-btn-join'
diff --git a/app/views/notify/member_invited_email_experiment.text.erb b/app/views/notify/member_invited_email_experiment.text.erb
deleted file mode 100644
index 6843cea4df7..00000000000
--- a/app/views/notify/member_invited_email_experiment.text.erb
+++ /dev/null
@@ -1,10 +0,0 @@
-<% project_and_role = s_('InviteEmail|to join the %{project_or_group_name} %{project_or_group} as a %{role}') \
- % { project_or_group_name: member_source.human_name, project_or_group: member_source.model_name.singular, role: member.human_access.downcase } %>
-
-<% if member.created_by %>
-<%= s_('InviteEmail|%{inviter} invited you') % { inviter: sanitize_name(member.created_by.name) } %> <%= project_and_role %>
-<% else %>
-<%= s_('InviteEmail|You have been invited') %> <%= project_and_role %>
-<% end %>
-
-Join now: <%= invite_url(@token, @invite_url_params) %>
diff --git a/app/views/notify/prometheus_alert_fired_email.html.haml b/app/views/notify/prometheus_alert_fired_email.html.haml
index 75ba66b44f9..cdc97d583df 100644
--- a/app/views/notify/prometheus_alert_fired_email.html.haml
+++ b/app/views/notify/prometheus_alert_fired_email.html.haml
@@ -1,5 +1,9 @@
+- body = @alert.resolved? ? _('An alert has been resolved in %{project_path}.') : _('An alert has been triggered in %{project_path}.')
+
+%p
+ = body % { project_path: @alert.project.full_path }
%p
- = _('An alert has been triggered in %{project_path}.') % { project_path: @alert.project.full_path }
+ = link_to(_('View alert details.'), @alert.details_url)
- if description = @alert.description
%p
diff --git a/app/views/notify/prometheus_alert_fired_email.text.erb b/app/views/notify/prometheus_alert_fired_email.text.erb
index 8853f2a317b..b23cd8b6ccc 100644
--- a/app/views/notify/prometheus_alert_fired_email.text.erb
+++ b/app/views/notify/prometheus_alert_fired_email.text.erb
@@ -1,4 +1,7 @@
-<%= _('An alert has been triggered in %{project_path}.') % { project_path: @alert.project.full_path } %>.
+<% body = @alert.resolved? ? _('An alert has been resolved in %{project_path}.') : _('An alert has been triggered in %{project_path}.') %>
+
+<%= body % { project_path: @alert.project.full_path } %>
+<%= _('View alert details at') %> <%= @alert.details_url %>
<% if description = @alert.description %>
<%= _('Description:') %> <%= description %>
diff --git a/app/views/profiles/_event_table.html.haml b/app/views/profiles/_event_table.html.haml
index b952868e4e3..f74902a3c3b 100644
--- a/app/views/profiles/_event_table.html.haml
+++ b/app/views/profiles/_event_table.html.haml
@@ -5,7 +5,7 @@
- events.each do |event|
%li
%span.description
- = audit_icon(event.details[:with], class: "gl-mr-2")
+ = audit_icon(event.details[:with], css_class: 'gl-mr-2')
= _('Signed in with %{authentication} authentication') % { authentication: event.details[:with]}
%span.float-right= time_ago_with_tooltip(event.created_at)
diff --git a/app/views/profiles/preferences/_gitpod.html.haml b/app/views/profiles/preferences/_gitpod.html.haml
deleted file mode 100644
index 589c3a27c18..00000000000
--- a/app/views/profiles/preferences/_gitpod.html.haml
+++ /dev/null
@@ -1,9 +0,0 @@
-%label.label-bold#gitpod
- = s_('Gitpod')
-= link_to sprite_icon('question-o'), help_page_path('integration/gitpod.md'), target: '_blank', class: 'has-tooltip', title: _('More information')
-.form-group.form-check
- = f.check_box :gitpod_enabled, class: 'form-check-input'
- = f.label :gitpod_enabled, class: 'form-check-label' do
- = s_('Gitpod|Enable Gitpod integration').html_safe
- .form-text.text-muted
- = gitpod_enable_description
diff --git a/app/views/profiles/preferences/_integrations.html.haml b/app/views/profiles/preferences/_integrations.html.haml
deleted file mode 100644
index 037fe5df263..00000000000
--- a/app/views/profiles/preferences/_integrations.html.haml
+++ /dev/null
@@ -1,18 +0,0 @@
-- views = integration_views
-- return unless views.any?
-
-.col-sm-12
- %hr
-
-.col-lg-4.profile-settings-sidebar#integrations
- %h4.gl-mt-0
- = s_('Preferences|Integrations')
- %p
- = s_('Preferences|Customize integrations with third party services.')
- = succeed '.' do
- = link_to _('Learn more'), help_page_path('user/profile/preferences.md', anchor: 'integrations'), target: '_blank'
-
-.col-lg-8
- - views.each do |view|
- = render view, f: f
-
diff --git a/app/views/profiles/preferences/_sourcegraph.html.haml b/app/views/profiles/preferences/_sourcegraph.html.haml
deleted file mode 100644
index fdd0be22664..00000000000
--- a/app/views/profiles/preferences/_sourcegraph.html.haml
+++ /dev/null
@@ -1,10 +0,0 @@
-%label.label-bold
- = s_('Preferences|Sourcegraph')
-= link_to sprite_icon('question-o'), help_page_path('user/profile/preferences.md', anchor: 'sourcegraph'), target: '_blank', class: 'has-tooltip', title: _('More information')
-.form-group.form-check
- = f.check_box :sourcegraph_enabled, class: 'form-check-input'
- = f.label :sourcegraph_enabled, class: 'form-check-label' do
- = s_('Preferences|Enable integrated code intelligence on code views').html_safe
- .form-text.text-muted
- = sourcegraph_url_message
- = sourcegraph_experimental_message
diff --git a/app/views/profiles/preferences/show.html.haml b/app/views/profiles/preferences/show.html.haml
index b8d7e1af005..ca5972f1b46 100644
--- a/app/views/profiles/preferences/show.html.haml
+++ b/app/views/profiles/preferences/show.html.haml
@@ -1,146 +1,151 @@
- page_title _('Preferences')
- @content_class = "limit-container-width" unless fluid_layout
+- user_fields = { gitpod_enabled: @user.gitpod_enabled, sourcegraph_enabled: @user.sourcegraph_enabled }
+- user_theme_id = Gitlab::Themes.for_user(@user).id
+- data_attributes = { integration_views: integration_views.to_json, user_fields: user_fields.to_json }
- Gitlab::Themes.each do |theme|
= stylesheet_link_tag "themes/#{theme.css_filename}" if theme.css_filename
-= form_for @user, url: profile_preferences_path, remote: true, method: :put, html: { class: 'row gl-mt-3 js-preferences-form' } do |f|
- .col-lg-4.application-theme#navigation-theme
- %h4.gl-mt-0
- = s_('Preferences|Navigation theme')
- %p
- = s_('Preferences|Customize the appearance of the application header and navigation sidebar.')
- .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.radio_button :theme_id, theme.id, checked: Gitlab::Themes.for_user(@user).id == theme.id
- = theme.name
+= form_for @user, url: profile_preferences_path, remote: true, method: :put do |f|
+ .row.gl-mt-3.js-preferences-form
+ .col-lg-4.application-theme#navigation-theme
+ %h4.gl-mt-0
+ = s_('Preferences|Navigation theme')
+ %p
+ = s_('Preferences|Customize the appearance of the application header and navigation sidebar.')
+ .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.radio_button :theme_id, theme.id, checked: user_theme_id == theme.id
+ = theme.name
- .col-sm-12
- %hr
+ .col-sm-12
+ %hr
- .col-lg-4.profile-settings-sidebar#syntax-highlighting-theme
- %h4.gl-mt-0
- = s_('Preferences|Syntax highlighting theme')
- %p
- = s_('Preferences|This setting allows you to customize the appearance of the syntax.')
- = succeed '.' do
- = link_to _('Learn more'), help_page_path('user/profile/preferences', anchor: 'syntax-highlighting-theme'), target: '_blank'
- .col-lg-8.syntax-theme
- - Gitlab::ColorSchemes.each do |scheme|
- = label_tag do
- .preview= image_tag "#{scheme.css_class}-scheme-preview.png"
- = f.radio_button :color_scheme_id, scheme.id
- = scheme.name
+ .col-lg-4.profile-settings-sidebar#syntax-highlighting-theme
+ %h4.gl-mt-0
+ = s_('Preferences|Syntax highlighting theme')
+ %p
+ = s_('Preferences|This setting allows you to customize the appearance of the syntax.')
+ = succeed '.' do
+ = link_to _('Learn more'), help_page_path('user/profile/preferences', anchor: 'syntax-highlighting-theme'), target: '_blank'
+ .col-lg-8.syntax-theme
+ - Gitlab::ColorSchemes.each do |scheme|
+ = label_tag do
+ .preview= image_tag "#{scheme.css_class}-scheme-preview.png"
+ = f.radio_button :color_scheme_id, scheme.id
+ = scheme.name
- .col-sm-12
- %hr
+ .col-sm-12
+ %hr
- .col-lg-4.profile-settings-sidebar#behavior
- %h4.gl-mt-0
- = s_('Preferences|Behavior')
- %p
- = s_('Preferences|This setting allows you to 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'
- .col-lg-8
- .form-group
- = f.label :layout, class: 'label-bold' do
- = s_('Preferences|Layout width')
- = f.select :layout, layout_choices, {}, class: 'select2'
- .form-text.text-muted
- = s_('Preferences|Choose between fixed (max. 1280px) and fluid (%{percentage}) application layout.').html_safe % { percentage: '100%' }
- .form-group
- = f.label :dashboard, class: 'label-bold' do
- = s_('Preferences|Homepage content')
- = f.select :dashboard, dashboard_choices, {}, class: 'select2'
- .form-text.text-muted
- = s_('Preferences|Choose what content you want to see on your homepage.')
+ .col-lg-4.profile-settings-sidebar#behavior
+ %h4.gl-mt-0
+ = s_('Preferences|Behavior')
+ %p
+ = s_('Preferences|This setting allows you to 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'
+ .col-lg-8
+ .form-group
+ = f.label :layout, class: 'label-bold' do
+ = s_('Preferences|Layout width')
+ = f.select :layout, layout_choices, {}, class: 'select2'
+ .form-text.text-muted
+ = s_('Preferences|Choose between fixed (max. 1280px) and fluid (%{percentage}) application layout.').html_safe % { percentage: '100%' }
+ .form-group
+ = f.label :dashboard, class: 'label-bold' do
+ = s_('Preferences|Homepage content')
+ = f.select :dashboard, dashboard_choices, {}, class: 'select2'
+ .form-text.text-muted
+ = s_('Preferences|Choose what content you want to see on your homepage.')
- = render_if_exists 'profiles/preferences/group_overview_selector', f: f # EE-specific
+ = render_if_exists 'profiles/preferences/group_overview_selector', f: f # EE-specific
- .form-group
- = f.label :project_view, class: 'label-bold' do
- = s_('Preferences|Project overview content')
- = f.select :project_view, project_view_choices, {}, class: 'select2'
- .form-text.text-muted
- = s_('Preferences|Choose what content you want to see on a project’s overview page.')
- .form-group.form-check
- = f.check_box :render_whitespace_in_code, class: 'form-check-input'
- = f.label :render_whitespace_in_code, class: 'form-check-label' do
- = s_('Preferences|Render whitespace characters in the Web IDE')
- .form-group.form-check
- = f.check_box :show_whitespace_in_diffs, class: 'form-check-input'
- = f.label :show_whitespace_in_diffs, class: 'form-check-label' do
- = s_('Preferences|Show whitespace changes in diffs')
- - if Feature.enabled?(:view_diffs_file_by_file, default_enabled: true)
+ .form-group
+ = f.label :project_view, class: 'label-bold' do
+ = s_('Preferences|Project overview content')
+ = f.select :project_view, project_view_choices, {}, class: 'select2'
+ .form-text.text-muted
+ = s_('Preferences|Choose what content you want to see on a project’s overview page.')
+ .form-group.form-check
+ = f.check_box :render_whitespace_in_code, class: 'form-check-input'
+ = f.label :render_whitespace_in_code, class: 'form-check-label' do
+ = s_('Preferences|Render whitespace characters in the Web IDE')
.form-group.form-check
- = f.check_box :view_diffs_file_by_file, class: 'form-check-input'
- = f.label :view_diffs_file_by_file, class: 'form-check-label' do
- = s_("Preferences|Show one file at a time on merge request's Changes tab")
+ = f.check_box :show_whitespace_in_diffs, class: 'form-check-input'
+ = f.label :show_whitespace_in_diffs, class: 'form-check-label' do
+ = s_('Preferences|Show whitespace changes in diffs')
+ - if Feature.enabled?(:view_diffs_file_by_file, default_enabled: true)
+ .form-group.form-check
+ = f.check_box :view_diffs_file_by_file, class: 'form-check-input'
+ = f.label :view_diffs_file_by_file, class: 'form-check-label' do
+ = s_("Preferences|Show one file at a time on merge request's Changes tab")
+ .form-text.text-muted
+ = 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
+ = f.label :tab_width, s_('Preferences|Tab width'), class: 'label-bold'
+ = f.number_field :tab_width,
+ class: 'form-control',
+ min: Gitlab::TabWidth::MIN,
+ max: Gitlab::TabWidth::MAX,
+ required: true
.form-text.text-muted
- = 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
- = f.label :tab_width, s_('Preferences|Tab width'), class: 'label-bold'
- = f.number_field :tab_width,
- class: 'form-control',
- 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
+ = s_('Preferences|Must be a number between %{min} and %{max}') % { min: Gitlab::TabWidth::MIN, max: Gitlab::TabWidth::MAX }
- .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'
- .col-lg-8
- .form-group
- = f.label :preferred_language, class: 'label-bold' do
- = _('Language')
- = f.select :preferred_language, language_choices, {}, class: 'select2'
- .form-text.text-muted
- = s_('Preferences|This feature is experimental and translations are not complete yet')
- .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: 'select2'
- - if Feature.enabled?(:user_time_settings)
.col-sm-12
%hr
- .col-lg-4.profile-settings-sidebar
- %h4.gl-mt-0= s_('Preferences|Time preferences')
- %p= s_('Preferences|These settings will update how dates and times are displayed for you.')
+
+ .col-lg-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'
.col-lg-8
.form-group
- %h5= s_('Preferences|Time format')
- .checkbox-icon-inline-wrapper
- - time_format_label = capture do
- = s_('Preferences|Display time in 24-hour format')
- = f.check_box :time_format_in_24h
- = f.label :time_format_in_24h do
- = time_format_label
- %h5= s_('Preferences|Time display')
- .checkbox-icon-inline-wrapper
- - time_display_label = capture do
- = s_('Preferences|Use relative times')
- = f.check_box :time_display_relative
- = f.label :time_display_relative do
- = time_display_label
- .form-text.text-muted
- = s_('Preferences|For example: 30 mins ago.')
+ = f.label :preferred_language, class: 'label-bold' do
+ = _('Language')
+ = f.select :preferred_language, language_choices, {}, class: 'select2'
+ .form-text.text-muted
+ = s_('Preferences|This feature is experimental and translations are not complete yet')
+ .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: 'select2'
+ - if Feature.enabled?(:user_time_settings)
+ .col-sm-12
+ %hr
+ .col-lg-4.profile-settings-sidebar
+ %h4.gl-mt-0= s_('Preferences|Time preferences')
+ %p= s_('Preferences|These settings will update how dates and times are displayed for you.')
+ .col-lg-8
+ .form-group
+ %h5= s_('Preferences|Time format')
+ .checkbox-icon-inline-wrapper
+ - time_format_label = capture do
+ = s_('Preferences|Display time in 24-hour format')
+ = f.check_box :time_format_in_24h
+ = f.label :time_format_in_24h do
+ = time_format_label
+ %h5= s_('Preferences|Time display')
+ .checkbox-icon-inline-wrapper
+ - time_display_label = capture do
+ = s_('Preferences|Use relative times')
+ = f.check_box :time_display_relative
+ = f.label :time_display_relative do
+ = time_display_label
+ .form-text.text-muted
+ = s_('Preferences|For example: 30 mins ago.')
- = render 'integrations', f: f
+ #js-profile-preferences-app{ data: data_attributes, user_fields: user_fields.to_json }
- .col-lg-4.profile-settings-sidebar
- .col-lg-8
- .form-group
- = f.submit _('Save changes'), class: 'gl-button btn btn-success'
+ .row.gl-mt-3.js-preferences-form
+ .col-lg-4.profile-settings-sidebar
+ .col-lg-8
+ .form-group
+ = f.submit _('Save changes'), class: 'gl-button btn btn-success'
diff --git a/app/views/profiles/show.html.haml b/app/views/profiles/show.html.haml
index f5fab727a57..bf9f1336a4f 100644
--- a/app/views/profiles/show.html.haml
+++ b/app/views/profiles/show.html.haml
@@ -2,6 +2,8 @@
- page_title s_("Profiles|Edit Profile")
- @content_class = "limit-container-width" unless fluid_layout
- gravatar_link = link_to Gitlab.config.gravatar.host, 'https://' + Gitlab.config.gravatar.host
+- availability = availability_values
+- custom_emoji = show_status_emoji?(@user.status)
= bootstrap_form_for @user, url: profile_path, method: :put, html: { multipart: true, class: 'edit-user gl-mt-3 js-quick-submit gl-show-field-errors' }, authenticity_token: true do |f|
= form_errors(@user)
@@ -48,9 +50,9 @@
- emoji_button = button_tag type: :button,
class: 'js-toggle-emoji-menu emoji-menu-toggle-button gl-button btn has-tooltip',
title: s_("Profiles|Add status emoji") do
- - if @user.status
+ - if custom_emoji
= emoji_icon @user.status.emoji
- %span#js-no-emoji-placeholder.no-emoji-placeholder{ class: ('hidden' if @user.status) }
+ %span#js-no-emoji-placeholder.no-emoji-placeholder{ class: ('hidden' if custom_emoji) }
= sprite_icon('slight-smile', css_class: 'award-control-icon-neutral')
= sprite_icon('smiley', css_class: 'award-control-icon-positive')
= sprite_icon('smile', css_class: 'award-control-icon-super-positive')
@@ -68,6 +70,10 @@
prepend: emoji_button,
append: reset_message_button,
placeholder: s_("Profiles|What's your status?")
+ - if Feature.enabled?(:set_user_availability_status, @user)
+ .checkbox-icon-inline-wrapper
+ = status_form.check_box :availability, { data: { testid: "user-availability-checkbox" }, label: s_("Profiles|Busy"), wrapper_class: 'gl-mr-0 gl-font-weight-bold' }, availability["busy"], availability["not_set"]
+ .gl-text-gray-600.gl-ml-5= s_('Profiles|"Busy" will be shown next to your name')
- if Feature.enabled?(:user_time_settings)
%hr
.row.user-time-preferences
diff --git a/app/views/projects/_find_file_link.html.haml b/app/views/projects/_find_file_link.html.haml
index 74cdb0f7409..c3b4a61c28a 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: 'btn shortcuts-find-file', rel: 'nofollow' do
+= link_to project_find_file_path(@project, @ref), class: 'gl-button btn 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 9f4496e7a13..569255ec2e5 100644
--- a/app/views/projects/_home_panel.html.haml
+++ b/app/views/projects/_home_panel.html.haml
@@ -3,21 +3,23 @@
- max_project_topic_length = 15
- emails_disabled = @project.emails_disabled?
+= render_if_exists 'projects/invite_members_modal', project: @project
+
.project-home-panel.js-show-on-project-root.gl-my-5{ class: [("empty-project" if empty_repo)] }
.row.gl-mb-3
.home-panel-title-row.col-md-12.col-lg-6.d-flex
.avatar-container.rect-avatar.s64.home-panel-avatar.gl-flex-shrink-0.gl-w-11.gl-h-11.gl-mr-3.float-none
- = project_icon(@project, alt: @project.name, class: 'avatar avatar-tile s64', width: 64, height: 64)
+ = project_icon(@project, alt: @project.name, class: 'avatar avatar-tile s64', width: 64, height: 64, itemprop: 'image')
.d-flex.flex-column.flex-wrap.align-items-baseline
.d-inline-flex.align-items-baseline
- %h1.home-panel-title.gl-mt-3.gl-mb-2.gl-font-size-h1.gl-line-height-24.gl-font-weight-bold{ data: { qa_selector: 'project_name_content' } }
+ %h1.home-panel-title.gl-mt-3.gl-mb-2.gl-font-size-h1.gl-line-height-24.gl-font-weight-bold{ data: { qa_selector: 'project_name_content' }, itemprop: 'name' }
= @project.name
%span.visibility-icon.text-secondary.gl-ml-2.has-tooltip{ data: { container: 'body' }, title: visibility_icon_description(@project) }
= visibility_level_icon(@project.visibility_level, options: { class: 'icon' })
= render_if_exists 'compliance_management/compliance_framework/compliance_framework_badge', project: @project
.home-panel-metadata.d-flex.flex-wrap.text-secondary.gl-font-base.gl-font-weight-normal.gl-line-height-normal
- if can?(current_user, :read_project, @project)
- %span.text-secondary
+ %span.text-secondary{ itemprop: 'identifier' }
= s_('ProjectPage|Project ID: %{project_id}') % { project_id: @project.id }
- if current_user
%span.access-request-links.gl-ml-3
@@ -30,10 +32,10 @@
- project_topics_classes = "badge badge-pill badge-secondary gl-mr-2"
- explore_project_topic_path = explore_projects_path(tag: topic)
- if topic.length > max_project_topic_length
- %a{ class: "#{ project_topics_classes } str-truncated-30 has-tooltip", data: { container: "body" }, title: topic, href: explore_project_topic_path }
+ %a{ class: "#{ project_topics_classes } str-truncated-30 has-tooltip", data: { container: "body" }, title: topic, href: explore_project_topic_path, itemprop: 'keywords' }
= topic.titleize
- else
- %a{ class: project_topics_classes, href: explore_project_topic_path }
+ %a{ class: project_topics_classes, href: explore_project_topic_path, itemprop: 'keywords' }
= topic.titleize
- if @project.has_extra_topics?
@@ -44,7 +46,7 @@
.project-repo-buttons.col-md-12.col-lg-6.d-inline-flex.flex-wrap.justify-content-lg-end
- if current_user
.d-inline-flex
- = render 'shared/notifications/new_button', notification_setting: @notification_setting, btn_class: 'btn-xs', emails_disabled: emails_disabled
+ = render 'shared/notifications/new_button', notification_setting: @notification_setting, btn_class: 'btn-xs', dropdown_container_class: 'gl-mr-3', emails_disabled: emails_disabled
.count-buttons.d-inline-flex
= render 'projects/buttons/star'
@@ -61,7 +63,7 @@
.home-panel-home-desc.mt-1
- if @project.description.present?
.home-panel-description.text-break
- .home-panel-description-markdown.read-more-container
+ .home-panel-description-markdown.read-more-container{ itemprop: 'abstract' }
= markdown_field(@project, :description)
%button.btn.btn-blank.btn-link.js-read-more-trigger.d-lg-none{ type: "button" }
= _("Read more")
diff --git a/app/views/projects/_invite_members_modal.html.haml b/app/views/projects/_invite_members_modal.html.haml
new file mode 100644
index 00000000000..ad95f39bbfa
--- /dev/null
+++ b/app/views/projects/_invite_members_modal.html.haml
@@ -0,0 +1,7 @@
+- if invite_members_allowed?(project.group)
+ .js-invite-members-modal{ data: { id: project.id,
+ name: project.name,
+ is_project: true,
+ access_levels: GroupMember.access_level_roles.to_json,
+ default_access_level: Gitlab::Access::GUEST,
+ help_link: help_page_url('user/permissions') } }
diff --git a/app/views/projects/_invite_members_side_nav_link.html.haml b/app/views/projects/_invite_members_side_nav_link.html.haml
new file mode 100644
index 00000000000..15e0b75cf57
--- /dev/null
+++ b/app/views/projects/_invite_members_side_nav_link.html.haml
@@ -0,0 +1,3 @@
+- if invite_members_allowed?(project.group) && body_data_page == 'projects:show'
+ %li
+ .js-invite-members-trigger{ data: { icon: 'plus', display_text: _('Invite team members') } }
diff --git a/app/views/projects/_merge_request_merge_options_settings.html.haml b/app/views/projects/_merge_request_merge_options_settings.html.haml
index 047b4dafbfc..8951f2ed22f 100644
--- a/app/views/projects/_merge_request_merge_options_settings.html.haml
+++ b/app/views/projects/_merge_request_merge_options_settings.html.haml
@@ -4,6 +4,7 @@
%b= s_('ProjectSettings|Merge options')
%p.text-secondary= s_('ProjectSettings|Additional merge request capabilities that influence how and when merges will be performed')
= render_if_exists 'projects/merge_pipelines_settings', form: form
+ = render_if_exists 'projects/merge_trains_settings', form: form
.form-check.mb-2
= form.check_box :resolve_outdated_diff_discussions, class: 'form-check-input'
= form.label :resolve_outdated_diff_discussions, class: 'form-check-label' do
diff --git a/app/views/projects/_remove.html.haml b/app/views/projects/_remove.html.haml
index 05eab3b3245..c246c45d0f7 100644
--- a/app/views/projects/_remove.html.haml
+++ b/app/views/projects/_remove.html.haml
@@ -1,5 +1,4 @@
- return unless can?(current_user, :remove_project, project)
-- confirm_phrase = s_('DeleteProject|Delete %{name}') % { name: project.full_name }
.sub-section
%h4.danger-title= _('Delete project')
@@ -7,4 +6,4 @@
%strong= _('Deleting the project will delete its repository and all related resources including issues, merge requests etc.')
%p
%strong= _('Deleted projects cannot be restored!')
- #js-project-delete-button{ data: { form_path: project_path(project), confirm_phrase: confirm_phrase } }
+ #js-project-delete-button{ data: { form_path: project_path(project), confirm_phrase: project.path } }
diff --git a/app/views/projects/_remove_fork.html.haml b/app/views/projects/_remove_fork.html.haml
new file mode 100644
index 00000000000..2a7453902a8
--- /dev/null
+++ b/app/views/projects/_remove_fork.html.haml
@@ -0,0 +1,10 @@
+- return unless @project.forked? && can?(current_user, :remove_fork_project, @project)
+
+.sub-section
+ %h4.danger-title= _('Remove fork relationship')
+ %p= remove_fork_project_description_message(@project)
+
+ = form_for @project, url: remove_fork_project_path(@project), method: :delete, remote: true, html: { class: 'transfer-project' } do |f|
+ %p
+ %strong= _('Once removed, the fork relationship cannot be restored. This project will no longer be able to receive or send merge requests to the source project or other forks.')
+ = button_to _('Remove fork relationship'), '#', class: "gl-button btn btn-danger js-confirm-danger", data: { "confirm-danger-message" => remove_fork_project_warning_message(@project) }
diff --git a/app/views/projects/_service_desk_settings.html.haml b/app/views/projects/_service_desk_settings.html.haml
index fceef0624d7..7c08955983a 100644
--- a/app/views/projects/_service_desk_settings.html.haml
+++ b/app/views/projects/_service_desk_settings.html.haml
@@ -10,7 +10,7 @@
- if ::Gitlab::ServiceDesk.supported?
.js-service-desk-setting-root{ data: { endpoint: project_service_desk_path(@project),
enabled: "#{@project.service_desk_enabled}",
- incoming_email: (@project.service_desk_address if @project.service_desk_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),
selected_template: "#{@project.service_desk_setting&.issue_template_key}",
outgoing_name: "#{@project.service_desk_setting&.outgoing_name}",
diff --git a/app/views/projects/_stat_anchor_list.html.haml b/app/views/projects/_stat_anchor_list.html.haml
index 516790fb6d9..8a93d93a538 100644
--- a/app/views/projects/_stat_anchor_list.html.haml
+++ b/app/views/projects/_stat_anchor_list.html.haml
@@ -5,5 +5,5 @@
%ul.nav
- anchors.each do |anchor|
%li.nav-item
- = link_to_if anchor.link, anchor.label, anchor.link, class: anchor.is_link ? 'nav-link stat-link d-flex align-items-center' : "nav-link btn btn-#{anchor.class_modifier || 'missing'} d-flex align-items-center" do
+ = link_to_if(anchor.link, anchor.label, anchor.link, stat_anchor_attrs(anchor)) do
.stat-text.d-flex.align-items-center{ class: ('btn btn-default disabled' if project_buttons) }= anchor.label
diff --git a/app/views/projects/_transfer.html.haml b/app/views/projects/_transfer.html.haml
new file mode 100644
index 00000000000..eb7feb7bd3b
--- /dev/null
+++ b/app/views/projects/_transfer.html.haml
@@ -0,0 +1,16 @@
+- return unless can?(current_user, :change_namespace, @project)
+
+.sub-section
+ %h4.danger-title= _('Transfer project')
+ = form_for @project, url: transfer_project_path(@project), method: :put, remote: true, html: { class: 'js-project-transfer-form' } do |f|
+ .form-group
+ = label_tag :new_namespace_id, nil, class: 'label-bold' do
+ %span= _('Select a new namespace')
+ .form-group
+ = select_tag :new_namespace_id, namespaces_options(nil), include_blank: true, class: 'select2'
+ %ul
+ %li= _("Be careful. Changing the project's namespace can have unintended side effects.")
+ %li= _('You can only transfer the project to namespaces you manage.')
+ %li= _('You will need to update your local repositories to point to the new location.')
+ %li= _('Project visibility level will be changed to match namespace rules when transferring to a group.')
+ = f.submit 'Transfer project', class: "gl-button btn btn-danger js-confirm-danger qa-transfer-button", data: { "confirm-danger-message" => transfer_project_message(@project) }
diff --git a/app/views/projects/alert_management/details.html.haml b/app/views/projects/alert_management/details.html.haml
index 5230d5e3476..b1d680e4f3d 100644
--- a/app/views/projects/alert_management/details.html.haml
+++ b/app/views/projects/alert_management/details.html.haml
@@ -1,4 +1,5 @@
- add_to_breadcrumbs s_('AlertManagement|Alerts'), project_alert_management_index_path(@project)
- page_title s_('AlertManagement|Alert detail')
+- add_page_specific_style 'page_bundles/alert_management_details'
#js-alert_details{ data: alert_management_detail_data(@project, @alert_id) }
diff --git a/app/views/projects/artifacts/_artifact.html.haml b/app/views/projects/artifacts/_artifact.html.haml
index 30f30fe922f..233a41a37b5 100644
--- a/app/views/projects/artifacts/_artifact.html.haml
+++ b/app/views/projects/artifacts/_artifact.html.haml
@@ -50,10 +50,10 @@
.table-action-buttons
.btn-group
- if can?(current_user, :read_build, @project)
- = link_to download_project_job_artifacts_path(@project, artifact.job), rel: 'nofollow', download: '', title: _('Download artifacts'), data: { placement: 'top', container: 'body' }, ref: 'tooltip', aria: { label: _('Download artifacts') }, class: 'btn btn-build has-tooltip ml-0' do
+ = link_to download_project_job_artifacts_path(@project, artifact.job), rel: 'nofollow', download: '', title: _('Download artifacts'), data: { placement: 'top', container: 'body' }, ref: 'tooltip', aria: { label: _('Download artifacts') }, class: 'gl-button btn btn-build has-tooltip ml-0' do
= sprite_icon('download')
- = link_to browse_project_job_artifacts_path(@project, artifact.job), rel: 'nofollow', title: _('Browse artifacts'), data: { placement: 'top', container: 'body' }, ref: 'tooltip', aria: { label: _('Browse artifacts') }, class: 'btn btn-build has-tooltip' do
+ = link_to browse_project_job_artifacts_path(@project, artifact.job), rel: 'nofollow', title: _('Browse artifacts'), data: { placement: 'top', container: 'body' }, ref: 'tooltip', aria: { label: _('Browse artifacts') }, class: 'gl-button btn btn-build has-tooltip' do
= sprite_icon('folder-open')
- if can?(current_user, :destroy_artifacts, @project)
diff --git a/app/views/projects/artifacts/_tree_file.html.haml b/app/views/projects/artifacts/_tree_file.html.haml
index f42d5128715..03d35c1c989 100644
--- a/app/views/projects/artifacts/_tree_file.html.haml
+++ b/app/views/projects/artifacts/_tree_file.html.haml
@@ -9,7 +9,7 @@
= link_to path_to_file, class: 'tree-item-file-external-link js-artifact-tree-tooltip str-truncated',
target: '_blank', rel: 'noopener noreferrer', title: _('Opens in a new window') do
%span>= blob.name
- = icon('external-link', class: 'js-artifact-tree-external-icon')
+ = sprite_icon('external-link', css_class: 'js-artifact-tree-external-icon')
- else
= link_to path_to_file, class: 'str-truncated' do
%span= blob.name
diff --git a/app/views/projects/artifacts/browse.html.haml b/app/views/projects/artifacts/browse.html.haml
index ff56cb53720..b363f0d4325 100644
--- a/app/views/projects/artifacts/browse.html.haml
+++ b/app/views/projects/artifacts/browse.html.haml
@@ -17,7 +17,7 @@
.tree-controls<
= link_to download_project_job_artifacts_path(@project, @build),
- rel: 'nofollow', download: '', class: 'btn btn-default download' do
+ rel: 'nofollow', download: '', class: 'gl-button btn btn-default download' do
= sprite_icon('download')
Download artifacts archive
diff --git a/app/views/projects/blob/_breadcrumb.html.haml b/app/views/projects/blob/_breadcrumb.html.haml
index 810c8b9082f..710417f90e3 100644
--- a/app/views/projects/blob/_breadcrumb.html.haml
+++ b/app/views/projects/blob/_breadcrumb.html.haml
@@ -23,13 +23,13 @@
- if blob.readable_text?
- if blame
= link_to 'Normal view', project_blob_path(@project, @id),
- class: 'btn'
+ class: 'gl-button btn'
- else
= link_to 'Blame', project_blame_path(@project, @id),
- class: 'btn js-blob-blame-link' unless blob.empty?
+ class: 'gl-button btn js-blob-blame-link' unless blob.empty?
= link_to 'History', project_commits_path(@project, @id),
- class: 'btn'
+ class: 'gl-button btn'
= link_to 'Permalink', project_blob_path(@project,
- tree_join(@commit.sha, @path)), class: 'btn js-data-file-blob-permalink-url'
+ tree_join(@commit.sha, @path)), class: 'gl-button btn js-data-file-blob-permalink-url'
diff --git a/app/views/projects/blob/_header.html.haml b/app/views/projects/blob/_header.html.haml
index 55ae9cded1c..6d01206a128 100644
--- a/app/views/projects/blob/_header.html.haml
+++ b/app/views/projects/blob/_header.html.haml
@@ -2,9 +2,9 @@
.js-file-title.file-title-flex-parent
= render 'projects/blob/header_content', blob: blob
- .file-actions<
+ .file-actions.gl-display-flex.gl-flex-fill-1.gl-align-self-start.gl-md-justify-content-end<
= render 'projects/blob/viewer_switcher', blob: blob unless blame
- - if Feature.enabled?(:consolidated_edit_button)
+ - if Feature.enabled?(:consolidated_edit_button, @project)
= render 'shared/web_ide_button', blob: blob
- else
= edit_blob_button(@project, @ref, @path, blob: blob)
diff --git a/app/views/projects/blob/_header_content.html.haml b/app/views/projects/blob/_header_content.html.haml
index 30356348941..b310939c5a3 100644
--- a/app/views/projects/blob/_header_content.html.haml
+++ b/app/views/projects/blob/_header_content.html.haml
@@ -1,7 +1,7 @@
.file-header-content
= blob_icon blob.mode, blob.name
- %strong.file-title-name
+ %strong.file-title-name.gl-word-break-all{ data: { qa_selector: 'file_name_content' } }
= blob.name
= copy_file_path_button(blob.path)
diff --git a/app/views/projects/blob/_pipeline_tour_success.html.haml b/app/views/projects/blob/_pipeline_tour_success.html.haml
index 3ea2defb2b3..ef1fe25ba1b 100644
--- a/app/views/projects/blob/_pipeline_tour_success.html.haml
+++ b/app/views/projects/blob/_pipeline_tour_success.html.haml
@@ -1,4 +1,6 @@
.js-success-pipeline-modal{ data: { 'commit-cookie': suggest_pipeline_commit_cookie_name,
'go-to-pipelines-path': project_pipelines_path(@project),
'project-merge-requests-path': project_merge_requests_path(@project),
+ 'example-link': help_page_path('ci/examples/README.md', anchor: 'gitlab-cicd-examples'),
+ 'code-quality-link': help_page_path('user/project/merge_requests/code_quality'),
'human-access': @project.team.human_max_access(current_user&.id) } }
diff --git a/app/views/projects/blob/_upload.html.haml b/app/views/projects/blob/_upload.html.haml
index 4dbfa2b1e3c..f400c7de5eb 100644
--- a/app/views/projects/blob/_upload.html.haml
+++ b/app/views/projects/blob/_upload.html.haml
@@ -21,7 +21,7 @@
.form-actions
= button_tag class: 'btn gl-button btn-success btn-upload-file', id: 'submit-all', type: 'button' do
- = icon('spin spinner', class: 'js-loading-icon hidden' )
+ .spinner.spinner-sm.gl-mr-2.js-loading-icon.hidden
= button_title
= link_to _("Cancel"), '#', class: "btn gl-button btn-cancel", "data-dismiss" => "modal"
diff --git a/app/views/projects/blob/viewers/_gitlab_ci_yml.html.haml b/app/views/projects/blob/viewers/_gitlab_ci_yml.html.haml
index 61d67a88a5a..3326cded42a 100644
--- a/app/views/projects/blob/viewers/_gitlab_ci_yml.html.haml
+++ b/app/views/projects/blob/viewers/_gitlab_ci_yml.html.haml
@@ -1,8 +1,8 @@
- if viewer.valid?(project: @project, sha: @commit.sha, user: @current_user)
- = icon('check fw')
+ = sprite_icon('check')
This GitLab CI configuration is valid.
- else
- = icon('warning fw')
+ = sprite_icon('warning-solid')
This GitLab CI configuration is invalid:
= viewer.validation_message(project: @project, sha: @commit.sha, user: @current_user)
diff --git a/app/views/projects/blob/viewers/_metrics_dashboard_yml.html.haml b/app/views/projects/blob/viewers/_metrics_dashboard_yml.html.haml
index de9c6c5320f..9c3f9b6c9fd 100644
--- a/app/views/projects/blob/viewers/_metrics_dashboard_yml.html.haml
+++ b/app/views/projects/blob/viewers/_metrics_dashboard_yml.html.haml
@@ -1,8 +1,8 @@
- if viewer.valid?
- = icon('check fw')
+ = sprite_icon('check')
= _('Metrics Dashboard YAML definition is valid.')
- else
- = icon('warning fw')
+ = sprite_icon('warning-solid')
= _('Metrics Dashboard YAML definition is invalid:')
%ul
- viewer.errors.each do |error|
diff --git a/app/views/projects/blob/viewers/_route_map.html.haml b/app/views/projects/blob/viewers/_route_map.html.haml
index 024e9b4ddb2..068cf400cd5 100644
--- a/app/views/projects/blob/viewers/_route_map.html.haml
+++ b/app/views/projects/blob/viewers/_route_map.html.haml
@@ -1,8 +1,8 @@
- if viewer.valid?
- = icon('check fw')
+ = sprite_icon('check')
This Route Map is valid.
- else
- = icon('warning fw')
+ = sprite_icon('warning-solid')
This Route Map is invalid:
= viewer.validation_message
diff --git a/app/views/projects/branches/_branch.html.haml b/app/views/projects/branches/_branch.html.haml
index 30e710ead7f..8f5fac1a40b 100644
--- a/app/views/projects/branches/_branch.html.haml
+++ b/app/views/projects/branches/_branch.html.haml
@@ -36,12 +36,12 @@
%svg.s24
- if merge_project && create_mr_button?(@repository.root_ref, branch.name)
- = link_to create_mr_path(@repository.root_ref, branch.name), class: 'btn btn-default' do
+ = link_to create_mr_path(@repository.root_ref, branch.name), class: 'gl-button btn btn-default' do
= _('Merge request')
- if branch.name != @repository.root_ref
= link_to project_compare_index_path(@project, from: @repository.root_ref, to: branch.name),
- class: "btn btn-default js-onboarding-compare-branches #{'gl-ml-3' unless merge_project}",
+ class: "gl-button btn btn-default js-onboarding-compare-branches #{'gl-ml-3' unless merge_project}",
method: :post,
title: s_('Branches|Compare') do
= s_('Branches|Compare')
diff --git a/app/views/projects/branches/_delete_protected_modal.html.haml b/app/views/projects/branches/_delete_protected_modal.html.haml
index 8aa79d2d464..24beeeb0ae1 100644
--- a/app/views/projects/branches/_delete_protected_modal.html.haml
+++ b/app/views/projects/branches/_delete_protected_modal.html.haml
@@ -36,7 +36,7 @@
.modal-footer
%button.btn{ data: { dismiss: 'modal' } } Cancel
= link_to s_('Branches|Delete protected branch'), '',
- class: "btn btn-danger js-delete-branch",
+ class: "gl-button btn btn-danger js-delete-branch",
title: s_('Branches|Delete branch'),
method: :delete,
'aria-label' => s_('Branches|Delete branch')
diff --git a/app/views/projects/branches/index.html.haml b/app/views/projects/branches/index.html.haml
index f3561ed5078..46cce59f67a 100644
--- a/app/views/projects/branches/index.html.haml
+++ b/app/views/projects/branches/index.html.haml
@@ -24,7 +24,7 @@
%button.dropdown-menu-toggle{ type: 'button', 'data-toggle' => 'dropdown' }
%span.light
= branches_sort_options_hash[@sort]
- = icon('chevron-down')
+ = sprite_icon('chevron-down', css_class: "dropdown-menu-toggle-icon gl-top-3")
%ul.dropdown-menu.dropdown-menu-right.dropdown-menu-selectable
%li.dropdown-header
= s_('Branches|Sort by')
@@ -40,7 +40,7 @@
data: { confirm: s_('Branches|Deleting the merged branches cannot be undone. Are you sure?'),
container: 'body' } do
= s_('Branches|Delete merged branches')
- = link_to new_project_branch_path(@project), class: 'btn btn-success' do
+ = link_to new_project_branch_path(@project), class: 'gl-button btn btn-success' do
= s_('Branches|New branch')
= render_if_exists 'projects/commits/mirror_status'
diff --git a/app/views/projects/branches/new.html.haml b/app/views/projects/branches/new.html.haml
index 7a8bc45a272..24dfb59dc85 100644
--- a/app/views/projects/branches/new.html.haml
+++ b/app/views/projects/branches/new.html.haml
@@ -22,10 +22,10 @@
= hidden_field_tag :ref, default_ref
= button_tag type: 'button', title: default_ref, class: 'dropdown-menu-toggle wide js-branch-select monospace', required: true, data: { toggle: 'dropdown', selected: default_ref, field_name: 'ref' } do
.text-left.dropdown-toggle-text= default_ref
- = icon('chevron-down')
+ = sprite_icon('chevron-down', css_class: "dropdown-menu-toggle-icon gl-top-3")
= render 'shared/ref_dropdown', dropdown_class: 'wide'
.form-text.text-muted Existing branch name, tag, or commit SHA
.form-actions
- = button_tag 'Create branch', class: 'btn btn-success', tabindex: 3
- = link_to 'Cancel', project_branches_path(@project), class: 'btn btn-cancel'
+ = button_tag 'Create branch', class: 'gl-button btn btn-success'
+ = link_to 'Cancel', project_branches_path(@project), class: 'gl-button btn btn-cancel'
%script#availableRefs{ type: "application/json" }= @project.repository.ref_names.to_json.html_safe
diff --git a/app/views/projects/buttons/_clone.html.haml b/app/views/projects/buttons/_clone.html.haml
index 7ce143a86b3..cf58cff7445 100644
--- a/app/views/projects/buttons/_clone.html.haml
+++ b/app/views/projects/buttons/_clone.html.haml
@@ -2,7 +2,7 @@
- dropdown_class = local_assigns.fetch(:dropdown_class, '')
.git-clone-holder.js-git-clone-holder
- %a#clone-dropdown.btn.btn-primary.clone-dropdown-btn.qa-clone-dropdown{ href: '#', data: { toggle: 'dropdown' } }
+ %a#clone-dropdown.gl-button.btn.btn-primary.clone-dropdown-btn.qa-clone-dropdown{ href: '#', data: { toggle: 'dropdown' } }
%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 c04687bd846..0fcbf2ca1eb 100644
--- a/app/views/projects/buttons/_download.html.haml
+++ b/app/views/projects/buttons/_download.html.haml
@@ -3,7 +3,7 @@
- if !project.empty_repo? && can?(current_user, :download_code, project)
- archive_prefix = "#{project.path}-#{ref.tr('/', '-')}"
.project-action-button.dropdown.inline>
- %button.btn.has-tooltip{ title: s_('DownloadSource|Download'), 'data-toggle' => 'dropdown', 'aria-label' => s_('DownloadSource|Download'), 'data-display' => 'static', data: { qa_selector: 'download_source_code_button' } }
+ %button.gl-button.btn.has-tooltip{ title: s_('DownloadSource|Download'), 'data-toggle' => 'dropdown', 'aria-label' => s_('DownloadSource|Download'), 'data-display' => 'static', data: { qa_selector: 'download_source_code_button' } }
= sprite_icon('download')
%span.sr-only= _('Select Archive Format')
= sprite_icon("chevron-down")
diff --git a/app/views/projects/buttons/_download_links.html.haml b/app/views/projects/buttons/_download_links.html.haml
index 990f3ff526b..c997df578c0 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: "btn btn-xs #{"btn-primary" if index == 0}"
+ = link_to fmt, external_storage_url_or_path(archive_path), rel: 'nofollow', download: '', class: "gl-button btn btn-xs #{"btn-primary" if index == 0}"
diff --git a/app/views/projects/buttons/_xcode_link.html.haml b/app/views/projects/buttons/_xcode_link.html.haml
index a8b32fb0ef5..e0f47f1ca3d 100644
--- a/app/views/projects/buttons/_xcode_link.html.haml
+++ b/app/views/projects/buttons/_xcode_link.html.haml
@@ -1,2 +1,2 @@
-%a.btn.btn-default{ href: xcode_uri_to_repo(@project) }
+%a.gl-button.btn.btn-default{ href: xcode_uri_to_repo(@project) }
= _("Open in Xcode")
diff --git a/app/views/projects/ci/lints/_create.html.haml b/app/views/projects/ci/lints/_create.html.haml
deleted file mode 100644
index 4b7cda0ef57..00000000000
--- a/app/views/projects/ci/lints/_create.html.haml
+++ /dev/null
@@ -1,51 +0,0 @@
-- if @result.valid?
- .bs-callout.bs-callout-success
- %p
- %b= _("Status:")
- = _("syntax is correct")
-
- = render "projects/ci/lints/lint_warnings", warnings: @result.warnings
-
- .table-holder
- %table.table.table-bordered
- %thead
- %tr
- %th= _("Parameter")
- %th= _("Value")
- %tbody
- - @result.jobs.each do |job|
- %tr
- %td #{job[:stage].capitalize} Job - #{job[:name]}
- %td
- %pre= job[:before_script].to_a.join('\n')
- %pre= job[:script].to_a.join('\n')
- %pre= job[:after_script].to_a.join('\n')
- %br
- %b= _("Tag list:")
- = job[:tag_list].to_a.join(", ")
- - unless @dry_run
- %br
- %b= _("Only policy:")
- = job[:only].to_a.join(", ")
- %br
- %b= _("Except policy:")
- = job[:except].to_a.join(", ")
- %br
- %b= _("Environment:")
- = job[:environment]
- %br
- %b= _("When:")
- = job[:when]
- - if job[:allow_failure]
- %b= _("Allowed to fail")
-
-- else
- .bs-callout.bs-callout-danger
- %p
- %b= _("Status:")
- = _("syntax is incorrect")
- %pre
- - @result.errors.each do |message|
- %p= message
-
- = render "projects/ci/lints/lint_warnings", warnings: @result.warnings
diff --git a/app/views/projects/ci/lints/_lint_warnings.html.haml b/app/views/projects/ci/lints/_lint_warnings.html.haml
deleted file mode 100644
index 90db65e6c27..00000000000
--- a/app/views/projects/ci/lints/_lint_warnings.html.haml
+++ /dev/null
@@ -1,10 +0,0 @@
-- if warnings
- - total_warnings = warnings.length
- - message = warning_header(total_warnings)
-
- - if warnings.any?
- .bs-callout.bs-callout-warning
- %details
- %summary.gl-mb-2= message
- - warnings.each do |warning|
- = markdown(warning)
diff --git a/app/views/projects/ci/lints/show.html.haml b/app/views/projects/ci/lints/show.html.haml
index 64f250bd607..feccea6cfc0 100644
--- a/app/views/projects/ci/lints/show.html.haml
+++ b/app/views/projects/ci/lints/show.html.haml
@@ -3,32 +3,4 @@
%h2.pt-3.pb-3= _("Validate your GitLab CI configuration")
-- if Feature.enabled?(:ci_lint_vue, @project)
- #js-ci-lint{ data: { endpoint: project_ci_lint_path(@project), help_page_path: help_page_path('ci/lint', anchor: 'pipeline-simulation') } }
-
-- else
- .project-ci-linter
- = form_tag project_ci_lint_path(@project), method: :post, class: 'js-ci-lint-form' do
- .row
- .col-sm-12
- .file-holder
- .js-file-title.file-title.clearfix
- = _("Contents of .gitlab-ci.yml")
- .file-editor.code
- .js-edit-mode-pane.qa-editor#editor{ data: { 'editor-loading': true } }<
- %pre.editor-loading-content= params[:content]
- = text_area_tag(:content, @content, class: 'hidden form-control span1', rows: 7, require: true)
- .col-sm-12
- .float-left.gl-mt-3
- = submit_tag(_('Validate'), class: 'btn btn-success submit-yml')
- - if Gitlab::Ci::Features.lint_creates_pipeline_with_dry_run?(@project)
- = check_box_tag(:dry_run, 'true', params[:dry_run])
- = label_tag(:dry_run, _('Simulate a pipeline created for the default branch'))
- = link_to sprite_icon('question-o'), help_page_path('ci/lint', anchor: 'pipeline-simulation'), target: '_blank', rel: 'noopener noreferrer'
- .float-right.prepend-top-10
- = button_tag(_('Clear'), type: 'button', class: 'btn btn-default clear-yml')
-
- .row.prepend-top-20
- .col-sm-12
- .results.project-ci-template
- = render partial: 'create' if defined?(@result)
+#js-ci-lint{ data: { endpoint: project_ci_lint_path(@project), pipeline_simulation_help_page_path: help_page_path('ci/lint', anchor: 'pipeline-simulation') , lint_help_page_path: help_page_path('ci/lint', anchor: 'validate-basic-logic-and-syntax') } }
diff --git a/app/views/projects/ci/pipeline_editor/show.html.haml b/app/views/projects/ci/pipeline_editor/show.html.haml
new file mode 100644
index 00000000000..0e032f2575e
--- /dev/null
+++ b/app/views/projects/ci/pipeline_editor/show.html.haml
@@ -0,0 +1,6 @@
+- page_title s_('Pipelines|Pipeline Editor')
+
+#js-pipeline-editor{ data: { "ci-config-path": @project.ci_config_path_or_default,
+ "project-path" => @project.full_path,
+ "default-branch" => @project.default_branch,
+} }
diff --git a/app/views/projects/cleanup/_show.html.haml b/app/views/projects/cleanup/_show.html.haml
index 02d35e690ca..37ec63cc871 100644
--- a/app/views/projects/cleanup/_show.html.haml
+++ b/app/views/projects/cleanup/_show.html.haml
@@ -26,4 +26,4 @@
.form-text.text-muted
= _("The maximum file size allowed is %{size}.") % { size: number_to_human_size(Gitlab::CurrentSettings.max_attachment_size.megabytes) }
- = f.submit _('Start cleanup'), class: 'btn btn-success'
+ = f.submit _('Start cleanup'), class: 'gl-button btn btn-success'
diff --git a/app/views/projects/commit/_change.html.haml b/app/views/projects/commit/_change.html.haml
index 4f5d69c614c..11adc7fd64a 100644
--- a/app/views/projects/commit/_change.html.haml
+++ b/app/views/projects/commit/_change.html.haml
@@ -33,7 +33,7 @@
- else
= hidden_field_tag 'create_merge_request', 1, id: nil
.form-actions
- = submit_tag label, class: 'btn btn-success'
- = link_to _("Cancel"), '#', class: "btn btn-cancel", "data-dismiss" => "modal"
+ = submit_tag label, class: 'gl-button btn btn-success'
+ = link_to _("Cancel"), '#', class: "gl-button btn btn-cancel", "data-dismiss" => "modal"
= render 'shared/projects/edit_information'
diff --git a/app/views/projects/commit/diff_files.html.haml b/app/views/projects/commit/diff_files.html.haml
index 3a473be3840..0c52c1a15a4 100644
--- a/app/views/projects/commit/diff_files.html.haml
+++ b/app/views/projects/commit/diff_files.html.haml
@@ -1,3 +1 @@
-- diff_files = diffs.diff_files
-
-= render partial: 'projects/diffs/file', collection: diff_files, as: :diff_file, locals: { project: diffs.project, environment: environment, diff_page_context: 'is-commit' }
+= render partial: 'projects/diffs/file', collection: diffs.diff_files, as: :diff_file, locals: { project: diffs.project, environment: environment, diff_page_context: 'is-commit' }
diff --git a/app/views/projects/commits/_commit.html.haml b/app/views/projects/commits/_commit.html.haml
index cd61576a96a..179b0c5efbd 100644
--- a/app/views/projects/commits/_commit.html.haml
+++ b/app/views/projects/commits/_commit.html.haml
@@ -23,7 +23,7 @@
= author_avatar(commit, size: 40, has_tooltip: false)
.commit-detail.flex-list
- .commit-content.qa-commit-content
+ .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?)]
- else
@@ -57,8 +57,8 @@
.js-commit-pipeline-status{ data: { endpoint: pipelines_project_commit_path(project, commit.id, ref: ref) } }
- .commit-sha-group.d-none.d-sm-flex
+ .commit-sha-group.btn-group.d-none.d-sm-flex
.label.label-monospace.monospace
= commit.short_id
- = clipboard_button(text: commit.id, title: _("Copy commit SHA"), class: "btn btn-default", container: "body")
+ = clipboard_button(text: commit.id, title: _("Copy commit SHA"), class: "gl-button btn btn-default", container: "body")
= link_to_browse_code(project, commit)
diff --git a/app/views/projects/commits/show.html.haml b/app/views/projects/commits/show.html.haml
index 40dd3a685d4..94bdab53cd0 100644
--- a/app/views/projects/commits/show.html.haml
+++ b/app/views/projects/commits/show.html.haml
@@ -34,4 +34,5 @@
%div{ id: dom_id(@project) }
%ol#commits-list.list-unstyled.content_list
= render 'commits', project: @project, ref: @ref
- = spinner
+ .loading.hide
+ = loading_icon(size: "lg")
diff --git a/app/views/projects/confluences/show.html.haml b/app/views/projects/confluences/show.html.haml
index 5814b7a00f5..1eeafac5f1e 100644
--- a/app/views/projects/confluences/show.html.haml
+++ b/app/views/projects/confluences/show.html.haml
@@ -8,7 +8,7 @@
- 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 }
= 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}.").html_safe % { wiki_confluence_epic_link_start: wiki_confluence_epic_link_start, wiki_confluence_epic_link_end: '</a>'.html_safe }
- = link_to @project.confluence_service.confluence_url, target: '_blank', rel: 'noopener noreferrer', class: 'btn btn-success external-url', title: s_('WikiEmpty|Go to Confluence') do
+ = link_to @project.confluence_service.confluence_url, target: '_blank', rel: 'noopener noreferrer', class: 'gl-button btn btn-success external-url', title: s_('WikiEmpty|Go to Confluence') do
= sprite_icon('external-link')
= s_('WikiEmpty|Go to Confluence')
diff --git a/app/views/projects/cycle_analytics/show.html.haml b/app/views/projects/cycle_analytics/show.html.haml
index d99579c25c0..b98ab9757fa 100644
--- a/app/views/projects/cycle_analytics/show.html.haml
+++ b/app/views/projects/cycle_analytics/show.html.haml
@@ -22,7 +22,7 @@
.dropdown.inline.js-ca-dropdown
%button.dropdown-menu-toggle{ "data-toggle" => "dropdown", :type => "button" }
%span.dropdown-label {{ n__('Last %d day', 'Last %d days', 30) }}
- %i.fa.fa-chevron-down
+ = sprite_icon("chevron-down", css_class: "dropdown-menu-toggle-icon gl-top-3")
%ul.dropdown-menu.dropdown-menu-right
%li
%a{ "href" => "#", "data-value" => "7" }
diff --git a/app/views/projects/default_branch/_show.html.haml b/app/views/projects/default_branch/_show.html.haml
index 2ba12601c79..a1c7f5027c5 100644
--- a/app/views/projects/default_branch/_show.html.haml
+++ b/app/views/projects/default_branch/_show.html.haml
@@ -28,4 +28,4 @@
= _("Issues referenced by merge requests and commits within the default branch will be closed automatically")
= link_to sprite_icon('question-o'), help_page_path('user/project/issues/managing_issues.md', anchor: 'disabling-automatic-issue-closing'), target: '_blank'
- = f.submit _('Save changes'), class: "btn btn-success"
+ = f.submit _('Save changes'), class: "gl-button btn btn-success"
diff --git a/app/views/projects/deploy_keys/edit.html.haml b/app/views/projects/deploy_keys/edit.html.haml
index 805d4983002..780ec128d63 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', class: 'btn-success btn'
- = link_to 'Cancel', project_settings_repository_path(@project), class: 'btn btn-cancel'
+ = link_to 'Cancel', project_settings_repository_path(@project), class: 'gl-button btn btn-cancel'
diff --git a/app/views/projects/diffs/_diffs.html.haml b/app/views/projects/diffs/_diffs.html.haml
index 43aaa7cb405..8364311796f 100644
--- a/app/views/projects/diffs/_diffs.html.haml
+++ b/app/views/projects/diffs/_diffs.html.haml
@@ -9,7 +9,7 @@
.files-changed-inner
.inline-parallel-buttons.d-none.d-md-block
- if !diffs_expanded? && diff_files.any? { |diff_file| diff_file.collapsed? }
- = link_to _('Expand all'), url_for(safe_params.merge(expanded: 1, format: nil)), class: 'btn btn-default'
+ = link_to _('Expand all'), url_for(safe_params.merge(expanded: 1, format: nil)), class: 'gl-button btn btn-default'
- 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 187ebcb739c..18da238d445 100644
--- a/app/views/projects/diffs/_file.html.haml
+++ b/app/views/projects/diffs/_file.html.haml
@@ -14,16 +14,15 @@
= submodule_diff_compare_link(diff_file)
- unless diff_file.submodule?
- - blob = diff_file.blob
.file-actions.d-none.d-sm-block
- - if blob&.readable_text?
- = link_to '#', class: 'js-toggle-diff-comments btn active has-tooltip', title: _("Toggle comments for this file"), disabled: @diff_notes_disabled do
+ - if diff_file.blob&.readable_text?
+ = link_to '#', class: 'js-toggle-diff-comments gl-button btn active has-tooltip', title: _("Toggle comments for this file"), disabled: @diff_notes_disabled do
= sprite_icon('comment')
\
- if editable_diff?(diff_file)
- link_opts = @merge_request.persisted? ? { from_merge_request_iid: @merge_request.iid } : {}
= edit_blob_button(@merge_request.source_project, @merge_request.source_branch, diff_file.new_path,
- blob: blob, link_opts: link_opts)
+ blob: diff_file.blob, link_opts: link_opts)
- if image_diff && image_replaced
= view_file_button(diff_file.old_content_sha, diff_file.old_path, project, replaced: true)
diff --git a/app/views/projects/diffs/_file_header.html.haml b/app/views/projects/diffs/_file_header.html.haml
index e9dfda4e927..cb43527def1 100644
--- a/app/views/projects/diffs/_file_header.html.haml
+++ b/app/views/projects/diffs/_file_header.html.haml
@@ -1,30 +1,27 @@
-- show_toggle = local_assigns.fetch(:show_toggle, true)
-
-- if show_toggle
+- if local_assigns.fetch(:show_toggle, true)
%i.fa.diff-toggle-caret.fa-fw
- if diff_file.submodule?
- - blob = diff_file.blob
%span
= sprite_icon('archive')
%strong.file-title-name
- = submodule_link(blob, diff_file.content_sha, diff_file.repository)
+ = submodule_link(diff_file.blob, diff_file.content_sha, diff_file.repository)
- = copy_file_path_button(blob.path)
+ = copy_file_path_button(diff_file.blob.path)
- else
= conditional_link_to url.present?, url do
= blob_icon diff_file.b_mode, diff_file.file_path
- if diff_file.renamed_file?
- old_path, new_path = mark_inline_diffs(diff_file.old_path, diff_file.new_path)
- %strong.file-title-name.has-tooltip{ data: { title: diff_file.old_path, container: 'body' } }
+ %strong.file-title-name.has-tooltip.gl-word-break-all{ data: { title: diff_file.old_path, container: 'body' } }
= old_path
&rarr;
- %strong.file-title-name.has-tooltip{ data: { title: diff_file.new_path, container: 'body' } }
+ %strong.file-title-name.has-tooltip.gl-word-break-all{ data: { title: diff_file.new_path, container: 'body' } }
= new_path
- else
- %strong.file-title-name.has-tooltip{ data: { title: diff_file.file_path, container: 'body' } }
+ %strong.file-title-name.has-tooltip.gl-word-break-all{ data: { title: diff_file.file_path, container: 'body' } }
= diff_file.file_path
- if diff_file.deleted_file?
@@ -33,7 +30,7 @@
= copy_file_path_button(diff_file.file_path)
- if diff_file.mode_changed?
- %small
+ %small.gl-mr-2
#{diff_file.a_mode} → #{diff_file.b_mode}
- if diff_file.stored_externally? && diff_file.external_storage == :lfs
diff --git a/app/views/projects/diffs/_line.html.haml b/app/views/projects/diffs/_line.html.haml
index 4d40071e07c..de7f9eba158 100644
--- a/app/views/projects/diffs/_line.html.haml
+++ b/app/views/projects/diffs/_line.html.haml
@@ -1,12 +1,11 @@
-- email = local_assigns.fetch(:email, false)
- plain = local_assigns.fetch(:plain, false)
- discussions = local_assigns.fetch(:discussions, nil)
-- type = line.type
- line_code = diff_file.line_code(line)
- if discussions && line.discussable?
- line_discussions = discussions[line_code]
-%tr.line_holder{ class: type, id: (line_code unless plain) }
- - case type
+
+%tr.line_holder{ class: line.type, id: (line_code unless plain) }
+ - case line.type
- when 'match'
= diff_match_line line.old_pos, line.new_pos, text: line.text
- when 'old-nonewline', 'new-nonewline'
@@ -14,21 +13,21 @@
%td.new_line.diff-line-num
%td.line_content.match= line.text
- else
- %td.old_line.diff-line-num{ class: [type, ("js-avatar-container" if !plain)], data: { linenumber: line.old_pos } }
- - link_text = type == "new" ? " " : line.old_pos
+ %td.old_line.diff-line-num{ class: [line.type, ("js-avatar-container" if !plain)], data: { linenumber: line.old_pos } }
- if plain
- = link_text
+ = diff_link_number(line.type, "new", line.old_pos)
- else
- = add_diff_note_button(line_code, diff_file.position(line), type)
- %a{ href: "##{line_code}", data: { linenumber: link_text } }
- %td.new_line.diff-line-num{ class: type, data: { linenumber: line.new_pos } }
- - link_text = type == "old" ? " " : line.new_pos
+ = add_diff_note_button(line_code, diff_file.position(line), line.type)
+ %a{ href: "##{line_code}", data: { linenumber: diff_link_number(line.type, "new", line.old_pos) } }
+
+ %td.new_line.diff-line-num{ class: line.type, data: { linenumber: line.new_pos } }
- if plain
- = link_text
+ = diff_link_number(line.type, "old", line.new_pos)
- else
- %a{ href: "##{line_code}", data: { linenumber: link_text } }
- %td.line_content{ class: type }<
- - if email
+ %a{ href: "##{line_code}", data: { linenumber: diff_link_number(line.type, "old", line.new_pos) } }
+
+ %td.line_content{ class: line.type }<
+ - if local_assigns.fetch(:email, false)
%pre= line.rich_text
- else
= diff_line_content(line.rich_text)
diff --git a/app/views/projects/diffs/_stats.html.haml b/app/views/projects/diffs/_stats.html.haml
index cee479aab0a..6429cf31bc3 100644
--- a/app/views/projects/diffs/_stats.html.haml
+++ b/app/views/projects/diffs/_stats.html.haml
@@ -10,7 +10,7 @@
%strong.cgreen= pluralize(sum_added_lines, 'addition')
and
%strong.cred= pluralize(sum_removed_lines, 'deletion')
- .diff-stats-additions-deletions-collapsed.float-right.d-none.d-sm-none{ "aria-hidden": "true", "aria-describedby": "diff-stats" }
+ .diff-stats-additions-deletions-collapsed.float-right.d-none{ "aria-hidden": "true", "aria-describedby": "diff-stats" }
%strong.cgreen<
+#{sum_added_lines}
%strong.cred<
diff --git a/app/views/projects/edit.html.haml b/app/views/projects/edit.html.haml
index 63d571e718e..10dd80501e0 100644
--- a/app/views/projects/edit.html.haml
+++ b/app/views/projects/edit.html.haml
@@ -93,31 +93,9 @@
%li= _('Your deployment services will be broken, you will need to manually fix the services after renaming.')
= f.submit _('Change path'), class: "btn btn-warning qa-change-path-button"
- - if can?(current_user, :change_namespace, @project)
- .sub-section
- %h4.danger-title= _('Transfer project')
- = form_for @project, url: transfer_project_path(@project), method: :put, remote: true, html: { class: 'js-project-transfer-form' } do |f|
- .form-group
- = label_tag :new_namespace_id, nil, class: 'label-bold' do
- %span= _('Select a new namespace')
- .form-group
- = select_tag :new_namespace_id, namespaces_options(nil), include_blank: true, class: 'select2'
- %ul
- %li= _("Be careful. Changing the project's namespace can have unintended side effects.")
- %li= _('You can only transfer the project to namespaces you manage.')
- %li= _('You will need to update your local repositories to point to the new location.')
- %li= _('Project visibility level will be changed to match namespace rules when transferring to a group.')
- = f.submit 'Transfer project', class: "gl-button btn btn-danger js-confirm-danger qa-transfer-button", data: { "confirm-danger-message" => transfer_project_message(@project) }
-
- - if @project.forked? && can?(current_user, :remove_fork_project, @project)
- .sub-section
- %h4.danger-title= _('Remove fork relationship')
- %p= remove_fork_project_description_message(@project)
-
- = form_for @project, url: remove_fork_project_path(@project), method: :delete, remote: true, html: { class: 'transfer-project' } do |f|
- %p
- %strong= _('Once removed, the fork relationship cannot be restored and you will no longer be able to send merge requests to the source.')
- = button_to _('Remove fork relationship'), '#', class: "gl-button btn btn-danger js-confirm-danger", data: { "confirm-danger-message" => remove_fork_project_warning_message(@project) }
+ = render 'transfer', project: @project
+
+ = render 'remove_fork', project: @project
= render 'remove', project: @project
diff --git a/app/views/projects/environments/_external_url.html.haml b/app/views/projects/environments/_external_url.html.haml
index 82567f88ccc..b9208969fb3 100644
--- a/app/views/projects/environments/_external_url.html.haml
+++ b/app/views/projects/environments/_external_url.html.haml
@@ -1,4 +1,4 @@
- if environment.external_url && can?(current_user, :read_environment, environment)
- = link_to environment.external_url, target: '_blank', rel: 'noopener noreferrer', class: 'btn external-url has-tooltip qa-view-deployment', title: s_('Environments|Open live environment') do
+ = link_to environment.external_url, target: '_blank', rel: 'noopener noreferrer', class: 'gl-button btn external-url has-tooltip qa-view-deployment', title: s_('Environments|Open live environment') do
= sprite_icon('external-link')
= _("View deployment")
diff --git a/app/views/projects/environments/_form.html.haml b/app/views/projects/environments/_form.html.haml
index 0b8f9fe220d..10890bf1921 100644
--- a/app/views/projects/environments/_form.html.haml
+++ b/app/views/projects/environments/_form.html.haml
@@ -17,5 +17,5 @@
= f.url_field :external_url, class: 'form-control'
.form-actions
- = f.submit _('Save'), class: 'btn btn-success'
- = link_to _('Cancel'), project_environments_path(@project), class: 'btn btn-cancel'
+ = f.submit _('Save'), class: 'gl-button btn btn-success'
+ = link_to _('Cancel'), project_environments_path(@project), class: 'gl-button btn btn-cancel'
diff --git a/app/views/projects/environments/_metrics_button.html.haml b/app/views/projects/environments/_metrics_button.html.haml
index c4f19ea79e7..5a691676a68 100644
--- a/app/views/projects/environments/_metrics_button.html.haml
+++ b/app/views/projects/environments/_metrics_button.html.haml
@@ -2,6 +2,6 @@
- return unless can?(current_user, :read_environment, environment)
-= link_to environment_metrics_path(environment), title: _('See metrics'), class: 'btn metrics-button' do
+= link_to environment_metrics_path(environment), title: _('See metrics'), class: 'gl-button btn metrics-button' do
= sprite_icon('chart')
= _("Monitoring")
diff --git a/app/views/projects/environments/_pin_button.html.haml b/app/views/projects/environments/_pin_button.html.haml
index 5c7bfc2b17b..ec3e7e20365 100644
--- a/app/views/projects/environments/_pin_button.html.haml
+++ b/app/views/projects/environments/_pin_button.html.haml
@@ -1,3 +1,3 @@
- if environment.auto_stop_at? && environment.available?
- = button_to cancel_auto_stop_project_environment_path(environment.project, environment), class: 'btn btn-secondary has-tooltip', title: _('Prevent environment from auto-stopping') do
+ = button_to cancel_auto_stop_project_environment_path(environment.project, environment), class: 'gl-button btn btn-secondary has-tooltip', title: _('Prevent environment from auto-stopping') do
= sprite_icon('thumbtack')
diff --git a/app/views/projects/environments/_terminal_button.html.haml b/app/views/projects/environments/_terminal_button.html.haml
index 38bc087664b..ab3363bbb07 100644
--- a/app/views/projects/environments/_terminal_button.html.haml
+++ b/app/views/projects/environments/_terminal_button.html.haml
@@ -1,3 +1,3 @@
- if environment.has_terminals? && can?(current_user, :admin_environment, @project)
- = link_to terminal_project_environment_path(@project, environment), class: 'btn terminal-button' do
+ = link_to terminal_project_environment_path(@project, environment), class: 'gl-button btn terminal-button' do
= sprite_icon('terminal')
diff --git a/app/views/projects/environments/empty_metrics.html.haml b/app/views/projects/environments/empty_metrics.html.haml
index 5642fb34da9..3ee51a318c6 100644
--- a/app/views/projects/environments/empty_metrics.html.haml
+++ b/app/views/projects/environments/empty_metrics.html.haml
@@ -11,4 +11,4 @@
%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: 'btn btn-success'
+ = link_to s_("Environments|Learn about environments"), help_page_path('ci/environments/index.md'), class: 'gl-button btn btn-success'
diff --git a/app/views/projects/environments/show.html.haml b/app/views/projects/environments/show.html.haml
index 5b1556c9f52..0cb44bd03fb 100644
--- a/app/views/projects/environments/show.html.haml
+++ b/app/views/projects/environments/show.html.haml
@@ -3,6 +3,7 @@
- page_title _("Environments")
- add_page_specific_style 'page_bundles/xterm'
- add_page_specific_style 'page_bundles/environments'
+- add_page_specific_style 'page_bundles/ci_status'
#environments-detail-view{ data: { name: @environment.name, id: @environment.id, delete_path: environment_delete_path(@environment)} }
- if @environment.available? && can?(current_user, :stop_environment, @environment)
@@ -27,8 +28,8 @@
rel: 'noopener noreferrer' }
= s_('Environments|Learn more about stopping environments')
.modal-footer
- = button_tag _('Cancel'), type: 'button', class: 'btn btn-cancel', data: { dismiss: 'modal' }
- = button_to stop_project_environment_path(@project, @environment), class: 'btn btn-danger has-tooltip', method: :post do
+ = button_tag _('Cancel'), type: 'button', class: 'gl-button btn btn-cancel', data: { dismiss: 'modal' }
+ = button_to stop_project_environment_path(@project, @environment), class: 'gl-button btn btn-danger has-tooltip', method: :post do
= s_('Environments|Stop environment')
- if can_destroy_environment?(@environment)
@@ -48,12 +49,12 @@
- if can?(current_user, :update_environment, @environment)
= link_to _('Edit'), edit_project_environment_path(@project, @environment), class: 'btn'
- if @environment.available? && can?(current_user, :stop_environment, @environment)
- = button_tag class: 'btn btn-danger', type: 'button', data: { toggle: 'modal',
+ = button_tag class: 'gl-button btn btn-danger', type: 'button', data: { toggle: 'modal',
target: '#stop-environment-modal' } do
= sprite_icon('stop')
= s_('Environments|Stop')
- if can_destroy_environment?(@environment)
- = button_tag class: 'btn btn-danger', type: 'button', data: { toggle: 'modal',
+ = button_tag class: 'gl-button btn btn-danger', type: 'button', data: { toggle: 'modal',
target: '#delete-environment-modal' } do
= s_('Environments|Delete')
@@ -66,7 +67,7 @@
%p.blank-state-text
= html_escape(_("Define environments in the deploy stage(s) in %{code_open}.gitlab-ci.yml%{code_close} to track deployments here.")) % { code_open: '<code>'.html_safe, code_close: '</code>'.html_safe }
.text-center
- = link_to _("Read more"), help_page_path("ci/environments/index.md"), class: "btn btn-success"
+ = link_to _("Read more"), help_page_path("ci/environments/index.md"), class: "gl-button btn btn-success"
- else
.table-holder.gl-overflow-visible
.ci-table.environments{ role: 'grid' }
diff --git a/app/views/projects/environments/terminal.html.haml b/app/views/projects/environments/terminal.html.haml
index ed0bc0680d7..ee31985eaf0 100644
--- a/app/views/projects/environments/terminal.html.haml
+++ b/app/views/projects/environments/terminal.html.haml
@@ -13,7 +13,7 @@
.col-sm-6
.nav-controls
- if @environment.external_url.present?
- = link_to @environment.external_url, class: 'btn btn-default', target: '_blank', rel: 'noopener noreferrer nofollow' do
+ = link_to @environment.external_url, class: 'gl-button btn btn-default', target: '_blank', rel: 'noopener noreferrer nofollow' do
= sprite_icon('external-link')
= render 'projects/deployments/actions', deployment: @environment.last_deployment
diff --git a/app/views/projects/generic_commit_statuses/_generic_commit_status.html.haml b/app/views/projects/generic_commit_statuses/_generic_commit_status.html.haml
index e341831e17d..2627552058b 100644
--- a/app/views/projects/generic_commit_statuses/_generic_commit_status.html.haml
+++ b/app/views/projects/generic_commit_statuses/_generic_commit_status.html.haml
@@ -19,7 +19,7 @@
- if ref
- if generic_commit_status.ref
.icon-container
- = generic_commit_status.tags.any? ? icon('tag') : sprite_icon('fork', size: 10)
+ = generic_commit_status.tags.any? ? sprite_icon('tag', size: 10) : sprite_icon('fork', size: 10)
= link_to generic_commit_status.ref, project_commits_path(generic_commit_status.project, generic_commit_status.ref)
- else
.light none
@@ -30,7 +30,8 @@
= link_to generic_commit_status.short_sha, project_commit_path(generic_commit_status.project, generic_commit_status.sha), class: "commit-sha"
- if retried
- = icon('warning', class: 'text-warning has-tooltip', title: 'Status was retried.')
+ %span.has-tooltip{ title: _('Status was retried.') }
+ = sprite_icon('warning-solid', css_class: 'text-warning')
.label-container
- if generic_commit_status.tags.any?
diff --git a/app/views/projects/hooks/index.html.haml b/app/views/projects/hooks/index.html.haml
index e40c36da29d..03ea623f4c6 100644
--- a/app/views/projects/hooks/index.html.haml
+++ b/app/views/projects/hooks/index.html.haml
@@ -9,6 +9,6 @@
.col-lg-8.gl-mb-3
= form_for @hook, as: :hook, url: polymorphic_path([@project, :hooks]) do |f|
= render partial: 'shared/web_hooks/form', locals: { form: f, hook: @hook }
- = f.submit 'Add webhook', class: 'btn btn-success'
+ = f.submit 'Add webhook', class: 'gl-button btn btn-success'
= render 'shared/web_hooks/index', hooks: @hooks, hook_class: @hook.class
diff --git a/app/views/projects/imports/new.html.haml b/app/views/projects/imports/new.html.haml
index 58981ca1556..3064b8bf873 100644
--- a/app/views/projects/imports/new.html.haml
+++ b/app/views/projects/imports/new.html.haml
@@ -16,4 +16,4 @@
= render "shared/import_form", f: f
.form-actions
- = f.submit 'Start import', class: "btn btn-success", tabindex: 4
+ = f.submit 'Start import', class: "gl-button btn btn-success"
diff --git a/app/views/projects/incidents/show.html.haml b/app/views/projects/incidents/show.html.haml
index b0ddc85df5d..4d4607e8e36 100644
--- a/app/views/projects/incidents/show.html.haml
+++ b/app/views/projects/incidents/show.html.haml
@@ -1 +1,6 @@
-= render template: 'projects/issues/show'
+- @content_class = "limit-container-width" unless fluid_layout
+- add_to_breadcrumbs _("Incidents"), project_incidents_path(@project)
+- breadcrumb_title @issue.to_reference
+- page_title "#{@issue.title} (#{@issue.to_reference})", _("Incidents")
+
+= render 'projects/issuable/show', issuable: @issue
diff --git a/app/views/projects/issuable/_show.html.haml b/app/views/projects/issuable/_show.html.haml
new file mode 100644
index 00000000000..48920c4e342
--- /dev/null
+++ b/app/views/projects/issuable/_show.html.haml
@@ -0,0 +1,10 @@
+- page_description issuable.description_html
+- page_card_attributes issuable.card_attributes
+- if issuable.relocation_target
+ - page_canonical_link issuable.relocation_target.present(current_user: current_user).web_url
+
+= render_if_exists "projects/issues/alert_blocked", issue: issuable, current_user: current_user
+= render "projects/issues/alert_moved_from_service_desk", issue: issuable
+
+= render 'shared/issue_type/details_header', issuable: issuable
+= render 'shared/issue_type/details_content', issuable: issuable
diff --git a/app/views/projects/issues/_design_management.html.haml b/app/views/projects/issues/_design_management.html.haml
index 6fc2f41b122..ad0605b10a8 100644
--- a/app/views/projects/issues/_design_management.html.haml
+++ b/app/views/projects/issues/_design_management.html.haml
@@ -6,6 +6,8 @@
- enable_lfs_message = s_("DesignManagement|To upload designs, you'll need to enable LFS and have admin enable hashed storage. %{requirements_link_start}More information%{requirements_link_end}").html_safe % { requirements_link_start: requirements_link_start, requirements_link_end: link_end }
- if @project.design_management_enabled?
+ - add_page_startup_graphql_call('design_management/get_design_list', { fullPath: @project.full_path, iid: @issue.iid.to_s, atVersion: nil })
+ - add_page_startup_graphql_call('design_management/design_permissions', { fullPath: @project.full_path, iid: @issue.iid.to_s })
.js-design-management{ data: { project_path: @project.full_path, issue_iid: @issue.iid, issue_path: project_issue_path(@project, @issue) } }
- else
.gl-border-solid.gl-border-1.gl-border-gray-100.gl-rounded-base.gl-mt-5.gl-p-3.gl-text-center
diff --git a/app/views/projects/issues/_discussion.html.haml b/app/views/projects/issues/_discussion.html.haml
index e1f1d8bb8f7..51130ae666c 100644
--- a/app/views/projects/issues/_discussion.html.haml
+++ b/app/views/projects/issues/_discussion.html.haml
@@ -5,8 +5,8 @@
- content_for :note_actions do
- if can?(current_user, :update_issue, @issue)
- = link_to 'Reopen issue', issue_path(@issue, issue: {state_event: :reopen}, format: 'json'), data: {original_text: "Reopen issue", alternative_text: "Comment & reopen issue"}, class: "btn btn-nr btn-reopen btn-comment js-note-target-reopen #{issue_button_visibility(@issue, false)}", title: 'Reopen issue'
- = link_to 'Close issue', issue_path(@issue, issue: {state_event: :close}, format: 'json'), data: {original_text: "Close issue", alternative_text: "Comment & close issue"}, class: "btn btn-nr btn-close btn-comment js-note-target-close #{issue_button_visibility(@issue, true)}", title: 'Close issue'
+ = link_to 'Reopen issue', issue_path(@issue, issue: {state_event: :reopen}, format: 'json'), data: {original_text: "Reopen issue", alternative_text: "Comment & reopen issue"}, class: "gl-button btn btn-nr btn-reopen btn-comment js-note-target-reopen #{issue_button_visibility(@issue, false)}", title: 'Reopen issue'
+ = link_to 'Close issue', issue_path(@issue, issue: {state_event: :close}, format: 'json'), data: {original_text: "Close issue", alternative_text: "Comment & close issue"}, class: "gl-button btn btn-nr btn-close btn-comment js-note-target-close #{issue_button_visibility(@issue, true)}", title: 'Close issue'
%section.issuable-discussion.js-vue-notes-event
#js-vue-notes{ data: { notes_data: notes_data(@issue).to_json,
diff --git a/app/views/projects/issues/_issue.html.haml b/app/views/projects/issues/_issue.html.haml
index 4f188ae273c..d9ad171a6cc 100644
--- a/app/views/projects/issues/_issue.html.haml
+++ b/app/views/projects/issues/_issue.html.haml
@@ -37,12 +37,15 @@
&nbsp;
= sprite_icon('calendar')
= issue.due_date.to_s(:medium)
+
+ = render_if_exists "projects/issues/issue_weight", issue: issue
+ = render_if_exists "projects/issues/health_status", issue: issue
+
- if issue.labels.any?
&nbsp;
- presented_labels_sorted_by_title(issue.labels, issue.project).each do |label|
= link_to_label(label, small: true)
- = render_if_exists "projects/issues/issue_weight", issue: issue
= render "projects/issues/issue_estimate", issue: issue
.issuable-meta
diff --git a/app/views/projects/issues/_issues.html.haml b/app/views/projects/issues/_issues.html.haml
index fa08c39e407..ef602da72e5 100644
--- a/app/views/projects/issues/_issues.html.haml
+++ b/app/views/projects/issues/_issues.html.haml
@@ -11,7 +11,8 @@
'empty-state-meta': data_empty_state_meta.to_json,
'can-bulk-edit': @can_bulk_update.to_json,
'sort-key': @sort,
- type: type } }
+ type: type,
+ 'scoped-labels-available': scoped_labels_available?(@project).to_json } }
- else
- empty_state_path = local_assigns.fetch(:empty_state_path, 'shared/empty_states/issues')
%ul.content-list.issues-list.issuable-list{ class: ("manual-ordering" if @sort == 'relative_position') }
diff --git a/app/views/projects/issues/_nav_btns.html.haml b/app/views/projects/issues/_nav_btns.html.haml
index cc6ca4aca4a..dbf6a1f1b94 100644
--- a/app/views/projects/issues/_nav_btns.html.haml
+++ b/app/views/projects/issues/_nav_btns.html.haml
@@ -8,22 +8,22 @@
.btn-group
- if show_export_button
- = render 'projects/issues/export_csv/button'
+ = render 'shared/issuable/csv_export/button', issuable_type: 'issues'
- if show_import_button
= render 'projects/issues/import_csv/button'
- if @can_bulk_update
- = button_tag _("Edit issues"), class: "btn btn-default gl-mr-3 js-bulk-update-toggle"
+ = button_tag _("Edit issues"), class: "gl-button btn btn-default gl-mr-3 js-bulk-update-toggle"
- if show_new_issue_link?(@project)
= link_to _("New issue"), new_project_issue_path(@project,
issue: { assignee_id: finder.assignee.try(:id),
milestone_id: finder.milestones.first.try(:id) }),
- class: "btn btn-success",
+ class: "gl-button btn btn-success",
id: "new_issue_link"
- if show_export_button
- = render 'projects/issues/export_csv/modal'
+ = render 'shared/issuable/csv_export/modal', issuable_type: 'issues'
- if show_import_button
= render 'projects/issues/import_csv/modal'
diff --git a/app/views/projects/issues/_new_branch.html.haml b/app/views/projects/issues/_new_branch.html.haml
index aa95cecb5fe..34260899d94 100644
--- a/app/views/projects/issues/_new_branch.html.haml
+++ b/app/views/projects/issues/_new_branch.html.haml
@@ -29,7 +29,7 @@
- if can_create_merge_request
%li.droplab-item-selected{ role: 'button', data: { value: 'create-mr', text: create_mr_text } }
.menu-item.text-nowrap
- = icon('check', class: 'icon')
+ = sprite_icon('check', css_class: 'icon')
- if can_create_confidential_merge_request?
= _('Create confidential merge request and branch')
- else
@@ -37,7 +37,7 @@
%li{ class: [!can_create_merge_request && 'droplab-item-selected'], role: 'button', data: { value: 'create-branch', text: _('Create branch') } }
.menu-item
- = icon('check', class: 'icon')
+ = sprite_icon('check', css_class: 'icon')
= _('Create branch')
%li.divider.droplab-item-ignore
diff --git a/app/views/projects/issues/_service_desk_empty_state.html.haml b/app/views/projects/issues/_service_desk_empty_state.html.haml
index 4f004439f45..40abedea9d4 100644
--- a/app/views/projects/issues/_service_desk_empty_state.html.haml
+++ b/app/views/projects/issues/_service_desk_empty_state.html.haml
@@ -21,7 +21,7 @@
- if can_edit_project_settings && !service_desk_enabled
.text-center
- = link_to _("Turn on Service Desk"), edit_project_path(@project), class: 'btn btn-success'
+ = link_to _("Turn on Service Desk"), edit_project_path(@project), class: 'gl-button btn btn-success'
- else
.empty-state
.svg-content
diff --git a/app/views/projects/issues/_service_desk_info_content.html.haml b/app/views/projects/issues/_service_desk_info_content.html.haml
index 7fa2f3fab00..1eb427f4f7c 100644
--- a/app/views/projects/issues/_service_desk_info_content.html.haml
+++ b/app/views/projects/issues/_service_desk_info_content.html.haml
@@ -20,4 +20,4 @@
- if can_edit_project_settings && !service_desk_enabled
.gl-mt-3
- = link_to _("Turn on Service Desk"), edit_project_path(@project), class: 'btn btn-success'
+ = link_to _("Turn on Service Desk"), edit_project_path(@project), class: 'gl-button btn btn-success'
diff --git a/app/views/projects/issues/export_csv/_modal.html.haml b/app/views/projects/issues/export_csv/_modal.html.haml
deleted file mode 100644
index 6610af63445..00000000000
--- a/app/views/projects/issues/export_csv/_modal.html.haml
+++ /dev/null
@@ -1,22 +0,0 @@
-- if current_user
- .issues-export-modal.modal
- .modal-dialog
- .modal-content{ data: { qa_selector: 'export_issues_modal' } }
- .modal-header
- %h3
- = _('Export issues')
- .svg-content.import-export-svg-container
- = image_tag 'illustrations/export-import.svg', alt: _('Import/Export illustration'), class: 'illustration'
- %a.close{ href: '#', 'data-dismiss' => 'modal' }
- = sprite_icon('close', css_class: 'gl-icon')
- .modal-body
- - issues_count = issuables_count_for_state(:issues, params[:state])
- - unless issues_count == -1 # The count timed out
- .modal-subheader
- = icon('check', { class: 'checkmark' })
- %strong.gl-ml-3
- = n_('%d issue selected', '%d issues selected', issues_count) % issues_count
- .modal-text
- = html_escape(_('The CSV export will be created in the background. Once finished, it will be sent to %{strong_open}%{email}%{strong_close} in an attachment.')) % { email: @current_user.notification_email, strong_open: '<strong>'.html_safe, strong_close: '</strong>'.html_safe }
- .modal-footer
- = link_to _('Export issues'), export_csv_project_issues_path(@project, request.query_parameters), method: :post, class: 'btn gl-button btn-success float-left', title: _('Export issues'), data: { track_label: "export_issues_csv", track_event: "click_button", track_value: "", qa_selector: "export_issues_button" }
diff --git a/app/views/projects/issues/import_csv/_modal.html.haml b/app/views/projects/issues/import_csv/_modal.html.haml
index fe4a4236896..e928a71b940 100644
--- a/app/views/projects/issues/import_csv/_modal.html.haml
+++ b/app/views/projects/issues/import_csv/_modal.html.haml
@@ -20,5 +20,5 @@
= _('It must have a header row and at least two columns: the first column is the issue title and the second column is the issue description. The separator is automatically detected.')
= _('The maximum file size allowed is %{size}.') % { size: number_to_human_size(Gitlab::CurrentSettings.max_attachment_size.megabytes) }
.modal-footer
- %button{ type: 'submit', class: 'btn btn-success', title: _('Import issues'), data: { track_label: "export_issues_csv", track_event: "click_button", track_value: ""} }
+ %button{ type: 'submit', class: 'gl-button btn btn-success', title: _('Import issues'), data: { track_label: "export_issues_csv", track_event: "click_button", track_value: ""} }
= _('Import issues')
diff --git a/app/views/projects/issues/show.html.haml b/app/views/projects/issues/show.html.haml
index 7785093466b..c3949a83e3f 100644
--- a/app/views/projects/issues/show.html.haml
+++ b/app/views/projects/issues/show.html.haml
@@ -1,103 +1,6 @@
- @content_class = "limit-container-width" unless fluid_layout
- add_to_breadcrumbs _("Issues"), project_issues_path(@project)
- breadcrumb_title @issue.to_reference
-- page_title "#{@issue.title} (#{@issue.to_reference})", _("Issues")
-- page_description @issue.description_html
-- page_card_attributes @issue.card_attributes
-- if @issue.relocation_target
- - page_canonical_link @issue.relocation_target.present(current_user: current_user).web_url
-- if @issue.sentry_issue.present?
- - add_page_specific_style 'page_bundles/error_tracking_details'
+- page_title "#{@issue.title} (#{@issue.to_reference})", _("Issues")
-- can_update_issue = can?(current_user, :update_issue, @issue)
-- can_reopen_issue = can?(current_user, :reopen_issue, @issue)
-- can_report_spam = @issue.submittable_as_spam_by?(current_user)
-- can_create_issue = show_new_issue_link?(@project)
-- related_branches_path = related_branches_project_issue_path(@project, @issue)
-
-= render_if_exists "projects/issues/alert_blocked", issue: @issue, current_user: current_user
-= render "projects/issues/alert_moved_from_service_desk", issue: @issue
-
-.detail-page-header
- .detail-page-header-body
- .issuable-status-box.status-box.status-box-issue-closed{ class: issue_status_visibility(@issue, status_box: :closed) }
- = sprite_icon('mobile-issue-close', css_class: 'd-block d-sm-none')
- .d-none.d-sm-block
- = issue_closed_text(@issue, current_user)
- .issuable-status-box.status-box.status-box-open{ class: issue_status_visibility(@issue, status_box: :open) }
- = sprite_icon('issue-open-m', css_class: 'd-block d-sm-none')
- %span.d-none.d-sm-block Open
-
- .issuable-meta
- #js-issuable-header-warnings
- = issuable_meta(@issue, @project, "Issue")
-
- %a.btn.btn-default.float-right.d-block.d-sm-none.gutter-toggle.issuable-gutter-toggle.js-sidebar-toggle{ href: "#" }
- = sprite_icon('chevron-double-lg-left')
-
- .detail-page-header-actions.js-issuable-actions.js-issuable-buttons{ data: { "action": "close-reopen" } }
- .clearfix.issue-btn-group.dropdown
- %button.btn.btn-default.float-left.d-md-none.d-lg-none.d-xl-none{ type: "button", data: { toggle: "dropdown" } }
- Options
- = icon('caret-down')
- .dropdown-menu.dropdown-menu-right.d-lg-none.d-xl-none
- %ul
- - unless current_user == @issue.author
- %li= link_to 'Report abuse', new_abuse_report_path(user_id: @issue.author.id, ref_url: issue_url(@issue))
- - if can_update_issue
- %li= link_to 'Close issue', issue_path(@issue, issue: { state_event: :close }, format: 'json'), class: "btn-close js-btn-issue-action #{issue_button_visibility(@issue, true)}", title: 'Close issue'
- - if can_reopen_issue
- %li= link_to 'Reopen issue', issue_path(@issue, issue: { state_event: :reopen }, format: 'json'), class: "btn-reopen js-btn-issue-action #{issue_button_visibility(@issue, false)}", title: 'Reopen issue'
- - if can_report_spam
- %li= link_to 'Submit as spam', mark_as_spam_project_issue_path(@project, @issue), method: :post, class: 'btn-spam', title: 'Submit as spam'
- - if can_create_issue
- - if can_update_issue || can_report_spam
- %li.divider
- %li= link_to 'New issue', new_project_issue_path(@project), id: 'new_issue_link'
-
- = render 'shared/issuable/close_reopen_button', issuable: @issue, can_update: can_update_issue, can_reopen: can_reopen_issue, warn_before_close: defined?(@issue.blocked?) && @issue.blocked?
-
- - if can_report_spam
- = link_to 'Submit as spam', mark_as_spam_project_issue_path(@project, @issue), method: :post, class: 'd-none d-sm-none d-md-block btn btn-grouped btn-spam', title: 'Submit as spam'
- - if can_create_issue
- = link_to new_project_issue_path(@project), class: 'd-none d-sm-none d-md-block btn btn-grouped btn-success btn-inverted', title: 'New issue', id: 'new_issue_link' do
- New issue
-
-.issue-details.issuable-details
- .detail-page-description.content-block
- #js-issuable-app{ data: { initial: issuable_initial_data(@issue).to_json} }
- .title-container
- %h2.title= markdown_field(@issue, :title)
- - if @issue.description.present?
- .description
- .md= markdown_field(@issue, :description)
-
- = edited_time_ago_with_tooltip(@issue, placement: 'bottom', html_class: 'issue-edited-ago js-issue-edited-ago')
-
- - if @issue.sentry_issue.present?
- #js-sentry-error-stack-trace{ data: error_details_data(@project, @issue.sentry_issue.sentry_issue_identifier) }
-
- = render 'projects/issues/design_management'
-
- = render_if_exists 'projects/issues/related_issues'
-
- #js-related-merge-requests{ data: { endpoint: expose_path(api_v4_projects_issues_related_merge_requests_path(id: @project.id, issue_iid: @issue.iid)), project_namespace: @project.namespace.path, project_path: @project.path } }
-
- - if can?(current_user, :download_code, @project)
- - add_page_startup_api_call related_branches_path
- #related-branches{ data: { url: related_branches_path } }
- -# This element is filled in using JavaScript.
-
- .content-block.emoji-block.emoji-block-sticky
- .row.gl-m-0.gl-justify-content-space-between
- .js-noteable-awards
- = render 'award_emoji/awards_block', awardable: @issue, inline: true
- .new-branch-col
- = render_if_exists "projects/issues/timeline_toggle", issue: @issue
- #js-vue-sort-issue-discussions
- #js-vue-discussion-filter{ data: { default_filter: current_user&.notes_filter_for(@issue), notes_filters: UserPreference.notes_filters.to_json } }
- = render 'new_branch' if show_new_branch_button?
-
- = render 'projects/issues/discussion'
-
-= render 'shared/issuable/sidebar', issuable_sidebar: @issuable_sidebar, assignees: @issue.assignees
+= render 'projects/issuable/show', issuable: @issue
diff --git a/app/views/projects/jobs/index.html.haml b/app/views/projects/jobs/index.html.haml
index 0b4b4aafeee..a1960fc99cf 100644
--- a/app/views/projects/jobs/index.html.haml
+++ b/app/views/projects/jobs/index.html.haml
@@ -1,4 +1,5 @@
- page_title _("Jobs")
+- add_page_specific_style 'page_bundles/ci_status'
.top-area
- build_path_proc = ->(scope) { project_jobs_path(@project, scope: scope) }
diff --git a/app/views/projects/jobs/show.html.haml b/app/views/projects/jobs/show.html.haml
index d7a778088ee..44336b95e0f 100644
--- a/app/views/projects/jobs/show.html.haml
+++ b/app/views/projects/jobs/show.html.haml
@@ -1,7 +1,9 @@
- add_to_breadcrumbs _("Jobs"), project_jobs_path(@project)
- breadcrumb_title "##{@build.id}"
- page_title "#{@build.name} (##{@build.id})", _("Jobs")
+- add_page_specific_style 'page_bundles/build'
- add_page_specific_style 'page_bundles/xterm'
+- add_page_specific_style 'page_bundles/ci_status'
= render_if_exists "shared/shared_runners_minutes_limit_flash_message"
diff --git a/app/views/projects/labels/index.html.haml b/app/views/projects/labels/index.html.haml
index 2699192adc9..357d4d193df 100644
--- a/app/views/projects/labels/index.html.haml
+++ b/app/views/projects/labels/index.html.haml
@@ -5,7 +5,7 @@
- labels_or_filters = @labels.exists? || @prioritized_labels.exists? || search.present? || subscribed.present?
- if labels_or_filters
- #promote-label-modal
+ #js-promote-label-modal
= render 'shared/labels/nav', labels_or_filters: labels_or_filters, can_admin_label: can_admin_label
.labels-container.gl-mt-3
@@ -17,7 +17,7 @@
-# Only show it in the first page
- hide = @available_labels.empty? || (params[:page].present? && params[:page] != '1')
- .prioritized-labels{ class: [('hide' if hide), ('is-not-draggable' unless can_admin_label)] }
+ .prioritized-labels.gl-mb-7{ class: [('hide' if hide), ('is-not-draggable' unless can_admin_label)] }
%h5.gl-mt-3= _('Prioritized Labels')
.content-list.manage-labels-list.js-prioritized-labels{ 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?}" }
diff --git a/app/views/projects/logs/empty_logs.html.haml b/app/views/projects/logs/empty_logs.html.haml
index afae2d30f6e..5e3db401d79 100644
--- a/app/views/projects/logs/empty_logs.html.haml
+++ b/app/views/projects/logs/empty_logs.html.haml
@@ -11,4 +11,4 @@
%p.state-description.text-center
= s_('Logs|To see the logs, deploy your code to an environment.')
.text-center
- = link_to s_('Environments|Learn about environments'), help_page_path('ci/environments/index.md'), class: 'btn btn-success'
+ = link_to s_('Environments|Learn about environments'), help_page_path('ci/environments/index.md'), class: 'gl-button btn btn-success'
diff --git a/app/views/projects/mattermosts/_no_teams.html.haml b/app/views/projects/mattermosts/_no_teams.html.haml
index 0377cd6586e..00efea81f8f 100644
--- a/app/views/projects/mattermosts/_no_teams.html.haml
+++ b/app/views/projects/mattermosts/_no_teams.html.haml
@@ -9,8 +9,8 @@
To install this service,
= link_to "#{Gitlab.config.mattermost.host}/select_team", target: '__blank' do
join a team
- = icon('external-link')
+ = sprite_icon('external-link')
and try again.
%hr
.clearfix
- = link_to 'Go back', edit_project_service_path(@project, @service), class: 'btn btn-lg float-right'
+ = link_to 'Go back', edit_project_service_path(@project, @service), class: 'gl-button btn btn-lg float-right'
diff --git a/app/views/projects/mattermosts/_team_selection.html.haml b/app/views/projects/mattermosts/_team_selection.html.haml
index d0a7f89df31..ea04a55a77c 100644
--- a/app/views/projects/mattermosts/_team_selection.html.haml
+++ b/app/views/projects/mattermosts/_team_selection.html.haml
@@ -19,7 +19,7 @@
To create a team,
= link_to "#{Gitlab.config.mattermost.host}/create_team" do
use Mattermost's interface
- = icon('external-link')
+ = sprite_icon('external-link')
or ask your Mattermost system administrator.
%hr
%h4 Command trigger word
@@ -38,9 +38,9 @@
Reserved:
= link_to 'https://docs.mattermost.com/help/messaging/executing-commands.html#built-in-commands', target: '__blank' do
see list of built-in slash commands
- = icon('external-link')
+ = sprite_icon('external-link')
%hr
.clearfix
.float-right
- = link_to 'Cancel', edit_project_service_path(@project, @service), class: 'btn btn-lg'
- = f.submit 'Install', class: 'btn btn-success btn-lg'
+ = link_to 'Cancel', edit_project_service_path(@project, @service), class: 'gl-button btn btn-lg'
+ = f.submit 'Install', class: 'gl-button btn btn-success btn-lg'
diff --git a/app/views/projects/merge_requests/_mr_title.html.haml b/app/views/projects/merge_requests/_mr_title.html.haml
index b56e2c3f985..cd4ffa8602e 100644
--- a/app/views/projects/merge_requests/_mr_title.html.haml
+++ b/app/views/projects/merge_requests/_mr_title.html.haml
@@ -25,10 +25,10 @@
.detail-page-header-actions.js-issuable-actions
.clearfix.issue-btn-group.dropdown
- %button.btn.btn-default.float-left.d-md-none.d-lg-none.d-xl-none{ type: "button", data: { toggle: "dropdown" } }
+ %button.btn.btn-default.float-left.d-md-none{ type: "button", data: { toggle: "dropdown" } }
Options
= icon('caret-down')
- .dropdown-menu.dropdown-menu-right.d-lg-none.d-xl-none
+ .dropdown-menu.dropdown-menu-right
%ul
- if can_update_merge_request
%li= link_to 'Edit', edit_namespace_project_merge_request_path(@project.namespace, @project, @merge_request)
@@ -41,10 +41,10 @@
- if can_reopen_merge_request
%li{ class: merge_request_button_visibility(@merge_request, false) }
= link_to 'Reopen', merge_request_path(@merge_request, merge_request: { state_event: :reopen }), method: :put, class: 'reopen-mr-link', title: 'Reopen merge request'
- - unless current_user == @merge_request.author
+ - unless @merge_request.merged? || current_user == @merge_request.author
%li= link_to 'Report abuse', new_abuse_report_path(user_id: @merge_request.author.id, ref_url: merge_request_url(@merge_request))
- if can_update_merge_request
- = link_to 'Edit', edit_project_merge_request_path(@project, @merge_request), class: "d-none d-sm-none d-md-block btn gl-button btn-grouped js-issuable-edit qa-edit-button"
+ = link_to 'Edit', edit_project_merge_request_path(@project, @merge_request), class: "d-none d-md-block btn gl-button btn-grouped js-issuable-edit qa-edit-button"
= render 'shared/issuable/close_reopen_button', issuable: @merge_request, can_update: can_update_merge_request, can_reopen: can_reopen_merge_request
diff --git a/app/views/projects/merge_requests/_nav_btns.html.haml b/app/views/projects/merge_requests/_nav_btns.html.haml
index 2ef10365c18..473490c6c35 100644
--- a/app/views/projects/merge_requests/_nav_btns.html.haml
+++ b/app/views/projects/merge_requests/_nav_btns.html.haml
@@ -1,5 +1,10 @@
+.btn-group
+ = render 'shared/issuable/csv_export/button', issuable_type: 'merge-requests'
+
- if @can_bulk_update
- = button_tag "Edit merge requests", class: "btn gl-mr-3 js-bulk-update-toggle"
+ = button_tag "Edit merge requests", class: "gl-button btn gl-mr-3 js-bulk-update-toggle"
- if merge_project
- = link_to new_merge_request_path, class: "btn btn-success", title: "New merge request" do
+ = link_to new_merge_request_path, class: "gl-button btn btn-success", title: "New merge request" do
New merge request
+
+ = render 'shared/issuable/csv_export/modal', issuable_type: 'merge_requests'
diff --git a/app/views/projects/merge_requests/conflicts/_submit_form.html.haml b/app/views/projects/merge_requests/conflicts/_submit_form.html.haml
index 55c89f137c5..94c262d300e 100644
--- a/app/views/projects/merge_requests/conflicts/_submit_form.html.haml
+++ b/app/views/projects/merge_requests/conflicts/_submit_form.html.haml
@@ -21,4 +21,4 @@
%button.btn.btn-success.js-submit-button{ type: "button", "@click" => "commit()", ":disabled" => "!readyToCommit" }
%span {{commitButtonText}}
.col-6.text-right
- = link_to "Cancel", project_merge_request_path(@merge_request.project, @merge_request), class: "btn btn-cancel"
+ = link_to "Cancel", project_merge_request_path(@merge_request.project, @merge_request), class: "gl-button btn btn-cancel"
diff --git a/app/views/projects/merge_requests/conflicts/components/_diff_file_editor.html.haml b/app/views/projects/merge_requests/conflicts/components/_diff_file_editor.html.haml
index 3ca82adccf1..7294c5d321a 100644
--- a/app/views/projects/merge_requests/conflicts/components/_diff_file_editor.html.haml
+++ b/app/views/projects/merge_requests/conflicts/components/_diff_file_editor.html.haml
@@ -7,7 +7,4 @@
%button.btn.btn-sm.btn-close{ "@click" => "acceptDiscardConfirmation(file)" } Discard changes
%button.btn.btn-sm{ "@click" => "cancelDiscardConfirmation(file)" } Cancel
.editor-wrap{ ":class" => "classObject" }
- .loading
- .spinner.spinner-md
- .editor
- %pre{ "style" => "height: 350px" }
+ .editor{ "style" => "height: 350px", data: { 'editor-loading': true } }
diff --git a/app/views/projects/merge_requests/conflicts/show.html.haml b/app/views/projects/merge_requests/conflicts/show.html.haml
index a7ffe825139..decdbce3fa7 100644
--- a/app/views/projects/merge_requests/conflicts/show.html.haml
+++ b/app/views/projects/merge_requests/conflicts/show.html.haml
@@ -1,7 +1,5 @@
- page_title _("Merge Conflicts"), "#{@merge_request.title} (#{@merge_request.to_reference}", _("Merge Requests")
- add_page_specific_style 'page_bundles/merge_conflicts'
-- content_for :page_specific_javascripts do
- = page_specific_javascript_tag('lib/ace.js')
= render "projects/merge_requests/mr_title"
.merge-request-details.issuable-details
diff --git a/app/views/projects/merge_requests/creations/_new_compare.html.haml b/app/views/projects/merge_requests/creations/_new_compare.html.haml
index f0a68512326..2cb75d43d4b 100644
--- a/app/views/projects/merge_requests/creations/_new_compare.html.haml
+++ b/app/views/projects/merge_requests/creations/_new_compare.html.haml
@@ -4,7 +4,6 @@
= form_for [@project, @merge_request], url: project_new_merge_request_path(@project), method: :get, html: { class: "merge-request-form js-requires-input" } do |f|
- if params[:nav_source].present?
= hidden_field_tag(:nav_source, params[:nav_source])
- .hide.alert.alert-danger.mr-compare-errors
.js-merge-request-new-compare.row{ 'data-source-branch-url': project_new_merge_request_branch_from_path(@source_project), 'data-target-branch-url': project_new_merge_request_branch_to_path(@source_project) }
.col-lg-6
.card.card-new-merge-request
@@ -65,4 +64,4 @@
- if @merge_request.errors.any?
= form_errors(@merge_request)
- = f.submit 'Compare branches and continue', class: "btn btn-success mr-compare-btn"
+ = f.submit 'Compare branches and continue', class: "gl-button btn btn-success mr-compare-btn"
diff --git a/app/views/projects/merge_requests/creations/new.html.haml b/app/views/projects/merge_requests/creations/new.html.haml
index 4c968c8e8eb..0741b24a5a1 100644
--- a/app/views/projects/merge_requests/creations/new.html.haml
+++ b/app/views/projects/merge_requests/creations/new.html.haml
@@ -2,6 +2,7 @@
- breadcrumb_title _("New")
- page_title _("New Merge Request")
- add_page_specific_style 'page_bundles/pipelines'
+- add_page_specific_style 'page_bundles/ci_status'
- if @merge_request.can_be_created && !params[:change_branches]
= render 'new_submit'
diff --git a/app/views/projects/merge_requests/show.html.haml b/app/views/projects/merge_requests/show.html.haml
index 1dbcd613ceb..6b506c38795 100644
--- a/app/views/projects/merge_requests/show.html.haml
+++ b/app/views/projects/merge_requests/show.html.haml
@@ -11,6 +11,7 @@
- add_page_specific_style 'page_bundles/merge_requests'
- add_page_specific_style 'page_bundles/pipelines'
- add_page_specific_style 'page_bundles/reports'
+- add_page_specific_style 'page_bundles/ci_status'
.merge-request{ data: { mr_action: mr_action, url: merge_request_path(@merge_request, format: :json), project_path: project_path(@merge_request.project), lock_version: @merge_request.lock_version } }
= render "projects/merge_requests/mr_title"
diff --git a/app/views/projects/milestones/_form.html.haml b/app/views/projects/milestones/_form.html.haml
index 907af326ec5..a21f519da0e 100644
--- a/app/views/projects/milestones/_form.html.haml
+++ b/app/views/projects/milestones/_form.html.haml
@@ -22,7 +22,7 @@
.form-actions
- if @milestone.new_record?
= f.submit _('Create milestone'), class: 'btn-success btn', data: { qa_selector: 'create_milestone_button' }
- = link_to _('Cancel'), project_milestones_path(@project), class: 'btn btn-cancel'
+ = link_to _('Cancel'), project_milestones_path(@project), class: 'gl-button btn btn-cancel'
- else
= f.submit _('Save changes'), class: 'btn-success btn'
- = link_to _('Cancel'), project_milestone_path(@project, @milestone), class: 'btn btn-cancel'
+ = link_to _('Cancel'), project_milestone_path(@project, @milestone), class: 'gl-button btn btn-cancel'
diff --git a/app/views/projects/milestones/index.html.haml b/app/views/projects/milestones/index.html.haml
index 2c52d2a5fbc..b964c8b1a93 100644
--- a/app/views/projects/milestones/index.html.haml
+++ b/app/views/projects/milestones/index.html.haml
@@ -8,7 +8,7 @@
= 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: 'btn btn-success', data: { qa_selector: "new_project_milestone_link" }, title: _('New milestone') do
+ = link_to new_project_milestone_path(@project), class: 'gl-button btn btn-success', data: { qa_selector: "new_project_milestone_link" }, title: _('New milestone') do
= _('New milestone')
.milestones
diff --git a/app/views/projects/mirrors/_authentication_method.html.haml b/app/views/projects/mirrors/_authentication_method.html.haml
index dae0fa958ba..88bd7da7fef 100644
--- a/app/views/projects/mirrors/_authentication_method.html.haml
+++ b/app/views/projects/mirrors/_authentication_method.html.haml
@@ -7,7 +7,7 @@
= f.select :auth_method,
options_for_select(auth_options, mirror.auth_method),
{}, { class: "form-control select-control js-mirror-auth-type qa-authentication-method" }
- = icon('chevron-down')
+ = sprite_icon('chevron-down', css_class: "gl-icon gl-absolute gl-top-3 gl-right-3 gl-text-gray-200")
= f.hidden_field :auth_method, value: "password", class: "js-hidden-mirror-auth-type"
.form-group
diff --git a/app/views/projects/mirrors/_mirror_repos.html.haml b/app/views/projects/mirrors/_mirror_repos.html.haml
index d2847de6ece..5b074ff8a28 100644
--- a/app/views/projects/mirrors/_mirror_repos.html.haml
+++ b/app/views/projects/mirrors/_mirror_repos.html.haml
@@ -33,7 +33,7 @@
= link_to sprite_icon('question-o'), help_page_path('user/project/protected_branches'), target: '_blank'
.panel-footer
- = f.submit _('Mirror repository'), class: 'btn btn-success js-mirror-submit qa-mirror-repository-button', name: :update_remote_mirror
+ = f.submit _('Mirror repository'), class: 'gl-button btn btn-success js-mirror-submit qa-mirror-repository-button', name: :update_remote_mirror
- else
.gl-alert.gl-alert-info{ role: 'alert' }
= sprite_icon('information-o', css_class: 'gl-icon gl-alert-icon gl-alert-icon-no-title')
@@ -72,6 +72,6 @@
- if mirror_settings_enabled
.btn-group.mirror-actions-group.float-right{ role: 'group' }
- if mirror.ssh_key_auth?
- = clipboard_button(text: mirror.ssh_public_key, class: 'btn btn-default', title: _('Copy SSH public key'), qa_selector: 'copy_public_key_button')
+ = clipboard_button(text: mirror.ssh_public_key, class: 'gl-button btn btn-default', title: _('Copy SSH public key'), qa_selector: 'copy_public_key_button')
= render 'shared/remote_mirror_update_button', remote_mirror: mirror
- %button.js-delete-mirror.qa-delete-mirror.rspec-delete-mirror.btn.gl-button.btn-danger{ type: 'button', data: { mirror_id: mirror.id, toggle: 'tooltip', container: 'body' }, title: _('Remove') }= sprite_icon('remove')
+ %button.js-delete-mirror.qa-delete-mirror.rspec-delete-mirror.btn.btn-icon.gl-button.btn-danger{ type: 'button', data: { mirror_id: mirror.id, toggle: 'tooltip', container: 'body' }, title: _('Remove') }= sprite_icon('remove')
diff --git a/app/views/projects/mirrors/_mirror_repos_form.html.haml b/app/views/projects/mirrors/_mirror_repos_form.html.haml
index dd794e03f48..215d0a59d1b 100644
--- a/app/views/projects/mirrors/_mirror_repos_form.html.haml
+++ b/app/views/projects/mirrors/_mirror_repos_form.html.haml
@@ -2,6 +2,6 @@
= label_tag :mirror_direction, _('Mirror direction'), class: 'label-light'
.select-wrapper
= select_tag :mirror_direction, options_for_select([[_('Push'), 'push']]), class: 'form-control select-control js-mirror-direction qa-mirror-direction', disabled: true
- = icon('chevron-down')
+ = sprite_icon('chevron-down', css_class: "gl-icon gl-absolute gl-top-3 gl-right-3 gl-text-gray-200")
= render partial: "projects/mirrors/mirror_repos_push", locals: { f: f }
diff --git a/app/views/projects/mirrors/_ssh_host_keys.html.haml b/app/views/projects/mirrors/_ssh_host_keys.html.haml
index 1690188f07a..4e3cd609d75 100644
--- a/app/views/projects/mirrors/_ssh_host_keys.html.haml
+++ b/app/views/projects/mirrors/_ssh_host_keys.html.haml
@@ -14,7 +14,7 @@
%code= fp.fingerprint
- if verified_at
.form-text.text-muted.js-fingerprint-verification
- %i.fa.fa-check.fingerprint-verified
+ = sprite_icon('check', css_class: 'gl-text-green-500')
Verified by
- if verified_by
= link_to verified_by.name, user_path(verified_by)
diff --git a/app/views/projects/new.html.haml b/app/views/projects/new.html.haml
index d5099f80ea4..f2972a9617b 100644
--- a/app/views/projects/new.html.haml
+++ b/app/views/projects/new.html.haml
@@ -4,7 +4,7 @@
- header_title _("Projects"), dashboard_projects_path
- active_tab = local_assigns.fetch(:active_tab, 'blank')
-.project-edit-container.gl-mt-3
+.project-edit-container.gl-mt-5
.project-edit-errors
= render 'projects/errors'
diff --git a/app/views/projects/no_repo.html.haml b/app/views/projects/no_repo.html.haml
index c44d3da23bb..65c4232b240 100644
--- a/app/views/projects/no_repo.html.haml
+++ b/app/views/projects/no_repo.html.haml
@@ -1,9 +1,10 @@
- breadcrumb_title _("Details")
- page_title _("Details")
-%h2
- %i.fa.fa-warning
- #{ _('No repository') }
+%h2.gl-display-flex
+ .gl-display-flex.gl-align-items-center.gl-justify-content-center
+ = sprite_icon('warning-solid', size: 24, css_class: 'gl-mr-2')
+ = _('No repository')
%p.slead
#{ _('The repository for this project does not exist.') }
@@ -11,6 +12,8 @@
#{ _('This means you can not push code until you create an empty repository or import existing one.') }
%hr
+= render_if_exists 'projects/invite_members_modal', project: @project
+
.no-repo-actions
= link_to project_repository_path(@project), method: :post, class: 'btn btn-primary' do
#{ _('Create empty repository') }
diff --git a/app/views/projects/pages/_ssl_limitations_warning.html.haml b/app/views/projects/pages/_ssl_limitations_warning.html.haml
index 7188e169824..1f2907d183e 100644
--- a/app/views/projects/pages/_ssl_limitations_warning.html.haml
+++ b/app/views/projects/pages/_ssl_limitations_warning.html.haml
@@ -1,5 +1,5 @@
.bs-callout.bs-callout-warning
- %i.fa.fa-warning
+ = sprite_icon("warning-solid", css_class: "gl-text-orange-600")
%strong= _("Warning:")
- pages_host = Gitlab.config.pages.host
= s_("GitLabPages|When using Pages under the general domain of a GitLab instance (%{pages_host}), you cannot use HTTPS with sub-subdomains. This means that if your username/groupname contains a dot it will not work. This is a limitation of the HTTP Over TLS protocol. HTTP pages will continue to work provided you don't redirect HTTP to HTTPS.").html_safe % { pages_host: pages_host }
diff --git a/app/views/projects/pages_domains/_dns.html.haml b/app/views/projects/pages_domains/_dns.html.haml
index 8e2a9c3bab4..dc8127ab068 100644
--- a/app/views/projects/pages_domains/_dns.html.haml
+++ b/app/views/projects/pages_domains/_dns.html.haml
@@ -30,4 +30,4 @@
= 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 to 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.").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 a86637c36b3..9072312c100 100644
--- a/app/views/projects/pages_domains/_lets_encrypt_callout.html.haml
+++ b/app/views/projects/pages_domains/_lets_encrypt_callout.html.haml
@@ -6,7 +6,7 @@
.col-sm-10.offset-sm-2
.bs-callout.bs-callout-warning.mt-0
.row.align-items-center.mx-2
- = icon('warning', class: 'mr-2')
+ = 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: "btn btn-sm btn-grouped btn-warning", method: :post
diff --git a/app/views/projects/pages_domains/show.html.haml b/app/views/projects/pages_domains/show.html.haml
index 20ecf948447..54522a70f4a 100644
--- a/app/views/projects/pages_domains/show.html.haml
+++ b/app/views/projects/pages_domains/show.html.haml
@@ -6,7 +6,7 @@
- if verification_enabled && domain_presenter.unverified?
= content_for :flash_message do
- .alert.alert-warning
+ .gl-alert.gl-alert-warning
.container-fluid.container-limited
= _("This domain is not verified. You will need to verify ownership before access is enabled.")
diff --git a/app/views/projects/pipeline_schedules/_form.html.haml b/app/views/projects/pipeline_schedules/_form.html.haml
index 1a8229350d9..ee0fe43e79c 100644
--- a/app/views/projects/pipeline_schedules/_form.html.haml
+++ b/app/views/projects/pipeline_schedules/_form.html.haml
@@ -39,5 +39,5 @@
= f.check_box :active, required: false, value: @schedule.active?
= f.label :active, _('Active'), class: 'gl-font-weight-normal'
.footer-block.row-content-block
- = f.submit _('Save pipeline schedule'), class: 'btn btn-success', tabindex: 3
+ = f.submit _('Save pipeline schedule'), class: 'btn btn-success'
= link_to _('Cancel'), pipeline_schedules_path(@project), class: 'btn btn-cancel'
diff --git a/app/views/projects/pipeline_schedules/edit.html.haml b/app/views/projects/pipeline_schedules/edit.html.haml
index d95fa6da903..29896500ea1 100644
--- a/app/views/projects/pipeline_schedules/edit.html.haml
+++ b/app/views/projects/pipeline_schedules/edit.html.haml
@@ -1,6 +1,7 @@
- add_to_breadcrumbs _("Schedules"), pipeline_schedules_path(@project)
- breadcrumb_title "##{@schedule.id}"
- page_title _("Edit"), @schedule.description, _("Pipeline Schedule")
+- add_page_specific_style 'page_bundles/pipeline_schedules'
%h3.page-title
= _("Edit Pipeline Schedule %{id}") % { id: @schedule.id }
diff --git a/app/views/projects/pipeline_schedules/index.html.haml b/app/views/projects/pipeline_schedules/index.html.haml
index 91083cc0768..a52a6138402 100644
--- a/app/views/projects/pipeline_schedules/index.html.haml
+++ b/app/views/projects/pipeline_schedules/index.html.haml
@@ -1,8 +1,8 @@
- breadcrumb_title _("Schedules")
-
- page_title _("Pipeline Schedules")
+- add_page_specific_style 'page_bundles/pipeline_schedules'
-#pipeline-schedules-callout{ data: { docs_url: help_page_path('ci/pipelines/schedules'), image_url: image_path('illustrations/pipeline_schedule_callout.svg') } }
+#pipeline-schedules-callout{ data: { docs_url: help_page_path('ci/pipelines/schedules'), illustration_url: image_path('illustrations/pipeline_schedule_callout.svg') } }
.top-area
- schedule_path_proc = ->(scope) { pipeline_schedules_path(@project, scope: scope) }
= render "tabs", schedule_path_proc: schedule_path_proc, all_schedules: @all_schedules, scope: @scope
diff --git a/app/views/projects/pipeline_schedules/new.html.haml b/app/views/projects/pipeline_schedules/new.html.haml
index cfdaf6d43bb..a2652304768 100644
--- a/app/views/projects/pipeline_schedules/new.html.haml
+++ b/app/views/projects/pipeline_schedules/new.html.haml
@@ -1,6 +1,7 @@
- breadcrumb_title "Schedules"
- @breadcrumb_link = namespace_project_pipeline_schedules_path(@project.namespace, @project)
- page_title _("New Pipeline Schedule")
+- add_page_specific_style 'page_bundles/pipeline_schedules'
- add_to_breadcrumbs("Pipelines", project_pipelines_path(@project))
diff --git a/app/views/projects/pipelines/_info.html.haml b/app/views/projects/pipelines/_info.html.haml
index 6d3b3f815e4..f77f22cc555 100644
--- a/app/views/projects/pipelines/_info.html.haml
+++ b/app/views/projects/pipelines/_info.html.haml
@@ -42,7 +42,7 @@
toggle: "popover",
placement: "top",
html: "true",
- trigger: "focus",
+ 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>",
} }
@@ -57,12 +57,7 @@
.well-segment.branch-info
.icon-container.commit-icon
= custom_icon("icon_commit")
- = link_to commit.short_id, project_commit_path(@project, @pipeline.sha), class: "commit-sha js-details-short"
- = link_to("#", class: "js-details-expand d-none d-md-inline") do
- %span.text-expander
- = sprite_icon('ellipsis_h', size: 12)
- %span.js-details-content.hide
- = link_to @pipeline.sha, project_commit_path(@project, @pipeline.sha), class: "commit-sha commit-hash-full"
+ = 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
diff --git a/app/views/projects/pipelines/_with_tabs.html.haml b/app/views/projects/pipelines/_with_tabs.html.haml
index 40a52f76641..8955b568741 100644
--- a/app/views/projects/pipelines/_with_tabs.html.haml
+++ b/app/views/projects/pipelines/_with_tabs.html.haml
@@ -9,7 +9,7 @@
- if dag_pipeline_tab_enabled
%li.js-dag-tab-link
= link_to dag_project_pipeline_path(@project, @pipeline), data: { target: '#js-tab-dag', action: 'dag', toggle: 'tab' }, class: 'dag-tab' do
- = _('DAG')
+ = _('Needs')
%li.js-builds-tab-link
= link_to builds_project_pipeline_path(@project, @pipeline), data: { target: '#js-tab-builds', action: 'builds', toggle: 'tab' }, class: 'builds-tab' do
= _('Jobs')
@@ -81,7 +81,7 @@
- if dag_pipeline_tab_enabled
#js-tab-dag.tab-pane
- #js-pipeline-dag-vue{ data: { pipeline_project_path: @project.full_path, pipeline_iid: @pipeline.iid, empty_svg_path: image_path('illustrations/empty-state/empty-dag-md.svg'), dag_doc_path: help_page_path('ci/yaml/README.md', anchor: 'needs')} }
+ #js-pipeline-dag-vue{ data: { pipeline_project_path: @project.full_path, pipeline_iid: @pipeline.iid, empty_svg_path: image_path('illustrations/empty-state/empty-dag-md.svg'), about_dag_doc_path: help_page_path('ci/directed_acyclic_graph/index.md'), dag_doc_path: help_page_path('ci/yaml/README.md', anchor: 'needs')} }
#js-tab-tests.tab-pane
#js-pipeline-tests-detail{ data: { summary_endpoint: summary_project_pipeline_tests_path(@project, @pipeline, format: :json),
diff --git a/app/views/projects/pipelines/index.html.haml b/app/views/projects/pipelines/index.html.haml
index ca07f33136b..6aa1a564499 100644
--- a/app/views/projects/pipelines/index.html.haml
+++ b/app/views/projects/pipelines/index.html.haml
@@ -1,5 +1,6 @@
- page_title _('Pipelines')
- add_page_specific_style 'page_bundles/pipelines'
+- add_page_specific_style 'page_bundles/ci_status'
= render_if_exists "shared/shared_runners_minutes_limit_flash_message"
diff --git a/app/views/projects/pipelines/new.html.haml b/app/views/projects/pipelines/new.html.haml
index cb5401cd329..bc8e6a6d9cc 100644
--- a/app/views/projects/pipelines/new.html.haml
+++ b/app/views/projects/pipelines/new.html.haml
@@ -6,7 +6,7 @@
= s_('Pipeline|Run Pipeline')
%hr
-- if Feature.enabled?(:new_pipeline_form, @project)
+- if Feature.enabled?(:new_pipeline_form, @project, default_enabled: true)
#js-new-pipeline{ data: { project_id: @project.id,
pipelines_path: project_pipelines_path(@project),
config_variables_path: config_variables_namespace_project_pipelines_path(@project.namespace, @project),
@@ -48,7 +48,7 @@
= (s_("Pipeline|Specify variable values to be used in this run. The values specified in %{settings_link} will be used by default.") % {settings_link: settings_link}).html_safe
.form-actions
- = f.submit s_('Pipeline|Run Pipeline'), class: 'btn btn-success js-variables-save-button', tabindex: 3
+ = f.submit s_('Pipeline|Run Pipeline'), class: 'btn btn-success js-variables-save-button'
= link_to _('Cancel'), project_pipelines_path(@project), class: 'btn btn-default float-right'
%script#availableRefs{ type: "application/json" }= @project.repository.ref_names.to_json.html_safe
diff --git a/app/views/projects/pipelines/show.html.haml b/app/views/projects/pipelines/show.html.haml
index 34f7744f825..0b07fe9921e 100644
--- a/app/views/projects/pipelines/show.html.haml
+++ b/app/views/projects/pipelines/show.html.haml
@@ -4,9 +4,10 @@
- pipeline_has_errors = @pipeline.builds.empty? && @pipeline.yaml_errors.present?
- add_page_specific_style 'page_bundles/pipeline'
- add_page_specific_style 'page_bundles/reports'
+- add_page_specific_style 'page_bundles/ci_status'
.js-pipeline-container{ data: { controller_action: "#{controller.action_name}" } }
- #js-pipeline-header-vue.pipeline-header-container{ data: {full_path: @project.full_path, retry_path: retry_project_pipeline_path(@pipeline.project, @pipeline), cancel_path: cancel_project_pipeline_path(@pipeline.project, @pipeline), delete_path: project_pipeline_path(@pipeline.project, @pipeline), pipeline_iid: @pipeline.iid, pipeline_id: @pipeline.id} }
+ #js-pipeline-header-vue.pipeline-header-container{ data: { full_path: @project.full_path, pipeline_iid: @pipeline.iid, pipeline_id: @pipeline.id, pipelines_path: project_pipelines_path(@project) } }
- if @pipeline.commit.present?
= render "projects/pipelines/info", commit: @pipeline.commit
diff --git a/app/views/projects/project_members/_team.html.haml b/app/views/projects/project_members/_team.html.haml
index 4d4705c4ed5..171212b6a96 100644
--- a/app/views/projects/project_members/_team.html.haml
+++ b/app/views/projects/project_members/_team.html.haml
@@ -1,5 +1,7 @@
- project = local_assigns.fetch(:project)
- members = local_assigns.fetch(:members)
+- group = local_assigns.fetch(:group)
+- current_user_is_group_owner = group && group.has_owner?(current_user)
.card
.card-header.flex-project-members-panel
@@ -14,5 +16,9 @@
= sprite_icon('search', css_class: 'gl-vertical-align-middle!')
= label_tag :sort_by, _('Sort by'), class: 'col-form-label label-bold px-2'
= render 'shared/members/sort_dropdown'
- %ul.content-list.members-list{ data: { qa_selector: 'members_list' } }
- = render partial: 'shared/members/member', collection: members, as: :member
+ %ul.content-list.members-list{ data: { qa_selector: 'members_list', testid: 'members-table' } }
+ = render partial: 'shared/members/member',
+ collection: members, as: :member,
+ locals: { membership_source: project,
+ group: group,
+ current_user_is_group_owner: current_user_is_group_owner }
diff --git a/app/views/projects/project_members/index.html.haml b/app/views/projects/project_members/index.html.haml
index 9a1e997fce7..cad76d7aeac 100644
--- a/app/views/projects/project_members/index.html.haml
+++ b/app/views/projects/project_members/index.html.haml
@@ -1,5 +1,6 @@
- page_title _("Members")
- can_admin_project_members = can?(current_user, :admin_project_member, @project)
+- group = @project.group
.js-remove-member-modal
.row.gl-mt-3
@@ -32,12 +33,12 @@
- elsif @project.allowed_to_share_with_group?
.invite-group= render 'shared/members/invite_group', access_levels: ProjectGroupLink.access_options, default_access_level: ProjectGroupLink.default_access, submit_url: project_group_links_path(@project), group_link_field: 'link_group_id', group_access_field: 'link_group_access'
- = render 'shared/members/requests', membership_source: @project, requesters: @requesters
+ = render 'shared/members/requests', membership_source: @project, group: group, requesters: @requesters
.clearfix
%h5.member.existing-title
= _("Existing members and groups")
- if @group_links.any?
= render 'projects/project_members/groups', group_links: @group_links
- = render 'projects/project_members/team', project: @project, members: @project_members
+ = render 'projects/project_members/team', project: @project, group: group, members: @project_members
= paginate @project_members, theme: "gitlab"
diff --git a/app/views/projects/runners/_runner.html.haml b/app/views/projects/runners/_runner.html.haml
index 74b6e981c00..1a3ba690184 100644
--- a/app/views/projects/runners/_runner.html.haml
+++ b/app/views/projects/runners/_runner.html.haml
@@ -37,8 +37,8 @@
- if runner.description.present?
%p.runner-description
= runner.description
- - if runner.tag_list.present?
+ - if runner.tags.present?
%p
- - runner.tag_list.sort.each do |tag|
+ - runner.tags.map(&:name).sort.each do |tag|
%span.badge.badge-primary
= tag
diff --git a/app/views/projects/runners/_specific_runners.html.haml b/app/views/projects/runners/_specific_runners.html.haml
index 4cc67a8f5d8..e02e2cc784a 100644
--- a/app/views/projects/runners/_specific_runners.html.haml
+++ b/app/views/projects/runners/_specific_runners.html.haml
@@ -9,15 +9,18 @@
= render partial: 'ci/runner/how_to_setup_runner',
locals: { registration_token: @project.runners_token,
type: 'specific',
- reset_token_url: reset_registration_token_namespace_project_settings_ci_cd_path }
+ reset_token_url: reset_registration_token_namespace_project_settings_ci_cd_path,
+ project_path: @project.path_with_namespace,
+ group_path: '' }
- if @project_runners.any?
%h4.underlined-title= _('Runners activated for this project')
%ul.bordered-list.activated-specific-runners
= render partial: 'projects/runners/runner', collection: @project_runners, as: :runner
+ = paginate @project_runners, theme: "gitlab", param_name: "project_page", params: { expand_runners: true, anchor: 'js-runners-settings' }
- if @assignable_runners.any?
%h4.underlined-title= _('Available specific runners')
%ul.bordered-list.available-specific-runners
= render partial: 'projects/runners/runner', collection: @assignable_runners, as: :runner
- = paginate @assignable_runners, theme: "gitlab", :params => { :anchor => '#js-runners-settings' }
+ = paginate @assignable_runners, theme: "gitlab", param_name: "specific_page", :params => { :anchor => 'js-runners-settings'}
diff --git a/app/views/projects/services/prometheus/_metrics.html.haml b/app/views/projects/services/prometheus/_metrics.html.haml
index 732a084d476..4bafd4d06e0 100644
--- a/app/views/projects/services/prometheus/_metrics.html.haml
+++ b/app/views/projects/services/prometheus/_metrics.html.haml
@@ -25,7 +25,8 @@
.card.hidden.js-panel-missing-env-vars
.card-header
- = icon('caret-right lg fw', class: 'panel-toggle js-panel-toggle', 'aria-label' => 'Toggle panel')
+ = sprite_icon('chevron-lg-right', css_class: 'panel-toggle js-panel-toggle-right' )
+ = sprite_icon('chevron-lg-down', css_class: 'panel-toggle js-panel-toggle-down hidden' )
= s_('PrometheusService|Missing environment variable')
%span.badge.badge-pill.js-env-var-count 0
.card-body.hidden
diff --git a/app/views/projects/settings/ci_cd/_form.html.haml b/app/views/projects/settings/ci_cd/_form.html.haml
index 4793e685163..d247e73a5b4 100644
--- a/app/views/projects/settings/ci_cd/_form.html.haml
+++ b/app/views/projects/settings/ci_cd/_form.html.haml
@@ -72,7 +72,7 @@
%li
= _("For public projects, anyone can view pipelines and access job details (output logs and artifacts)")
%li
- = _("For internal projects, any logged in user can view pipelines and access job details (output logs and artifacts)")
+ = _("For internal projects, any logged in user except external users can view pipelines and access job details (output logs and artifacts)")
%li
= _("For private projects, any member (guest or higher) can view pipelines and access job details (output logs and artifacts)")
%p
@@ -120,6 +120,9 @@
pytest-cov (Python) -
%code ^TOTAL.+?(\d+\%)$
%li
+ Scoverage (Scala) -
+ %code Statement coverage[A-Za-z\.*]\s*:\s*([^%]+)
+ %li
phpunit --coverage-text --colors=never (PHP) -
%code ^\s*Lines:\s*\d+.\d+\%
%li
diff --git a/app/views/projects/settings/ci_cd/show.html.haml b/app/views/projects/settings/ci_cd/show.html.haml
index 8e3be5fa086..f6ecb923100 100644
--- a/app/views/projects/settings/ci_cd/show.html.haml
+++ b/app/views/projects/settings/ci_cd/show.html.haml
@@ -33,7 +33,7 @@
= render_if_exists 'projects/settings/ci_cd/protected_environments', expanded: expanded
-%section.settings.no-animate#js-runners-settings{ class: ('expanded' if expanded), data: { qa_selector: 'runners_settings_content' } }
+%section.settings.no-animate#js-runners-settings{ class: ('expanded' if expanded || params[:expand_runners]), data: { qa_selector: 'runners_settings_content' } }
.settings-header
%h4
= _("Runners")
@@ -75,6 +75,8 @@
.settings-content
= render 'projects/registry/settings/index'
+= render_if_exists 'projects/settings/ci_cd/auto_rollback', expanded: expanded
+
- if can?(current_user, :create_freeze_period, @project)
%section.settings.no-animate#js-deploy-freeze-settings{ class: ('expanded' if expanded) }
.settings-header
diff --git a/app/views/projects/settings/operations/_alert_management.html.haml b/app/views/projects/settings/operations/_alert_management.html.haml
index 5c16a5e2758..9e76ad52ecb 100644
--- a/app/views/projects/settings/operations/_alert_management.html.haml
+++ b/app/views/projects/settings/operations/_alert_management.html.haml
@@ -1,5 +1,6 @@
- return unless can?(current_user, :admin_operations, @project)
- expanded = expanded_by_default?
+- add_page_specific_style 'page_bundles/alert_management_settings'
%section.settings.no-animate#js-alert-management-settings{ class: ('expanded' if expanded) }
.settings-header
diff --git a/app/views/projects/settings/operations/_error_tracking.html.haml b/app/views/projects/settings/operations/_error_tracking.html.haml
index 62b344b38f1..6ab8beff99f 100644
--- a/app/views/projects/settings/operations/_error_tracking.html.haml
+++ b/app/views/projects/settings/operations/_error_tracking.html.haml
@@ -1,4 +1,4 @@
-- return unless can?(current_user, :read_environment, @project)
+- return unless can?(current_user, :admin_operations, @project)
- setting = error_tracking_setting
diff --git a/app/views/projects/show.html.haml b/app/views/projects/show.html.haml
index 67bdcd0d9d6..f7c51e9ada9 100644
--- a/app/views/projects/show.html.haml
+++ b/app/views/projects/show.html.haml
@@ -1,5 +1,4 @@
- breadcrumb_title _("Details")
-- page_title _("Projects")
- @content_class = "limit-container-width" unless fluid_layout
= content_for :meta_tags do
diff --git a/app/views/projects/tags/_tag.html.haml b/app/views/projects/tags/_tag.html.haml
index d7231e758c7..7679e0714fe 100644
--- a/app/views/projects/tags/_tag.html.haml
+++ b/app/views/projects/tags/_tag.html.haml
@@ -1,5 +1,6 @@
- commit = @repository.commit(tag.dereferenced_target)
- release = @releases.find { |release| release.tag == tag.name }
+- commit_status = @tag_pipeline_statuses[tag.name] unless @tag_pipeline_statuses.nil?
%li.flex-row.allow-wrap.js-tag-list
.row-main-content
@@ -34,6 +35,12 @@
- if tag.has_signature?
= render partial: 'projects/commit/signature', object: tag.signature
+ - if commit_status
+ = render 'ci/status/icon', size: 24, status: commit_status, option_css_classes: 'gl-display-inline-flex gl-vertical-align-middle gl-mr-5'
+ - elsif @tag_pipeline_statuses && @tag_pipeline_statuses.any?
+ .gl-display-inline-flex.gl-vertical-align-middle.gl-mr-5
+ %svg.s24
+
= render 'projects/buttons/download', project: @project, ref: tag.name, pipeline: @tags_pipelines[tag.name]
- if can?(current_user, :admin_tag, @project)
diff --git a/app/views/projects/terraform/index.html.haml b/app/views/projects/terraform/index.html.haml
new file mode 100644
index 00000000000..136e7ded224
--- /dev/null
+++ b/app/views/projects/terraform/index.html.haml
@@ -0,0 +1,4 @@
+- breadcrumb_title _('Terraform')
+- page_title _('Terraform')
+
+#js-terraform-list{ data: js_terraform_list_data(@project) }
diff --git a/app/views/projects/tree/_tree_header.html.haml b/app/views/projects/tree/_tree_header.html.haml
index dc9fb9e7792..cd6e85d60ed 100644
--- a/app/views/projects/tree/_tree_header.html.haml
+++ b/app/views/projects/tree/_tree_header.html.haml
@@ -13,7 +13,7 @@
= render 'shared/web_ide_button', blob: nil
- if show_xcode_link?(@project)
- .project-action-button.project-xcode.inline<
+ .project-action-button.project-xcode<
= render "projects/buttons/xcode_link"
= render 'projects/buttons/download', project: @project, ref: @ref
diff --git a/app/views/projects/tree/show.html.haml b/app/views/projects/tree/show.html.haml
index 4d8c357cee1..355277b7d41 100644
--- a/app/views/projects/tree/show.html.haml
+++ b/app/views/projects/tree/show.html.haml
@@ -1,5 +1,7 @@
- current_route_path = request.fullpath.match(/-\/tree\/[^\/]+\/(.+$)/).to_a[1]
-- add_page_startup_graphql_call('repository/path_last_commit', { projectPath: @project.full_path, ref: current_ref, path: current_route_path })
+- add_page_startup_graphql_call('repository/path_last_commit', { projectPath: @project.full_path, ref: current_ref, path: current_route_path || "" })
+- add_page_startup_graphql_call('repository/permissions', { projectPath: @project.full_path })
+- add_page_startup_graphql_call('repository/files', { nextPageCursor: "", pageSize: 100, projectPath: @project.full_path, ref: current_ref, path: current_route_path || "/"})
- breadcrumb_title _("Repository")
- @content_class = "limit-container-width" unless fluid_layout
diff --git a/app/views/registrations/welcome.html.haml b/app/views/registrations/welcome/show.html.haml
index bebcc2152af..278c0ff7739 100644
--- a/app/views/registrations/welcome.html.haml
+++ b/app/views/registrations/welcome/show.html.haml
@@ -1,6 +1,6 @@
- page_title _('Your profile')
-.row.gl-flex-grow-1.gl-bg-gray-10
+.row.gl-flex-grow-1
.d-flex.gl-flex-direction-column.gl-align-items-center.gl-w-full.gl-p-5
.edit-profile.login-page.d-flex.flex-column.gl-align-items-center.pt-lg-3
= render_if_exists "registrations/welcome/progress_bar"
@@ -8,7 +8,7 @@
%p
.gl-text-center= html_escape(_('In order to personalize your experience with GitLab%{br_tag}we would like to know a bit more about you.')) % { br_tag: '<br/>'.html_safe }
- = form_for(current_user, url: users_sign_up_update_registration_path, html: { class: 'card gl-w-full! gl-p-5', 'aria-live' => 'assertive' }) do |f|
+ = form_for(current_user, url: users_sign_up_welcome_path, html: { class: 'card gl-w-full! gl-p-5', 'aria-live' => 'assertive' }) do |f|
.devise-errors
= render 'devise/shared/error_messages', resource: current_user
.row
diff --git a/app/views/search/_filter.html.haml b/app/views/search/_filter.html.haml
index e7febd4638b..964a2a2772a 100644
--- a/app/views/search/_filter.html.haml
+++ b/app/views/search/_filter.html.haml
@@ -2,25 +2,14 @@
= hidden_field_tag :group_id, params[:group_id]
- if params[:project_id].present?
= hidden_field_tag :project_id, params[:project_id]
-.dropdown.form-group.mb-lg-0.mx-lg-1{ data: { testid: "group-filter" } }
+.dropdown.form-group.mb-lg-0.mx-lg-1.gl-p-0{ data: { testid: "group-filter" } }
%label.d-block{ for: "dashboard_search_group" }
= _("Group")
- %button.dropdown-menu-toggle.gl-display-inline-flex.js-search-group-dropdown.gl-mt-0{ type: "button", id: "dashboard_search_group", data: { toggle: "dropdown", group_id: params[:group_id] } }
- %span.dropdown-toggle-text.gl-flex-grow-1.str-truncated-100
- = @group&.name || _("Any")
- - if @group.present?
- = link_to sprite_icon("clear"), url_for(safe_params.except(:project_id, :group_id)), class: 'search-clear js-search-clear has-tooltip', title: _('Clear')
- = icon("chevron-down")
- .dropdown-menu.dropdown-select.dropdown-menu-selectable.dropdown-menu-right
- = dropdown_title(_("Filter results by group"))
- = dropdown_filter(_("Search groups"))
- = dropdown_content
- = dropdown_loading
-
-.dropdown.project-filter.form-group.mb-lg-0.mx-lg-1
+ %input#js-search-group-dropdown.dropdown-menu-toggle{ value: "Loading...", data: { "initial-group-data": @group.to_json } }
+.dropdown.form-group.mb-lg-0.mx-lg-1{ data: { testid: "project-filter" } }
%label.d-block{ for: "dashboard_search_project" }
= _("Project")
- %button.dropdown-menu-toggle.gl-display-inline-flex.js-search-project-dropdown.gl-mt-0{ type: "button", id: "dashboard_search_project", data: { toggle: "dropdown", target: '.project-filter' } }
+ %button.dropdown-menu-toggle.gl-display-inline-flex.js-search-project-dropdown.gl-mt-0{ type: "button", id: "dashboard_search_project", data: { toggle: "dropdown" } }
%span.dropdown-toggle-text.gl-flex-grow-1.str-truncated-100
= @project&.full_name || _("Any")
- if @project.present?
diff --git a/app/views/search/_form.html.haml b/app/views/search/_form.html.haml
index c8fa016662f..80973c2b273 100644
--- a/app/views/search/_form.html.haml
+++ b/app/views/search/_form.html.haml
@@ -17,4 +17,4 @@
- unless params[:snippets].eql? 'true'
= render 'filter'
.d-flex-center.flex-column.flex-lg-row
- = button_tag _("Search"), class: "btn btn-success btn-search form-control mt-lg-0 ml-lg-1 align-self-end"
+ = button_tag _("Search"), class: "gl-button btn btn-success btn-search form-control mt-lg-0 ml-lg-1 align-self-end"
diff --git a/app/views/search/_results.html.haml b/app/views/search/_results.html.haml
index 95c378bff7c..855112bdba2 100644
--- a/app/views/search/_results.html.haml
+++ b/app/views/search/_results.html.haml
@@ -1,38 +1,47 @@
- if @search_objects.to_a.empty?
- = render partial: "search/results/filters"
- = render partial: "search/results/empty"
- = render_if_exists 'shared/promotions/promote_advanced_search'
+ .gl-display-md-flex
+ - if %w(issues merge_requests).include?(@scope)
+ #js-search-sidebar.gl-display-flex.gl-flex-direction-column.col-md-3.gl-mr-4{ }
+ .gl-w-full
+ = render partial: "search/results/empty"
+ = render_if_exists 'shared/promotions/promote_advanced_search'
- else
- .row-content-block.d-md-flex.text-left.align-items-center
- - unless @search_objects.is_a?(Kaminari::PaginatableWithoutCount)
- = search_entries_info(@search_objects, @scope, @search_term)
- - unless @show_snippets
- - if @project
- - link_to_project = link_to(@project.full_name, @project, class: 'ml-md-1')
- - if @scope == 'blobs'
- = s_("SearchCodeResults|in")
- .mx-md-1
- = render partial: "shared/ref_switcher", locals: { ref: repository_ref(@project), form_path: request.fullpath, field_name: 'repository_ref' }
- = s_('SearchCodeResults|of %{link_to_project}').html_safe % { link_to_project: link_to_project }
- - else
- = _("in project %{link_to_project}").html_safe % { link_to_project: link_to_project }
- - elsif @group
- - link_to_group = link_to(@group.name, @group, class: 'ml-md-1')
- = _("in group %{link_to_group}").html_safe % { link_to_group: link_to_group }
+ .search-results-status
+ .row-content-block.gl-display-flex
+ .gl-display-md-flex.gl-text-left.gl-align-items-center.gl-flex-grow-1
+ - unless @search_objects.is_a?(Kaminari::PaginatableWithoutCount)
+ = search_entries_info(@search_objects, @scope, @search_term)
+ - unless @show_snippets
+ - if @project
+ - link_to_project = link_to(@project.full_name, @project, class: 'ml-md-1')
+ - if @scope == 'blobs'
+ = s_("SearchCodeResults|in")
+ .mx-md-1
+ = render partial: "shared/ref_switcher", locals: { ref: repository_ref(@project), form_path: request.fullpath, field_name: 'repository_ref' }
+ = s_('SearchCodeResults|of %{link_to_project}').html_safe % { link_to_project: link_to_project }
+ - else
+ = _("in project %{link_to_project}").html_safe % { link_to_project: link_to_project }
+ - elsif @group
+ - link_to_group = link_to(@group.name, @group, class: 'ml-md-1')
+ = _("in group %{link_to_group}").html_safe % { link_to_group: link_to_group }
+ .gl-display-md-flex.gl-flex-direction-column
+ = render partial: 'search/sort_dropdown'
= render_if_exists 'shared/promotions/promote_advanced_search'
- = render partial: "search/results/filters"
- .results.gl-mt-3
- - if @scope == 'commits'
- %ul.content-list.commit-list
- = render partial: "search/results/commit", collection: @search_objects
- - else
- .search-results
- - if @scope == 'projects'
- .term
- = render 'shared/projects/list', projects: @search_objects, pipeline_status: false
- - else
- = render_if_exists partial: "search/results/#{@scope.singularize}", collection: @search_objects
+ .results.gl-display-md-flex.gl-mt-3
+ - if %w(issues merge_requests).include?(@scope)
+ #js-search-sidebar.gl-display-flex.gl-flex-direction-column.col-md-3.gl-mr-4{ }
+ .gl-w-full
+ - if @scope == 'commits'
+ %ul.content-list.commit-list
+ = render partial: "search/results/commit", collection: @search_objects
+ - else
+ .search-results
+ - if @scope == 'projects'
+ .term
+ = render 'shared/projects/list', projects: @search_objects, pipeline_status: false
+ - else
+ = render_if_exists partial: "search/results/#{@scope.singularize}", collection: @search_objects
- - if @scope != 'projects'
- = paginate_collection(@search_objects)
+ - if @scope != 'projects'
+ = paginate_collection(@search_objects)
diff --git a/app/views/search/_sort_dropdown.html.haml b/app/views/search/_sort_dropdown.html.haml
new file mode 100644
index 00000000000..085e2f348f7
--- /dev/null
+++ b/app/views/search/_sort_dropdown.html.haml
@@ -0,0 +1,16 @@
+- return unless ['issues', 'merge_requests'].include?(@scope)
+
+- sort_value = @sort
+- sort_title = search_sort_option_title(sort_value)
+
+.dropdown.gl-display-inline-block.gl-ml-3.filter-dropdown-container
+ .btn-group{ role: 'group' }
+ .btn-group{ role: 'group' }
+ %button.dropdown-menu-toggle{ type: 'button', data: { toggle: 'dropdown', display: 'static' }, class: 'btn btn-default' }
+ = sort_title
+ = icon('chevron-down')
+ %ul.dropdown-menu.dropdown-menu-right.dropdown-menu-selectable.dropdown-menu-sort
+ %li
+ = render_if_exists('search/sort_by_relevancy', sort_title: sort_title)
+ = sortable_item(sort_title_recently_created, page_filter_path(sort: sort_value_recently_created), sort_title)
+ = search_sort_direction_button(sort_value)
diff --git a/app/views/search/results/_blob_data.html.haml b/app/views/search/results/_blob_data.html.haml
index d873a15d051..16d640273b0 100644
--- a/app/views/search/results/_blob_data.html.haml
+++ b/app/views/search/results/_blob_data.html.haml
@@ -7,4 +7,4 @@
= search_blob_title(project, path)
- if blob.data
.file-content.code.term{ data: { qa_selector: 'file_text_content' } }
- = render 'shared/file_highlight', blob: blob, first_line_number: blob.startline, blob_link: blob_link
+ = render 'shared/file_highlight', blob: blob, first_line_number: blob.startline, blob_link: blob_link, highlight_line: blob.highlight_line
diff --git a/app/views/search/results/_empty.html.haml b/app/views/search/results/_empty.html.haml
index 3cd1c901f8e..0462c29f5c1 100644
--- a/app/views/search/results/_empty.html.haml
+++ b/app/views/search/results/_empty.html.haml
@@ -1,5 +1,5 @@
-.search_box
+.search_box.gl-my-8
.search_glyph
%h4
= sprite_icon('search', size: 24, css_class: 'gl-vertical-align-text-bottom')
- = search_entries_empty_message(@scope, @search_term)
+ = search_entries_empty_message(@scope, @search_term, @group, @project)
diff --git a/app/views/search/results/_filters.html.haml b/app/views/search/results/_filters.html.haml
deleted file mode 100644
index 632d3dfd58c..00000000000
--- a/app/views/search/results/_filters.html.haml
+++ /dev/null
@@ -1,7 +0,0 @@
-.d-lg-flex.align-items-end
- #js-search-filter-by-state{ 'v-cloak': true }
- - if Feature.enabled?(:search_filter_by_confidential, @group)
- #js-search-filter-by-confidential{ 'v-cloak': true }
-
- - if %w(issues merge_requests).include?(@scope)
- %hr.gl-mt-4.gl-mb-4
diff --git a/app/views/search/results/_issuable.html.haml b/app/views/search/results/_issuable.html.haml
new file mode 100644
index 00000000000..288ac53a954
--- /dev/null
+++ b/app/views/search/results/_issuable.html.haml
@@ -0,0 +1,10 @@
+%div{ class: 'search-result-row gl-pb-3! gl-mt-5 gl-mb-0!' }
+ %span.gl-display-flex.gl-align-items-center
+ %span.badge.badge-pill.gl-badge.sm{ class: "badge-#{issuable_state_to_badge_class(issuable)}" }= issuable_state_text(issuable)
+ = sprite_icon('eye-slash', css_class: 'gl-text-gray-500 gl-ml-2') if issuable.respond_to?(:confidential?) && issuable.confidential?
+ = link_to issuable_path(issuable), data: { track_event: 'click_text', track_label: "#{issuable.class.name.downcase}_title", track_property: 'search_result' }, class: 'gl-w-full' do
+ %span.term.str-truncated.gl-font-weight-bold.gl-ml-2= issuable.title
+ .gl-text-gray-500.gl-my-3
+ = sprintf(s_(' %{project_name}#%{issuable_iid} &middot; opened %{issuable_created} by %{author}'), { project_name: issuable.project.full_name, issuable_iid: issuable.iid, issuable_created: time_ago_with_tooltip(issuable.created_at, placement: 'bottom'), author: link_to_member(@project, issuable.author, avatar: false) }).html_safe
+ .description.term.col-sm-10.gl-px-0
+ = highlight_and_truncate_issuable(issuable, @search_term, @search_highlight)
diff --git a/app/views/search/results/_issue.html.haml b/app/views/search/results/_issue.html.haml
index a101e60f297..6fb463b75fc 100644
--- a/app/views/search/results/_issue.html.haml
+++ b/app/views/search/results/_issue.html.haml
@@ -1,13 +1 @@
-%div{ class: 'search-result-row gl-pb-3! gl-mt-5 gl-mb-0!' }
- %span.gl-display-flex.gl-align-items-center
- - if issue.closed?
- %span.badge.badge-info.badge-pill.gl-badge.sm= _("Closed")
- - else
- %span.badge.badge-success.badge-pill.gl-badge.sm= _("Open")
- = sprite_icon('eye-slash', css_class: 'gl-text-gray-500 gl-ml-2') if issue.confidential?
- = link_to project_issue_path(issue.project, issue), data: { track_event: 'click_text', track_label: 'issue_title', track_property: 'search_result' }, class: 'gl-w-full' do
- %span.term.str-truncated.gl-font-weight-bold.gl-ml-2= issue.title
- .gl-text-gray-500.gl-my-3
- = sprintf(s_(' %{project_name}#%{issue_iid} &middot; opened %{issue_created} by %{author}'), { project_name: issue.project.full_name, issue_iid: issue.iid, issue_created: time_ago_with_tooltip(issue.created_at, placement: 'bottom'), author: link_to_member(@project, issue.author, avatar: false) }).html_safe
- .description.term.col-sm-10.gl-px-0
- = highlight_and_truncate_issue(issue, @search_term, @search_highlight)
+= render partial: 'search/results/issuable', object: issue
diff --git a/app/views/search/results/_merge_request.html.haml b/app/views/search/results/_merge_request.html.haml
index 3135ab9a17e..b2b067bcf68 100644
--- a/app/views/search/results/_merge_request.html.haml
+++ b/app/views/search/results/_merge_request.html.haml
@@ -1,14 +1 @@
-.search-result-row
- %h4
- = link_to project_merge_request_path(merge_request.target_project, merge_request), data: {track_event: 'click_text', track_label: 'merge_request_title', track_property: 'search_result'} do
- %span.term.str-truncated= merge_request.title
- - if merge_request.merged?
- %span.badge.badge-primary.gl-ml-2= _("Merged")
- - elsif merge_request.closed?
- %span.badge.badge-danger.gl-ml-2= _("Closed")
- .float-right= merge_request.to_reference
- - if merge_request.description.present?
- .description.term
- = search_md_sanitize(merge_request.description)
- %span.light
- #{merge_request.project.full_name}
+= render partial: 'search/results/issuable', object: merge_request
diff --git a/app/views/search/results/_wiki_blob.html.haml b/app/views/search/results/_wiki_blob.html.haml
index 3040917dd6e..55161ce333b 100644
--- a/app/views/search/results/_wiki_blob.html.haml
+++ b/app/views/search/results/_wiki_blob.html.haml
@@ -1,4 +1,9 @@
- project = wiki_blob.project
- wiki_blob_link = project_wiki_path(project, wiki_blob.basename)
-= render partial: 'search/results/blob_data', locals: { blob: wiki_blob, project: project, path: wiki_blob.path, blob_link: wiki_blob_link }
+%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_event: 'click_text', track_label: "wiki_title", track_property: 'search_result' }, class: 'gl-w-full' do
+ %span.term.str-truncated.gl-font-weight-bold= ::Gitlab::Git::Wiki::GollumSlug.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 2ad29707c9f..a286693e2b6 100644
--- a/app/views/sent_notifications/unsubscribe.html.haml
+++ b/app/views/sent_notifications/unsubscribe.html.haml
@@ -15,5 +15,5 @@
%p
= link_to _('Unsubscribe'), unsubscribe_sent_notification_path(@sent_notification, force: true),
- class: 'btn btn-primary gl-mr-3'
- = link_to _('Cancel'), new_user_session_path, class: 'btn gl-mr-3'
+ class: 'gl-button btn btn-primary gl-mr-3'
+ = link_to _('Cancel'), new_user_session_path, class: 'gl-button btn gl-mr-3'
diff --git a/app/views/shared/_broadcast_message.html.haml b/app/views/shared/_broadcast_message.html.haml
index 7be11b0fb81..7aaae3a88f3 100644
--- a/app/views/shared/_broadcast_message.html.haml
+++ b/app/views/shared/_broadcast_message.html.haml
@@ -8,5 +8,5 @@
= render_broadcast_message(message)
.gl-flex-grow-1.gl-flex-basis-0.gl-text-right
- if (message.notification? || message.dismissable?) && opts[:preview].blank?
- %button.broadcast-message-dismiss.js-dismiss-current-broadcast-notification.btn.btn-link.gl-button{ 'aria-label' => _('Close'), :type => 'button', data: { id: message.id, expire_date: message.ends_at.iso8601 } }
- = sprite_icon('close', size: 16, css_class: 'gl-icon gl-text-white gl-mx-3!')
+ %button.js-dismiss-current-broadcast-notification.btn.btn-link.gl-button{ 'aria-label' => _('Close'), :type => 'button', data: { id: message.id, expire_date: message.ends_at.iso8601 } }
+ = sprite_icon('close', size: 16, css_class: "gl-icon gl-mx-3! #{is_banner ? 'gl-text-white' : 'gl-text-gray-700'}")
diff --git a/app/views/shared/_file_highlight.html.haml b/app/views/shared/_file_highlight.html.haml
index 7d328728332..b1f53e4d0f6 100644
--- a/app/views/shared/_file_highlight.html.haml
+++ b/app/views/shared/_file_highlight.html.haml
@@ -1,16 +1,17 @@
#blob-content.file-content.code.js-syntax-highlight
+ - offset = defined?(first_line_number) ? first_line_number : 1
.line-numbers
- if blob.data.present?
- link_icon = sprite_icon('link', size: 12)
- link = blob_link if defined?(blob_link)
- blob.data.each_line.each_with_index do |_, index|
- - offset = defined?(first_line_number) ? first_line_number : 1
- i = index + offset
-# We're not using `link_to` because it is too slow once we get to thousands of lines.
%a.diff-line-num{ href: "#{link}#L#{i}", id: "L#{i}", 'data-line-number' => i }
= link_icon
= i
- .blob-content{ data: { blob_id: blob.id, path: blob.path } }
+ - highlight = defined?(highlight_line) && highlight_line ? highlight_line - offset : nil
+ .blob-content{ data: { blob_id: blob.id, path: blob.path, highlight_line: highlight, qa_selector: 'file_content' } }
%pre.code.highlight
%code
= blob.present.highlight
diff --git a/app/views/shared/_issuable_meta_data.html.haml b/app/views/shared/_issuable_meta_data.html.haml
index f21ec45eefb..352d51dbb8e 100644
--- a/app/views/shared/_issuable_meta_data.html.haml
+++ b/app/views/shared/_issuable_meta_data.html.haml
@@ -6,7 +6,7 @@
- if issuable_mr > 0
%li.issuable-mr.gl-display-none.gl-display-sm-block.has-tooltip{ title: _('Related merge requests') }
- = image_tag('icon-merge-request-unmerged.svg', class: 'icon-merge-request-unmerged')
+ = sprite_icon('merge-request', css_class: "gl-vertical-align-middle")
= issuable_mr
- if upvotes > 0
diff --git a/app/views/shared/_label.html.haml b/app/views/shared/_label.html.haml
index 1dadb4384b9..4b09e8de896 100644
--- a/app/views/shared/_label.html.haml
+++ b/app/views/shared/_label.html.haml
@@ -34,10 +34,7 @@
label_title: label.title,
label_color: label.color,
label_text_color: label.text_color,
- group_name: label.project.group.name,
- target: '#promote-label-modal',
- container: 'body',
- toggle: 'modal' } }
+ group_name: label.project.group.name } }
= _('Promote to group label')
- if can?(current_user, :admin_label, label)
%li
diff --git a/app/views/shared/_label_row.html.haml b/app/views/shared/_label_row.html.haml
index 9c9ac5f7b2c..252f9c26f06 100644
--- a/app/views/shared/_label_row.html.haml
+++ b/app/views/shared/_label_row.html.haml
@@ -5,9 +5,9 @@
.label-name.gl-flex-shrink-0.gl-mt-2.gl-mr-3
= render_label(label, tooltip: false)
-.label-description.gl-flex-grow-1.gl-overflow-hidden
- .gl-display-flex.gl-align-items-center.gl-flex-wrap.gl-mt-2
- .description-text.gl-flex-grow-1.gl-overflow-hidden
+.label-description.gl-overflow-hidden.gl-w-full
+ .gl-display-flex.gl-align-items-stretch.gl-flex-wrap.gl-mt-2
+ .gl-flex-basis-half.gl-flex-grow-1.gl-overflow-hidden.gl-mr-2
- if label.description.present?
= markdown_field(label, :description)
- elsif show_labels_full_path?(@project, @group)
diff --git a/app/views/shared/_ping_consent.html.haml b/app/views/shared/_ping_consent.html.haml
index ded9b55056a..d0f1e4d7221 100644
--- a/app/views/shared/_ping_consent.html.haml
+++ b/app/views/shared/_ping_consent.html.haml
@@ -1,12 +1,14 @@
- if session[:ask_for_usage_stats_consent]
- .ping-consent-message.alert.alert-warning.flex-alert
- - settings_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer" class="alert-link">'.html_safe % { url: metrics_and_profiling_admin_application_settings_path(anchor: 'js-usage-settings') }
- - info_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer" class="alert-link">'.html_safe % { url: help_page_path('user/admin_area/settings/usage_statistics.md') }
- .alert-message
- = s_('To help improve GitLab, we would like to periodically collect usage information. This can be changed at any time in %{settings_link_start}Settings%{link_end}. %{info_link_start}More Information%{link_end}').html_safe % { settings_link_start: settings_link_start, info_link_start: info_link_start, link_end: '</a>'.html_safe }
- .alert-link-group
+ .ping-consent-message.gl-alert.gl-alert-info
+ = sprite_icon('information-o', css_class: 'gl-icon gl-alert-icon gl-alert-icon-no-title')
+ %button.js-close.gl-alert-dismiss{ type: 'button', 'aria-label' => _('Dismiss') }
+ = sprite_icon('close', css_class: 'gl-icon')
+ .gl-alert-body
+ - docs_link = link_to _('collect usage information'), help_page_path('user/admin_area/settings/usage_statistics.md'), class: 'gl-link'
+ - settings_link = link_to _('your settings'), metrics_and_profiling_admin_application_settings_path(anchor: 'js-usage-settings'), class: 'gl-link'
+ = s_('To help improve GitLab, we would like to periodically %{docs_link}. This can be changed at any time in %{settings_link}.').html_safe % { docs_link: docs_link, settings_link: settings_link }
+ .gl-alert-actions.gl-mt-3
- send_usage_data_path = admin_application_settings_path(application_setting: { version_check_enabled: 1, usage_ping_enabled: 1 })
- not_now_path = admin_application_settings_path(application_setting: { version_check_enabled: 0, usage_ping_enabled: 0 })
- = link_to _("Send usage data"), send_usage_data_path, 'data-url' => admin_application_settings_path, method: :put, 'data-check-enabled': true, 'data-ping-enabled': true, class: 'alert-link js-usage-consent-action'
- |
- = link_to _('Not now'), not_now_path, 'data-url' => admin_application_settings_path, method: :put, 'data-check-enabled': false, 'data-ping-enabled': false, class: 'hide-ping-consent-message alert-link js-usage-consent-action'
+ = link_to _("Send usage data"), send_usage_data_path, 'data-url' => admin_application_settings_path, method: :put, 'data-check-enabled': true, 'data-ping-enabled': true, class: 'js-usage-consent-action alert-link btn gl-button btn-info'
+ = link_to _("Don't send usage data"), not_now_path, 'data-url' => admin_application_settings_path, method: :put, 'data-check-enabled': false, 'data-ping-enabled': false, class: 'js-usage-consent-action alert-link btn gl-button btn-default gl-ml-2'
diff --git a/app/views/shared/_remote_mirror_update_button.html.haml b/app/views/shared/_remote_mirror_update_button.html.haml
index 54bd4ba04a0..70b72f74ab3 100644
--- a/app/views/shared/_remote_mirror_update_button.html.haml
+++ b/app/views/shared/_remote_mirror_update_button.html.haml
@@ -1,6 +1,6 @@
- if remote_mirror.update_in_progress?
- %button.btn.disabled{ type: 'button', data: { toggle: 'tooltip', container: 'body', qa_selector: 'updating_button' }, title: _('Updating') }
- = icon("refresh spin")
+ %button.btn.btn-icon.gl-button.disabled{ type: 'button', data: { toggle: 'tooltip', container: 'body', qa_selector: 'updating_button' }, title: _('Updating') }
+ = sprite_icon("retry", css_class: "spin")
- elsif remote_mirror.enabled?
- = link_to update_now_project_mirror_path(@project, sync_remote: true), method: :post, class: "btn qa-update-now-button rspec-update-now-button", data: { toggle: 'tooltip', container: 'body' }, title: _('Update now') do
- = icon("refresh")
+ = link_to update_now_project_mirror_path(@project, sync_remote: true), method: :post, class: "btn btn-icon gl-button qa-update-now-button rspec-update-now-button", data: { toggle: 'tooltip', container: 'body' }, title: _('Update now') do
+ = sprite_icon("retry")
diff --git a/app/views/shared/access_tokens/_form.html.haml b/app/views/shared/access_tokens/_form.html.haml
index 820a6cbd15d..f206a2152c2 100644
--- a/app/views/shared/access_tokens/_form.html.haml
+++ b/app/views/shared/access_tokens/_form.html.haml
@@ -13,7 +13,7 @@
.row
.form-group.col-md-6
= f.label :name, _('Name'), class: 'label-bold'
- = f.text_field :name, class: 'form-control', required: true, data: { qa_selector: 'access_token_name_field' }
+ = f.text_field :name, class: 'form-control gl-form-input', required: true, data: { qa_selector: 'access_token_name_field' }
.row
.form-group.col-md-6
@@ -23,8 +23,7 @@
= render_if_exists 'personal_access_tokens/callout_max_personal_access_token_lifetime'
.js-access-tokens-expires-at
- %expires-at-field
- = f.text_field :expires_at, class: 'datepicker form-control gl-datepicker-input', placeholder: 'YYYY-MM-DD', autocomplete: 'off', inputmode: 'none', data: { qa_selector: 'expiry_date_field' }
+ = f.text_field :expires_at, class: 'datepicker gl-datepicker-input form-control gl-form-input', placeholder: 'YYYY-MM-DD', autocomplete: 'off'
.form-group
= f.label :scopes, _('Scopes'), class: 'label-bold'
diff --git a/app/views/shared/boards/_show.html.haml b/app/views/shared/boards/_show.html.haml
index c3137120034..ce48691166b 100644
--- a/app/views/shared/boards/_show.html.haml
+++ b/app/views/shared/boards/_show.html.haml
@@ -15,10 +15,9 @@
%script#js-board-modal-filter{ type: "text/x-template" }= render "shared/issuable/search_bar", type: :boards_modal, show_sorting_dropdown: false
%script#js-board-promotion{ type: "text/x-template" }= render_if_exists "shared/promotions/promote_issue_board"
+= render 'shared/issuable/search_bar', type: :boards, board: board
#board-app.boards-app.position-relative{ "v-cloak" => "true", data: board_data, ":class" => "{ 'is-compact': detailIssueVisible }" }
- = render 'shared/issuable/search_bar', type: :boards, board: board
-
- - if Feature.enabled?(:boards_with_swimlanes, current_board_parent) || Feature.enabled?(:graphql_board_lists, current_board_parent)
+ - if Feature.enabled?(:boards_with_swimlanes, current_board_parent, default_enabled: true) || Feature.enabled?(:graphql_board_lists, current_board_parent)
%board-content{ "v-cloak" => "true",
"ref" => "board_content",
":lists" => "state.lists",
diff --git a/app/views/shared/boards/components/sidebar/_assignee.html.haml b/app/views/shared/boards/components/sidebar/_assignee.html.haml
index af6a519a967..e22a7807b3b 100644
--- a/app/views/shared/boards/components/sidebar/_assignee.html.haml
+++ b/app/views/shared/boards/components/sidebar/_assignee.html.haml
@@ -23,7 +23,7 @@
%button.dropdown-menu-toggle.js-user-search.js-author-search.js-multiselect.js-save-user-data.js-issue-board-sidebar{ type: 'button', ref: 'assigneeDropdown', data: board_sidebar_user_data,
":data-issuable-id" => "issue.iid" }
= dropdown_options[:title]
- = icon("chevron-down")
+ = sprite_icon('chevron-down', css_class: "dropdown-menu-toggle-icon gl-top-3")
.dropdown-menu.dropdown-select.dropdown-menu-user.dropdown-menu-selectable.dropdown-menu-author
= dropdown_title("Assign to")
= dropdown_filter("Search users")
diff --git a/app/views/shared/boards/components/sidebar/_due_date.html.haml b/app/views/shared/boards/components/sidebar/_due_date.html.haml
index d8ed3b13bf1..ab4d22ac03d 100644
--- a/app/views/shared/boards/components/sidebar/_due_date.html.haml
+++ b/app/views/shared/boards/components/sidebar/_due_date.html.haml
@@ -24,7 +24,7 @@
%button.dropdown-menu-toggle.js-due-date-select.js-issue-boards-due-date{ type: 'button',
data: { toggle: 'dropdown', field_name: "issue[due_date]", ability_name: "issue" } }
%span.dropdown-toggle-text= _("Due date")
- = icon('chevron-down')
+ = sprite_icon('chevron-down', css_class: "dropdown-menu-toggle-icon gl-top-3")
.dropdown-menu.dropdown-menu-due-date
= dropdown_title(_('Due date'))
= dropdown_content do
diff --git a/app/views/shared/boards/components/sidebar/_labels.html.haml b/app/views/shared/boards/components/sidebar/_labels.html.haml
index 61f3ebcdba4..5af52d4de23 100644
--- a/app/views/shared/boards/components/sidebar/_labels.html.haml
+++ b/app/views/shared/boards/components/sidebar/_labels.html.haml
@@ -27,7 +27,7 @@
data: label_dropdown_data(@project, namespace_path: @namespace_path, field_name: "issue[label_names][]") }
%span.dropdown-toggle-text
{{ labelDropdownTitle }}
- = icon('chevron-down')
+ = sprite_icon('chevron-down', css_class: "dropdown-menu-toggle-icon gl-top-3")
.dropdown-menu.dropdown-select.dropdown-menu-paging.dropdown-menu-labels.dropdown-menu-selectable.dropdown-extended-height
= render partial: "shared/issuable/label_page_default"
- if can?(current_user, :admin_label, current_board_parent)
diff --git a/app/views/shared/boards/components/sidebar/_milestone.html.haml b/app/views/shared/boards/components/sidebar/_milestone.html.haml
index 2c894e9b1b3..6143f1d5afe 100644
--- a/app/views/shared/boards/components/sidebar/_milestone.html.haml
+++ b/app/views/shared/boards/components/sidebar/_milestone.html.haml
@@ -21,7 +21,7 @@
":data-issuable-id" => "issue.iid",
":data-project-id" => "issue.project_id" }
= _("Milestone")
- = icon("chevron-down")
+ = sprite_icon('chevron-down', css_class: "dropdown-menu-toggle-icon gl-top-3")
.dropdown-menu.dropdown-select.dropdown-menu-selectable
= dropdown_title(_("Assign milestone"))
= dropdown_filter(_("Search milestones"))
diff --git a/app/views/shared/form_elements/_apply_template_warning.html.haml b/app/views/shared/form_elements/_apply_template_warning.html.haml
index b1edfba6df4..73be0c741dc 100644
--- a/app/views/shared/form_elements/_apply_template_warning.html.haml
+++ b/app/views/shared/form_elements/_apply_template_warning.html.haml
@@ -1,6 +1,5 @@
-.form-group.row.js-template-warning.mb-0.hidden.js-issuable-template-warning{ :class => ("gl-mb-5!" if issuable.supports_issue_type? && can?(current_user, :admin_issue, @project)) }
- .offset-sm-2.col-sm-10
-
+.form-group.row.js-template-warning.hidden.js-issuable-template-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")
diff --git a/app/views/shared/form_elements/_description.html.haml b/app/views/shared/form_elements/_description.html.haml
index 413df29da77..7f4aed5d1f7 100644
--- a/app/views/shared/form_elements/_description.html.haml
+++ b/app/views/shared/form_elements/_description.html.haml
@@ -14,6 +14,9 @@
- if model.is_a?(Issuable)
= render 'shared/issuable/form/template_selector', issuable: model
+
+ = render 'shared/form_elements/apply_template_warning', issuable: model
+
= render layout: 'shared/md_preview', locals: { url: preview_url, referenced_users: true } do
= render 'shared/zen', f: form, attr: :description,
classes: 'note-textarea qa-issuable-form-description rspec-issuable-form-description',
diff --git a/app/views/shared/groups/_empty_state.html.haml b/app/views/shared/groups/_empty_state.html.haml
index f6b3a49eacb..1d3bc1d6959 100644
--- a/app/views/shared/groups/_empty_state.html.haml
+++ b/app/views/shared/groups/_empty_state.html.haml
@@ -1,8 +1,13 @@
-.group-empty-state.row.align-items-center.justify-content-center
- .icon.text-center.order-md-2
+.row.gl-align-items-center.gl-justify-content-center
+ .order-md-2
= custom_icon("icon_empty_groups")
- .text-content.m-0.order-md-1
+ .text-content.order-md-1{ class: 'gl-m-0!' }
%h4= s_("GroupsEmptyState|A group is a collection of several projects.")
%p= s_("GroupsEmptyState|If you organize your projects under a group, it works like a folder.")
%p= s_("GroupsEmptyState|You can manage your group member’s permissions and access to each project in the group.")
+ - if invite_group_members?(@group)
+ = link_to _('Invite your team'),
+ group_group_members_path(@group),
+ class: 'gl-button btn btn-success-secondary',
+ data: { track_event: 'click_invite_team_group_empty_state', track_label: 'invite_team_group_empty_state' }
diff --git a/app/views/shared/groups/_search_form.html.haml b/app/views/shared/groups/_search_form.html.haml
index 49b812baefc..a574394694d 100644
--- a/app/views/shared/groups/_search_form.html.haml
+++ b/app/views/shared/groups/_search_form.html.haml
@@ -1,2 +1,2 @@
= form_tag request.path, method: :get, class: "group-filter-form js-group-filter-form", id: 'group-filter-form' do |f|
- = search_field_tag :filter, params[:filter], placeholder: s_('GroupsTree|Search by name'), class: 'group-filter-form-field form-control js-groups-list-filter qa-groups-filter', spellcheck: false, id: 'group-filter-form-field', tabindex: "2"
+ = search_field_tag :filter, params[:filter], placeholder: s_('GroupsTree|Search by name'), class: 'group-filter-form-field form-control js-groups-list-filter qa-groups-filter', spellcheck: false, id: 'group-filter-form-field'
diff --git a/app/views/shared/issuable/_close_reopen_button.html.haml b/app/views/shared/issuable/_close_reopen_button.html.haml
index 8365bc6f863..3453db9f209 100644
--- a/app/views/shared/issuable/_close_reopen_button.html.haml
+++ b/app/views/shared/issuable/_close_reopen_button.html.haml
@@ -21,5 +21,6 @@
- else
= render 'shared/issuable/close_reopen_report_toggle', issuable: issuable, warn_before_close: add_blocked_class
- else
- = link_to _('Report abuse'), new_abuse_report_path(user_id: issuable.author.id, ref_url: issuable_url(issuable)),
- class: 'd-none d-md-block btn btn-grouped btn-close-color', title: _('Report abuse')
+ - unless issuable.is_a?(MergeRequest) && issuable.merged?
+ = link_to _('Report abuse'), new_abuse_report_path(user_id: issuable.author.id, ref_url: issuable_url(issuable)),
+ class: 'd-none d-md-block btn btn-grouped btn-close-color', title: _('Report abuse')
diff --git a/app/views/shared/issuable/_close_reopen_report_toggle.html.haml b/app/views/shared/issuable/_close_reopen_report_toggle.html.haml
index df441e6d0af..48d1e146629 100644
--- a/app/views/shared/issuable/_close_reopen_report_toggle.html.haml
+++ b/app/views/shared/issuable/_close_reopen_report_toggle.html.haml
@@ -21,7 +21,7 @@
data: { text: _("Close %{display_issuable_type}") % { display_issuable_type: display_issuable_type }, url: close_issuable_path(issuable),
button_class: "#{button_class} btn-close", toggle_class: "#{toggle_class} btn-close-color" } }
%button.btn.btn-transparent
- = icon('check', class: 'icon')
+ = sprite_icon('check', css_class: 'icon')
.description
%strong.title
= _('Close')
@@ -31,7 +31,7 @@
data: { text: _("Reopen %{display_issuable_type}") % { display_issuable_type: display_issuable_type }, url: reopen_issuable_path(issuable),
button_class: "#{button_class} btn-reopen", toggle_class: "#{toggle_class} btn-reopen-color" } }
%button.btn.btn-transparent
- = icon('check', class: 'icon')
+ = sprite_icon('check', css_class: 'icon')
.description
%strong.title
= _('Reopen')
diff --git a/app/views/shared/issuable/_form.html.haml b/app/views/shared/issuable/_form.html.haml
index 728b527f499..c0aba0eef7f 100644
--- a/app/views/shared/issuable/_form.html.haml
+++ b/app/views/shared/issuable/_form.html.haml
@@ -20,8 +20,6 @@
= render 'shared/issuable/form/title', issuable: issuable, form: form, has_wip_commits: commits && commits.detect(&:work_in_progress?)
#js-suggestions{ data: { project_path: @project.full_path } }
-= render 'shared/form_elements/apply_template_warning', issuable: issuable
-
= render 'shared/issuable/form/type_selector', issuable: issuable, form: form
= render 'shared/form_elements/description', model: issuable, form: form, project: project
diff --git a/app/views/shared/issuable/_label_dropdown.html.haml b/app/views/shared/issuable/_label_dropdown.html.haml
index 535af522c1a..08883bb3372 100644
--- a/app/views/shared/issuable/_label_dropdown.html.haml
+++ b/app/views/shared/issuable/_label_dropdown.html.haml
@@ -26,7 +26,7 @@
- apply_is_default_styles = (selected.nil? || selected.empty?) && !no_default_styles
%span.dropdown-toggle-text{ class: ("is-default" if apply_is_default_styles) }
= multi_label_name(selected, label_name)
- = icon('chevron-down')
+ = sprite_icon('chevron-down', css_class: "dropdown-menu-toggle-icon gl-top-3")
.dropdown-menu.dropdown-select.dropdown-menu-paging.dropdown-menu-labels.dropdown-menu-selectable.dropdown-extended-height
= render partial: "shared/issuable/label_page_default", locals: { title: dropdown_title, show_footer: show_footer, show_create: show_create }
- if show_create && project && can?(current_user, :admin_label, project)
diff --git a/app/views/shared/issuable/_search_bar.html.haml b/app/views/shared/issuable/_search_bar.html.haml
index ae79d5e3c3e..00b235809ed 100644
--- a/app/views/shared/issuable/_search_bar.html.haml
+++ b/app/views/shared/issuable/_search_bar.html.haml
@@ -96,6 +96,7 @@
%li.filter-dropdown-item
%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' } }
@@ -181,7 +182,7 @@
= render 'shared/issuable/board_create_list_dropdown', board: board
- if @project
#js-add-issues-btn.gl-ml-3{ data: { can_admin_list: can?(current_user, :admin_list, @project) } }
- - if current_user && Feature.enabled?(:boards_with_swimlanes, @group)
+ - if current_user && Feature.enabled?(:boards_with_swimlanes, @group, default_enabled: true)
#js-board-epics-swimlanes-toggle
#js-toggle-focus-btn
- elsif is_not_boards_modal_or_productivity_analytics && show_sorting_dropdown
diff --git a/app/views/shared/issuable/_sidebar.html.haml b/app/views/shared/issuable/_sidebar.html.haml
index 458703ebc5f..1f20c1a30aa 100644
--- a/app/views/shared/issuable/_sidebar.html.haml
+++ b/app/views/shared/issuable/_sidebar.html.haml
@@ -96,24 +96,14 @@
%button.dropdown-menu-toggle.js-due-date-select{ type: 'button', data: { toggle: 'dropdown', field_name: "#{issuable_type}[due_date]", ability_name: issuable_type, issue_update: issuable_sidebar[:issuable_json_path], display: 'static' } }
%span.dropdown-toggle-text
= _('Due date')
- = icon('chevron-down', 'aria-hidden': 'true')
+ = sprite_icon('chevron-down', css_class: "dropdown-menu-toggle-icon gl-top-3")
.dropdown-menu.dropdown-menu-due-date
= dropdown_title(_('Due date'))
= dropdown_content do
.js-due-date-calendar
- .js-sidebar-labels{ data: { allow_label_create: issuable_sidebar.dig(:current_user, :can_admin_label).to_s,
- allow_scoped_labels: issuable_sidebar[:scoped_labels_available].to_s,
- can_edit: can_edit_issuable.to_s,
- iid: issuable_sidebar[:iid],
- issuable_type: issuable_type,
- labels_fetch_path: issuable_sidebar[:project_labels_path],
- labels_manage_path: project_labels_path(@project),
- labels_update_path: issuable_sidebar[:issuable_json_path],
- project_issues_path: issuable_sidebar[:project_issuables_path],
- project_path: @project.full_path,
- selected_labels: issuable_sidebar[:labels].to_json } }
+ .js-sidebar-labels{ data: sidebar_labels_data(issuable_sidebar, @project) }
= render_if_exists 'shared/issuable/sidebar_weight', issuable_sidebar: issuable_sidebar
diff --git a/app/views/shared/issuable/_sort_dropdown.html.haml b/app/views/shared/issuable/_sort_dropdown.html.haml
index 81dbecb430b..f60be3f3e4a 100644
--- a/app/views/shared/issuable/_sort_dropdown.html.haml
+++ b/app/views/shared/issuable/_sort_dropdown.html.haml
@@ -7,7 +7,7 @@
.btn-group{ role: 'group' }
%button.dropdown-menu-toggle{ type: 'button', data: { toggle: 'dropdown', display: 'static' }, class: 'btn btn-default' }
= sort_title
- = icon('chevron-down')
+ = sprite_icon('chevron-down', css_class: "dropdown-menu-toggle-icon gl-top-3")
%ul.dropdown-menu.dropdown-menu-right.dropdown-menu-selectable.dropdown-menu-sort
%li
= sortable_item(sort_title_priority, page_filter_path(sort: sort_value_priority), sort_title)
diff --git a/app/views/projects/issues/export_csv/_button.html.haml b/app/views/shared/issuable/csv_export/_button.html.haml
index e5710fcdb60..3584c9c1ed5 100644
--- a/app/views/projects/issues/export_csv/_button.html.haml
+++ b/app/views/shared/issuable/csv_export/_button.html.haml
@@ -1,4 +1,4 @@
- if current_user
%button.csv_download_link.btn.gl-button.has-tooltip{ title: _('Export as CSV'),
- data: { toggle: 'modal', target: '.issues-export-modal', qa_selector: 'export_as_csv_button' } }
+ data: { toggle: 'modal', target: ".#{issuable_type}-export-modal", qa_selector: 'export_as_csv_button' } }
= sprite_icon('export')
diff --git a/app/views/shared/issuable/csv_export/_modal.html.haml b/app/views/shared/issuable/csv_export/_modal.html.haml
new file mode 100644
index 00000000000..4a4c6b90cd9
--- /dev/null
+++ b/app/views/shared/issuable/csv_export/_modal.html.haml
@@ -0,0 +1,29 @@
+- class_name = "#{issuable_type.dasherize}-export-modal"
+- if current_user
+ .modal.issuable-export-modal{ class: class_name }
+ .modal-dialog
+ .modal-content{ data: { qa_selector: "export_issuable_modal" } }
+ .modal-header
+ %h3
+ = _("Export %{issuable_type}" % { issuable_type: issuable_type.humanize(capitalize: false) })
+ .svg-content.import-export-svg-container
+ = image_tag 'illustrations/export-import.svg', role: "presentation", class: 'illustration'
+ %button.close{ type: "button", "data-dismiss": "modal", "aria-label" => _('Close') }
+ = sprite_icon('close', css_class: 'gl-icon')
+ .modal-body
+ - issuable_count = issuables_count_for_state(issuable_type.to_sym, params[:state])
+ - unless issuable_count == -1 # The count timed out
+ .modal-subheader
+ = sprite_icon('check', css_class: 'gl-icon gl-color-green-400')
+ %strong.gl-ml-3
+ - if issuable_type.eql?('merge_requests')
+ = n_("%{count} merge request selected", "%{count} merge requests selected", issuable_count) % { count: issuable_count }
+ - else
+ = n_("%{count} issue selected", "%{count} issues selected", issuable_count) % { count: issuable_count }
+ .modal-text
+ = html_escape(_('The CSV export will be created in the background. Once finished, it will be sent to %{strong_open}%{email}%{strong_close} in an attachment.')) % { email: @current_user.notification_email, strong_open: '<strong>'.html_safe, strong_close: '</strong>'.html_safe }
+ .modal-footer
+ - if issuable_type.eql?('merge_requests')
+ = link_to _("Export merge requests"), export_csv_project_merge_requests_path(@project, request.query_parameters), method: :post, class: 'btn gl-button btn-success', data: { track_label: "export_merge_requests_csv", track_event: "click_button", track_value: "" }
+ - else
+ = link_to _('Export issues'), export_csv_project_issues_path(@project, request.query_parameters), method: :post, class: 'btn gl-button btn-success', data: { track_label: "export_issues_csv", track_event: "click_button", track_value: "", qa_selector: "export_issues_button" }
diff --git a/app/views/shared/issuable/form/_type_selector.html.haml b/app/views/shared/issuable/form/_type_selector.html.haml
index 3347966f39a..5d64c15d9f9 100644
--- a/app/views/shared/issuable/form/_type_selector.html.haml
+++ b/app/views/shared/issuable/form/_type_selector.html.haml
@@ -8,7 +8,7 @@
%button.dropdown-menu-toggle{ type: 'button', 'data-toggle' => 'dropdown' }
%span.dropdown-toggle-text.is-default
= issuable.issue_type.capitalize || _("Select type")
- = icon('chevron-down')
+ = sprite_icon('chevron-down', css_class: "dropdown-menu-toggle-icon gl-top-3")
.dropdown-menu.dropdown-menu-selectable.dropdown-select
.dropdown-title.gl-display-flex
%span.gl-ml-auto
diff --git a/app/views/shared/issue_type/_details_content.html.haml b/app/views/shared/issue_type/_details_content.html.haml
new file mode 100644
index 00000000000..7c1ec332ba4
--- /dev/null
+++ b/app/views/shared/issue_type/_details_content.html.haml
@@ -0,0 +1,31 @@
+- related_branches_path = related_branches_project_issue_path(@project, issuable)
+
+.issue-details.issuable-details
+ .detail-page-description.content-block
+ #js-issuable-app{ data: { initial: issuable_initial_data(issuable).to_json} }
+ .title-container
+ %h2.title= markdown_field(issuable, :title)
+ - if issuable.description.present?
+ .description
+ .md= markdown_field(issuable, :description)
+
+ = edited_time_ago_with_tooltip(issuable, placement: 'bottom', html_class: 'issue-edited-ago js-issue-edited-ago')
+
+ = render 'shared/issue_type/sentry_stack_trace', issuable: issuable
+
+ = render 'projects/issues/design_management'
+
+ = render_if_exists 'projects/issues/related_issues'
+
+ #js-related-merge-requests{ data: { endpoint: expose_path(api_v4_projects_issues_related_merge_requests_path(id: @project.id, issue_iid: issuable.iid)), project_namespace: @project.namespace.path, project_path: @project.path } }
+
+ - if can?(current_user, :download_code, @project)
+ - add_page_startup_api_call related_branches_path
+ #related-branches{ data: { url: related_branches_path } }
+ -# This element is filled in using JavaScript.
+
+ = render 'shared/issue_type/emoji_block', issuable: issuable
+
+ = render 'projects/issues/discussion'
+
+= render 'shared/issuable/sidebar', issuable_sidebar: @issuable_sidebar, assignees: @issue.assignees
diff --git a/app/views/shared/issue_type/_details_header.html.haml b/app/views/shared/issue_type/_details_header.html.haml
new file mode 100644
index 00000000000..ea4df288839
--- /dev/null
+++ b/app/views/shared/issue_type/_details_header.html.haml
@@ -0,0 +1,55 @@
+- can_update_issue = can?(current_user, :update_issue, issuable)
+- can_reopen_issue = can?(current_user, :reopen_issue, issuable)
+- can_report_spam = issuable.submittable_as_spam_by?(current_user)
+- can_create_issue = show_new_issue_link?(@project)
+- display_issuable_type = issuable_display_type(issuable)
+- new_issuable_params = ({ issuable_template: 'incident', issue: { issue_type: 'incident' } } if issuable.incident?)
+
+.detail-page-header
+ .detail-page-header-body
+ .issuable-status-box.status-box.status-box-issue-closed{ class: issue_status_visibility(issuable, status_box: :closed) }
+ = sprite_icon('mobile-issue-close', css_class: 'gl-display-block gl-display-sm-none!')
+ .gl-display-none.gl-display-sm-block!
+ = issue_closed_text(issuable, current_user)
+ .issuable-status-box.status-box.status-box-open{ class: issue_status_visibility(issuable, status_box: :open) }
+ = sprite_icon('issue-open-m', css_class: 'gl-display-block gl-display-sm-none!')
+ %span.gl-display-none.gl-display-sm-block!
+ = _('Open')
+
+ .issuable-meta
+ #js-issuable-header-warnings
+ = issuable_meta(issuable, @project, display_issuable_type)
+
+ %a.btn.gl-button.btn-default.float-right.gl-display-block.d-sm-none.gutter-toggle.issuable-gutter-toggle.js-sidebar-toggle{ href: "#" }
+ = sprite_icon('chevron-double-lg-left')
+
+ - if Feature.enabled?(:vue_issue_header, @project, default_enabled: true)
+ .js-issue-header-actions{ data: issue_header_actions_data(@project, issuable, current_user) }
+ - else
+ .detail-page-header-actions.js-issuable-actions.js-issuable-buttons{ data: { "action": "close-reopen" } }
+ .clearfix.issue-btn-group.dropdown
+ %button.btn.gl-button.btn-default.float-left.gl-display-md-none{ type: "button", data: { toggle: "dropdown" } }
+ = _('Options')
+ = icon('caret-down')
+ .dropdown-menu.dropdown-menu-right
+ %ul
+ - unless current_user == issuable.author
+ %li= link_to _('Report abuse'), new_abuse_report_path(user_id: issuable.author.id, ref_url: issue_url(issuable))
+ - if can_update_issue
+ %li= link_to _('Close %{display_issuable_type}') % { display_issuable_type: display_issuable_type }, issue_path(issuable, issue: { state_event: :close }, format: 'json'), class: "btn-close js-btn-issue-action #{issue_button_visibility(issuable, true)}", title: _('Close %{display_issuable_type}') % { display_issuable_type: display_issuable_type }, data: { endpoint: close_reopen_issuable_path(issuable) }
+ - if can_reopen_issue
+ %li= link_to _('Reopen %{display_issuable_type}') % { display_issuable_type: display_issuable_type }, issue_path(issuable, issue: { state_event: :reopen }, format: 'json'), class: "btn-reopen js-btn-issue-action #{issue_button_visibility(issuable, false)}", title: _('Reopen %{display_issuable_type}') % { display_issuable_type: display_issuable_type }, data: { endpoint: close_reopen_issuable_path(issuable) }
+ - if can_report_spam
+ %li= link_to _('Submit as spam'), mark_as_spam_project_issue_path(@project, issuable), method: :post, class: 'btn-spam', title: 'Submit as spam'
+ - if can_create_issue
+ - if can_update_issue || can_report_spam
+ %li.divider
+ %li= link_to _('New %{display_issuable_type}') % { display_issuable_type: display_issuable_type }, new_project_issue_path(@project, new_issuable_params), id: 'new_%{display_issuable_type}_link' % { display_issuable_type: display_issuable_type }
+
+ = render 'shared/issuable/close_reopen_button', issuable: issuable, can_update: can_update_issue, can_reopen: can_reopen_issue, warn_before_close: defined?(issuable.blocked?) && issuable.blocked?
+
+ - if can_report_spam
+ = link_to _('Submit as spam'), mark_as_spam_project_issue_path(@project, issuable), method: :post, class: 'gl-display-none gl-display-md-block gl-button btn btn-grouped btn-spam', title: 'Submit as spam'
+ - if can_create_issue
+ = link_to new_project_issue_path(@project, new_issuable_params), class: 'gl-display-none gl-display-md-block gl-button btn btn-grouped btn-success btn-inverted', title: _('New %{display_issuable_type}') % { display_issuable_type: display_issuable_type }, id: 'new_%{display_issuable_type}_link' % { display_issuable_type: display_issuable_type } do
+ = _('New %{display_issuable_type}') % { display_issuable_type: display_issuable_type }
diff --git a/app/views/shared/issue_type/_emoji_block.html.haml b/app/views/shared/issue_type/_emoji_block.html.haml
new file mode 100644
index 00000000000..42d149b2ab3
--- /dev/null
+++ b/app/views/shared/issue_type/_emoji_block.html.haml
@@ -0,0 +1,9 @@
+.content-block.emoji-block.emoji-block-sticky
+ .row.gl-m-0.gl-justify-content-space-between
+ .js-noteable-awards
+ = render 'award_emoji/awards_block', awardable: issuable, inline: true
+ .new-branch-col
+ = render_if_exists "projects/issues/timeline_toggle", issuable: issuable
+ #js-vue-sort-issue-discussions
+ #js-vue-discussion-filter{ data: { default_filter: current_user&.notes_filter_for(issuable), notes_filters: UserPreference.notes_filters.to_json } }
+ = render 'new_branch' if show_new_branch_button?
diff --git a/app/views/shared/issue_type/_sentry_stack_trace.html.haml b/app/views/shared/issue_type/_sentry_stack_trace.html.haml
new file mode 100644
index 00000000000..40b29a74b53
--- /dev/null
+++ b/app/views/shared/issue_type/_sentry_stack_trace.html.haml
@@ -0,0 +1,4 @@
+- return unless issuable.sentry_issue.present?
+- add_page_specific_style 'page_bundles/error_tracking_details'
+
+#js-sentry-error-stack-trace{ data: error_details_data(@project, issuable.sentry_issue.sentry_issue_identifier) }
diff --git a/app/views/shared/members/_filter_2fa_dropdown.html.haml b/app/views/shared/members/_filter_2fa_dropdown.html.haml
index a2bc5e9ecdf..8187a9bde15 100644
--- a/app/views/shared/members/_filter_2fa_dropdown.html.haml
+++ b/app/views/shared/members/_filter_2fa_dropdown.html.haml
@@ -1,7 +1,7 @@
- filter = params[:two_factor] || 'everyone'
- filter_options = { 'everyone' => _('Everyone'), 'enabled' => _('Enabled'), 'disabled' => _('Disabled') }
-.dropdown.inline.member-filter-2fa-dropdown
- = dropdown_toggle(filter_options[filter], { toggle: 'dropdown' })
+.dropdown.inline.member-filter-2fa-dropdown{ data: { testid: 'member-filter-2fa-dropdown' } }
+ = dropdown_toggle(filter_options[filter], { toggle: 'dropdown', testid: 'dropdown-toggle' })
%ul.dropdown-menu.dropdown-menu-align-right.dropdown-menu-selectable
%li.dropdown-header
= _("Filter by two-factor authentication")
diff --git a/app/views/shared/members/_invite_group.html.haml b/app/views/shared/members/_invite_group.html.haml
index a87a4c6a45c..5e3a6918ab2 100644
--- a/app/views/shared/members/_invite_group.html.haml
+++ b/app/views/shared/members/_invite_group.html.haml
@@ -13,7 +13,7 @@
= label_tag group_access_field, _("Max access level"), class: "label-bold"
.select-wrapper
= select_tag group_access_field, options_for_select(access_levels, default_access_level), data: { qa_selector: 'group_access_field' }, class: "form-control select-control"
- = icon('chevron-down')
+ = sprite_icon('chevron-down', css_class: "gl-icon gl-absolute gl-top-3 gl-right-3 gl-text-gray-200")
.form-text.text-muted.gl-mb-3
- permissions_docs_path = help_page_path('user/permissions')
- link_start = %q{<a href="%{url}">}.html_safe % { url: permissions_docs_path }
diff --git a/app/views/shared/members/_invite_member.html.haml b/app/views/shared/members/_invite_member.html.haml
index 5f9046b3dcb..59b0600e2dd 100644
--- a/app/views/shared/members/_invite_member.html.haml
+++ b/app/views/shared/members/_invite_member.html.haml
@@ -5,7 +5,7 @@
- import_path = local_assigns[:import_path]
.row
.col-sm-12
- = form_tag submit_url, class: 'invite-users-form', method: :post do
+ = form_tag submit_url, class: 'invite-users-form', data: { testid: 'invite-users-form' }, method: :post do
.form-group
= label_tag :user_ids, _("GitLab member or Email address"), class: "label-bold"
= users_select_tag(:user_ids, multiple: true, class: 'input-clamp qa-member-select-field', scope: :all, email_user: true, placeholder: 'Search for members to update or invite')
@@ -13,7 +13,7 @@
= label_tag :access_level, _("Choose a role permission"), class: "label-bold"
.select-wrapper
= select_tag :access_level, options_for_select(access_levels, default_access_level), class: "form-control project-access-select select-control"
- = icon('chevron-down')
+ = sprite_icon('chevron-down', css_class: "gl-icon gl-absolute gl-top-3 gl-right-3 gl-text-gray-200")
.form-text.text-muted.gl-mb-3
- permissions_docs_path = help_page_path('user/permissions')
- link_start = %q{<a href="%{url}">}.html_safe % { url: permissions_docs_path }
diff --git a/app/views/shared/members/_member.html.haml b/app/views/shared/members/_member.html.haml
index 164d38986ec..e294936f82c 100644
--- a/app/views/shared/members/_member.html.haml
+++ b/app/views/shared/members/_member.html.haml
@@ -2,6 +2,9 @@
- show_controls = local_assigns.fetch(:show_controls, true)
- force_mobile_view = local_assigns.fetch(:force_mobile_view, false)
- member = local_assigns.fetch(:member)
+- current_user_is_group_owner = local_assigns.fetch(:current_user_is_group_owner, false)
+- membership_source = local_assigns.fetch(:membership_source)
+- group = local_assigns.fetch(:group)
- user = local_assigns.fetch(:user, member.user)
- source = member.source
- override = member.try(:override)
@@ -25,13 +28,13 @@
= render 'shared/members/its_you_badge', user: user, current_user: current_user
- = render_if_exists 'shared/members/ee/license_badge', user: user, group: @group
+ = render_if_exists 'shared/members/ee/license_badge', user: user, group: group, current_user_is_group_owner: current_user_is_group_owner
= render 'shared/members/blocked_badge', user: user
= render 'shared/members/two_factor_auth_badge', user: user
- - if source.instance_of?(Group) && source != @group
+ - if source.instance_of?(Group) && source != membership_source
&middot;
= link_to source.full_name, source, class: "gl-display-inline-block inline-link"
@@ -57,10 +60,9 @@
= link_to member.created_by.name, user_path(member.created_by)
= time_ago_with_tooltip(member.created_at)
- if show_roles
- - current_resource = @project || @group
.controls.member-controls.align-items-center
= render_if_exists 'shared/members/ee/ldap_tag', can_override: member.can_override?
- - if show_controls && member.source == current_resource
+ - if show_controls && member.source == membership_source
- if member.can_resend_invite?
= link_to sprite_icon('paper-airplane'), polymorphic_path([:resend_invite, member]),
@@ -88,7 +90,7 @@
class: ("is-active" if member.access_level == role_id),
data: { id: role_id, el_id: dom_id(member), qa_selector: "#{role.downcase}_access_level_link" }
= render_if_exists 'shared/members/ee/revert_ldap_group_sync_option',
- group: @group,
+ group: group,
member: member,
can_override: member.can_override?
.clearable-input.member-form-control{ class: [("d-sm-inline-block" unless force_mobile_view)] }
@@ -105,12 +107,12 @@
- if member.can_approve?
= link_to polymorphic_path([:approve_access_request, member]),
method: :post,
- class: "btn btn-success align-self-center m-0 mb-2 #{'mb-sm-0 ml-sm-2' unless force_mobile_view}",
+ class: "btn btn-success btn-icon gl-button align-self-center m-0 mb-2 #{'mb-sm-0 ml-sm-2' unless force_mobile_view}",
title: _('Grant access') do
%span{ class: ('d-block d-sm-none' unless force_mobile_view) }
= _('Grant access')
- unless force_mobile_view
- = icon('check inverse', class: 'd-none d-sm-block')
+ = sprite_icon('check', css_class: 'd-none d-sm-block')
- if member.can_remove?
- if current_user == user
@@ -125,8 +127,8 @@
= _("Delete")
- unless force_mobile_view
= sprite_icon('remove', css_class: 'd-none d-sm-block gl-icon')
- = render_if_exists 'shared/members/ee/override_member_buttons', group: @group, member: member, user: user, action: :edit, can_override: member.can_override?
+ = render_if_exists 'shared/members/ee/override_member_buttons', group: group, member: member, user: user, action: :edit, can_override: member.can_override?
- else
%span.member-access-text.user-access-role= member.human_access
-= render_if_exists 'shared/members/ee/override_member_buttons', group: @group, member: member, user: user, action: :confirm, can_override: member.can_override?
+= render_if_exists 'shared/members/ee/override_member_buttons', group: group, member: member, user: user, action: :confirm, can_override: member.can_override?
diff --git a/app/views/shared/members/_requests.html.haml b/app/views/shared/members/_requests.html.haml
index e1e7aa36a78..3aa43ed1922 100644
--- a/app/views/shared/members/_requests.html.haml
+++ b/app/views/shared/members/_requests.html.haml
@@ -1,6 +1,8 @@
- membership_source = local_assigns.fetch(:membership_source)
- requesters = local_assigns.fetch(:requesters)
- force_mobile_view = local_assigns.fetch(:force_mobile_view, false)
+- group = local_assigns.fetch(:group)
+- current_user_is_group_owner = group && group.has_owner?(current_user)
- return if requesters.empty?
@@ -10,4 +12,9 @@
%strong= membership_source.name
%span.badge.badge-pill= requesters.size
%ul.content-list.members-list
- = render partial: 'shared/members/member', collection: requesters, as: :member, locals: { force_mobile_view: force_mobile_view }
+ = render partial: 'shared/members/member',
+ collection: requesters, as: :member,
+ locals: { membership_source: membership_source,
+ group: group,
+ force_mobile_view: force_mobile_view,
+ current_user_is_group_owner: current_user_is_group_owner }
diff --git a/app/views/shared/members/_search_field.html.haml b/app/views/shared/members/_search_field.html.haml
index e70cb063324..b1e3134f7aa 100644
--- a/app/views/shared/members/_search_field.html.haml
+++ b/app/views/shared/members/_search_field.html.haml
@@ -2,5 +2,5 @@
.search-control-wrap.gl-relative
= search_field_tag name, params[name], { placeholder: _('Search'), class: 'form-control', spellcheck: false }
- %button.user-search-btn.border-left.gl-display-flex.gl-align-items-center.gl-justify-content-center{ type: 'submit', 'aria': { label: _('Submit search') } }
+ %button.user-search-btn.border-left.gl-display-flex.gl-align-items-center.gl-justify-content-center{ type: 'submit', 'aria': { label: _('Submit search') }, data: { testid: 'user-search-submit' } }
= sprite_icon('search')
diff --git a/app/views/shared/members/_sort_dropdown.html.haml b/app/views/shared/members/_sort_dropdown.html.haml
index 606d3bcdfa8..682e3a0433b 100644
--- a/app/views/shared/members/_sort_dropdown.html.haml
+++ b/app/views/shared/members/_sort_dropdown.html.haml
@@ -1,5 +1,5 @@
-.dropdown.inline.qa-user-sort-dropdown
- = dropdown_toggle(member_sort_options_hash[@sort], { toggle: 'dropdown' })
+.dropdown.inline.qa-user-sort-dropdown{ data: { testid: 'user-sort-dropdown' } }
+ = dropdown_toggle(member_sort_options_hash[@sort], { toggle: 'dropdown', testid: 'dropdown-toggle' })
%ul.dropdown-menu.dropdown-menu-right.dropdown-menu-selectable
%li.dropdown-header
= _("Sort by")
@@ -8,12 +8,12 @@
= link_to filter_group_project_member_path(sort: value), class: ("is-active" if @sort == value) do
= title
%li.divider
- %li{ data: { 'qa-selector': 'filter-members-with-inherited-permissions' } }
+ %li{ data: { testid: 'filter-members-with-inherited-permissions' } }
= link_to filter_group_project_member_path(with_inherited_permissions: nil), class: ("is-active" unless params[:with_inherited_permissions].present?) do
= _("Show all members")
- %li{ data: { 'qa-selector': 'filter-members-with-inherited-permissions' } }
+ %li{ data: { testid: 'filter-members-with-inherited-permissions' } }
= link_to filter_group_project_member_path(with_inherited_permissions: 'exclude'), class: ("is-active" if params[:with_inherited_permissions] == 'exclude') do
= _("Show only direct members")
- %li{ data: { 'qa-selector': 'filter-members-with-inherited-permissions' } }
+ %li{ data: { testid: 'filter-members-with-inherited-permissions' } }
= link_to filter_group_project_member_path(with_inherited_permissions: 'only'), class: ("is-active" if params[:with_inherited_permissions] == 'only') do
= _("Show only inherited members")
diff --git a/app/views/shared/milestones/_delete_button.html.haml b/app/views/shared/milestones/_delete_button.html.haml
index 7a813e110c4..09c783a0b24 100644
--- a/app/views/shared/milestones/_delete_button.html.haml
+++ b/app/views/shared/milestones/_delete_button.html.haml
@@ -1,6 +1,6 @@
- milestone_url = @milestone.project_milestone? ? project_milestone_path(@project, @milestone) : group_milestone_path(@group, @milestone)
-%button.js-delete-milestone-button.btn.btn-grouped.btn-danger{ data: { milestone_id: @milestone.id,
+%button.js-delete-milestone-button.btn.gl-button.btn-grouped.btn-danger{ data: { milestone_id: @milestone.id,
milestone_title: markdown_field(@milestone, :title),
milestone_url: milestone_url,
milestone_issue_count: @milestone.issues.count,
diff --git a/app/views/shared/milestones/_header.html.haml b/app/views/shared/milestones/_header.html.haml
index ea90b674b34..93da319fce7 100644
--- a/app/views/shared/milestones/_header.html.haml
+++ b/app/views/shared/milestones/_header.html.haml
@@ -11,10 +11,10 @@
.milestone-buttons
- if can?(current_user, :admin_milestone, @group || @project)
- = link_to _('Edit'), edit_milestone_path(milestone), class: 'btn btn-grouped'
+ = link_to _('Edit'), edit_milestone_path(milestone), class: 'btn gl-button btn-grouped'
- if milestone.project_milestone? && milestone.project.group
- %button.js-promote-project-milestone-button.btn.btn-grouped{ data: { toggle: 'modal',
+ %button.js-promote-project-milestone-button.btn.gl-button.btn-grouped{ data: { toggle: 'modal',
target: '#promote-milestone-modal',
milestone_title: milestone.title,
group_name: milestone.project.group.name,
@@ -26,11 +26,11 @@
#promote-milestone-modal
- if milestone.active?
- = link_to _('Close milestone'), update_milestone_path(milestone, { state_event: :close }), method: :put, class: 'btn btn-grouped btn-close'
+ = link_to _('Close milestone'), update_milestone_path(milestone, { state_event: :close }), method: :put, class: 'btn gl-button btn-grouped btn-close'
- else
- = link_to _('Reopen milestone'), update_milestone_path(milestone, { state_event: :activate }), method: :put, class: 'btn btn-grouped btn-reopen'
+ = link_to _('Reopen milestone'), update_milestone_path(milestone, { state_event: :activate }), method: :put, class: 'btn gl-button btn-grouped btn-reopen'
= render 'shared/milestones/delete_button'
- %button.btn.btn-default.btn-grouped.float-right.d-block.d-sm-none.js-sidebar-toggle{ type: 'button' }
+ %button.btn.gl-button.btn-default.btn-grouped.float-right.d-block.d-sm-none.js-sidebar-toggle{ type: 'button' }
= sprite_icon('chevron-double-lg-left')
diff --git a/app/views/shared/milestones/_labels_tab.html.haml b/app/views/shared/milestones/_labels_tab.html.haml
index 3b4d29ca7b0..a419e749f35 100644
--- a/app/views/shared/milestones/_labels_tab.html.haml
+++ b/app/views/shared/milestones/_labels_tab.html.haml
@@ -7,8 +7,8 @@
%span.prepend-description-left
= markdown_field(label, :description)
- .float-right.d-none.d-lg-block.d-xl-block
- = link_to milestones_issues_path(options.merge(state: 'opened')), class: 'btn btn-transparent btn-action' do
+ .float-right.d-none.d-lg-block
+ = link_to milestones_issues_path(options.merge(state: 'opened')), class: 'btn gl-button btn-default-tertiary btn-action' do
- pluralize milestone_issues_by_label_count(@milestone, label, state: :opened), _('open issue')
- = link_to milestones_issues_path(options.merge(state: 'closed')), class: 'btn btn-transparent btn-action' do
+ = link_to milestones_issues_path(options.merge(state: 'closed')), class: 'btn gl-button btn-default-tertiary btn-action' do
- pluralize milestone_issues_by_label_count(@milestone, label, state: :closed), _('closed issue')
diff --git a/app/views/shared/milestones/_milestone.html.haml b/app/views/shared/milestones/_milestone.html.haml
index f28aa406784..1597a011a45 100644
--- a/app/views/shared/milestones/_milestone.html.haml
+++ b/app/views/shared/milestones/_milestone.html.haml
@@ -46,7 +46,7 @@
.milestone-actions.d-flex.justify-content-sm-start.justify-content-md-end
- if @project # if in milestones list on project level
- if can_admin_group_milestones?
- %button.js-promote-project-milestone-button.btn.btn-blank.btn-sm.btn-grouped.has-tooltip{ title: s_('Milestones|Promote to Group Milestone'),
+ %button.js-promote-project-milestone-button.btn.gl-button.btn-default-tertiary.btn-sm.btn-grouped.has-tooltip{ title: s_('Milestones|Promote to Group Milestone'),
disabled: true,
type: 'button',
data: { url: promote_project_milestone_path(milestone.project, milestone),
@@ -59,6 +59,6 @@
- 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 btn-sm btn-grouped btn-reopen"
+ = link_to s_('Milestones|Reopen Milestone'), milestone_path(milestone, milestone: { state_event: :activate }), method: :put, class: "btn gl-button btn-sm btn-grouped btn-reopen"
- else
- = link_to s_('Milestones|Close Milestone'), milestone_path(milestone, milestone: { state_event: :close }), method: :put, class: "btn btn-sm btn-grouped btn-close"
+ = link_to s_('Milestones|Close Milestone'), milestone_path(milestone, milestone: { state_event: :close }), method: :put, class: "btn gl-button btn-warning-secondary btn-sm btn-grouped btn-close"
diff --git a/app/views/shared/notes/_comment_button.html.haml b/app/views/shared/notes/_comment_button.html.haml
index e151e55d0d2..45af4b51b27 100644
--- a/app/views/shared/notes/_comment_button.html.haml
+++ b/app/views/shared/notes/_comment_button.html.haml
@@ -10,7 +10,7 @@
%ul#resolvable-comment-menu.dropdown-menu.dropdown-open-top{ data: { dropdown: true } }
%li#comment.droplab-item-selected{ data: { value: '', 'submit-text' => _('Comment'), 'close-text' => _("Comment & close %{noteable_name}") % { noteable_name: noteable_name }, 'reopen-text' => _("Comment & reopen %{noteable_name}") % { noteable_name: noteable_name } } }
%button.btn.btn-transparent
- = icon('check', class: 'icon')
+ = sprite_icon('check', css_class: 'icon')
.description
%strong= _("Comment")
%p
@@ -20,7 +20,7 @@
%li#discussion{ data: { value: 'DiscussionNote', 'submit-text' => _('Start thread'), 'close-text' => _("Start thread & close %{noteable_name}") % { noteable_name: noteable_name }, 'reopen-text' => _("Start thread & reopen %{noteable_name}") % { noteable_name: noteable_name } } }
%button.btn.btn-transparent
- = icon('check', class: 'icon')
+ = sprite_icon('check', css_class: 'icon')
.description
%strong= _("Start thread")
%p
diff --git a/app/views/shared/notes/_hints.html.haml b/app/views/shared/notes/_hints.html.haml
index 3703cca2290..a03e8446f5d 100644
--- a/app/views/shared/notes/_hints.html.haml
+++ b/app/views/shared/notes/_hints.html.haml
@@ -23,13 +23,20 @@
= sprite_icon('media', css_class: 'gl-icon gl-vertical-align-text-bottom')
%span.uploading-error-message
-# Populated by app/assets/javascripts/dropzone_input.js
- %button.retry-uploading-link{ type: 'button' }= _("Try again")
- or
- %button.attach-new-file.markdown-selector{ type: 'button' }= _("attach a new file")
+ %button.btn.gl-button.btn-link.gl-vertical-align-baseline.retry-uploading-link
+ %span.gl-button-text
+ = _("Try again")
+ = _("or")
+ %button.btn.gl-button.btn-link.attach-new-file.markdown-selector.gl-vertical-align-baseline
+ %span.gl-button-text
+ = _("attach a new file")
+ = _(".")
- %button.btn.markdown-selector.button-attach-file.btn-link{ type: 'button' }
+ %button.btn.gl-button.btn-link.button-attach-file.markdown-selector.button-attach-file.gl-vertical-align-text-bottom
= sprite_icon('media')
- %span.text-attach-file<>
+ %span.gl-button-text
= _("Attach a file")
- %button.btn.btn-default.btn-sm.hide.button-cancel-uploading-files{ type: 'button' }= _("Cancel")
+ %button.btn.gl-button.btn-link.button-cancel-uploading-files.gl-vertical-align-baseline.hide
+ %span.gl-button-text
+ = _("Cancel")
diff --git a/app/views/shared/notes/_note.html.haml b/app/views/shared/notes/_note.html.haml
index 97ed2852871..f1352be28e3 100644
--- a/app/views/shared/notes/_note.html.haml
+++ b/app/views/shared/notes/_note.html.haml
@@ -72,7 +72,7 @@
= image_tag note.attachment.url, class: 'note-image-attach'
.attachment
= link_to note.attachment.url, target: '_blank' do
- = icon('paperclip')
+ = sprite_icon('paperclip')
= note.attachment_identifier
= link_to delete_attachment_project_note_path(note.project, note),
title: _('Delete this attachment'), method: :delete, remote: true, data: { confirm: _('Are you sure you want to remove the attachment?') }, class: 'danger js-note-attachment-delete' do
diff --git a/app/views/shared/notes/_notes_with_form.html.haml b/app/views/shared/notes/_notes_with_form.html.haml
index 9baa340376b..1b03225d48d 100644
--- a/app/views/shared/notes/_notes_with_form.html.haml
+++ b/app/views/shared/notes/_notes_with_form.html.haml
@@ -19,7 +19,7 @@
= render "shared/notes/form", view: diff_view, supports_autocomplete: autocomplete
- elsif !current_user
.disabled-comment.text-center.gl-mt-3
- - link_to_register = link_to(_("register"), new_session_path(:user, redirect_to_referer: 'yes', anchor: 'register-pane'), class: 'js-register-link')
+ - link_to_register = link_to(_("register"), new_user_registration_path(redirect_to_referer: 'yes'), class: 'js-register-link')
- link_to_sign_in = link_to(_("sign in"), new_session_path(:user, redirect_to_referer: 'yes'), class: 'js-sign-in-link')
= _("Please %{link_to_register} or %{link_to_sign_in} to comment").html_safe % { link_to_register: link_to_register, link_to_sign_in: link_to_sign_in }
- elsif discussion_locked
diff --git a/app/views/shared/notifications/_custom_notifications.html.haml b/app/views/shared/notifications/_custom_notifications.html.haml
index 51b7da7dee8..946e3c67dcf 100644
--- a/app/views/shared/notifications/_custom_notifications.html.haml
+++ b/app/views/shared/notifications/_custom_notifications.html.haml
@@ -30,4 +30,5 @@
%label.form-check-label{ for: field_id }
%strong
= notification_event_name(event)
- .fa.custom-notification-event-loading.spinner
+ %span.spinner.is-loading.gl-vertical-align-middle.gl-display-none
+ = sprite_icon('check', css_class: 'is-done gl-display-none gl-vertical-align-middle gl-text-green-600')
diff --git a/app/views/shared/notifications/_new_button.html.haml b/app/views/shared/notifications/_new_button.html.haml
index fbcfec5fd96..14f4b04ef78 100644
--- a/app/views/shared/notifications/_new_button.html.haml
+++ b/app/views/shared/notifications/_new_button.html.haml
@@ -1,4 +1,5 @@
- btn_class = local_assigns.fetch(:btn_class, '')
+- dropdown_container_class = local_assigns.fetch(:dropdown_container_class, '')
- emails_disabled = local_assigns.fetch(:emails_disabled, false)
- if notification_setting
@@ -8,8 +9,8 @@
- else
- button_title = _("Notification setting - %{notification_title}") % { notification_title: notification_title(notification_setting.level) }
- .js-notification-dropdown.notification-dropdown.home-panel-action-button.gl-mt-3.gl-mr-3.dropdown.inline
- = form_for notification_setting, remote: true, html: { class: "inline notification-form no-label" } do |f|
+ .js-notification-dropdown.notification-dropdown.home-panel-action-button.gl-mt-3.dropdown.inline{ class: dropdown_container_class }
+ = form_for notification_setting, remote: true, html: { class: "notification-form no-label" } do |f|
= hidden_setting_source_input(notification_setting)
= hidden_field_tag "hide_label", true
= f.hidden_field :level, class: "notification_setting_level"
diff --git a/app/views/shared/projects/_search_form.html.haml b/app/views/shared/projects/_search_form.html.haml
index 7b76d6d789b..e96a9152c80 100644
--- a/app/views/shared/projects/_search_form.html.haml
+++ b/app/views/shared/projects/_search_form.html.haml
@@ -7,7 +7,6 @@
class: "project-filter-form-field form-control #{form_field_classes}",
spellcheck: false,
id: 'project-filter-form-field',
- tabindex: "2",
autofocus: local_assigns[:autofocus]
- if local_assigns[:icon]
diff --git a/app/views/shared/web_hooks/_form.html.haml b/app/views/shared/web_hooks/_form.html.haml
index 9c60201412c..c5234f14090 100644
--- a/app/views/shared/web_hooks/_form.html.haml
+++ b/app/views/shared/web_hooks/_form.html.haml
@@ -78,6 +78,18 @@
%strong= s_('Webhooks|Deployment events')
%p.text-muted.ml-1
= s_('Webhooks|This URL is triggered when a deployment starts, finishes, fails, or is canceled')
+ %li
+ = form.check_box :feature_flag_events, class: 'form-check-input'
+ = form.label :feature_flag_events, class: 'list-label form-check-label ml-1' do
+ %strong= s_('Webhooks|Feature Flag events')
+ %p.text-muted.ml-1
+ = s_('Webhooks|This URL is triggered when a feature flag is turned on or off')
+ %li
+ = form.check_box :releases_events, class: 'form-check-input'
+ = form.label :releases_events, class: 'list-label form-check-label ml-1' do
+ %strong= s_('Webhooks|Releases events')
+ %p.text-muted.ml-1
+ = s_('Webhooks|This URL is triggered when a release is created/updated')
.form-group
= form.label :enable_ssl_verification, s_('Webhooks|SSL verification'), class: 'label-bold checkbox'
.form-check
diff --git a/app/views/shared/wikis/_sidebar.html.haml b/app/views/shared/wikis/_sidebar.html.haml
index 893661755ab..c0ed7b4c6f2 100644
--- a/app/views/shared/wikis/_sidebar.html.haml
+++ b/app/views/shared/wikis/_sidebar.html.haml
@@ -1,7 +1,7 @@
%aside.right-sidebar.right-sidebar-expanded.wiki-sidebar.js-wiki-sidebar.js-right-sidebar{ data: { "offset-top" => "50", "spy" => "affix" } }
.sidebar-container
.block.wiki-sidebar-header.gl-mb-3.w-100
- %a.gutter-toggle.float-right.d-block.d-sm-block.d-md-none.js-sidebar-wiki-toggle{ href: "#" }
+ %a.gutter-toggle.float-right.d-block.d-md-none.js-sidebar-wiki-toggle{ href: "#" }
= sprite_icon('chevron-double-lg-right', css_class: 'gl-icon')
- if @wiki.container.is_a?(Project)
diff --git a/app/views/sherlock/transactions/_file_samples.html.haml b/app/views/sherlock/transactions/_file_samples.html.haml
index 5b3448605f2..110eb42f9ea 100644
--- a/app/views/sherlock/transactions/_file_samples.html.haml
+++ b/app/views/sherlock/transactions/_file_samples.html.haml
@@ -21,4 +21,4 @@
%td
= link_to(t('sherlock.view'),
sherlock_transaction_file_sample_path(@transaction, sample),
- class: 'btn btn-sm')
+ class: 'gl-button btn btn-sm')
diff --git a/app/views/sherlock/transactions/_queries.html.haml b/app/views/sherlock/transactions/_queries.html.haml
index 5e224f3aa0e..afe23d61bcd 100644
--- a/app/views/sherlock/transactions/_queries.html.haml
+++ b/app/views/sherlock/transactions/_queries.html.haml
@@ -21,4 +21,4 @@
%td
= link_to(t('sherlock.view'),
sherlock_transaction_query_path(@transaction, query),
- class: 'btn btn-sm')
+ class: 'gl-button btn btn-sm')
diff --git a/app/views/sherlock/transactions/index.html.haml b/app/views/sherlock/transactions/index.html.haml
index 1e16c88571e..a2be6cae1e0 100644
--- a/app/views/sherlock/transactions/index.html.haml
+++ b/app/views/sherlock/transactions/index.html.haml
@@ -4,7 +4,7 @@
.row-content-block
.float-right
= link_to(destroy_all_sherlock_transactions_path,
- class: 'btn btn-danger',
+ class: 'gl-button btn btn-danger',
method: :delete) do
= sprite_icon('remove')
= t('sherlock.delete_all_transactions')
@@ -37,5 +37,5 @@
%td
= time_ago_with_tooltip trans.finished_at
%td
- = link_to(sherlock_transaction_path(trans), class: 'btn btn-sm') do
+ = link_to(sherlock_transaction_path(trans), class: 'gl-button btn btn-sm') do
= t('sherlock.view')
diff --git a/app/views/snippets/notes/_actions.html.haml b/app/views/snippets/notes/_actions.html.haml
index 310d9946663..2e94bbe4baf 100644
--- a/app/views/snippets/notes/_actions.html.haml
+++ b/app/views/snippets/notes/_actions.html.haml
@@ -8,7 +8,7 @@
- if note_editable
.note-actions-item
- = button_tag title: _('Edit comment'), class: 'note-action-button js-note-edit has-tooltip btn btn-transparent', data: { container: 'body', qa_selector: 'edit_comment_button' } do
+ = button_tag title: _('Edit comment'), class: 'note-action-button js-note-edit has-tooltip gl-button btn btn-transparent', data: { container: 'body', qa_selector: 'edit_comment_button' } do
%span.link-highlight
= custom_icon('icon_pencil')
diff --git a/app/views/snippets/show.html.haml b/app/views/snippets/show.html.haml
index 77a6ff5455e..beb4cf4a6aa 100644
--- a/app/views/snippets/show.html.haml
+++ b/app/views/snippets/show.html.haml
@@ -1,3 +1,9 @@
+- add_page_startup_graphql_call('snippet/snippet', { ids: [@snippet.to_global_id.uri] })
+- add_page_startup_graphql_call('snippet/snippet_blob_content', { ids: [@snippet.to_global_id.uri], rich: false, paths: [@snippet.file_name] })
+- if @snippet.project_id?
+ - add_page_startup_graphql_call('snippet/project_permissions', { fullPath: @snippet.project_id })
+- else
+ - add_page_startup_graphql_call('snippet/user_permissions')
- @hide_top_links = true
- @content_class = "limit-container-width limited-inner-width-container" unless fluid_layout
- add_to_breadcrumbs _("Snippets"), dashboard_snippets_path
diff --git a/app/views/users/_groups.html.haml b/app/views/users/_groups.html.haml
deleted file mode 100644
index 6d7a52c7688..00000000000
--- a/app/views/users/_groups.html.haml
+++ /dev/null
@@ -1,5 +0,0 @@
-.clearfix
- - groups.each do |group|
- = link_to group, class: 'profile-groups-avatars inline', title: group.name do
- .avatar-container.rect-avatar.s40
- = group_icon(group, class: 'avatar group-avatar s40')
diff --git a/app/views/users/_overview.html.haml b/app/views/users/_overview.html.haml
index 294af53e35b..1367d80cf54 100644
--- a/app/views/users/_overview.html.haml
+++ b/app/views/users/_overview.html.haml
@@ -1,12 +1,14 @@
- activity_pane_class = Feature.enabled?(:security_auto_fix) && @user.bot? ? "col-12" : "col-md-12 col-lg-6"
-.row
- .col-12
- .calendar-block.gl-mt-3.gl-mb-3
- .user-calendar.d-none.d-sm-block{ data: { calendar_path: user_calendar_path(@user, :json), calendar_activities_path: user_calendar_activities_path, utc_offset: Time.zone.utc_offset } }
- %h4.center.light
- .spinner.spinner-md
- .user-calendar-activities.d-none.d-sm-block
+.row.d-none.d-sm-flex
+ .col-12.calendar-block.gl-my-3
+ .user-calendar.light{ data: { calendar_path: user_calendar_path(@user, :json), calendar_activities_path: user_calendar_activities_path, utc_offset: Time.zone.utc_offset } }
+ .spinner.spinner-md.gl-my-8
+ .user-calendar-error.invisible
+ = _('There was an error loading users activity calendar.')
+ %a.js-retry-load{ href: '#' }
+ = s_('UserProfile|Retry')
+ .user-calendar-activities
.row
%div{ class: activity_pane_class }
- if can?(current_user, :read_cross_project)
diff --git a/app/views/users/show.html.haml b/app/views/users/show.html.haml
index 2746a139dd0..ee037a7d66a 100644
--- a/app/views/users/show.html.haml
+++ b/app/views/users/show.html.haml
@@ -4,6 +4,7 @@
- page_title @user.blocked? ? s_('UserProfile|Blocked user') : @user.name
- page_description @user.bio_html
- header_title @user.name, user_path(@user)
+- page_itemtype 'http://schema.org/Person'
- link_classes = "flex-grow-1 mx-1 "
= content_for :meta_tags do
@@ -35,7 +36,7 @@
.profile-header{ class: [('with-no-profile-tabs' if profile_tabs.empty?)] }
.avatar-holder
= link_to avatar_icon_for_user(@user, 400), target: '_blank', rel: 'noopener noreferrer' do
- = image_tag avatar_icon_for_user(@user, 90), class: "avatar s90", alt: ''
+ = image_tag avatar_icon_for_user(@user, 90), class: "avatar s90", alt: '', itemprop: 'image'
- if @user.blocked?
.user-info
@@ -44,25 +45,27 @@
= render "users/profile_basic_info"
- else
.user-info
- .cover-title
+ .cover-title{ itemprop: 'name' }
= @user.name
+ - if @user&.status && user_status_set_to_busy?(@user.status)
+ %span.gl-font-base.gl-text-gray-500.gl-vertical-align-middle= s_("UserProfile|(Busy)")
- - if @user.status
+ - if show_status_emoji?(@user.status)
.cover-status
= emoji_icon(@user.status.emoji)
= markdown_field(@user.status, :message)
= render "users/profile_basic_info"
.cover-desc.cgray.mb-1.mb-sm-2
- unless @user.location.blank?
- .profile-link-holder.middle-dot-divider-sm.d-block.d-sm-inline.mb-1.mb-sm-0
+ .profile-link-holder.middle-dot-divider-sm.d-block.d-sm-inline.mb-1.mb-sm-0{ itemprop: 'address', itemscope: true, itemtype: 'https://schema.org/PostalAddress' }
= sprite_icon('location', css_class: 'vertical-align-sub fgray')
- %span.vertical-align-middle
+ %span.vertical-align-middle{ itemprop: 'addressLocality' }
= @user.location
- unless work_information(@user).blank?
.profile-link-holder.middle-dot-divider-sm.d-block.d-sm-inline
= sprite_icon('work', css_class: 'vertical-align-middle fgray')
%span.vertical-align-middle
- = work_information(@user)
+ = work_information(@user, with_schema_markup: true)
.cover-desc.cgray.mb-1.mb-sm-2
- unless @user.skype.blank?
.profile-link-holder.middle-dot-divider
@@ -80,10 +83,10 @@
.profile-link-holder.middle-dot-divider-sm.d-block.d-sm-inline.mt-1.mt-sm-0
- if Feature.enabled?(:security_auto_fix) && @user.bot?
= sprite_icon('question', css_class: 'gl-text-blue-600')
- = link_to @user.short_website_url, @user.full_website_url, class: 'text-link', target: '_blank', rel: 'me noopener noreferrer nofollow'
+ = link_to @user.short_website_url, @user.full_website_url, class: 'text-link', target: '_blank', rel: 'me noopener noreferrer nofollow', itemprop: 'url'
- unless @user.public_email.blank?
.profile-link-holder.middle-dot-divider-sm.d-block.d-sm-inline.mt-1.mt-sm-0
- = link_to @user.public_email, "mailto:#{@user.public_email}", class: 'text-link'
+ = link_to @user.public_email, "mailto:#{@user.public_email}", class: 'text-link', itemprop: 'email'
- if @user.bio.present?
.cover-desc.cgray
.profile-user-bio
diff --git a/app/views/users/terms/index.html.haml b/app/views/users/terms/index.html.haml
index 175fde1c862..da8b73fd4fd 100644
--- a/app/views/users/terms/index.html.haml
+++ b/app/views/users/terms/index.html.haml
@@ -6,13 +6,13 @@
.card-footer.footer-block.clearfix
- if can?(current_user, :accept_terms, @term)
.float-right
- = button_to accept_term_path(@term, redirect_params), class: 'btn btn-success gl-ml-3', data: { qa_selector: 'accept_terms_button' } do
+ = button_to accept_term_path(@term, redirect_params), class: 'gl-button btn btn-success gl-ml-3', data: { qa_selector: 'accept_terms_button' } do
= _('Accept terms')
- else
.float-right
- = link_to root_path, class: 'btn btn-success gl-ml-3' do
+ = link_to root_path, class: 'gl-button btn btn-success gl-ml-3' do
= _('Continue')
- if can?(current_user, :decline_terms, @term)
.float-right
- = button_to decline_term_path(@term, redirect_params), class: 'btn btn-default gl-ml-3' do
+ = button_to decline_term_path(@term, redirect_params), class: 'gl-button btn btn-default gl-ml-3' do
= _('Decline and sign out')