diff options
Diffstat (limited to 'app/views')
228 files changed, 1237 insertions, 1053 deletions
diff --git a/app/views/admin/application_settings/_account_and_limit.html.haml b/app/views/admin/application_settings/_account_and_limit.html.haml index 1e2c9f821d2..eb30efabb98 100644 --- a/app/views/admin/application_settings/_account_and_limit.html.haml +++ b/app/views/admin/application_settings/_account_and_limit.html.haml @@ -53,6 +53,14 @@ = _('Specify an e-mail address regex pattern to identify default internal users.') = link_to _('More information'), help_page_path('user/permissions', anchor: 'setting-new-users-to-external'), target: '_blank' + - unless Gitlab.com? + .form-group + = f.label :deactivate_dormant_users, _('Dormant users'), class: 'label-bold' + .form-check + = f.check_box :deactivate_dormant_users, class: 'form-check-input' + = f.label :deactivate_dormant_users, class: 'form-check-label' do + = _('Deactivate dormant users after 90 days of inactivity. Users can return to active status by signing in to their account. While inactive, a user is not counted as an active user in the instance.') + = link_to _('More information'), help_page_path('user/admin_area/moderate_users', anchor: 'automatically-deactivate-dormant-users'), target: '_blank' .form-group = f.label :personal_access_token_prefix, _('Personal Access Token prefix'), class: 'label-light' = f.text_field :personal_access_token_prefix, placeholder: _('Max 20 characters'), class: 'form-control gl-form-input' diff --git a/app/views/admin/application_settings/_ci_cd.html.haml b/app/views/admin/application_settings/_ci_cd.html.haml index 0af244d54f3..5ae45d5a9da 100644 --- a/app/views/admin/application_settings/_ci_cd.html.haml +++ b/app/views/admin/application_settings/_ci_cd.html.haml @@ -3,15 +3,13 @@ %fieldset .form-group - .card.auto-devops-card - .card-body - .form-check - = f.check_box :auto_devops_enabled, class: 'form-check-input' - = f.label :auto_devops_enabled, class: 'form-check-label' do - = s_('CICD|Default to Auto DevOps pipeline for all projects') - .form-text.text-muted - = s_('CICD|The Auto DevOps pipeline will run if no alternative CI configuration file is found.') - = link_to _('More information'), help_page_path('topics/autodevops/index.md'), target: '_blank' + .form-check + = f.check_box :auto_devops_enabled, class: 'form-check-input' + = f.label :auto_devops_enabled, class: 'form-check-label' do + %strong= s_('CICD|Default to Auto DevOps pipeline for all projects') + .form-text.text-muted + = s_('CICD|The Auto DevOps pipeline runs by default in all projects with no CI/CD configuration file.') + = link_to _('What is Auto DevOps?'), help_page_path('topics/autodevops/index.md'), target: '_blank' .form-group = f.label :auto_devops_domain, s_('AdminSettings|Auto DevOps domain'), class: 'label-bold' = f.text_field :auto_devops_domain, class: 'form-control gl-form-input', placeholder: 'domain.com' @@ -26,9 +24,9 @@ = render_if_exists 'admin/application_settings/shared_runners_minutes_setting', form: f .form-group - = f.label :shared_runners_text, class: 'label-bold' + = f.label :shared_runners_text, _('Shared runners details'), class: 'label-bold' = f.text_area :shared_runners_text, class: 'form-control gl-form-input', rows: 4 - .form-text.text-muted= _("Markdown enabled") + .form-text.text-muted= _("Add a custom message with details about the instance's shared runners. The message is visible in group and project CI/CD settings, in the Runners section. Markdown is supported.") .form-group = f.label :max_artifacts_size, _('Maximum artifacts size (MB)'), class: 'label-bold' = f.number_field :max_artifacts_size, class: 'form-control gl-form-input' @@ -58,14 +56,14 @@ .form-check = f.check_box :protected_ci_variables, class: 'form-check-input' = f.label :protected_ci_variables, class: 'form-check-label' do - = s_('AdminSettings|Environment variables are protected by default') + %strong= s_('AdminSettings|Protect CI/CD variables by default') .form-text.text-muted - = s_('AdminSettings|When creating a new environment variable it will be protected by default.') + = s_('AdminSettings|New CI/CD variables in projects and groups default to protected.') .form-group - = f.label :ci_config_path, _('Default CI configuration path'), class: 'label-bold' + = f.label :ci_config_path, _('Default CI/CD configuration file'), class: 'label-bold' = f.text_field :default_ci_config_path, class: 'form-control gl-form-input', placeholder: '.gitlab-ci.yml' %p.form-text.text-muted - = _("The default CI configuration path for new projects.").html_safe - = link_to sprite_icon('question-o'), help_page_path('ci/pipelines/settings', anchor: 'custom-cicd-configuration-path'), target: '_blank' + = _("The default CI/CD configuration file and path for new projects.").html_safe + = link_to sprite_icon('question-o'), help_page_path('ci/pipelines/settings', anchor: 'custom-cicd-configuration-file'), target: '_blank' = f.submit _('Save changes'), class: "gl-button btn btn-confirm" diff --git a/app/views/admin/application_settings/_diff_limits.html.haml b/app/views/admin/application_settings/_diff_limits.html.haml index 7286fffcaf6..6a51d2e39d4 100644 --- a/app/views/admin/application_settings/_diff_limits.html.haml +++ b/app/views/admin/application_settings/_diff_limits.html.haml @@ -3,13 +3,30 @@ %fieldset .form-group - = f.label :diff_max_patch_bytes, 'Maximum diff patch size (Bytes)', class: 'label-light' + = f.label :diff_max_patch_bytes, _('Maximum diff patch size (Bytes)'), class: 'label-light' = f.number_field :diff_max_patch_bytes, class: 'form-control gl-form-input' %span.form-text.text-muted - Diff files surpassing this limit will be presented as 'too large' - and won't be expandable. + = _("Diff files surpassing this limit will be presented as 'too large' and won't be expandable.") = link_to sprite_icon('question-o'), help_page_path('user/admin_area/diff_limits', - anchor: 'maximum-diff-patch-size') + anchor: 'diff-limits-administration') + + = f.label :diff_max_files, _('Maximum files in a diff'), class: 'label-light' + = f.number_field :diff_max_files, class: 'form-control gl-form-input' + %span.form-text.text-muted + = _("Diff files surpassing this limit will be presented as 'too large' and won't be expandable.") + + = link_to sprite_icon('question-o'), + help_page_path('user/admin_area/diff_limits', + anchor: 'diff-limits-administration') + + = f.label :diff_max_lines, _('Maximum lines in a diff'), class: 'label-light' + = f.number_field :diff_max_lines, class: 'form-control gl-form-input' + %span.form-text.text-muted + = _("Diff files surpassing this limit will be presented as 'too large' and won't be expandable.") + + = link_to sprite_icon('question-o'), + help_page_path('user/admin_area/diff_limits', + anchor: 'diff-limits-administration') = f.submit _('Save changes'), class: 'gl-button btn btn-confirm' diff --git a/app/views/admin/application_settings/_gitpod.html.haml b/app/views/admin/application_settings/_gitpod.html.haml index 6d335e2db16..c08b41e8c55 100644 --- a/app/views/admin/application_settings/_gitpod.html.haml +++ b/app/views/admin/application_settings/_gitpod.html.haml @@ -22,7 +22,9 @@ = f.label :gitpod_enabled, s_('Gitpod|Enable Gitpod integration'), class: 'form-check-label' .form-group = f.label :gitpod_url, s_('Gitpod|Gitpod URL'), class: 'label-bold' - = f.text_field :gitpod_url, class: 'form-control gl-form-input', placeholder: s_('Gitpod|e.g. https://gitpod.example.com') + = f.text_field :gitpod_url, class: 'form-control gl-form-input', placeholder: s_('Gitpod|https://gitpod.example.com') .form-text.text-muted - = s_('Gitpod|Add the URL to your Gitpod instance configured to read your GitLab projects.') + = s_('Gitpod|The URL to your Gitpod instance configured to read your GitLab projects, such as https://gitpod.example.com.') + - link_start = '<a href="%{url}">'.html_safe % { url: help_page_path('integration/gitpod', anchor: 'enable-gitpod-in-your-user-settings') } + = s_('Gitpod|To use the integration, each user must also enable Gitpod on their GitLab account. %{link_start}How do I enable it?%{link_end} ').html_safe % { link_start: link_start, link_end: '</a>'.html_safe } = f.submit s_('Save changes'), class: 'gl-button btn btn-confirm' diff --git a/app/views/admin/appearances/_form.html.haml b/app/views/admin/application_settings/appearances/_form.html.haml index 872a6bef18b..a48b57bffd9 100644 --- a/app/views/admin/appearances/_form.html.haml +++ b/app/views/admin/application_settings/appearances/_form.html.haml @@ -1,6 +1,6 @@ - parsed_with_gfm = (_("Content parsed with %{link}.") % { link: link_to('GitLab Flavored Markdown', help_page_path('user/markdown'), target: '_blank') }).html_safe -= form_for @appearance, url: admin_appearances_path, html: { class: 'gl-mt-3' } do |f| += form_for @appearance, url: admin_application_settings_appearances_path, html: { class: 'gl-mt-3' } do |f| = form_errors(@appearance) @@ -16,7 +16,7 @@ = image_tag @appearance.header_logo_path, class: 'appearance-light-logo-preview' - if @appearance.persisted? %br - = link_to _('Remove header logo'), header_logos_admin_appearances_path, data: { confirm: _("Header logo will be removed. Are you sure?") }, method: :delete, class: "btn gl-button btn-danger btn-danger-secondary btn-sm" + = link_to _('Remove header logo'), header_logos_admin_application_settings_appearances_path, data: { confirm: _("Header logo will be removed. Are you sure?") }, method: :delete, class: "btn gl-button btn-danger btn-danger-secondary btn-sm" %hr = f.hidden_field :header_logo_cache = f.file_field :header_logo, class: "", accept: 'image/*' @@ -35,7 +35,7 @@ = image_tag @appearance.favicon_path, class: 'appearance-light-logo-preview' - if @appearance.persisted? %br - = link_to _('Remove favicon'), favicon_admin_appearances_path, data: { confirm: _("Favicon will be removed. Are you sure?") }, method: :delete, class: "btn gl-button btn-danger btn-danger-secondary btn-sm" + = link_to _('Remove favicon'), favicon_admin_application_settings_appearances_path, data: { confirm: _("Favicon will be removed. Are you sure?") }, method: :delete, class: "btn gl-button btn-danger btn-danger-secondary btn-sm" %hr = f.hidden_field :favicon_cache = f.file_field :favicon, class: '', accept: 'image/*' @@ -44,7 +44,7 @@ %br = _("Images with incorrect dimensions are not resized automatically, and may result in unexpected behavior.") - = render partial: 'admin/appearances/system_header_footer_form', locals: { form: f } + = render partial: 'admin/application_settings/appearances/system_header_footer_form', locals: { form: f } %hr .row @@ -67,7 +67,7 @@ = image_tag @appearance.logo_path, class: 'appearance-logo-preview' - if @appearance.persisted? %br - = link_to _('Remove logo'), logo_admin_appearances_path, data: { confirm: _("Logo will be removed. Are you sure?") }, method: :delete, class: "btn gl-button btn-danger btn-danger-secondary btn-sm remove-logo" + = link_to _('Remove logo'), logo_admin_application_settings_appearances_path, data: { confirm: _("Logo will be removed. Are you sure?") }, method: :delete, class: "btn gl-button btn-danger btn-danger-secondary btn-sm remove-logo" %hr = f.hidden_field :logo_cache = f.file_field :logo, class: "", accept: 'image/*' @@ -106,7 +106,7 @@ .mt-4 - if @appearance.persisted? Preview last save: - = link_to _('Sign-in page'), preview_sign_in_admin_appearances_path, class: 'btn', target: '_blank', rel: 'noopener noreferrer' + = link_to _('Sign-in page'), preview_sign_in_admin_application_settings_appearances_path, class: 'btn', target: '_blank', rel: 'noopener noreferrer' = link_to _('New project page'), new_project_path, class: 'btn', target: '_blank', rel: 'noopener noreferrer' - if @appearance.updated_at diff --git a/app/views/admin/appearances/_system_header_footer_form.html.haml b/app/views/admin/application_settings/appearances/_system_header_footer_form.html.haml index 4571d34a497..4571d34a497 100644 --- a/app/views/admin/appearances/_system_header_footer_form.html.haml +++ b/app/views/admin/application_settings/appearances/_system_header_footer_form.html.haml diff --git a/app/views/admin/appearances/preview_sign_in.html.haml b/app/views/admin/application_settings/appearances/preview_sign_in.html.haml index a317611862c..77c37abbeef 100644 --- a/app/views/admin/appearances/preview_sign_in.html.haml +++ b/app/views/admin/application_settings/appearances/preview_sign_in.html.haml @@ -8,5 +8,5 @@ = label_tag :password = password_field_tag :password, nil, class: "form-control gl-form-input bottom", title: _('This field is required.') .form-group - = button_tag _("Sign in"), class: "btn gl-button btn-confirm" + = button_tag _("Sign in"), class: "btn gl-button btn-confirm", type: "button" diff --git a/app/views/admin/appearances/show.html.haml b/app/views/admin/application_settings/appearances/show.html.haml index 77a08913666..77a08913666 100644 --- a/app/views/admin/appearances/show.html.haml +++ b/app/views/admin/application_settings/appearances/show.html.haml diff --git a/app/views/admin/application_settings/ci/_header.html.haml b/app/views/admin/application_settings/ci/_header.html.haml index 919f501d2ee..40486e9a9e6 100644 --- a/app/views/admin/application_settings/ci/_header.html.haml +++ b/app/views/admin/application_settings/ci/_header.html.haml @@ -8,7 +8,7 @@ %p = _('Variables store information, like passwords and secret keys, that you can use in job scripts. All projects on the instance can use these variables.') - = link_to s_('Learn more.'), help_page_path('ci/variables/README', anchor: 'instance-cicd-variables'), target: '_blank', rel: 'noopener noreferrer' + = link_to s_('Learn more.'), help_page_path('ci/variables/README', anchor: 'add-a-cicd-variable-to-an-instance'), target: '_blank', rel: 'noopener noreferrer' %p = _('Variables can be:') %ul diff --git a/app/views/admin/application_settings/ci_cd.html.haml b/app/views/admin/application_settings/ci_cd.html.haml index d38b4cba40a..127ab8ea1f4 100644 --- a/app/views/admin/application_settings/ci_cd.html.haml +++ b/app/views/admin/application_settings/ci_cd.html.haml @@ -19,7 +19,7 @@ %button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' } = expanded_by_default? ? _('Collapse') : _('Expand') %p - = _('Auto DevOps, runners and job artifacts') + = _('Customize CI/CD settings, including Auto DevOps, shared runners, and job artifacts.') .settings-content = render 'ci_cd' diff --git a/app/views/admin/application_settings/general.html.haml b/app/views/admin/application_settings/general.html.haml index 217225e6186..0fbbef02613 100644 --- a/app/views/admin/application_settings/general.html.haml +++ b/app/views/admin/application_settings/general.html.haml @@ -31,7 +31,7 @@ %button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' } = expanded_by_default? ? _('Collapse') : _('Expand') %p - = _('Diff content limits') + = _('Set size limits for displaying diffs in the browser.') .settings-content = render 'diff_limits' @@ -88,7 +88,7 @@ %button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' } = expanded_by_default? ? _('Collapse') : _('Expand') %p - = _('Manage Web IDE features') + = _('Manage Web IDE features.') .settings-content = form_for @application_setting, url: general_admin_application_settings_path(anchor: "#js-web-ide-settings"), html: { class: 'fieldset-form', id: 'web-ide-settings' } do |f| = form_errors(@application_setting) @@ -100,7 +100,8 @@ = f.label :web_ide_clientside_preview_enabled, class: 'form-check-label' do = s_('IDE|Live Preview') %span.form-text.text-muted - = s_('IDE|Allow live previews of JavaScript projects in the Web IDE using CodeSandbox Live Preview.') + - link_start = '<a href="%{url}">'.html_safe % { url: help_page_path('user/project/web_ide/index', anchor: 'enable-live-preview') } + = s_('Preview JavaScript projects in the Web IDE with CodeSandbox Live Preview. %{link_start}Learn more.%{link_end} ').html_safe % { link_start: link_start, link_end: '</a>'.html_safe } = f.submit _('Save changes'), class: "gl-button btn btn-confirm" = render_if_exists 'admin/application_settings/maintenance_mode_settings_form' diff --git a/app/views/admin/application_settings/integrations.html.haml b/app/views/admin/application_settings/integrations.html.haml index 93bc054754e..7a81d53c085 100644 --- a/app/views/admin/application_settings/integrations.html.haml +++ b/app/views/admin/application_settings/integrations.html.haml @@ -2,19 +2,8 @@ - page_title _('Integrations') - @content_class = 'limit-container-width' unless fluid_layout -- if show_admin_integrations_moved? - .gl-alert.gl-alert-info.js-admin-integrations-moved.mt-3{ role: 'alert', data: { feature_id: UserCalloutsHelper::ADMIN_INTEGRATIONS_MOVED, dismiss_endpoint: user_callouts_path } } - = 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 - %h4.gl-alert-title= s_('AdminSettings|Some settings have moved') - = html_escape_once(s_('AdminSettings|PlantUML, Slack application, Third party offers, Snowplow, Amazon EKS have moved to Settings > General.')).html_safe - .gl-alert-actions - = link_to s_('AdminSettings|Go to General Settings'), general_admin_application_settings_path, class: 'btn gl-alert-action btn-info gl-button' - %h3= s_('Integrations|Project integration management') - integrations_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: integrations_help_page_path } -%p= s_('Integrations|As a GitLab administrator, you can set default configuration parameters for a given integration that all projects can inherit and use. When you set these parameters, your changes update the integration for all projects that are not already using custom settings. Learn more about %{integrations_link_start}Project integration management%{link_end}.').html_safe % { integrations_link_start: integrations_link_start, link_end: '</a>'.html_safe } +%p= s_("Integrations|GitLab administrators can set up integrations that all projects inherit and use by default. These integrations apply to all projects that don't already use custom settings. You can override custom settings for a group or project if the settings are necessary at that level. Learn more about %{integrations_link_start}project integration management%{link_end}.").html_safe % { integrations_link_start: integrations_link_start, link_end: "</a>".html_safe } = render 'shared/integrations/index', integrations: @integrations diff --git a/app/views/admin/background_migrations/_migration.html.haml b/app/views/admin/background_migrations/_migration.html.haml new file mode 100644 index 00000000000..40860ea9400 --- /dev/null +++ b/app/views/admin/background_migrations/_migration.html.haml @@ -0,0 +1,10 @@ +%tr{ role: 'row' } + %td{ role: 'cell', data: { label: _('Migration') } }= migration.job_class_name + ': ' + migration.table_name + %td{ role: 'cell', data: { label: _('Progress') } } + - progress = batched_migration_progress(migration, @successful_rows_counts[migration.id]) + - if progress + = number_to_percentage(progress, precision: 2) + - else + = _('Unknown') + %td{ role: 'cell', data: { label: _('Status') } } + %span.badge.badge-pill.gl-badge.sm{ class: batched_migration_status_badge_class_name(migration) }= migration.status.humanize diff --git a/app/views/admin/background_migrations/index.html.haml b/app/views/admin/background_migrations/index.html.haml new file mode 100644 index 00000000000..2a372c89912 --- /dev/null +++ b/app/views/admin/background_migrations/index.html.haml @@ -0,0 +1,35 @@ +- page_title _('Background Migrations') + +.tabs.gl-tabs + %div + %ul.nav.gl-tabs-nav{ role: 'tablist' } + - active_tab_classes = ['gl-tab-nav-item-active', 'gl-tab-nav-item-active-indigo'] + + %li.nav-item{ role: 'presentation' } + %a.nav-link.gl-tab-nav-item{ href: admin_background_migrations_path, class: (active_tab_classes if @current_tab == 'queued'), role: 'tab' } + = _('Queued') + %span.badge.gl-tab-counter-badge.badge-muted.badge-pill.gl-badge.sm + = limited_counter_with_delimiter(@relations_by_tab['queued']) + %li.nav-item{ role: 'presentation' } + %a.nav-link.gl-tab-nav-item{ href: admin_background_migrations_path(tab: 'failed'), class: (active_tab_classes if @current_tab == 'failed'), role: 'tab' } + = _('Failed') + %span.badge.gl-tab-counter-badge.badge-muted.badge-pill.gl-badge.sm + = limited_counter_with_delimiter(@relations_by_tab['failed']) + %li.nav-item{ role: 'presentation' } + %a.nav-link.gl-tab-nav-item{ href: admin_background_migrations_path(tab: 'finished'), class: (active_tab_classes if @current_tab == 'finished'), role: 'tab' } + = _('Finished') + %span.badge.gl-tab-counter-badge.badge-muted.badge-pill.gl-badge.sm + = limited_counter_with_delimiter(@relations_by_tab['finished']) + + .tab-content.gl-tab-content + .tab-pane.active{ role: 'tabpanel' } + %table.table.b-table.gl-table.b-table-stacked-md{ role: 'table' } + %thead{ role: 'rowgroup' } + %tr{ role: 'row' } + %th.table-th-transparent.border-bottom{ role: 'cell' }= _('Migration') + %th.table-th-transparent.border-bottom{ role: 'cell' }= _('Progress') + %th.table-th-transparent.border-bottom{ role: 'cell' }= _('Status') + %tbody{ role: 'rowgroup' } + = render partial: 'migration', collection: @migrations + + = paginate_collection @migrations diff --git a/app/views/admin/broadcast_messages/_form.html.haml b/app/views/admin/broadcast_messages/_form.html.haml index fe5759ecdbf..b68c22b6942 100644 --- a/app/views/admin/broadcast_messages/_form.html.haml +++ b/app/views/admin/broadcast_messages/_form.html.haml @@ -1,10 +1,12 @@ .broadcast-message.broadcast-banner-message.gl-alert-warning.js-broadcast-banner-message-preview.gl-mt-3{ style: broadcast_message_style(@broadcast_message), class: ('gl-display-none' unless @broadcast_message.banner? ) } - = sprite_icon('bullhorn', css_class: 'vertical-align-text-top') - .js-broadcast-message-preview - - if @broadcast_message.message.present? - = render_broadcast_message(@broadcast_message) - - else - = _('Your message here') + .gl-alert-container + = sprite_icon('bullhorn', css_class: 'vertical-align-text-top') + .js-broadcast-message-preview + .gl-alert-content + - if @broadcast_message.message.present? + = render_broadcast_message(@broadcast_message) + - else + = _('Your message here') .d-flex.justify-content-center .broadcast-message.broadcast-notification-message.preview.js-broadcast-notification-message-preview.mt-2{ class: ('hidden' unless @broadcast_message.notification? ) } = sprite_icon('bullhorn', css_class: 'vertical-align-text-top') diff --git a/app/views/admin/dashboard/index.html.haml b/app/views/admin/dashboard/index.html.haml index 2dbb804d537..58c65bdc8c7 100644 --- a/app/views/admin/dashboard/index.html.haml +++ b/app/views/admin/dashboard/index.html.haml @@ -9,6 +9,9 @@ dismissible: true.to_s } } = notice[:message].html_safe +- if Gitlab.ee? && display_upcoming_reconciliation_alert? + #js-qrtly-reconciliation-alert{ data: upcoming_reconciliation_hash } + - if @license.present? .license-panel.gl-mt-5 = render_if_exists 'admin/licenses/summary' diff --git a/app/views/admin/groups/_form.html.haml b/app/views/admin/groups/_form.html.haml index 84a9b988d22..e7e0e58f6fb 100644 --- a/app/views/admin/groups/_form.html.haml +++ b/app/views/admin/groups/_form.html.haml @@ -27,10 +27,12 @@ - if @group.new_record? .form-group.row .offset-sm-2.col-sm-10 - .gl-alert.gl-alert-info - = sprite_icon('information-o', size: 16, css_class: 'gl-icon gl-alert-icon gl-alert-icon-no-title') - .gl-alert-body - = render 'shared/group_tips' + .gl-alert.gl-alert- + .gl-alert-container + = sprite_icon('information-o', size: 16, css_class: 'gl-icon gl-alert-icon gl-alert-icon-no-title') + .gl-alert-content + .gl-alert-body + = render 'shared/group_tips' .form-actions = f.submit _('Create group'), class: "gl-button btn btn-confirm" = link_to _('Cancel'), admin_groups_path, class: "gl-button btn btn-default btn-cancel" diff --git a/app/views/admin/runners/_runner.html.haml b/app/views/admin/runners/_runner.html.haml index c3e4626c14e..da2fcd5a4a6 100644 --- a/app/views/admin/runners/_runner.html.haml +++ b/app/views/admin/runners/_runner.html.haml @@ -1,7 +1,7 @@ -# Note: This file should stay aligned with: -# `app/views/groups/runners/_runner.html.haml` -.gl-responsive-table-row{ id: dom_id(runner) } +.gl-responsive-table-row{ data: { testid: "runner-row-#{runner.id}" } } .table-section.section-10.section-wrap .table-mobile-header{ role: 'rowheader' }= _('Type') .table-mobile-content diff --git a/app/views/admin/runners/index.html.haml b/app/views/admin/runners/index.html.haml index 359e5b411b1..07fbc3e5398 100644 --- a/app/views/admin/runners/index.html.haml +++ b/app/views/admin/runners/index.html.haml @@ -1,87 +1,97 @@ - breadcrumb_title _('Runners') - page_title _('Runners') -.row - .col-sm-6 - .bs-callout - %p - = _("Runners are processes that pick up and execute CI/CD jobs for GitLab.") - %br - = _('You can register runners as separate users, on separate servers, and on your local machine. Register as many runners as you want.') - %br +- if Feature.enabled?(:runner_list_view_vue_ui, current_user, default_enabled: :yaml) + #js-runner-list{ data: { registration_token: Gitlab::CurrentSettings.runners_registration_token, runner_install_help_page: 'https://docs.gitlab.com/runner/install/', active_runners_count: @active_runners_count } } +- else + .row + .col-sm-6 + .bs-callout + %p + = _("Runners are processes that pick up and execute CI/CD jobs for GitLab.") + %br + = _('You can register runners as separate users, on separate servers, and on your local machine. Register as many runners as you want.') + %br - %div - %span= _('Runners can be:') - %ul - %li - %span.badge.badge-pill.gl-badge.sm.badge-success shared - \- - = _('Runs jobs from all unassigned projects.') - %li - %span.badge.badge-pill.gl-badge.sm.badge-success group - \- - = _('Runs jobs from all unassigned projects in its group.') - %li - %span.badge.badge-pill.gl-badge.sm.badge-info specific - \- - = _('Runs jobs from assigned projects.') - %li - %span.badge.badge-pill.gl-badge.sm.badge-warning locked - \- - = _('Cannot be assigned to other projects.') - %li - %span.badge.badge-pill.gl-badge.sm.badge-danger paused - \- - = _('Not available to run jobs.') + %div + %span= _('Runners can be:') + %ul + %li + %span.badge.badge-pill.gl-badge.sm.badge-success shared + \- + = _('Runs jobs from all unassigned projects.') + %li + %span.badge.badge-pill.gl-badge.sm.badge-success group + \- + = _('Runs jobs from all unassigned projects in its group.') + %li + %span.badge.badge-pill.gl-badge.sm.badge-info specific + \- + = _('Runs jobs from assigned projects.') + %li + %span.badge.badge-pill.gl-badge.sm.badge-warning locked + \- + = _('Cannot be assigned to other projects.') + %li + %span.badge.badge-pill.gl-badge.sm.badge-danger paused + \- + = _('Not available to run jobs.') - .col-sm-6 - .bs-callout - = render partial: 'ci/runner/how_to_setup_runner', - locals: { registration_token: Gitlab::CurrentSettings.runners_registration_token, - type: 'shared', - reset_token_url: reset_registration_token_admin_application_settings_path, - project_path: '', - group_path: '' } + .col-sm-6 + .bs-callout + = 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, + project_path: '', + group_path: '' } -.row - .col-sm-9 - = form_tag admin_runners_path, id: 'runners-search', method: :get, class: 'filter-form js-filter-form' do - .filtered-search-wrapper.d-flex - .filtered-search-box - = dropdown_tag(_('Recent searches'), - options: { wrapper_class: 'filtered-search-history-dropdown-wrapper', - toggle_class: 'gl-button btn btn-default filtered-search-history-dropdown-toggle-button', - dropdown_class: 'filtered-search-history-dropdown', - content_class: 'filtered-search-history-dropdown-content' }) do - .js-filtered-search-history-dropdown{ data: { full_path: admin_runners_path } } - .filtered-search-box-input-container.droplab-dropdown - .scroll-container - %ul.tokens-container.list-unstyled - %li.input-token - %input.form-control.filtered-search{ search_filter_input_options('runners') } - #js-dropdown-hint.filtered-search-input-dropdown-menu.dropdown-menu.hint-dropdown - %ul.filter-dropdown{ data: { dynamic: true, dropdown: true } } - %li.filter-dropdown-item{ data: {hint: "#{'{{hint}}'}", tag: "#{'{{tag}}'}", action: "#{'{{hint === \'search\' ? \'submit\' : \'\' }}'}" } } - = button_tag class: %w[gl-button btn btn-link] do - -# Encapsulate static class name `{{icon}}` inside #{} to bypass - -# haml lint's ClassAttributeWithStaticValue - %svg - %use{ 'xlink:href': "#{'{{icon}}'}" } - %span.js-filter-hint - {{formattedKey}} - #js-dropdown-operator.filtered-search-input-dropdown-menu.dropdown-menu - %ul.filter-dropdown{ data: { dropdown: true, dynamic: true } } - %li.filter-dropdown-item{ data: { value: "{{ title }}" } } - %button.gl-button.btn.btn-link{ type: 'button' } - {{ title }} - %span.btn-helptext - {{ help }} - #js-dropdown-admin-runner-status.filtered-search-input-dropdown-menu.dropdown-menu - %ul{ data: { dropdown: true } } - - Ci::Runner::AVAILABLE_STATUSES.each do |status| - %li.filter-dropdown-item{ data: { value: status } } + .row + .col-sm-9 + = form_tag admin_runners_path, id: 'runners-search', method: :get, class: 'filter-form js-filter-form' do + .filtered-search-wrapper.d-flex + .filtered-search-box + = dropdown_tag(_('Recent searches'), + options: { wrapper_class: 'filtered-search-history-dropdown-wrapper', + toggle_class: 'gl-button btn btn-default filtered-search-history-dropdown-toggle-button', + dropdown_class: 'filtered-search-history-dropdown', + content_class: 'filtered-search-history-dropdown-content' }) do + .js-filtered-search-history-dropdown{ data: { full_path: admin_runners_path } } + .filtered-search-box-input-container.droplab-dropdown + .scroll-container + %ul.tokens-container.list-unstyled + %li.input-token + %input.form-control.filtered-search{ search_filter_input_options('runners') } + #js-dropdown-hint.filtered-search-input-dropdown-menu.dropdown-menu.hint-dropdown + %ul.filter-dropdown{ data: { dynamic: true, dropdown: true } } + %li.filter-dropdown-item{ data: {hint: "#{'{{hint}}'}", tag: "#{'{{tag}}'}", action: "#{'{{hint === \'search\' ? \'submit\' : \'\' }}'}" } } = button_tag class: %w[gl-button btn btn-link] do - = status.titleize + -# Encapsulate static class name `{{icon}}` inside #{} to bypass + -# haml lint's ClassAttributeWithStaticValue + %svg + %use{ 'xlink:href': "#{'{{icon}}'}" } + %span.js-filter-hint + {{formattedKey}} + #js-dropdown-operator.filtered-search-input-dropdown-menu.dropdown-menu + %ul.filter-dropdown{ data: { dropdown: true, dynamic: true } } + %li.filter-dropdown-item{ data: { value: "{{ title }}" } } + %button.gl-button.btn.btn-link{ type: 'button' } + {{ title }} + %span.btn-helptext + {{ help }} + #js-dropdown-admin-runner-status.filtered-search-input-dropdown-menu.dropdown-menu + %ul{ data: { dropdown: true } } + - Ci::Runner::AVAILABLE_STATUSES.each do |status| + %li.filter-dropdown-item{ data: { value: status } } + = button_tag class: %w[gl-button btn btn-link] do + = status.titleize + + #js-dropdown-admin-runner-type.filtered-search-input-dropdown-menu.dropdown-menu + %ul{ data: { dropdown: true } } + - Ci::Runner::AVAILABLE_TYPES.each do |runner_type| + %li.filter-dropdown-item{ data: { value: runner_type } } + = button_tag class: %w[gl-button btn btn-link] do + = runner_type.titleize #js-dropdown-admin-runner-type.filtered-search-input-dropdown-menu.dropdown-menu %ul{ data: { dropdown: true } } @@ -90,49 +100,41 @@ = button_tag class: %w[gl-button btn btn-link] do = runner_type.titleize - #js-dropdown-admin-runner-type.filtered-search-input-dropdown-menu.dropdown-menu - %ul{ data: { dropdown: true } } - - Ci::Runner::AVAILABLE_TYPES.each do |runner_type| - %li.filter-dropdown-item{ data: { value: runner_type } } - = button_tag class: %w[gl-button btn btn-link] do - = runner_type.titleize - - #js-dropdown-runner-tag.filtered-search-input-dropdown-menu.dropdown-menu - %ul{ data: { dropdown: true } } - %li.filter-dropdown-item{ data: { value: 'none' } } - %button.gl-button.btn.btn-link - = _('No Tag') - %li.divider.droplab-item-ignore - %ul.filter-dropdown{ data: { dynamic: true, dropdown: true } } - %li.filter-dropdown-item - %button.gl-button.btn.btn-link.js-data-value - %span.dropdown-light-content - {{name}} - - = button_tag class: %w[clear-search hidden] do - = sprite_icon('close', size: 16, css_class: 'clear-search-icon') - .filter-dropdown-container - = render 'sort_dropdown' + #js-dropdown-runner-tag.filtered-search-input-dropdown-menu.dropdown-menu + %ul{ data: { dropdown: true } } + %li.filter-dropdown-item{ data: { value: 'none' } } + %button.gl-button.btn.btn-link + = _('No Tag') + %li.divider.droplab-item-ignore + %ul.filter-dropdown{ data: { dynamic: true, dropdown: true } } + %li.filter-dropdown-item + %button.gl-button.btn.btn-link.js-data-value + %span.dropdown-light-content + {{name}} - .col-sm-3.text-right-lg - = _('Runners currently online: %{active_runners_count}') % { active_runners_count: @active_runners_count } + = button_tag class: %w[clear-search hidden] do + = sprite_icon('close', size: 16, css_class: 'clear-search-icon') + .filter-dropdown-container + = render 'sort_dropdown' -- if @runners.any? - .content-list{ data: { testid: 'runners-table' } } - .table-holder - .gl-responsive-table-row.table-row-header{ role: 'row' } - .table-section.section-10{ role: 'rowheader' }= _('Type/State') - .table-section.section-30{ role: 'rowheader' }= s_('Runners|Runner') - .table-section.section-10{ role: 'rowheader' }= _('Version') - .table-section.section-10{ role: 'rowheader' }= _('IP Address') - .table-section.section-5{ role: 'rowheader' }= _('Projects') - .table-section.section-5{ role: 'rowheader' }= _('Jobs') - .table-section.section-10{ role: 'rowheader' }= _('Tags') - .table-section.section-10{ role: 'rowheader' }= _('Last contact') - .table-section.section-10{ role: 'rowheader' } + .col-sm-3.text-right-lg + = _('Runners currently online: %{active_runners_count}') % { active_runners_count: @active_runners_count } + - if @runners.any? + .content-list{ data: { testid: 'runners-table' } } + .table-holder + .gl-responsive-table-row.table-row-header{ role: 'row' } + .table-section.section-10{ role: 'rowheader' }= _('Type/State') + .table-section.section-30{ role: 'rowheader' }= s_('Runners|Runner') + .table-section.section-10{ role: 'rowheader' }= _('Version') + .table-section.section-10{ role: 'rowheader' }= _('IP Address') + .table-section.section-5{ role: 'rowheader' }= _('Projects') + .table-section.section-5{ role: 'rowheader' }= _('Jobs') + .table-section.section-10{ role: 'rowheader' }= _('Tags') + .table-section.section-10{ role: 'rowheader' }= _('Last contact') + .table-section.section-10{ role: 'rowheader' } - - @runners.each do |runner| - = render 'admin/runners/runner', runner: runner - = paginate @runners, theme: 'gitlab' -- else - .nothing-here-block= _('No runners found') + - @runners.each do |runner| + = render 'admin/runners/runner', runner: runner + = paginate @runners, theme: 'gitlab' + - else + .nothing-here-block= _('No runners found') diff --git a/app/views/admin/runners/show.html.haml b/app/views/admin/runners/show.html.haml index d911f35d946..d03a782756b 100644 --- a/app/views/admin/runners/show.html.haml +++ b/app/views/admin/runners/show.html.haml @@ -10,11 +10,9 @@ %h2.page-title = s_('Runners|Runner #%{runner_id}' % { runner_id: @runner.id }) = render 'shared/runners/runner_type_badge', runner: @runner - -= render 'shared/runners/runner_type_alert', runner: @runner - -.gl-mb-6 - = render 'shared/runners/form', runner: @runner, runner_form_url: admin_runner_path(@runner), in_gitlab_com_admin_context: Gitlab.com? + = render 'shared/runners/runner_type_alert', runner: @runner + .gl-mb-6 + = render 'shared/runners/form', runner: @runner, runner_form_url: admin_runner_path(@runner), in_gitlab_com_admin_context: Gitlab.com? .row .col-md-6 diff --git a/app/views/admin/serverless/domains/_form.html.haml b/app/views/admin/serverless/domains/_form.html.haml index 85f2260163a..a3e1ccc5d4a 100644 --- a/app/views/admin/serverless/domains/_form.html.haml +++ b/app/views/admin/serverless/domains/_form.html.haml @@ -79,7 +79,7 @@ .modal-header %h3.page-title= _('Delete serverless domain?') %button.close{ type: "button", "data-dismiss": "modal", "aria-label" => _('Close') } - %span{ "aria-hidden": true } × + %span{ "aria-hidden": "true" } × .modal-body - if domain_attached diff --git a/app/views/admin/services/_service_templates_deprecated_alert.html.haml b/app/views/admin/services/_service_templates_deprecated_alert.html.haml index 0cc44099049..eac2f9c7f4e 100644 --- a/app/views/admin/services/_service_templates_deprecated_alert.html.haml +++ b/app/views/admin/services/_service_templates_deprecated_alert.html.haml @@ -2,7 +2,9 @@ - settings_link_start = "<a href=\"#{integrations_admin_application_settings_path}\">".html_safe .gl-alert.gl-alert-danger.gl-mt-5{ role: 'alert' } - = sprite_icon('error', css_class: 'gl-alert-icon gl-alert-icon-no-title') - %h4.gl-alert-title= s_('AdminSettings|Service templates are deprecated and will be removed in GitLab 14.0.') - .gl-alert-body - = html_escape_once(s_("AdminSettings|You can't add new templates. To migrate or remove a Service template, create a new integration at %{settings_link_start}Settings > Integrations%{link_end}. Learn more about %{doc_link_start}Project integration management%{link_end}.")).html_safe % { settings_link_start: settings_link_start, doc_link_start: doc_link_start, link_end: '</a>'.html_safe } + .gl-alert-container + = sprite_icon('error', css_class: 'gl-alert-icon gl-alert-icon-no-title') + .gl-alert-content + %h4.gl-alert-title= s_('AdminSettings|Service templates are deprecated and will be removed in GitLab 14.0.') + .gl-alert-body + = html_escape_once(s_("AdminSettings|You can't add new templates. To migrate or remove a Service template, create a new integration at %{settings_link_start}Settings > Integrations%{link_end}. Learn more about %{doc_link_start}Project integration management%{link_end}.")).html_safe % { settings_link_start: settings_link_start, doc_link_start: doc_link_start, link_end: '</a>'.html_safe } diff --git a/app/views/admin/users/_access_levels.html.haml b/app/views/admin/users/_access_levels.html.haml index 573580bc5c5..aeb274fe2cb 100644 --- a/app/views/admin/users/_access_levels.html.haml +++ b/app/views/admin/users/_access_levels.html.haml @@ -48,3 +48,17 @@ %row.hidden#warning_external_automatically_set.hidden .badge.badge-warning.text-white = s_('AdminUsers|Automatically marked as default internal user') + + .form-group.row + - @user.credit_card_validation || @user.build_credit_card_validation + = f.fields_for :credit_card_validation do |ff| + .col-sm-2.col-form-label.gl-pt-0 + = ff.label s_("AdminUsers|Validate user account") + .col-sm-10.gl-display-flex.gl-align-items-baseline + = ff.check_box :credit_card_validated_at, checked: @user.credit_card_validated_at.present? + .gl-pl-2 + .light + = s_('AdminUsers|User is validated and can use free CI minutes on shared runners.') + .gl-text-gray-600 + = s_('AdminUsers|A user can validate themselves by inputting a credit/debit card, or an admin can manually validate a user.') + diff --git a/app/views/admin/users/_modals.html.haml b/app/views/admin/users/_modals.html.haml index f6e7cefafe7..0890990f476 100644 --- a/app/views/admin/users/_modals.html.haml +++ b/app/views/admin/users/_modals.html.haml @@ -1,5 +1,5 @@ #js-delete-user-modal -#js-modal-texts.hidden{ "hidden": true, "aria-hidden": true } +#js-modal-texts.hidden{ "hidden": true, "aria-hidden": "true" } %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 deleted file mode 100644 index 2816a1061b9..00000000000 --- a/app/views/admin/users/_user.html.haml +++ /dev/null @@ -1,72 +0,0 @@ -.gl-responsive-table-row{ role: 'row', data: { qa_selector: 'user_row_content' } } - .table-section.section-40 - .table-mobile-header{ role: 'rowheader' } - = _('Name') - .table-mobile-content - = render 'user_detail', user: user - .table-section.section-10 - .table-mobile-header{ role: 'rowheader' } - = _('Projects') - .table-mobile-content.gl-str-truncated{ data: { testid: "user-project-count-#{user.id}" } } - = user.authorized_projects.length - .table-section.section-15 - .table-mobile-header{ role: 'rowheader' } - = _('Created on') - .table-mobile-content - = l(user.created_at.to_date, format: :admin) - .table-section.section-15 - .table-mobile-header{ role: 'rowheader' } - = _('Last activity') - .table-mobile-content - = user.last_activity_on.nil? ? _('Never') : l(user.last_activity_on, format: :admin) - - unless user.internal? - .table-section.section-20.table-button-footer - .table-action-buttons{ data: { testid: "user-actions-#{user.id}" } } - = link_to _('Edit'), edit_admin_user_path(user), class: 'btn gl-button btn-default' - - unless user == current_user - %button.dropdown-new.btn.gl-button.btn-default{ type: 'button', data: { testid: "dropdown-toggle", toggle: 'dropdown' } } - = sprite_icon('settings') - = sprite_icon('chevron-down') - %ul.dropdown-menu.dropdown-menu-right - %li.dropdown-header - = _('Settings') - %li - - if user.ldap_blocked? - %span.small - = s_('AdminUsers|Cannot unblock LDAP blocked users') - - elsif user.blocked? - - if user.blocked_pending_approval? - = link_to s_('AdminUsers|Approve'), approve_admin_user_path(user), method: :put - = link_to s_('AdminUsers|Reject'), reject_admin_user_path(user), method: :delete - - else - %button.gl-button.btn.btn-default-tertiary.js-confirm-modal-button{ data: user_unblock_data(user) } - = s_('AdminUsers|Unblock') - - else - %button.gl-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 - %button.gl-button.btn.btn-default-tertiary.js-confirm-modal-button{ data: user_deactivation_data(user, user_deactivation_effects) } - = s_('AdminUsers|Deactivate') - - elsif user.deactivated? - %li - %button.gl-button.btn.btn-default-tertiary.js-confirm-modal-button{ data: user_activation_data(user) } - = s_('AdminUsers|Activate') - - if user.access_locked? - %li - = link_to _('Unlock'), unlock_admin_user_path(user), method: :put, data: { confirm: _('Are you sure?') } - - if can?(current_user, :destroy_user, user) && !user.blocked_pending_approval? - %li.divider - - if user.can_be_removed? - %li - %button.js-delete-user-modal-button.gl-button.btn.btn-danger-tertiary{ data: { 'gl-modal-action': 'delete', - delete_user_url: admin_user_path(user), - block_user_url: block_admin_user_path(user), - username: sanitize_name(user.name) } } - = s_('AdminUsers|Delete user') - %li - %button.js-delete-user-modal-button.gl-button.btn.btn-danger-tertiary{ data: { 'gl-modal-action': 'delete-with-contributions', - delete_user_url: admin_user_path(user, hard_delete: true), - block_user_url: block_admin_user_path(user), - username: sanitize_name(user.name) } } - = s_('AdminUsers|Delete user and contributions') diff --git a/app/views/admin/users/_users.html.haml b/app/views/admin/users/_users.html.haml index e4438f38a47..1a43d91b800 100644 --- a/app/views/admin/users/_users.html.haml +++ b/app/views/admin/users/_users.html.haml @@ -73,20 +73,9 @@ = link_to admin_users_path(sort: value, filter: params[:filter], search_query: params[:search_query]) do = title -- if Feature.enabled?(:vue_admin_users, default_enabled: :yaml) - #js-admin-users-app{ data: admin_users_data_attributes(@users) } - .gl-spinner-container.gl-my-7 - %span.gl-vertical-align-bottom.gl-spinner.gl-spinner-dark.gl-spinner-lg{ aria: { label: _('Loading') } } -- elsif @users.empty? - .nothing-here-block.border-top-0 - = s_('AdminUsers|No users found') -- else - .table-holder - .thead-white.text-nowrap.gl-responsive-table-row.table-row-header{ role: 'row' } - - user_table_headers.each do |header| - .table-section{ class: header[:section_class_name], role: 'rowheader' }= header[:header_text] - - = render partial: 'admin/users/user', collection: @users +#js-admin-users-app{ data: admin_users_data_attributes(@users) } + .gl-spinner-container.gl-my-7 + %span.gl-vertical-align-bottom.gl-spinner.gl-spinner-dark.gl-spinner-lg{ aria: { label: _('Loading') } } = paginate_collection @users diff --git a/app/views/admin/users/show.html.haml b/app/views/admin/users/show.html.haml index 19cc29668f5..08c1e089f21 100644 --- a/app/views/admin/users/show.html.haml +++ b/app/views/admin/users/show.html.haml @@ -59,6 +59,7 @@ = _('Disabled') = render_if_exists 'admin/namespace_plan_info', namespace: @user.namespace + = render_if_exists 'admin/users/credit_card_info', user: @user %li %span.light= _('External User:') 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 03a3c9b0de8..cddea17efbf 100644 --- a/app/views/ci/runner/_how_to_setup_runner.html.haml +++ b/app/views/ci/runner/_how_to_setup_runner.html.haml @@ -14,7 +14,7 @@ %br = _("And this registration token:") %br - %code#registration_token= registration_token + %code#registration_token{ data: {testid: 'registration_token' } }= registration_token = clipboard_button(target: '#registration_token', title: _("Copy token"), class: "btn-transparent btn-clipboard") .gl-mt-3.gl-mb-3 diff --git a/app/views/ci/runner/_setup_runner_in_aws.html.haml b/app/views/ci/runner/_setup_runner_in_aws.html.haml new file mode 100644 index 00000000000..b0a5b40f2ad --- /dev/null +++ b/app/views/ci/runner/_setup_runner_in_aws.html.haml @@ -0,0 +1,16 @@ +%h5= _('Use GitLab Runner in AWS') + +%p + = _('Use an AWS CloudFormation Template (CFT) to install and configure GitLab Runner in AWS.') + +%ol + %li + = _('Copy this registration token.') + %br + %code#registration_token{ data: { testid: 'registration_token' } }= registration_token + = clipboard_button(target: '#registration_token', title: _('Copy token'), class: 'btn-transparent btn-clipboard') + %li + = _('Choose the preferred Runner and populate the AWS CFT.') + = link_to _('Learn more.'), 'https://gitlab.com/guided-explorations/aws/gitlab-runner-autoscaling-aws-asg', target: '_blank', rel: 'noopener noreferrer' + +#js-runner-aws-deployments diff --git a/app/views/clusters/clusters/_advanced_settings.html.haml b/app/views/clusters/clusters/_advanced_settings.html.haml index 7f508fd0a59..c84b3a923ca 100644 --- a/app/views/clusters/clusters/_advanced_settings.html.haml +++ b/app/views/clusters/clusters/_advanced_settings.html.haml @@ -16,7 +16,7 @@ .sub-section.form-group = form_for @cluster, url: clusterable.cluster_path(@cluster), as: :cluster, html: { class: 'cluster_management_form' } do |field| %h4 - = s_('ClusterIntegration|Cluster management project (alpha)') + = s_('ClusterIntegration|Cluster management project') %p = project_select_tag('cluster[management_project_id]', class: 'hidden-filter-value', toggle_class: 'js-project-search js-project-filter js-filter-submit', dropdown_class: 'dropdown-menu-selectable dropdown-menu-project js-filter-submit', diff --git a/app/views/clusters/clusters/_health.html.haml b/app/views/clusters/clusters/_health.html.haml index 025f52d8771..75609465eb3 100644 --- a/app/views/clusters/clusters/_health.html.haml +++ b/app/views/clusters/clusters/_health.html.haml @@ -1,5 +1,5 @@ %section.settings.no-animate.expanded.cluster-health-graphs.qa-cluster-health-section#cluster-health - - if @cluster&.application_prometheus_available? + - if @cluster&.integration_prometheus_available? #prometheus-graphs{ data: @cluster.health_data(clusterable) } - else diff --git a/app/views/clusters/clusters/gcp/_form.html.haml b/app/views/clusters/clusters/gcp/_form.html.haml index ee2817879be..73a09f00fd6 100644 --- a/app/views/clusters/clusters/gcp/_form.html.haml +++ b/app/views/clusters/clusters/gcp/_form.html.haml @@ -62,13 +62,12 @@ %p.form-text.text-muted = s_('ClusterIntegration|Learn more about %{help_link_start_machine_type}machine types%{help_link_end} and %{help_link_start_pricing}pricing%{help_link_end}.').html_safe % { help_link_start_machine_type: help_link_start % { url: machine_type_link_url }, help_link_start_pricing: help_link_start % { url: pricing_link_url }, help_link_end: help_link_end } - - if Feature.enabled?(:create_cloud_run_clusters, clusterable, default_enabled: true) - .form-group - = provider_gcp_field.check_box :cloud_run, { label: s_('ClusterIntegration|Enable Cloud Run for Anthos'), - label_class: 'label-bold' } - .form-text.text-muted - = s_('ClusterIntegration|Uses the Cloud Run, Istio, and HTTP Load Balancing addons for this cluster.') - = link_to _('More information'), help_page_path('user/project/clusters/add_gke_clusters.md', anchor: 'cloud-run-for-anthos'), target: '_blank' + .form-group + = provider_gcp_field.check_box :cloud_run, { label: s_('ClusterIntegration|Enable Cloud Run for Anthos'), + label_class: 'label-bold' } + .form-text.text-muted + = s_('ClusterIntegration|Uses the Cloud Run, Istio, and HTTP Load Balancing addons for this cluster.') + = link_to _('More information'), help_page_path('user/project/clusters/add_gke_clusters.md', anchor: 'cloud-run-for-anthos'), target: '_blank' .form-group = field.check_box :managed, { label: s_('ClusterIntegration|GitLab-managed cluster'), diff --git a/app/views/clusters/clusters/show.html.haml b/app/views/clusters/clusters/show.html.haml index 001ca80dbd6..7336b9fe86b 100644 --- a/app/views/clusters/clusters/show.html.haml +++ b/app/views/clusters/clusters/show.html.haml @@ -17,7 +17,6 @@ install_knative_path: clusterable.install_applications_cluster_path(@cluster, :knative), update_knative_path: clusterable.update_applications_cluster_path(@cluster, :knative), install_elastic_stack_path: clusterable.install_applications_cluster_path(@cluster, :elastic_stack), - install_fluentd_path: clusterable.install_applications_cluster_path(@cluster, :fluentd), cluster_environments_path: cluster_environments_path, toggle_status: @cluster.enabled? ? 'true': 'false', has_rbac: has_rbac_enabled?(@cluster) ? 'true': 'false', @@ -26,11 +25,7 @@ cluster_status_reason: @cluster.status_reason, provider_type: @cluster.provider_type, pre_installed_knative: @cluster.knative_pre_installed? ? 'true': 'false', - help_path: help_page_path('user/project/clusters/index.md', anchor: 'installing-applications'), - helm_help_path: help_page_path('user/clusters/applications.md', anchor: 'helm'), - ingress_help_path: help_page_path('user/clusters/applications.md', anchor: 'determining-the-external-endpoint-automatically'), - ingress_dns_help_path: help_page_path('user/clusters/applications.md', anchor: 'pointing-your-dns-at-the-external-endpoint'), - ingress_mod_security_help_path: help_page_path('user/clusters/applications.md', anchor: 'web-application-firewall-modsecurity'), + help_path: help_page_path('user/project/clusters/index.md'), environments_help_path: help_page_path('ci/environments/index.md', anchor: 'create-a-static-environment'), clusters_help_path: help_page_path('user/project/clusters/index.md', anchor: 'deploying-to-a-kubernetes-cluster'), deploy_boards_help_path: help_page_path('user/project/deploy_boards.md', anchor: 'enabling-deploy-boards'), @@ -52,13 +47,20 @@ = render 'banner' + .gl-alert.gl-alert-warning{ role: 'alert' } + = sprite_icon('warning', css_class: "gl-alert-icon gl-alert-icon-no-title gl-icon") + %button.js-close.gl-alert-dismiss{ type: 'button', 'aria-label' => _('Dismiss'), data: { testid: 'dismiss-one-click-application-removal' } } + = sprite_icon('close', css_class: 'gl-icon') + .gl-alert-body + = s_('ClusterApplicationsRemoved|One-click application management was removed in GitLab 14.0. Your applications are still installed in your cluster, and integrations continue working.') + = link_to _('More information.'), help_page_path("user/clusters/applications"), target: '_blank' + - if cluster_created?(@cluster) .js-toggle-container %ul.nav-links.mobile-separator.nav.nav-tabs{ role: 'tablist' } = render 'details_tab' = render_if_exists 'clusters/clusters/environments_tab' = render 'clusters/clusters/health_tab' - = render 'applications_tab' = render 'integrations_tab' = render 'advanced_settings_tab' diff --git a/app/views/dashboard/todos/_todo.html.haml b/app/views/dashboard/todos/_todo.html.haml index e7d8171d276..2c6c721a51c 100644 --- a/app/views/dashboard/todos/_todo.html.haml +++ b/app/views/dashboard/todos/_todo.html.haml @@ -3,7 +3,7 @@ .todo-avatar.gl-display-none.gl-sm-display-inline-block = author_avatar(todo, size: 40) - .todo-item.gl-w-full.gl-align-self-center{ data: { qa_selector: "todo_item_container" } } + .todo-item.flex-fill.gl-overflow-hidden.gl-overflow-x-auto.gl-align-self-center{ data: { qa_selector: "todo_item_container" } } .todo-title.gl-mb-3.gl-md-mb-0 - if todo_author_display?(todo) = todo_target_state_pill(todo) diff --git a/app/views/dashboard/todos/index.html.haml b/app/views/dashboard/todos/index.html.haml index 52e41946ed1..ca10861115b 100644 --- a/app/views/dashboard/todos/index.html.haml +++ b/app/views/dashboard/todos/index.html.haml @@ -37,7 +37,7 @@ .todos-filters .issues-details-filters.row-content-block.second-block = form_tag todos_filter_path(without: [:project_id, :author_id, :type, :action_id]), method: :get, class: 'filter-form gl-display-flex gl-flex-direction-column gl-sm-flex-direction-row' do - .filter-categories.gl-display-flex.gl-flex-direction-column.gl-md-flex-direction-row.gl-flex-fill-1.gl-flex-wrap.gl-mx-n2 + .filter-categories.gl-display-flex.gl-flex-direction-column.gl-md-flex-direction-row.gl-flex-grow-1.gl-flex-wrap.gl-mx-n2 .filter-item.gl-m-2 - if params[:group_id].present? = hidden_field_tag(:group_id, params[:group_id]) diff --git a/app/views/devise/confirmations/almost_there.haml b/app/views/devise/confirmations/almost_there.haml index 684af933f3a..037b2f247c1 100644 --- a/app/views/devise/confirmations/almost_there.haml +++ b/app/views/devise/confirmations/almost_there.haml @@ -1,8 +1,10 @@ +- user_email = "(#{params[:email]})" if params[:email].present? + .well-confirmation.gl-text-center.gl-mb-6 %h1.gl-mt-0 = _("Almost there...") %p.lead.gl-mb-6 - = _("Please check your email to confirm your account") + = _('Please check your email %{email} to confirm your account') % { email: user_email } %hr - if Gitlab::CurrentSettings.after_sign_up_text.present? .well-confirmation.gl-text-center @@ -10,5 +12,5 @@ %p.text-center = _("No confirmation email received? Please check your spam folder or") .gl-mb-6.prepend-top-20.gl-text-center - %a.btn.gl-button.btn-confirm{ href: new_user_confirmation_path } + %a.gl-link{ href: new_user_confirmation_path } = _("Request new confirmation email") diff --git a/app/views/devise/passwords/new.html.haml b/app/views/devise/passwords/new.html.haml index ef876779ad6..7f6ce712af2 100644 --- a/app/views/devise/passwords/new.html.haml +++ b/app/views/devise/passwords/new.html.haml @@ -6,6 +6,8 @@ .form-group = f.label :email = f.email_field :email, class: "form-control gl-form-input", required: true, value: params[:user_email], autofocus: true, title: _('Please provide a valid email address.') + .form-text.text-muted + = _('Requires your primary GitLab email address.') .clearfix = f.submit _("Reset password"), class: "gl-button btn-confirm btn" diff --git a/app/views/devise/registrations/new.html.haml b/app/views/devise/registrations/new.html.haml index 00429f1acbc..4ec3fcde337 100644 --- a/app/views/devise/registrations/new.html.haml +++ b/app/views/devise/registrations/new.html.haml @@ -8,6 +8,5 @@ = 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 + show_omniauth_providers: omniauth_enabled? && button_based_providers_enabled? = render 'devise/shared/sign_in_link' diff --git a/app/views/devise/shared/_signup_box.html.haml b/app/views/devise/shared/_signup_box.html.haml index 1b410f0b671..09b7f247450 100644 --- a/app/views/devise/shared/_signup_box.html.haml +++ b/app/views/devise/shared/_signup_box.html.haml @@ -1,6 +1,4 @@ - max_first_name_length = max_last_name_length = 127 -- max_username_length = 255 -- min_username_length = 2 - omniauth_providers_placement ||= :bottom .gl-mb-3.gl-p-4.gl-border-gray-100.gl-border-1.gl-border-solid.gl-rounded-base @@ -11,26 +9,53 @@ .devise-errors = render 'devise/shared/error_messages', resource: resource - if Gitlab::CurrentSettings.invisible_captcha_enabled - = invisible_captcha nonce: true + = invisible_captcha nonce: true, autocomplete: SecureRandom.alphanumeric(12) .name.form-row .col.form-group = f.label :first_name, _('First name'), for: 'new_user_first_name', class: 'label-bold' - = f.text_field :first_name, class: 'form-control gl-form-input top js-block-emoji js-validate-length', :data => { :max_length => max_first_name_length, :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.') + = f.text_field :first_name, + class: 'form-control gl-form-input top js-block-emoji js-validate-length', + data: { max_length: max_first_name_length, + 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 gl-form-input 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.') + = f.text_field :last_name, + class: 'form-control gl-form-input top js-block-emoji js-validate-length', + data: { max_length: max_last_name_length, + 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 gl-form-input 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.') + = f.text_field :username, + class: 'form-control gl-form-input middle js-block-emoji js-validate-length js-validate-username', + data: signup_username_data_attributes, + 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 gl-form-input middle', data: { qa_selector: 'new_user_email_field' }, required: true, title: _('Please provide a valid email address.') + = f.email_field :email, + value: @invite_email, + class: 'form-control gl-form-input middle', + data: { qa_selector: 'new_user_email_field' }, + required: true, + title: _('Please provide a valid email address.') .form-group.gl-mb-5#password-strength = f.label :password, class: 'label-bold' - = f.password_field :password, class: 'form-control gl-form-input 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 } + = f.password_field :password, + class: 'form-control gl-form-input 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? diff --git a/app/views/events/_event.atom.builder b/app/views/events/_event.atom.builder index 17bf43a4590..c429bbbb610 100644 --- a/app/views/events/_event.atom.builder +++ b/app/views/events/_event.atom.builder @@ -3,10 +3,11 @@ return unless event.visible_to_user?(current_user) event = event.present +event_url = event_feed_url(event) xml.entry do xml.id "tag:#{request.host},#{event.created_at.strftime("%Y-%m-%d")}:#{event.id}" - xml.link href: event_feed_url(event) + xml.link href: event_url if event_url xml.title truncate(event_feed_title(event), length: 80) xml.updated event.updated_at.xmlschema diff --git a/app/views/events/_event_push.atom.haml b/app/views/events/_event_push.atom.haml index c5b033b1185..c3786d7c16d 100644 --- a/app/views/events/_event_push.atom.haml +++ b/app/views/events/_event_push.atom.haml @@ -1,7 +1,9 @@ +- event_url = event_feed_url(event) + %div{ xmlns: "http://www.w3.org/1999/xhtml" } %p %strong= event.author_name - = link_to "(#{truncate_sha(event.commit_id)})", event_feed_url(event) + = link_to "(#{truncate_sha(event.commit_id)})", event_url if event_url %i at = event.created_at.to_s(:short) diff --git a/app/views/groups/_invite_members_modal.html.haml b/app/views/groups/_invite_members_modal.html.haml index 69ed94e99cc..f4f3c8ce8f7 100644 --- a/app/views/groups/_invite_members_modal.html.haml +++ b/app/views/groups/_invite_members_modal.html.haml @@ -4,4 +4,4 @@ is_project: 'false', access_levels: GroupMember.access_level_roles.to_json, default_access_level: Gitlab::Access::GUEST, - help_link: help_page_url('user/permissions') } } + help_link: help_page_url('user/permissions') }.merge(group_select_data(group)) } diff --git a/app/views/groups/_new_group_fields.html.haml b/app/views/groups/_new_group_fields.html.haml index fbf9438718e..49c8c2700ce 100644 --- a/app/views/groups/_new_group_fields.html.haml +++ b/app/views/groups/_new_group_fields.html.haml @@ -22,6 +22,6 @@ .col-sm-4 = recaptcha_tags nonce: content_security_policy_nonce .row - .form-actions.col-sm-12 + .col-sm-12 = f.submit _('Create group'), class: "btn gl-button btn-confirm" = link_to _('Cancel'), dashboard_groups_path, class: 'btn gl-button btn-default btn-cancel' diff --git a/app/views/groups/dependency_proxies/show.html.haml b/app/views/groups/dependency_proxies/show.html.haml index 2ecf92e0769..5cf4ff4bc26 100644 --- a/app/views/groups/dependency_proxies/show.html.haml +++ b/app/views/groups/dependency_proxies/show.html.haml @@ -24,5 +24,7 @@ = 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.') + .gl-alert-container + = sprite_icon('information-o', size: 16, css_class: 'gl-icon gl-alert-icon gl-alert-icon-no-title') + .gl-alert-content + = _('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 45488791272..c5b8c5e25a3 100644 --- a/app/views/groups/group_members/index.html.haml +++ b/app/views/groups/group_members/index.html.haml @@ -1,8 +1,6 @@ - add_page_specific_style 'page_bundles/members' - page_title _('Group members') -- show_invited_members = can_manage_members? && @invited_members.load.any? -- show_access_requests = can_manage_members? && @requesters.load.any? -- invited_active = params[:search_invited].present? || params[:invited_members_page].present? +- groups_select_tag_data = group_select_data(@group).merge({ skip_groups: @skip_groups }) .js-remove-member-modal .row.gl-mt-3 @@ -18,7 +16,10 @@ .gl-w-half.gl-xs-w-full .gl-display-flex.gl-flex-wrap.gl-justify-content-end.gl-mb-3 .js-invite-group-trigger{ data: { classes: 'gl-mt-3 gl-sm-w-auto gl-w-full', display_text: _('Invite a group') } } - .js-invite-members-trigger{ data: { variant: 'success', classes: 'gl-mt-3 gl-sm-w-auto gl-w-full gl-sm-ml-3', display_text: _('Invite members') } } + .js-invite-members-trigger{ data: { variant: 'success', + classes: 'gl-mt-3 gl-sm-w-auto gl-w-full gl-sm-ml-3', + trigger_source: 'group-members-page', + display_text: _('Invite members') } } = render 'groups/invite_members_modal', group: @group - if can_manage_members? && Feature.disabled?(:invite_members_group_modal, @group) %hr.gl-mt-4 @@ -31,51 +32,13 @@ .tab-pane.active{ id: 'invite-member-pane', role: 'tabpanel' } = render_invite_member_for_group(@group, @group_member.access_level) .tab-pane{ id: 'invite-group-pane', role: 'tabpanel' } - = render 'shared/members/invite_group', submit_url: group_group_links_path(@group), access_levels: GroupMember.access_level_roles, default_access_level: @group_member.access_level, group_link_field: 'shared_with_group_id', group_access_field: 'shared_group_access' + = render 'shared/members/invite_group', submit_url: group_group_links_path(@group), access_levels: GroupMember.access_level_roles, default_access_level: @group_member.access_level, group_link_field: 'shared_with_group_id', group_access_field: 'shared_group_access', groups_select_tag_data: groups_select_tag_data = render_if_exists 'groups/group_members/ldap_sync' - %ul.nav-links.mobile-separator.nav.nav-tabs - %li.nav-item - = link_to '#tab-members', class: ['nav-link', ('active' unless invited_active)], data: { toggle: 'tab' } do - %span - = _('Members') - %span.badge.gl-tab-counter-badge.badge-muted.badge-pill.gl-badge.sm= @members.total_count - - if @group.shared_with_group_links.present? - %li.nav-item - = link_to '#tab-groups', class: ['nav-link'] , data: { toggle: 'tab', qa_selector: 'groups_list_tab' } do - %span - = _('Groups') - %span.badge.gl-tab-counter-badge.badge-muted.badge-pill.gl-badge.sm= @group.shared_with_group_links.count - - if show_invited_members - %li.nav-item - = link_to '#tab-invited-members', class: ['nav-link', ('active' if invited_active)], data: { toggle: 'tab' } do - %span - = _('Invited') - %span.badge.gl-tab-counter-badge.badge-muted.badge-pill.gl-badge.sm= @invited_members.total_count - - if show_access_requests - %li.nav-item - = link_to '#tab-access-requests', class: 'nav-link', data: { toggle: 'tab' } do - %span - = _('Access requests') - %span.badge.gl-tab-counter-badge.badge-muted.badge-pill.gl-badge.sm= @requesters.count - .tab-content - #tab-members.tab-pane{ class: ('active' unless invited_active) } - .js-group-members-list{ data: { members_data: group_members_list_data_json(@group, @members, { param_name: :page, params: { invited_members_page: nil, search_invited: nil } }) } } - .loading - .gl-spinner.gl-spinner-md - - if @group.shared_with_group_links.present? - #tab-groups.tab-pane - .js-group-group-links-list{ data: { members_data: group_group_links_list_data_json(@group) } } - .loading - .gl-spinner.gl-spinner-md - - if show_invited_members - #tab-invited-members.tab-pane{ class: ('active' if invited_active) } - .js-group-invited-members-list{ data: { members_data: group_members_list_data_json(@group, @invited_members, { param_name: :invited_members_page, params: { page: nil } }) } } - .loading - .gl-spinner.gl-spinner-md - - if show_access_requests - #tab-access-requests.tab-pane - .js-group-access-requests-list{ data: { members_data: group_members_list_data_json(@group, @requesters) } } - .loading - .gl-spinner.gl-spinner-md + .js-group-members-list-app{ data: { members_data: group_members_app_data_json(@group, + members: @members, + invited: @invited_members, + access_requests: @requesters) } } + .loading + .gl-spinner.gl-spinner-md diff --git a/app/views/groups/new.html.haml b/app/views/groups/new.html.haml index 920a6ccd9ec..11927142ea6 100644 --- a/app/views/groups/new.html.haml +++ b/app/views/groups/new.html.haml @@ -2,47 +2,24 @@ - @hide_top_links = true - page_title _('New Group') - header_title _("Groups"), dashboard_groups_path -- active_tab = local_assigns.fetch(:active_tab, 'create') +- add_page_specific_style 'page_bundles/new_namespace' -.group-edit-container.gl-mt-3 - .row - .col-lg-3.group-settings-sidebar - %h4.prepend-top-0 - = _('New group') - %p - - group_docs_path = help_page_path('user/group/index') - - group_docs_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: group_docs_path } - = s_('%{group_docs_link_start}Groups%{group_docs_link_end} allow you to manage and collaborate across multiple projects. Members of a group have access to all of its projects.').html_safe % { group_docs_link_start: group_docs_link_start, group_docs_link_end: '</a>'.html_safe } - %p - - subgroup_docs_path = help_page_path('user/group/subgroups/index') - - subgroup_docs_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: subgroup_docs_path } - = s_('Groups can also be nested by creating %{subgroup_docs_link_start}subgroups%{subgroup_docs_link_end}.').html_safe % { subgroup_docs_link_start: subgroup_docs_link_start, subgroup_docs_link_end: '</a>'.html_safe } - %p - = _('Projects that belong to a group are prefixed with the group namespace. Existing projects may be moved into a group.') +.group-edit-container.gl-mt-5 - .col-lg-9.js-toggle-container - %ul.nav.nav-tabs.nav-links.gitlab-tabs{ role: 'tablist' } - %li.nav-item{ role: 'presentation' } - %a.nav-link.active{ href: '#create-group-pane', id: 'create-group-tab', role: 'tab', data: { toggle: 'tab', track_label: 'create_group', track_event: 'click_tab', track_value: '' } } - %span.d-none.d-sm-block= s_('GroupsNew|Create group') - %span.d-block.d-sm-none= s_('GroupsNew|Create') - %li.nav-item{ role: 'presentation' } - %a.nav-link{ href: '#import-group-pane', id: 'import-group-tab', role: 'tab', data: { toggle: 'tab', track_label: 'import_group', track_event: 'click_tab', track_value: '' } } - %span.d-none.d-sm-block= s_('GroupsNew|Import group') - %span.d-block.d-sm-none= s_('GroupsNew|Import') + .js-new-group-creation{ data: { has_errors: @group.errors.any?.to_s } } - .tab-content.gitlab-tab-content.gl-border-none - .tab-pane.js-toggle-container{ id: 'create-group-pane', class: active_when(active_tab == 'create'), role: 'tabpanel' } - = form_for @group, html: { class: 'group-form gl-show-field-errors' } do |f| - = render 'new_group_fields', f: f, group_name_id: 'create-group-name' + .row{ 'v-cloak': true } + #create-group-pane.tab-pane + = form_for @group, html: { class: 'group-form gl-show-field-errors' } do |f| + = render 'new_group_fields', f: f, group_name_id: 'create-group-name' - .tab-pane.no-padding.js-toggle-container{ id: 'import-group-pane', class: active_when(active_tab) == 'import', role: 'tabpanel' } - - if import_sources_enabled? - - if Feature.enabled?(:bulk_import) - = render 'import_group_from_another_instance_panel' - .gl-mt-7.gl-border-b-solid.gl-border-gray-100.gl-border-1 - = render 'import_group_from_file_panel' - - else - .nothing-here-block - %h4= s_('GroupsNew|No import options available') - %p= s_('GroupsNew|Contact an administrator to enable options for importing your group.') + #import-group-pane.tab-pane + - if import_sources_enabled? + - if Feature.enabled?(:bulk_import) + = render 'import_group_from_another_instance_panel' + .gl-mt-7.gl-border-b-solid.gl-border-gray-100.gl-border-1 + = render 'import_group_from_file_panel' + - else + .nothing-here-block + %h4= s_('GroupsNew|No import options available') + %p= s_('GroupsNew|Contact an administrator to enable options for importing your group.') diff --git a/app/views/groups/runners/_group_runners.html.haml b/app/views/groups/runners/_group_runners.html.haml index 910b36770f1..823d908c5e2 100644 --- a/app/views/groups/runners/_group_runners.html.haml +++ b/app/views/groups/runners/_group_runners.html.haml @@ -13,6 +13,10 @@ = render partial: 'ci/runner/how_to_setup_runner_automatically', locals: { type: 'group', clusters_path: group_clusters_path(@group) } + - if params[:ci_runner_templates] + %hr + = render partial: 'ci/runner/setup_runner_in_aws', + locals: { registration_token: @group.runners_token } %hr = render partial: 'ci/runner/how_to_setup_runner', locals: { registration_token: @group.runners_token, diff --git a/app/views/groups/settings/_permissions.html.haml b/app/views/groups/settings/_permissions.html.haml index fcfe70bd694..d1f356ed665 100644 --- a/app/views/groups/settings/_permissions.html.haml +++ b/app/views/groups/settings/_permissions.html.haml @@ -7,13 +7,21 @@ .form-group = render 'shared/allow_request_access', form: f + - if @group.root? + .form-group.gl-mb-3 + .gl-form-checkbox.custom-control.custom-checkbox + = f.check_box :prevent_sharing_groups_outside_hierarchy, disabled: !can_change_prevent_sharing_groups_outside_hierarchy?(@group), class: 'custom-control-input' + = f.label :prevent_sharing_groups_outside_hierarchy, class: 'custom-control-label' do + %span + = s_('GroupSettings|Prevent members from sending invitations to groups outside of %{group} and its subgroups.').html_safe % { group: link_to_group(@group) } + %p.js-descr.help-text= prevent_sharing_groups_outside_hierarchy_help_text(@group) + .form-group.gl-mb-3 .gl-form-checkbox.custom-control.custom-checkbox = f.check_box :share_with_group_lock, disabled: !can_change_share_with_group_lock?(@group), class: 'custom-control-input' = f.label :share_with_group_lock, class: 'custom-control-label' do %span - - group_link = link_to @group.name, group_path(@group) - = s_('GroupSettings|Prevent sharing a project within %{group} with other groups').html_safe % { group: group_link } + = s_('GroupSettings|Prevent sharing a project within %{group} with other groups').html_safe % { group: link_to_group(@group) } %p.js-descr.help-text= share_with_group_lock_help_text(@group) .form-group.gl-mb-3 diff --git a/app/views/groups/settings/ci_cd/_form.html.haml b/app/views/groups/settings/ci_cd/_form.html.haml index c5cc3eb693c..b6f70879d17 100644 --- a/app/views/groups/settings/ci_cd/_form.html.haml +++ b/app/views/groups/settings/ci_cd/_form.html.haml @@ -8,6 +8,5 @@ = f.number_field :max_artifacts_size, class: 'form-control' %p.form-text.text-muted = _("The maximum file size in megabytes for individual job artifacts.") - = link_to sprite_icon('question-o'), help_page_path('user/admin_area/settings/continuous_integration', anchor: 'maximum-artifacts-size'), target: '_blank' - + = link_to s_('Learn more.'), help_page_path('user/admin_area/settings/continuous_integration', anchor: 'maximum-artifacts-size'), target: '_blank', rel: 'noopener noreferrer' = f.submit _('Save changes'), class: "btn gl-button btn-confirm" diff --git a/app/views/groups/settings/integrations/index.html.haml b/app/views/groups/settings/integrations/index.html.haml index 92b545cad0a..7a81d53c085 100644 --- a/app/views/groups/settings/integrations/index.html.haml +++ b/app/views/groups/settings/integrations/index.html.haml @@ -5,5 +5,5 @@ %h3= s_('Integrations|Project integration management') - integrations_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: integrations_help_page_path } -%p= s_('Integrations|As a GitLab administrator, you can set default configuration parameters for a given integration that all projects can inherit and use. When you set these parameters, your changes update the integration for all projects that are not already using custom settings. Learn more about %{integrations_link_start}Project integration management%{link_end}.').html_safe % { integrations_link_start: integrations_link_start, link_end: '</a>'.html_safe } +%p= s_("Integrations|GitLab administrators can set up integrations that all projects inherit and use by default. These integrations apply to all projects that don't already use custom settings. You can override custom settings for a group or project if the settings are necessary at that level. Learn more about %{integrations_link_start}project integration management%{link_end}.").html_safe % { integrations_link_start: integrations_link_start, link_end: "</a>".html_safe } = render 'shared/integrations/index', integrations: @integrations diff --git a/app/views/groups/show.html.haml b/app/views/groups/show.html.haml index 9f7f0a08df5..628425bf463 100644 --- a/app/views/groups/show.html.haml +++ b/app/views/groups/show.html.haml @@ -1,6 +1,7 @@ - @content_class = "limit-container-width" unless fluid_layout - page_itemtype 'https://schema.org/Organization' - @skip_current_level_breadcrumb = true +- add_page_specific_style 'page_bundles/group' - if show_thanks_for_purchase_banner? = render_if_exists 'shared/thanks_for_purchase_banner', plan_title: plan_title, quantity: params[:purchased_quantity].to_i diff --git a/app/views/groups/sidebar/_packages.html.haml b/app/views/groups/sidebar/_packages.html.haml index 7e0ee032aeb..e0158e4bf22 100644 --- a/app/views/groups/sidebar/_packages.html.haml +++ b/app/views/groups/sidebar/_packages.html.haml @@ -2,7 +2,7 @@ - if group_packages_nav? = nav_link(controller: ['groups/packages', 'groups/registry/repositories', 'groups/dependency_proxies']) do - = link_to packages_link, title: _('Packages') do + = link_to packages_link, title: _('Packages'), class: 'has-sub-items' do .nav-icon-container = sprite_icon('package') %span.nav-item-name diff --git a/app/views/import/_githubish_status.html.haml b/app/views/import/_githubish_status.html.haml index 4cf08b1d2be..02a8f3142c6 100644 --- a/app/views/import/_githubish_status.html.haml +++ b/app/views/import/_githubish_status.html.haml @@ -1,10 +1,13 @@ - add_page_specific_style 'page_bundles/import' -- provider = local_assigns.fetch(:provider) +- provider = local_assigns.fetch(:provider).to_sym - extra_data = local_assigns.fetch(:extra_data, {}) - filterable = local_assigns.fetch(:filterable, true) - paginatable = local_assigns.fetch(:paginatable, false) - provider_title = Gitlab::ImportSources.title(provider) +- header_title _("New project"), new_project_path +- add_to_breadcrumbs s_('ProjectsNew|Import project'), new_projects_path(anchor: 'import_project') + #import-projects-mount-element{ data: { provider: provider, provider_title: provider_title, can_select_namespace: current_user.can_select_namespace?.to_s, ci_cd_only: has_ci_cd_only_params?.to_s, diff --git a/app/views/import/bitbucket_server/new.html.haml b/app/views/import/bitbucket_server/new.html.haml index 8a3fe1a816c..ce6bdd7a2fb 100644 --- a/app/views/import/bitbucket_server/new.html.haml +++ b/app/views/import/bitbucket_server/new.html.haml @@ -1,7 +1,6 @@ -- title = _('Bitbucket Server Import') -- page_title title -- breadcrumb_title title -- header_title _("Projects"), root_path +- page_title _('Bitbucket Server Import') +- header_title _("New project"), new_project_path +- add_to_breadcrumbs s_('ProjectsNew|Import project'), new_projects_path(anchor: 'import_project') %h3.page-title.d-flex .gl-display-flex.gl-align-items-center.gl-justify-content-center diff --git a/app/views/import/bitbucket_server/status.html.haml b/app/views/import/bitbucket_server/status.html.haml index 7c4e6913c53..79b2810e06d 100644 --- a/app/views/import/bitbucket_server/status.html.haml +++ b/app/views/import/bitbucket_server/status.html.haml @@ -1,5 +1,4 @@ - page_title _('Bitbucket Server import') -- header_title _('Projects'), root_path %h3.page-title.d-flex .gl-display-flex.gl-align-items-center.gl-justify-content-center diff --git a/app/views/import/fogbugz/new.html.haml b/app/views/import/fogbugz/new.html.haml index ab836174024..51156797270 100644 --- a/app/views/import/fogbugz/new.html.haml +++ b/app/views/import/fogbugz/new.html.haml @@ -1,5 +1,7 @@ - page_title _("FogBugz Import") -- header_title _("Projects"), root_path +- header_title _("New project"), new_project_path +- add_to_breadcrumbs s_('ProjectsNew|Import project'), new_projects_path(anchor: 'import_project') + %h3.page-title.d-flex .gl-display-flex.gl-align-items-center.gl-justify-content-center = sprite_icon('bug', css_class: 'gl-mr-2') diff --git a/app/views/import/fogbugz/new_user_map.html.haml b/app/views/import/fogbugz/new_user_map.html.haml index 832289c3166..4281d77e833 100644 --- a/app/views/import/fogbugz/new_user_map.html.haml +++ b/app/views/import/fogbugz/new_user_map.html.haml @@ -1,5 +1,7 @@ - page_title _('User map'), _('FogBugz import') -- header_title _("Projects"), root_path +- header_title _("New project"), new_project_path +- add_to_breadcrumbs s_('ProjectsNew|Import project'), new_projects_path(anchor: 'import_project') + %h3.page-title.d-flex .gl-display-flex.gl-align-items-center.gl-justify-content-center = sprite_icon('bug', css_class: 'gl-mr-2') diff --git a/app/views/import/fogbugz/status.html.haml b/app/views/import/fogbugz/status.html.haml index e04a412e3bc..dcc0e94441c 100644 --- a/app/views/import/fogbugz/status.html.haml +++ b/app/views/import/fogbugz/status.html.haml @@ -1,5 +1,4 @@ - page_title _("FogBugz import") -- header_title _("Projects"), root_path %h3.page-title.d-flex .gl-display-flex.gl-align-items-center.gl-justify-content-center = sprite_icon('bug', css_class: 'gl-mr-2') diff --git a/app/views/import/gitea/new.html.haml b/app/views/import/gitea/new.html.haml index 27786806d17..288ae5f1cec 100644 --- a/app/views/import/gitea/new.html.haml +++ b/app/views/import/gitea/new.html.haml @@ -1,5 +1,6 @@ - page_title _("Gitea Import") -- header_title _("Projects"), root_path +- header_title _("New project"), new_project_path +- add_to_breadcrumbs s_('ProjectsNew|Import project'), new_projects_path(anchor: 'import_project') %h3.page-title = custom_icon('gitea_logo') diff --git a/app/views/import/gitea/status.html.haml b/app/views/import/gitea/status.html.haml index ef0693e73c3..1bdcec0c574 100644 --- a/app/views/import/gitea/status.html.haml +++ b/app/views/import/gitea/status.html.haml @@ -1,5 +1,4 @@ - page_title _("Gitea Import") -- header_title _("Projects"), root_path %h3.page-title = custom_icon('gitea_logo') = _('Import Projects from Gitea') diff --git a/app/views/import/github/new.html.haml b/app/views/import/github/new.html.haml index 32143f823d7..3407f9202bf 100644 --- a/app/views/import/github/new.html.haml +++ b/app/views/import/github/new.html.haml @@ -1,9 +1,9 @@ - title = _('Authenticate with GitHub') - page_title title -- breadcrumb_title title -- header_title _("Projects"), root_path +- header_title _("New project"), new_project_path +- add_to_breadcrumbs s_('ProjectsNew|Import project'), new_projects_path(anchor: 'import_project') -%h2.page-title +%h3.page-title = title %p diff --git a/app/views/import/github/status.html.haml b/app/views/import/github/status.html.haml index b62f98f5ded..820c2f06c8f 100644 --- a/app/views/import/github/status.html.haml +++ b/app/views/import/github/status.html.haml @@ -1,7 +1,5 @@ - title = has_ci_cd_only_params? ? _('Connect repositories from GitHub') : _('GitHub import') - page_title title -- breadcrumb_title title -- header_title _("Projects"), root_path %h3.page-title.mb-0.gl-display-flex .gl-display-flex.gl-align-items-center.gl-justify-content-center = sprite_icon('github', css_class: 'gl-mr-2') diff --git a/app/views/import/gitlab/status.html.haml b/app/views/import/gitlab/status.html.haml index ef803a36e79..b7b1fae1b73 100644 --- a/app/views/import/gitlab/status.html.haml +++ b/app/views/import/gitlab/status.html.haml @@ -1,5 +1,4 @@ - page_title _("GitLab.com import") -- header_title _("Projects"), root_path %h3.page-title = sprite_icon('heart', css_class: 'gl-vertical-align-middle') = _('Import projects from GitLab.com') diff --git a/app/views/import/gitlab_projects/new.html.haml b/app/views/import/gitlab_projects/new.html.haml index 8ba62c91e6a..8daddbb0042 100644 --- a/app/views/import/gitlab_projects/new.html.haml +++ b/app/views/import/gitlab_projects/new.html.haml @@ -1,5 +1,6 @@ - page_title _("GitLab Import") -- header_title _("Projects"), root_path +- header_title _("New project"), new_project_path +- add_to_breadcrumbs s_('ProjectsNew|Import project'), new_projects_path(anchor: 'import_project') %h3.page-title.d-flex .gl-display-flex.gl-align-items-center.gl-justify-content-center diff --git a/app/views/import/manifest/new.html.haml b/app/views/import/manifest/new.html.haml index 852f269f2ed..bfaff3bb300 100644 --- a/app/views/import/manifest/new.html.haml +++ b/app/views/import/manifest/new.html.haml @@ -1,5 +1,7 @@ - page_title _("Manifest file import") -- header_title _("Projects"), root_path +- header_title _("New project"), new_project_path +- add_to_breadcrumbs s_('ProjectsNew|Import project'), new_projects_path(anchor: 'import_project') + %h3.page-title = _('Manifest file import') diff --git a/app/views/import/manifest/status.html.haml b/app/views/import/manifest/status.html.haml index c3e77554b09..45d03575713 100644 --- a/app/views/import/manifest/status.html.haml +++ b/app/views/import/manifest/status.html.haml @@ -1,5 +1,4 @@ - page_title _("Manifest import") -- header_title _("Projects"), root_path %h3.page-title = _('Manifest file import') diff --git a/app/views/import/phabricator/new.html.haml b/app/views/import/phabricator/new.html.haml index 960d3df2c42..9596fdb615a 100644 --- a/app/views/import/phabricator/new.html.haml +++ b/app/views/import/phabricator/new.html.haml @@ -1,7 +1,6 @@ -- title = _('Phabricator Server Import') -- page_title title -- breadcrumb_title title -- header_title _("Projects"), root_path +- page_title _('Phabricator Server Import') +- header_title _("New project"), new_project_path +- add_to_breadcrumbs s_('ProjectsNew|Import project'), new_projects_path(anchor: 'import_project') %h3.page-title.d-flex .gl-display-flex.gl-align-items-center.gl-justify-content-center diff --git a/app/views/import/shared/_errors.html.haml b/app/views/import/shared/_errors.html.haml index 32b4a39924b..badd8c1278f 100644 --- a/app/views/import/shared/_errors.html.haml +++ b/app/views/import/shared/_errors.html.haml @@ -1,6 +1,8 @@ - if @errors.present? .gl-alert.gl-alert-danger.gl-mb-5 - = sprite_icon('error', size: 16, css_class: 'gl-icon gl-alert-icon gl-alert-icon-no-title') - .gl-alert-body - - @errors.each do |error| - = error + .gl-alert-container + = sprite_icon('error', size: 16, css_class: 'gl-icon gl-alert-icon gl-alert-icon-no-title') + .gl-alert-content + .gl-alert-body + - @errors.each do |error| + = error diff --git a/app/views/kaminari/gitlab/_keyset_paginator.html.haml b/app/views/kaminari/gitlab/_keyset_paginator.html.haml new file mode 100644 index 00000000000..f64c70dadfc --- /dev/null +++ b/app/views/kaminari/gitlab/_keyset_paginator.html.haml @@ -0,0 +1,30 @@ +- previous_path = url_for(page_params.merge(cursor: paginator.cursor_for_previous_page)) +- next_path = url_for(page_params.merge(cursor: paginator.cursor_for_next_page)) + +.gl-pagination.gl-mt-3 + %ul.pagination.justify-content-center + + - if paginator.has_previous_page? + - unless without_first_and_last_pages + %li.page-item + - first_page_path = url_for(page_params.merge(cursor: paginator.cursor_for_first_page)) + = link_to first_page_path, rel: 'first', class: 'page-link' do + = sprite_icon('angle-double-left', size: 8) + = s_('Pagination|First') + + %li.page-item.prev + = link_to previous_path, rel: 'prev', class: 'page-link' do + = sprite_icon('angle-left', size: 8) + = s_('Pagination|Prev') + + - if paginator.has_next_page? + %li.page-item.next + = link_to next_path, rel: 'next', class: 'page-link' do + = s_('Pagination|Next') + = sprite_icon('angle-right', size: 8) + - unless without_first_and_last_pages + %li.page-item + - last_page_path = url_for(page_params.merge(cursor: paginator.cursor_for_last_page)) + = link_to last_page_path, rel: 'last', class: 'page-link' do + = s_('Pagination|Last') + = sprite_icon('angle-double-right', size: 8) diff --git a/app/views/layouts/_head.html.haml b/app/views/layouts/_head.html.haml index b28cd47efcc..683d3a6ad1b 100644 --- a/app/views/layouts/_head.html.haml +++ b/app/views/layouts/_head.html.haml @@ -36,7 +36,7 @@ = favicon_link_tag favicon, id: 'favicon', data: { original_href: favicon }, type: 'image/png' - = render 'layouts/startup_css' + = render 'layouts/startup_css', { startup_filename: local_assigns.fetch(:startup_filename, nil) } - if user_application_theme == 'gl-dark' = stylesheet_link_tag_defer "application_dark" = yield :page_specific_styles @@ -54,8 +54,6 @@ = stylesheet_link_tag 'performance_bar' if performance_bar_enabled? - -# Rendering this above Gon, to use in JS later - = render 'layouts/header/new_repo_experiment' = Gon::Base.render_data(nonce: content_security_policy_nonce) = javascript_include_tag locale_path unless I18n.locale == :en @@ -73,7 +71,7 @@ = action_cable_meta_tag %meta{ name: 'viewport', content: 'width=device-width, initial-scale=1, maximum-scale=1' } - %meta{ name: 'theme-color', content: '#474D57' } + %meta{ name: 'theme-color', content: user_theme_primary_color } -# Apple Safari/iOS home screen icons = favicon_link_tag 'touch-icon-iphone.png', rel: 'apple-touch-icon' diff --git a/app/views/layouts/_page.html.haml b/app/views/layouts/_page.html.haml index c91d27e3ed1..2b63e2c647c 100644 --- a/app/views/layouts/_page.html.haml +++ b/app/views/layouts/_page.html.haml @@ -1,7 +1,7 @@ -.layout-page{ class: page_with_sidebar_class } +.layout-page.hide-when-top-nav-responsive-open{ class: page_with_sidebar_class } - if defined?(nav) && nav = render "layouts/nav/sidebar/#{nav}" - .content-wrapper{ class: "#{@content_wrapper_class}" } + .content-wrapper.content-wrapper-margin{ class: "#{@content_wrapper_class}" } .mobile-overlay = yield :group_invite_members_banner .alert-wrapper.gl-force-block-formatting-context @@ -27,3 +27,5 @@ = render "layouts/flash", extra_flash_class: 'limit-container-width' = yield :before_content = yield + += render "layouts/nav/top_nav_responsive", class: 'layout-page content-wrapper-margin' diff --git a/app/views/layouts/_search.html.haml b/app/views/layouts/_search.html.haml index 2032d1e95a6..e617b4358e3 100644 --- a/app/views/layouts/_search.html.haml +++ b/app/views/layouts/_search.html.haml @@ -1,5 +1,5 @@ .search.search-form{ data: { track_label: "navbar_search", track_event: "activate_form_input", track_value: "" } } - = form_tag search_path, method: :get, class: 'form-inline' do |_f| + = form_tag search_path, method: :get, class: 'form-inline form-control' do |_f| .search-input-container .search-input-wrap .dropdown{ data: { url: search_autocomplete_path } } diff --git a/app/views/layouts/_startup_css.haml b/app/views/layouts/_startup_css.haml index 7d3cfe28007..67c871b95f5 100644 --- a/app/views/layouts/_startup_css.haml +++ b/app/views/layouts/_startup_css.haml @@ -1,4 +1,5 @@ -- startup_filename = current_path?("sessions#new") ? 'signin' : user_application_theme == 'gl-dark' ? 'dark' : 'general' +- startup_filename_default = user_application_theme == 'gl-dark' ? 'dark' : 'general' +- startup_filename = local_assigns.fetch(:startup_filename, nil) || startup_filename_default %style = Rails.application.assets_manifest.find_sources("themes/#{user_application_theme_css_filename}.css").first.to_s.html_safe if user_application_theme_css_filename diff --git a/app/views/layouts/application.html.haml b/app/views/layouts/application.html.haml index 58408ec822c..47c092e199a 100644 --- a/app/views/layouts/application.html.haml +++ b/app/views/layouts/application.html.haml @@ -1,10 +1,12 @@ - page_classes = page_class << @html_class - page_classes = page_classes.flatten.compact +- body_classes = [user_application_theme, user_tab_width, @body_class, client_class_list] +- body_classes << 'sidebar-refactoring' if sidebar_refactor_enabled? !!! 5 %html{ lang: I18n.locale, class: page_classes } = render "layouts/head" - %body{ class: "#{user_application_theme} #{user_tab_width} #{@body_class} #{client_class_list}", data: body_data } + %body{ class: body_classes, data: body_data } = render "layouts/init_auto_complete" if @gfm_form = render "layouts/init_client_detection_flags" = render 'peek/bar' diff --git a/app/views/layouts/devise.html.haml b/app/views/layouts/devise.html.haml index ef61a04c288..ae7c160c060 100644 --- a/app/views/layouts/devise.html.haml +++ b/app/views/layouts/devise.html.haml @@ -1,6 +1,6 @@ !!! 5 %html.devise-layout-html{ class: system_message_class } - = render "layouts/head" + = render "layouts/head", { startup_filename: 'signin' } %body.ui-indigo.login-page.application.navless{ class: "#{client_class_list}", data: { page: body_data_page, qa_selector: 'login_page' } } = header_message = render "layouts/init_client_detection_flags" diff --git a/app/views/layouts/fullscreen.html.haml b/app/views/layouts/fullscreen.html.haml index 63bb9f8fff5..2a865aeda40 100644 --- a/app/views/layouts/fullscreen.html.haml +++ b/app/views/layouts/fullscreen.html.haml @@ -6,11 +6,12 @@ = header_message = render partial: "layouts/header/default", locals: { project: @project, group: @group } .mobile-overlay - .alert-wrapper + .alert-wrapper.hide-when-top-nav-responsive-open = render 'shared/outdated_browser' = render "layouts/broadcast" = yield :flash_message = render "layouts/flash" - .content-wrapper{ id: "content-body", class: "d-flex flex-column align-items-stretch mt-0" } + .content-wrapper.hide-when-top-nav-responsive-open{ id: "content-body", class: "d-flex flex-column align-items-stretch" } = yield + = render "layouts/nav/top_nav_responsive", class: "gl-flex-grow-1 gl-overflow-y-auto" = footer_message diff --git a/app/views/layouts/header/_default.html.haml b/app/views/layouts/header/_default.html.haml index ae333cffb84..87580e57e75 100644 --- a/app/views/layouts/header/_default.html.haml +++ b/app/views/layouts/header/_default.html.haml @@ -1,11 +1,12 @@ - has_impersonation_link = header_link?(:admin_impersonation) - user_status_data = user_status_properties(current_user) +- use_top_nav_redesign = Feature.enabled?(:combined_menu, current_user, default_enabled: :yaml) %header.navbar.navbar-gitlab.navbar-expand-sm.js-navbar{ data: { qa_selector: 'navbar' } } %a.gl-sr-only.gl-accessibility{ href: "#content-body" } Skip to content .container-fluid .header-content - .title-container + .title-container.hide-when-menu-expanded %h1.title %span.gl-sr-only GitLab = link_to root_path, title: _('Dashboard'), id: 'logo', **tracking_attrs('main_navigation', 'click_gitlab_logo_link', 'navigation') do @@ -19,8 +20,9 @@ %span.gl-badge.gl-bg-green-500.gl-text-white.gl-rounded-pill.gl-font-weight-bold.gl-py-1 = _('Next') - - if Feature.enabled?(:combined_menu, current_user, default_enabled: :yaml) - = render "layouts/nav/top_nav" + - if use_top_nav_redesign + .gl-display-none.gl-sm-display-block + = render "layouts/nav/top_nav" - else - if current_user = render "layouts/nav/dashboard" @@ -30,13 +32,14 @@ .navbar-collapse.collapse %ul.nav.navbar-nav - if current_user - = render 'layouts/header/new_dropdown' - - if header_link?(:search) + = render 'layouts/header/new_dropdown', class: ('gl-display-none gl-sm-display-block' if use_top_nav_redesign) + - if top_nav_show_search + - search_menu_item = top_nav_search_menu_item_attrs %li.nav-item.d-none.d-lg-block.m-auto = render 'layouts/search' unless current_controller?(:search) - %li.nav-item.d-inline-block.d-lg-none - = link_to search_context.search_url, title: _('Search'), aria: { label: _('Search') }, data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do - = sprite_icon('search') + %li.nav-item{ class: use_top_nav_redesign ? 'd-none d-sm-inline-block d-lg-none' : 'd-inline-block d-lg-none' } + = link_to search_menu_item.fetch(:href), title: search_menu_item.fetch(:title), aria: { label: search_menu_item.fetch(:title) }, data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do + = sprite_icon(search_menu_item.fetch(:icon)) - if header_link?(:issues) = nav_link(path: 'dashboard#issues', html_options: { class: "user-counter" }) do = link_to assigned_issues_dashboard_path, title: _('Issues'), class: 'dashboard-shortcuts-issues', aria: { label: _('Issues') }, @@ -115,10 +118,15 @@ - sign_in_text = allow_signup? ? _('Sign in / Register') : _('Sign in') = link_to sign_in_text, new_session_path(:user, redirect_to_referer: 'yes'), class: 'gl-button btn btn-default btn-sign-in' - %button.navbar-toggler.d-block.d-sm-none{ type: 'button' } + %button.navbar-toggler.d-block.d-sm-none{ type: 'button', class: ('gl-border-none!' if use_top_nav_redesign) } %span.sr-only= _('Toggle navigation') - = sprite_icon('ellipsis_h', size: 12, css_class: 'more-icon js-navbar-toggle-right') - = sprite_icon('close', size: 12, css_class: 'close-icon js-navbar-toggle-left') + - if use_top_nav_redesign + %span.more-icon.gl-px-3.gl-font-sm.gl-font-weight-bold + %span.gl-pr-2= _('Menu') + = sprite_icon('hamburger', size: 16) + - else + = sprite_icon('ellipsis_h', size: 12, css_class: 'more-icon') + = sprite_icon('close', size: 12, css_class: 'close-icon') - if display_whats_new? #whats-new-app{ data: { version_digest: whats_new_version_digest } } diff --git a/app/views/layouts/header/_group_invite_members_new_dropdown_item.html.haml b/app/views/layouts/header/_group_invite_members_new_dropdown_item.html.haml deleted file mode 100644 index cb74c77dff8..00000000000 --- a/app/views/layouts/header/_group_invite_members_new_dropdown_item.html.haml +++ /dev/null @@ -1,3 +0,0 @@ -- return unless Gitlab::Experimentation.active?(:invite_members_new_dropdown) && can?(current_user, :admin_group_member, @group) - -%li= dropdown_invite_members_link(@group) diff --git a/app/views/layouts/header/_help_dropdown.html.haml b/app/views/layouts/header/_help_dropdown.html.haml index c3769dd2993..01e59b8e2ef 100644 --- a/app/views/layouts/header/_help_dropdown.html.haml +++ b/app/views/layouts/header/_help_dropdown.html.haml @@ -10,7 +10,7 @@ %li %button.js-shortcuts-modal-trigger{ type: "button" } = _("Keyboard shortcuts") - %span.text-secondary.float-right{ "aria-hidden": true }= '?'.html_safe + %span.text-secondary.float-right{ "aria-hidden": "true" }= '?'.html_safe %li.divider %li = link_to _("Submit feedback"), "https://about.gitlab.com/submit-feedback" diff --git a/app/views/layouts/header/_new_dropdown.html.haml b/app/views/layouts/header/_new_dropdown.html.haml index ca90d2e02fa..c5f43fb2c16 100644 --- a/app/views/layouts/header/_new_dropdown.html.haml +++ b/app/views/layouts/header/_new_dropdown.html.haml @@ -1,47 +1,27 @@ -- new_repo_experiment_text = content_for(:new_repo_experiment) -%li.header-new.dropdown{ data: { track_label: "new_dropdown", track_event: "click_dropdown", track_experiment: "new_repo" } } - = link_to new_project_path, class: "header-new-dropdown-toggle has-tooltip qa-new-menu-toggle", id: "js-onboarding-new-project-link", title: _("New..."), ref: 'tooltip', aria: { label: _("New...") }, data: { toggle: 'dropdown', placement: 'bottom', container: 'body', display: 'static' } do +- view_model = new_dropdown_view_model(project: @project, group: @group) +- menu_sections = view_model.fetch(:menu_sections) +- title = view_model.fetch(:title) +- show_headers = menu_sections.length > 1 +- top_class = local_assigns.fetch(:class, nil) + +- return if menu_sections.empty? + +%li.header-new.dropdown{ class: top_class, data: { track_label: "new_dropdown", track_event: "click_dropdown", track_experiment: "new_repo" } } + = link_to new_project_path, class: "header-new-dropdown-toggle has-tooltip", id: "js-onboarding-new-project-link", title: title, ref: 'tooltip', aria: { label: title }, data: { toggle: 'dropdown', placement: 'bottom', container: 'body', display: 'static', qa_selector: 'new_menu_toggle' } do = sprite_icon('plus-square') = sprite_icon('chevron-down', css_class: 'caret-down') .dropdown-menu.dropdown-menu-right.dropdown-extended-height %ul - - if @group&.persisted? - - create_group_project = can?(current_user, :create_projects, @group) - - create_group_subgroup = can?(current_user, :create_subgroup, @group) - - - if create_group_project || create_group_subgroup - %li.dropdown-bold-header - = _('This group') - - if create_group_project - %li= link_to new_repo_experiment_text, new_project_path(namespace_id: @group.id), data: { track_experiment: 'new_repo', track_event: 'click_link_new_project_group', track_label: 'plus_menu_dropdown' } - - if create_group_subgroup - %li= link_to _('New subgroup'), new_group_path(parent_id: @group.id), data: { track_event: 'click_link_new_subgroup', track_label: 'plus_menu_dropdown' } - = render_if_exists 'layouts/header/create_epic_new_dropdown_item' - = render 'layouts/header/group_invite_members_new_dropdown_item' + - menu_sections.each_with_index do |section, index| + - if index > 0 %li.divider - %li.dropdown-bold-header GitLab - - - if @project&.persisted? - - create_project_issue = show_new_issue_link?(@project) - - merge_project = merge_request_source_project_for_project(@project) - - create_project_snippet = can?(current_user, :create_snippet, @project) - - - if create_project_issue || merge_project || create_project_snippet + - if show_headers %li.dropdown-bold-header - = _('This project') - - if create_project_issue - %li= link_to _('New issue'), new_project_issue_path(@project), data: { track_event: 'click_link_new_issue', track_label: 'plus_menu_dropdown' } - - if merge_project - %li= link_to _('New merge request'), project_new_merge_request_path(merge_project), data: { track_event: 'click_link_new_mr', track_label: 'plus_menu_dropdown' } - - - if create_project_snippet - %li= link_to _('New snippet'), new_project_snippet_path(@project), data: { track_event: 'click_link_new_snippet_project', track_label: 'plus_menu_dropdown' } - = render 'layouts/header/project_invite_members_new_dropdown_item' - %li.divider - %li.dropdown-bold-header GitLab - - if current_user.can_create_project? - %li= link_to new_repo_experiment_text, new_project_path, class: 'qa-global-new-project-link', data: { track_experiment: 'new_repo', track_event: 'click_link_new_project', track_label: 'plus_menu_dropdown' } - - if current_user.can_create_group? - %li= link_to _('New group'), new_group_path, data: { track_event: 'click_link_new_group', track_label: 'plus_menu_dropdown' } - - if current_user.can?(:create_snippet) - %li= link_to _('New snippet'), new_snippet_path, data: { track_event: 'click_link_new_snippet_parent', track_label: 'plus_menu_dropdown' }, class: 'qa-global-new-snippet-link' + = section.fetch(:title) + - section.fetch(:menu_items).each do |menu_item| + %li< + = link_to menu_item.fetch(:href), class: menu_item.fetch(:css_class), data: menu_item.fetch(:data) do + = menu_item.fetch(:title) + - if menu_item.fetch(:emoji) + -# We need to insert a space between the title and emoji + = " #{emoji_icon(menu_item.fetch(:emoji), 'aria-hidden': true, class: "gl-font-base gl-vertical-align-baseline")}".html_safe diff --git a/app/views/layouts/header/_new_repo_experiment.html.haml b/app/views/layouts/header/_new_repo_experiment.html.haml deleted file mode 100644 index aaa13d593cd..00000000000 --- a/app/views/layouts/header/_new_repo_experiment.html.haml +++ /dev/null @@ -1,6 +0,0 @@ -- content_for :new_repo_experiment do - - experiment(:new_repo, user: current_user) do |e| - - e.use do - = _('New project') - - e.try do - = _('New project/repository') diff --git a/app/views/layouts/header/_project_invite_members_new_dropdown_item.html.haml b/app/views/layouts/header/_project_invite_members_new_dropdown_item.html.haml deleted file mode 100644 index 2cb67e857e3..00000000000 --- a/app/views/layouts/header/_project_invite_members_new_dropdown_item.html.haml +++ /dev/null @@ -1,3 +0,0 @@ -- return unless Gitlab::Experimentation.active?(:invite_members_new_dropdown) && can_import_members? - -%li= dropdown_invite_members_link(@project) diff --git a/app/views/layouts/header/_registration_enabled_callout.html.haml b/app/views/layouts/header/_registration_enabled_callout.html.haml index 1b1804edcc7..9266702e44e 100644 --- a/app/views/layouts/header/_registration_enabled_callout.html.haml +++ b/app/views/layouts/header/_registration_enabled_callout.html.haml @@ -1,15 +1,14 @@ - 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') += render 'shared/global_alert', + title: _('Open registration is enabled on your instance.'), + variant: :warning, + alert_class: 'js-registration-enabled-callout', + alert_data: { feature_id: UserCalloutsHelper::REGISTRATION_ENABLED_CALLOUT, dismiss_endpoint: user_callouts_path }, + close_button_data: { testid: 'close-registration-enabled-callout' } do + .gl-alert-body + = html_escape(_('%{anchorOpen}Learn more%{anchorClose} about how you can customize / disable registration on your instance.')) % { anchorOpen: "<a href=\"#{help_page_path('user/admin_area/settings/sign_up_restrictions')}\">".html_safe, anchorClose: '</a>'.html_safe } + .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/nav/_dashboard.html.haml b/app/views/layouts/nav/_dashboard.html.haml index 718b2002422..117382d87b5 100644 --- a/app/views/layouts/nav/_dashboard.html.haml +++ b/app/views/layouts/nav/_dashboard.html.haml @@ -4,7 +4,7 @@ -# [1]: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/56587 %ul.list-unstyled.navbar-sub-nav - if dashboard_nav_link?(:projects) - = nav_link(path: ['root#index', 'projects#trending', 'projects#starred', 'dashboard/projects#index'], html_options: { id: 'nav-projects-dropdown', class: "home dropdown header-projects qa-projects-dropdown", data: { track_label: "projects_dropdown", track_event: "click_dropdown", track_experiment: "new_repo" } }) do + = nav_link(path: ['root#index', 'projects#trending', 'projects#starred', 'dashboard/projects#index'], html_options: { id: 'nav-projects-dropdown', class: "home dropdown header-projects", data: { track_label: "projects_dropdown", track_event: "click_dropdown", track_experiment: "new_repo" } }) do %button{ type: 'button', data: { toggle: "dropdown" } } = _('Projects') = sprite_icon('chevron-down', css_class: 'caret-down') @@ -12,7 +12,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" } }) do + = nav_link(controller: ['dashboard/groups', 'explore/groups'], html_options: { id: 'nav-groups-dropdown', class: "d-none d-md-block home dropdown header-groups", data: { track_label: "groups_dropdown", track_event: "click_dropdown" } }) do %button{ type: 'button', data: { toggle: "dropdown" } } = _('Groups') = sprite_icon('chevron-down', css_class: 'caret-down') @@ -21,28 +21,28 @@ - if any_dashboard_nav_link?([:groups, :milestones, :activity, :snippets]) = nav_link(html_options: { id: 'nav-more-dropdown', class: "header-more dropdown", data: { track_label: "more_dropdown", track_event: "click_more_link" } }) do - %a{ href: "#", data: { toggle: "dropdown", qa_selector: 'more_dropdown' } } + %a{ href: "#", data: { toggle: "dropdown" } } = _('More') = sprite_icon('chevron-down', css_class: 'caret-down') .dropdown-menu %ul - if dashboard_nav_link?(:groups) %li.d-md-none - = link_to dashboard_groups_path, class: 'dashboard-shortcuts-groups', data: { qa_selector: 'groups_link' } do + = link_to dashboard_groups_path, class: 'dashboard-shortcuts-groups' do = _('Groups') - if dashboard_nav_link?(:activity) = nav_link(path: 'dashboard#activity') do - = link_to activity_dashboard_path, class: 'dashboard-shortcuts-activity', data: { qa_selector: 'activity_link' } do + = link_to activity_dashboard_path, class: 'dashboard-shortcuts-activity' do = _('Activity') - if dashboard_nav_link?(:milestones) = nav_link(controller: 'dashboard/milestones') do - = link_to dashboard_milestones_path, class: 'dashboard-shortcuts-milestones', data: { qa_selector: 'milestones_link' } do + = link_to dashboard_milestones_path, class: 'dashboard-shortcuts-milestones' do = _('Milestones') - if dashboard_nav_link?(:snippets) = nav_link(controller: 'dashboard/snippets') do - = link_to dashboard_snippets_path, class: 'dashboard-shortcuts-snippets', data: { qa_selector: 'snippets_link' } do + = link_to dashboard_snippets_path, class: 'dashboard-shortcuts-snippets' do = _('Snippets') %li.dropdown @@ -50,7 +50,7 @@ - if current_user.admin? = nav_link(controller: 'admin/dashboard') do - = link_to admin_root_path, class: 'admin-icon qa-admin-area-link d-xl-none' do + = link_to admin_root_path, class: 'admin-icon d-xl-none' do = _('Admin Area') - if Gitlab::CurrentSettings.admin_mode - if header_link?(:admin_mode) @@ -68,7 +68,7 @@ - if current_user.admin? = nav_link(controller: 'admin/dashboard', html_options: { class: "d-none d-xl-block"}) do - = link_to admin_root_path, class: 'admin-icon qa-admin-area-link', title: _('Admin Area'), aria: { label: _('Admin Area') }, data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do + = link_to admin_root_path, class: 'admin-icon', title: _('Admin Area'), aria: { label: _('Admin Area') }, data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do = sprite_icon('admin', size: 18) - if Gitlab::CurrentSettings.admin_mode diff --git a/app/views/layouts/nav/_top_nav.html.haml b/app/views/layouts/nav/_top_nav.html.haml index 50c003f8e13..42119ddb291 100644 --- a/app/views/layouts/nav/_top_nav.html.haml +++ b/app/views/layouts/nav/_top_nav.html.haml @@ -2,6 +2,10 @@ %ul.list-unstyled.navbar-sub-nav#js-top-nav{ data: { view_model: view_model.to_json } } %li %a.top-nav-toggle{ href: '#', type: 'button', data: { toggle: "dropdown" } } - = sprite_icon('dot-grid', css_class: "dropdown-icon") + = sprite_icon('hamburger', css_class: "dropdown-icon") = view_model[:activeTitle] - = sprite_icon('chevron-down') + +.hidden + - view_model[:shortcuts].each do |shortcut| + = link_to shortcut[:href], class: shortcut[:css_class] do + = shortcut[:title] diff --git a/app/views/layouts/nav/_top_nav_responsive.html.haml b/app/views/layouts/nav/_top_nav_responsive.html.haml new file mode 100644 index 00000000000..0d122f1adff --- /dev/null +++ b/app/views/layouts/nav/_top_nav_responsive.html.haml @@ -0,0 +1,7 @@ +- return unless Feature.enabled?(:combined_menu, current_user, default_enabled: :yaml) + +- top_class = local_assigns.fetch(:class, nil) +- view_model = top_nav_responsive_view_model(project: @project, group: @group) + +.top-nav-responsive{ class: top_class } + #js-top-nav-responsive{ data: { view_model: view_model.to_json } } diff --git a/app/views/layouts/nav/groups_dropdown/_show.html.haml b/app/views/layouts/nav/groups_dropdown/_show.html.haml index 036647e2be1..d7b0c7150d4 100644 --- a/app/views/layouts/nav/groups_dropdown/_show.html.haml +++ b/app/views/layouts/nav/groups_dropdown/_show.html.haml @@ -4,19 +4,20 @@ -# [1]: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/56587 - group_meta = { id: @group.id, name: @group.name, namespace: @group.full_name, web_url: group_path(@group), avatar_url: @group.avatar_url } if @group&.persisted? .frequent-items-dropdown-container.with-deprecated-styles - .frequent-items-dropdown-sidebar.qa-groups-dropdown-sidebar + .frequent-items-dropdown-sidebar %ul = nav_link(path: 'dashboard/groups#index') do - = link_to dashboard_groups_path, class: 'qa-your-groups-link', data: { track_label: "groups_dropdown_your_groups", track_event: "click_link" } do + = link_to dashboard_groups_path, data: { track_label: "groups_dropdown_your_groups", track_event: "click_link" } do = _('Your groups') = nav_link(path: 'groups#explore') do = link_to explore_groups_path, data: { track_label: "groups_dropdown_explore_groups", track_event: "click_link" } do = _('Explore groups') - = nav_link(path: 'groups/new#create-group-pane', html_options: { class: 'gl-border-0 gl-border-t-1 gl-border-solid gl-border-gray-100' }) do - = link_to new_group_path(anchor: 'create-group-pane'), data: { track_label: "groups_dropdown_create_group", track_event: "click_link", qa_selector: 'create_group_link' } do - = _('Create group') - = nav_link(path: 'groups/new#import-group-pane') do - = link_to new_group_path(anchor: 'import-group-pane'), data: { track_label: "groups_dropdown_import_group", track_event: "click_link", qa_selector: 'import_group_link' } do - = _('Import group') + - if current_user.can_create_group? + = nav_link(path: 'groups/new#create-group-pane', html_options: { class: 'gl-border-0 gl-border-t-1 gl-border-solid gl-border-gray-100' }) do + = link_to new_group_path(anchor: 'create-group-pane'), data: { track_label: "groups_dropdown_create_group", track_event: "click_link" } do + = _('Create group') + = nav_link(path: 'groups/new#import-group-pane') do + = link_to new_group_path(anchor: 'import-group-pane'), data: { track_label: "groups_dropdown_import_group", track_event: "click_link" } do + = _('Import group') .frequent-items-dropdown-content #js-groups-dropdown{ data: { user_name: current_user.username, group: group_meta } } diff --git a/app/views/layouts/nav/projects_dropdown/_show.html.haml b/app/views/layouts/nav/projects_dropdown/_show.html.haml index 2517508ba6c..46070975566 100644 --- a/app/views/layouts/nav/projects_dropdown/_show.html.haml +++ b/app/views/layouts/nav/projects_dropdown/_show.html.haml @@ -4,10 +4,10 @@ -# [1]: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/56587 - project_meta = { id: @project.id, name: @project.name, namespace: @project.full_name, web_url: project_path(@project), avatar_url: @project.avatar_url } if @project&.persisted? .frequent-items-dropdown-container.with-deprecated-styles - .frequent-items-dropdown-sidebar.qa-projects-dropdown-sidebar + .frequent-items-dropdown-sidebar %ul = nav_link(path: 'dashboard/projects#index') do - = link_to dashboard_projects_path, class: 'qa-your-projects-link', data: { track_label: "projects_dropdown_your_projects", track_event: "click_link" } do + = link_to dashboard_projects_path, data: { track_label: "projects_dropdown_your_projects", track_event: "click_link" } do = _('Your projects') = nav_link(path: 'projects#starred') do = link_to starred_dashboard_projects_path, data: { track_label: "projects_dropdown_starred_projects", track_event: "click_link" } do @@ -18,10 +18,10 @@ - experiment(:new_repo, user: current_user) do |e| - e.use do = nav_link(path: 'projects/new#blank_project', html_options: { class: 'gl-border-0 gl-border-t-1 gl-border-solid gl-border-gray-100' }) do - = link_to new_project_path(anchor: 'blank_project'), data: { track_label: "projects_dropdown_blank_project", track_event: "click_link", track_experiment: "new_repo" } do + = link_to new_project_path(anchor: 'blank_project'), data: { track_label: "projects_dropdown_blank_project", track_event: "click_link", track_experiment: "new_repo", qa_selector: "create_project_link" } do = _('Create blank project') = nav_link(path: 'projects/new#import_project') do - = link_to new_project_path(anchor: 'import_project'), data: { track_label: "projects_dropdown_import_project", track_event: "click_link", track_experiment: "new_repo" } do + = link_to new_project_path(anchor: 'import_project'), data: { track_label: "projects_dropdown_import_project", track_event: "click_link", track_experiment: "new_repo", qa_selector: "import_project_link" } do = _('Import project') - e.try do = nav_link(path: 'projects/new#blank_project', html_options: { class: 'gl-border-0 gl-border-t-1 gl-border-solid gl-border-gray-100' }) do diff --git a/app/views/layouts/nav/sidebar/_admin.html.haml b/app/views/layouts/nav/sidebar/_admin.html.haml index b71866c9138..7a80c4e0ba9 100644 --- a/app/views/layouts/nav/sidebar/_admin.html.haml +++ b/app/views/layouts/nav/sidebar/_admin.html.haml @@ -1,14 +1,17 @@ +- avatar_size = sidebar_refactor_disabled? ? 24 : 18 +- avatar_size_class = sidebar_refactor_disabled? ? 's40' : 's32' + %aside.nav-sidebar.qa-admin-sidebar{ class: ("sidebar-collapsed-desktop" if collapsed_sidebar?), 'aria-label': _('Admin navigation') } .nav-sidebar-inner-scroll .context-header = link_to admin_root_path, title: _('Admin Overview') do - %span.avatar-container.s40.settings-avatar - = sprite_icon('admin', size: 24) + %span{ class: ['avatar-container', 'settings-avatar', 'rect-avatar', avatar_size_class] } + = sprite_icon('admin', size: avatar_size) %span.sidebar-context-title = _('Admin Area') %ul.sidebar-top-level-items{ data: { qa_selector: 'admin_sidebar_overview_submenu_content' } } = nav_link(controller: %w(dashboard admin admin/projects users groups jobs runners gitaly_servers), html_options: {class: 'home'}) do - = link_to admin_root_path do + = link_to admin_root_path, class: 'has-sub-items' do .nav-icon-container = sprite_icon('overview') %span.nav-item-name @@ -49,7 +52,7 @@ = _('Gitaly Servers') = nav_link(controller: admin_analytics_nav_links) do - = link_to admin_dev_ops_report_path, data: { qa_selector: 'admin_analytics_link' } do + = link_to admin_dev_ops_report_path, data: { qa_selector: 'admin_analytics_link' }, class: 'has-sub-items' do .nav-icon-container = sprite_icon('chart') %span.nav-item-name @@ -71,14 +74,14 @@ = _('Usage Trends') = nav_link(controller: admin_monitoring_nav_links) do - = link_to admin_system_info_path, data: { qa_selector: 'admin_monitoring_link' } do + = link_to admin_system_info_path, data: { qa_selector: 'admin_monitoring_link' }, class: 'has-sub-items' do .nav-icon-container = sprite_icon('monitor') %span.nav-item-name = _('Monitoring') %ul.sidebar-sub-level-items{ data: { qa_selector: 'admin_sidebar_monitoring_submenu_content' } } - = nav_link(controller: %w(system_info background_jobs health_check requests_profiles), html_options: { class: "fly-out-top-item" } ) do + = nav_link(controller: admin_monitoring_nav_links, html_options: { class: "fly-out-top-item" } ) do = link_to admin_system_info_path do %strong.fly-out-top-item-name = _('Monitoring') @@ -87,6 +90,10 @@ = link_to admin_system_info_path, title: _('System Info') do %span = _('System Info') + = nav_link(controller: :background_migrations) do + = link_to admin_background_migrations_path, title: _('Background Migrations') do + %span + = _('Background Migrations') = nav_link(controller: :background_jobs) do = link_to admin_background_jobs_path, title: _('Background Jobs') do %span @@ -227,20 +234,8 @@ %strong.fly-out-top-item-name = _('Labels') - = nav_link(controller: :appearances) do - = link_to admin_appearances_path do - .nav-icon-container - = sprite_icon('appearance') - %span.nav-item-name - = _('Appearance') - %ul.sidebar-sub-level-items.is-fly-out-only - = nav_link(controller: :appearances, html_options: { class: "fly-out-top-item" } ) do - = link_to admin_appearances_path do - %strong.fly-out-top-item-name - = _('Appearance') - - = nav_link(controller: [:application_settings, :integrations]) do - = link_to general_admin_application_settings_path do + = nav_link(controller: [:application_settings, :integrations, :appearances]) do + = link_to general_admin_application_settings_path, class: 'has-sub-items' do .nav-icon-container = sprite_icon('settings') %span.nav-item-name.qa-admin-settings-item @@ -248,7 +243,7 @@ %ul.sidebar-sub-level-items{ data: { qa_selector: 'admin_sidebar_settings_submenu_content' } } -# This active_nav_link check is also used in `app/views/layouts/admin.html.haml` - = nav_link(controller: [:application_settings, :integrations], html_options: { class: "fly-out-top-item" } ) do + = nav_link(controller: [:application_settings, :integrations, :appearances], html_options: { class: "fly-out-top-item" } ) do = link_to general_admin_application_settings_path do %strong.fly-out-top-item-name = _('Settings') @@ -295,6 +290,10 @@ = link_to network_admin_application_settings_path, title: _('Network'), data: { qa_selector: 'admin_settings_network_item' } do %span = _('Network') + = nav_link(controller: :appearances ) do + = link_to admin_application_settings_appearances_path do + %span + = _('Appearance') = nav_link(path: 'application_settings#preferences') do = link_to preferences_admin_application_settings_path, title: _('Preferences'), data: { qa_selector: 'admin_settings_preferences_link' } do %span diff --git a/app/views/layouts/nav/sidebar/_analytics_links.html.haml b/app/views/layouts/nav/sidebar/_analytics_links.html.haml index 970a1d5f2c7..58989d6afc4 100644 --- a/app/views/layouts/nav/sidebar/_analytics_links.html.haml +++ b/app/views/layouts/nav/sidebar/_analytics_links.html.haml @@ -4,7 +4,7 @@ - if navbar_links.any? = nav_link(path: all_paths) do - = link_to analytics_link.link, {class: 'shortcuts-analytics', data: { qa_selector: 'analytics_anchor' } } do + = link_to analytics_link.link, {class: 'shortcuts-analytics has-sub-items', data: { qa_selector: 'analytics_anchor' } } do .nav-icon-container = sprite_icon('chart') %span.nav-item-name{ data: { qa_selector: 'analytics_link' } } diff --git a/app/views/layouts/nav/sidebar/_context_menu_body.html.haml b/app/views/layouts/nav/sidebar/_context_menu_body.html.haml new file mode 100644 index 00000000000..321bcda5702 --- /dev/null +++ b/app/views/layouts/nav/sidebar/_context_menu_body.html.haml @@ -0,0 +1,9 @@ +- avatar_size_class = sidebar_refactor_disabled? ? 's40' : 's32' +- avatar_classes = ['avatar-container', 'rect-avatar', 'group-avatar'] +- avatar_classes << avatar_size_class + += link_to group_path(@group), title: @group.name, data: { qa_selector: 'group_scope_link' } do + %span{ class: avatar_classes } + = group_icon(@group, class: ['avatar', 'avatar-tile', avatar_size_class]) + %span.sidebar-context-title + = @group.name diff --git a/app/views/layouts/nav/sidebar/_group.html.haml b/app/views/layouts/nav/sidebar/_group.html.haml index 757f95f864a..0ce1d48a2de 100644 --- a/app/views/layouts/nav/sidebar/_group.html.haml +++ b/app/views/layouts/nav/sidebar/_group.html.haml @@ -1,36 +1,39 @@ - issues_count = cached_issuables_count(@group, type: :issues) -- merge_requests_count = group_open_merge_requests_count(@group) +- merge_requests_count = cached_issuables_count(@group, type: :merge_requests) - aside_title = @group.subgroup? ? _('Subgroup navigation') : _('Group navigation') %aside.nav-sidebar{ class: ("sidebar-collapsed-desktop" if collapsed_sidebar?), **sidebar_tracking_attributes_by_object(@group), 'aria-label': aside_title } .nav-sidebar-inner-scroll - .context-header - = link_to group_path(@group), title: @group.name do - %span.avatar-container.rect-avatar.s40.group-avatar - = group_icon(@group, class: "avatar s40 avatar-tile") - %span.sidebar-context-title - = @group.name + - if sidebar_refactor_disabled? + .context-header + = render 'layouts/nav/sidebar/context_menu_body' + %ul.sidebar-top-level-items.qa-group-sidebar + - if sidebar_refactor_enabled? + = nav_link(path: ['groups#show', 'groups#details'], html_options: { class: 'context-header' }) do + = render 'layouts/nav/sidebar/context_menu_body' + = render_if_exists 'layouts/nav/sidebar/group_trial_status_widget', group: @group - if group_sidebar_link?(:overview) - paths = group_overview_nav_link_paths = nav_link(path: paths, unless: -> { current_path?('groups/contribution_analytics#show') }, html_options: { class: 'home' }) do - = link_to group_path(@group) do + - information_link = sidebar_refactor_enabled? ? activity_group_path(@group) : group_path(@group) + = link_to information_link, class: 'has-sub-items', data: { qa_selector: 'group_information_link' } do .nav-icon-container - - sprite = Feature.enabled?(:sidebar_refactor, current_user) ? 'group' : 'home' + - sprite = sidebar_refactor_enabled? ? 'group' : 'home' = sprite_icon(sprite) %span.nav-item-name = group_information_title(@group) - %ul.sidebar-sub-level-items + %ul.sidebar-sub-level-items{ data: { qa_selector: 'group_information_submenu'} } = nav_link(path: paths, html_options: { class: "fly-out-top-item" } ) do - = link_to group_path(@group) do + = link_to information_link do %strong.fly-out-top-item-name = group_information_title(@group) %li.divider.fly-out-top-item - - if Feature.disabled?(:sidebar_refactor, current_user) + - if sidebar_refactor_disabled? = nav_link(path: ['groups#show', 'groups#details', 'groups#subgroups'], html_options: { class: 'home' }) do = link_to details_group_path(@group), title: _('Group details') do %span @@ -42,13 +45,13 @@ %span = _('Activity') - - if group_sidebar_link?(:labels) && Feature.enabled?(:sidebar_refactor, current_user, default_enabled: :yaml) + - if group_sidebar_link?(:labels) && sidebar_refactor_enabled? = nav_link(path: 'labels#index') do = link_to group_labels_path(@group), title: _('Labels') do %span = _('Labels') - - if Feature.enabled?(:sidebar_refactor, current_user, default_enabled: :yaml) + - if sidebar_refactor_enabled? - if group_sidebar_link?(:group_members) = nav_link(path: 'group_members#index') do = link_to group_group_members_path(@group), title: _('Members'), data: { qa_selector: 'group_members_item' } do @@ -59,7 +62,7 @@ - if group_sidebar_link?(:issues) = nav_link(path: group_issues_sub_menu_items, unless: -> { current_path?('issues_analytics#show') }) do - = link_to issues_group_path(@group), data: { qa_selector: 'group_issues_item' } do + = link_to issues_group_path(@group), data: { qa_selector: 'group_issues_item' }, class: 'has-sub-items' do .nav-icon-container = sprite_icon('issues') %span.nav-item-name @@ -85,7 +88,7 @@ %span = boards_link_text - - if group_sidebar_link?(:labels) && Feature.disabled?(:sidebar_refactor, current_user, default_enabled: :yaml) + - if group_sidebar_link?(:labels) && sidebar_refactor_disabled? = nav_link(path: 'labels#index') do = link_to group_labels_path(@group), title: _('Labels') do %span @@ -138,7 +141,7 @@ - if group_sidebar_link?(:wiki) = render 'layouts/nav/sidebar/wiki_link', wiki_url: @group.wiki.web_url - - if Feature.disabled?(:sidebar_refactor, current_user, default_enabled: :yaml) + - if sidebar_refactor_disabled? - if group_sidebar_link?(:group_members) = nav_link(path: 'group_members#index') do = link_to group_group_members_path(@group) do @@ -154,7 +157,7 @@ - if group_sidebar_link?(:settings) = nav_link(path: group_settings_nav_link_paths) do - = link_to edit_group_path(@group) do + = link_to edit_group_path(@group), class: 'has-sub-items' do .nav-icon-container = sprite_icon('settings') %span.nav-item-name{ data: { qa_selector: 'group_settings' } } diff --git a/app/views/layouts/nav/sidebar/_profile.html.haml b/app/views/layouts/nav/sidebar/_profile.html.haml index 63b97e3133c..daafabdb799 100644 --- a/app/views/layouts/nav/sidebar/_profile.html.haml +++ b/app/views/layouts/nav/sidebar/_profile.html.haml @@ -1,9 +1,12 @@ +- avatar_size = sidebar_refactor_disabled? ? 40 : 32 +- avatar_size_class = sidebar_refactor_disabled? ? 's40' : 's32' + %aside.nav-sidebar{ class: ("sidebar-collapsed-desktop" if collapsed_sidebar?), **sidebar_tracking_attributes_by_object(current_user), 'aria-label': _('User settings') } .nav-sidebar-inner-scroll .context-header = link_to profile_path, title: _('Profile Settings') do - %span.avatar-container.s40.settings-avatar - = image_tag avatar_icon_for_user(current_user, 40), class: "avatar s40 avatar-tile js-sidebar-user-avatar", alt: current_user.name, data: { testid: 'sidebar-user-avatar' } + %span{ class: ['avatar-container', 'settings-avatar', avatar_size_class] } + = image_tag avatar_icon_for_user(current_user, avatar_size), class: ['avatar', 'avatar-tile', 'js-sidebar-user-avatar', avatar_size_class], alt: current_user.name, data: { testid: 'sidebar-user-avatar' } %span.sidebar-context-title= _('User Settings') %ul.sidebar-top-level-items = nav_link(path: 'profiles#show', html_options: {class: 'home'}) do diff --git a/app/views/layouts/terms.html.haml b/app/views/layouts/terms.html.haml index e39cb5ee0a2..4d5c354388f 100644 --- a/app/views/layouts/terms.html.haml +++ b/app/views/layouts/terms.html.haml @@ -5,7 +5,7 @@ %body{ data: { page: body_data_page } } .layout-page.terms{ class: page_class } - .content-wrapper.gl-mt-0 + .content-wrapper .mobile-overlay .alert-wrapper = render "layouts/broadcast" diff --git a/app/views/notify/_failed_builds.html.haml b/app/views/notify/_failed_builds.html.haml index 11cbd700258..afed3c95130 100644 --- a/app/views/notify/_failed_builds.html.haml +++ b/app/views/notify/_failed_builds.html.haml @@ -3,10 +3,10 @@ had = failed.size failed - #{'build'.pluralize(failed.size)}. + #{'job'.pluralize(failed.size)}. %tr.table-warning %td{ style: "font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; border: 1px solid #ededed; border-bottom: 0; border-radius: 4px 4px 0 0; overflow: hidden; background-color: #fdf4f6; color: #d22852; font-size: 14px; line-height: 1.4; text-align: center; padding: 8px 16px;" } - Failed builds + Failed jobs %tr.section %td{ style: "font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; padding: 0 16px; border: 1px solid #ededed; border-radius: 4px; overflow: hidden; border-top: 0; border-radius: 0 0 4px 4px;" } %table.builds{ border: "0", cellpadding: "0", cellspacing: "0", style: "width: 100%; border-collapse: collapse;" } diff --git a/app/views/notify/in_product_marketing_email.html.haml b/app/views/notify/in_product_marketing_email.html.haml index a1c3ecfb87e..45b002757e3 100644 --- a/app/views/notify/in_product_marketing_email.html.haml +++ b/app/views/notify/in_product_marketing_email.html.haml @@ -184,9 +184,32 @@ - @message.body_line2&.tap do |line| %p{ style: "margin: 0 0 20px 0;" } = line.html_safe - %tr - %td{ align: "center", style: "padding: 10px 20px 80px 20px; font-family: 'Source Sans Pro', helvetica, arial, sans-serif;" } - .cta_link= @message.cta_link + - if @message.cta_text + %tr + %td{ align: "center", style: "padding: 10px 20px 80px 20px; font-family: 'Source Sans Pro', helvetica, arial, sans-serif;" } + .cta_link= @message.cta_link + - else + %tr + %td{ style: "padding: 10px 20px 10px 20px; font-family: 'Source Sans Pro', helvetica, arial, sans-serif; color:#000000; font-size: 16px; line-height: 20px;" } + %table{ border: "0", cellpadding: "0", cellspacing: "0", width: "100%", style: "width: 100%; min-width: 100%;" } + %tr + %td{ width: "50%", style: "width: 50%; min-width: 50%; color: #000000; font-family: 'Source Sans Pro', helvetica, arial, sans-serif; font-size: 16px; line-height: 100%; padding-bottom: 16px; text-align: left;", align: "left" } + = @message.feedback_ratings(1) + %td{ width: "50%", style: "width: 50%; min-width: 50%; color: #000000; font-family: 'Source Sans Pro', helvetica, arial, sans-serif; font-size: 16px; line-height: 100%; padding-bottom: 16px; text-align: right;", align: "right" } + = @message.feedback_ratings(5) + %tr + %td{ align: "center", style: "padding: 10px 1px 30px 1px;" } + %table{ align: "center", cellpadding: "5", cellspacing: "0", width: "100%", style: "width: 100%; min-width: 100%; border: 1px solid #dae0ea; border-radius: 0; min-width: 100%; text-align: center; font-family: 'Source Sans Pro', helvetica, arial, sans-serif; font-size: 16px;" } + %tr + - (1..5).each do |rating| + %td{ height: "54", style: "border-left: 1px solid #dae0ea; padding-bottom: 0; width: 9% !important;", width: "9%" } + %a{ href: @message.feedback_link(rating), style: "color: #424242; display: block; text-decoration: none;" } + %span{ height: "54", style: "display: block; font-size: 18px; height: 22px; line-height: 22px; padding: 16px 0; width: 100%; text-decoration: none;" } + = rating + %tr + %td{ style: "padding: 10px 20px 30px 20px; font-family: 'Source Sans Pro', helvetica, arial, sans-serif; color:#000000; font-size: 18px; line-height: 24px;" } + %p{ style: "margin: 0 0 50px 0;" } + = @message.feedback_thanks %tr{ style: "background-color: #ffffff;" } %td{ align: "center", style: "padding:75px 20px 25px;" } = about_link('gitlab_logo.png', 80) diff --git a/app/views/notify/in_product_marketing_email.text.erb b/app/views/notify/in_product_marketing_email.text.erb index 7d0fe7aec6d..6f0a2efa410 100644 --- a/app/views/notify/in_product_marketing_email.text.erb +++ b/app/views/notify/in_product_marketing_email.text.erb @@ -8,10 +8,19 @@ <%= @message.body_line2 %> +<% if @message.cta_text %> <%= @message.cta_link %> +<% else %> +<% (1..5).each do |rating| %> +<%= "#{rating} - #{@message.feedback_ratings(rating).upcase} - #{@message.feedback_link(rating)}" %> +<% end %> + + +<%= @message.feedback_thanks %> +<% end %> diff --git a/app/views/notify/member_invited_email.html.haml b/app/views/notify/member_invited_email.html.haml index f7dc1fa662c..a4ea63e3d53 100644 --- a/app/views/notify/member_invited_email.html.haml +++ b/app/views/notify/member_invited_email.html.haml @@ -13,28 +13,48 @@ = html_escape(s_("InviteEmail|You are invited to join the %{strong_start}%{project_or_group_name}%{strong_end}%{br_tag}%{project_or_group} as a %{role}")) % placeholders %p.invite-actions = link_to s_('InviteEmail|Join now'), invite_url(@token, invite_type: Members::InviteEmailExperiment::INVITE_TYPE), class: 'invite-btn-join' - - experiment_instance.try(:avatar) do - %tr - %td.text-content - %img.mail-avatar{ height: "60", src: avatar_icon_for_user(member.created_by, 60, only_path: false), width: "60", alt: "" } - %p - = html_escape(s_("InviteEmail|%{inviter} invited you to join the %{strong_start}%{project_or_group_name}%{strong_end}%{br_tag}%{project_or_group} as a %{role}")) % placeholders.merge({ inviter: (link_to member.created_by.name, user_url(member.created_by)).html_safe }) - %p.invite-actions - = link_to s_('InviteEmail|Join now'), invite_url(@token, invite_type: Members::InviteEmailExperiment::INVITE_TYPE), class: 'invite-btn-join' - - experiment_instance.try(:permission_info) do + - experiment_instance.try(:activity) do %tr %td.text-content{ colspan: 2 } %img.mail-avatar{ height: "60", src: avatar_icon_for_user(member.created_by, 60, only_path: false), width: "60", alt: "" } %p - = html_escape(s_("InviteEmail|%{inviter} invited you to join the %{strong_start}%{project_or_group_name}%{strong_end}%{br_tag}%{project_or_group} with the %{role} permission level.")) % placeholders.merge({ inviter: (link_to member.created_by.name, user_url(member.created_by)).html_safe }) + = html_escape(s_("InviteEmail|%{inviter} invited you to join the %{strong_start}%{project_or_group_name}%{strong_end}%{br_tag}%{project_or_group} as a %{role}")) % placeholders.merge({ inviter: (link_to member.created_by.name, user_url(member.created_by)).html_safe }) %p.invite-actions = link_to s_('InviteEmail|Join now'), invite_url(@token, invite_type: Members::InviteEmailExperiment::INVITE_TYPE), class: 'invite-btn-join' %tr.border-top - %td.text-content.half-width + %td.text-content.mailer-align-left.half-width %h4 - = s_('InviteEmail|What is a GitLab %{project_or_group}?') % { project_or_group: member_source.model_name.singular } - %p= invited_to_description(member_source.model_name.singular) - %td.text-content.half-width + = s_('InviteEmail|%{project_or_group} details') % { project_or_group: member_source.model_name.singular.capitalize } + %ul + %li + %div + %img.mailer-icon{ alt: '', src: image_url("mailers/members/users.png") } + %span + - member_count = member_source.members.size + = n_('%{bold_start}%{count}%{bold_end} member', '%{bold_start}%{count}%{bold_end} members', + member_count).html_safe % { count: number_with_delimiter(member_count), + bold_start: '<b>'.html_safe, + bold_end: '</b>'.html_safe } + %li + %div + %img.mailer-icon{ alt: '', src: image_url("mailers/members/issues.png") } + %span + - issue_count = member_source.open_issues_count(member.created_by) + = n_('%{bold_start}%{count}%{bold_end} issue', '%{bold_start}%{count}%{bold_end} issues', + issue_count).html_safe % { count: number_with_delimiter(issue_count), + bold_start: '<b>'.html_safe, + bold_end: '</b>'.html_safe } + %li + %div + %img.mailer-icon{ alt: '', src: image_url("mailers/members/merge-request-open.png") } + %span + - mr_count = member_source.open_merge_requests_count(member.created_by) + = n_('%{bold_start}%{count}%{bold_end} opened merge request', '%{bold_start}%{count}%{bold_end} opened merge requests', + mr_count).html_safe % { count: number_with_delimiter(mr_count), + bold_start: '<b>'.html_safe, + bold_end: '</b>'.html_safe } + %td.text-content.mailer-align-left.half-width %h4 - = s_('InviteEmail|What can I do with the %{role} permission level?') % { role: member.human_access.downcase } - %p= invited_role_description(member.human_access) + = s_("InviteEmail|What's it about?") + %p + = invited_to_description(member_source) diff --git a/app/views/notify/pipeline_failed_email.text.erb b/app/views/notify/pipeline_failed_email.text.erb index 1fe7d554bc3..6ab74bcfb1a 100644 --- a/app/views/notify/pipeline_failed_email.text.erb +++ b/app/views/notify/pipeline_failed_email.text.erb @@ -28,7 +28,7 @@ Pipeline #<%= @pipeline.id %> ( <%= pipeline_url(@pipeline) %> ) triggered by <% Pipeline #<%= @pipeline.id %> ( <%= pipeline_url(@pipeline) %> ) triggered by API <% end -%> <% failed = @pipeline.latest_statuses.failed -%> -had <%= failed.size %> failed <%= 'build'.pluralize(failed.size) %>. +had <%= failed.size %> failed <%= 'job'.pluralize(failed.size) %>. <% failed.each do |build| -%> <%= render "notify/links/#{build.to_partial_path}", pipeline: @pipeline, build: build %> diff --git a/app/views/notify/ssh_key_expired_email.html.haml b/app/views/notify/ssh_key_expired_email.html.haml index 651bdac7acb..79a09b74683 100644 --- a/app/views/notify/ssh_key_expired_email.html.haml +++ b/app/views/notify/ssh_key_expired_email.html.haml @@ -1,7 +1,7 @@ %p = _('Hi %{username}!') % { username: sanitize_name(@user.name) } %p - = _('Your SSH keys with the following fingerprints have expired. Expired SSH keys will not be usable in future versions of GitLab:') + = _('SSH keys with the following fingerprints have expired and can no longer be used:') %table %tbody - @fingerprints.each do |fingerprint| diff --git a/app/views/notify/ssh_key_expired_email.text.erb b/app/views/notify/ssh_key_expired_email.text.erb index aa6e79d59b8..0eb0859e4b9 100644 --- a/app/views/notify/ssh_key_expired_email.text.erb +++ b/app/views/notify/ssh_key_expired_email.text.erb @@ -1,6 +1,6 @@ <%= _('Hi %{username}!') % { username: sanitize_name(@user.name) } %> -<%= _('Your SSH keys with the following fingerprints have expired. Expired SSH keys will not be usable in future versions of GitLab:') %> +<%= _('SSH keys with the following fingerprints have expired and can no longer be used:') %> <% @fingerprints.each do |fingerprint| %> - <%= fingerprint %> diff --git a/app/views/notify/ssh_key_expiring_soon.text.erb b/app/views/notify/ssh_key_expiring_soon.text.erb index ff6feb87662..372c55ecb87 100644 --- a/app/views/notify/ssh_key_expiring_soon.text.erb +++ b/app/views/notify/ssh_key_expiring_soon.text.erb @@ -1,6 +1,6 @@ <%= _('Hi %{username}!') % { username: sanitize_name(@user.name) } %> -<%= _('Your SSH keys with the following fingerprints are scheduled to expire soon. Expired SSH keys will not be usable in future versions of GitLab:') %> +<%= _('SSH keys with the following fingerprints are scheduled to expire soon. Expired SSH keys can not be used:') %> <% @fingerprints.each do |fingerprint| %> - <%= fingerprint %> diff --git a/app/views/notify/ssh_key_expiring_soon_email.html.haml b/app/views/notify/ssh_key_expiring_soon_email.html.haml index 924165ecf3d..cd4ee23e3db 100644 --- a/app/views/notify/ssh_key_expiring_soon_email.html.haml +++ b/app/views/notify/ssh_key_expiring_soon_email.html.haml @@ -1,7 +1,7 @@ %p = _('Hi %{username}!') % { username: sanitize_name(@user.name) } %p - = _('Your SSH keys with the following fingerprints are scheduled to expire soon. Expired SSH keys will not be usable in future versions of GitLab:') + = _('SSH keys with the following fingerprints are scheduled to expire soon. Expired SSH keys can not be used:') %table %tbody - @fingerprints.each do |fingerprint| diff --git a/app/views/notify/unknown_sign_in_email.html.haml b/app/views/notify/unknown_sign_in_email.html.haml index 8d0993e9ff8..47c5656db27 100644 --- a/app/views/notify/unknown_sign_in_email.html.haml +++ b/app/views/notify/unknown_sign_in_email.html.haml @@ -32,7 +32,7 @@ %td{ style: "#{default_style}border-top:1px solid #ededed;" } = _('Time') %td{ style: "#{default_style}color:#333333;font-weight:400;width:75%;padding-left:5px;border-top:1px solid #ededed;" } - = @time.strftime('%Y-%m-%d %l:%M:%S %p %Z') + = @time.strftime('%Y-%m-%d %H:%M:%S %Z') %tr.spacer %td{ style: spacer_style } diff --git a/app/views/profiles/emails/index.html.haml b/app/views/profiles/emails/index.html.haml index d78b542ae8a..c14efa99555 100644 --- a/app/views/profiles/emails/index.html.haml +++ b/app/views/profiles/emails/index.html.haml @@ -22,15 +22,15 @@ .account-well.gl-mb-3 %ul %li - = _('Your Primary Email will be used for avatar detection.') + - profile_message = _('Your primary email is used for avatar detection. You can change it in your %{openingTag}profile settings%{closingTag}.') % { openingTag: "<a href='#{profile_path}'>".html_safe, closingTag: '</a>'.html_safe} + = profile_message.html_safe %li - = _('Your Commit Email will be used for web based operations, such as edits and merges.') + = _('Your commit email is used for web based operations, such as edits and merges.') %li - - address = profile_notifications_path - - notification_message = _('Your Default Notification Email will be used for account notifications if a %{openingTag}group-specific email address%{closingTag} is not set.') % { openingTag: "<a href='#{address}'>".html_safe, closingTag: '</a>'.html_safe} + - notification_message = _('Your default notification email is used for account notifications if a %{openingTag}group-specific email address%{closingTag} is not set.') % { openingTag: "<a href='#{profile_notifications_path}'>".html_safe, closingTag: '</a>'.html_safe} = notification_message.html_safe %li - = _('Your Public Email will be displayed on your public profile.') + = _('Your public email will be displayed on your public profile.') %li = _('All email addresses will be used to identify your commits.') %ul.content-list diff --git a/app/views/profiles/notifications/show.html.haml b/app/views/profiles/notifications/show.html.haml index 853188c563f..22cb95b346a 100644 --- a/app/views/profiles/notifications/show.html.haml +++ b/app/views/profiles/notifications/show.html.haml @@ -4,13 +4,15 @@ %div - if @user.errors.any? .gl-alert.gl-alert-danger.gl-my-5 - %button.js-close.gl-alert-dismiss{ type: 'button', 'aria-label' => _('Dismiss') } - = sprite_icon('close', css_class: 'gl-icon') - = sprite_icon('error', css_class: 'gl-icon gl-alert-icon gl-alert-icon-no-title') - .gl-alert-body - %ul - - @user.errors.full_messages.each do |msg| - %li= msg + .gl-alert-container + %button.js-close.btn.gl-dismiss-btn.btn-default.btn-sm.gl-button.btn-default-tertiary.btn-icon{ type: 'button', 'aria-label' => _('Dismiss') } + = sprite_icon('close', css_class: 'gl-icon') + = sprite_icon('error', css_class: 'gl-icon gl-alert-icon gl-alert-icon-no-title') + .gl-alert-content + .gl-alert-body + %ul + - @user.errors.full_messages.each do |msg| + %li= msg = hidden_field_tag :notification_type, 'global' .row.gl-mt-3 diff --git a/app/views/profiles/personal_access_tokens/index.html.haml b/app/views/profiles/personal_access_tokens/index.html.haml index ee04d9142b1..3661b93e33c 100644 --- a/app/views/profiles/personal_access_tokens/index.html.haml +++ b/app/views/profiles/personal_access_tokens/index.html.haml @@ -40,15 +40,15 @@ %h4.gl-mt-0 = s_('AccessTokens|Feed token') %p - = s_('AccessTokens|Your feed token is used to authenticate you when your RSS reader loads a personalized RSS feed or when your calendar application loads a personalized calendar, and is included in those feed URLs.') + = s_('AccessTokens|Your feed token authenticates you when your RSS reader loads a personalized RSS feed or when your calendar application loads a personalized calendar. It is visible in those feed URLs.') %p = s_('AccessTokens|It cannot be used to access any other data.') .col-lg-8.feed-token-reset = label_tag :feed_token, s_('AccessTokens|Feed token'), class: 'label-bold' = text_field_tag :feed_token, current_user.feed_token, class: 'form-control gl-form-input js-select-on-focus', readonly: true %p.form-text.text-muted - - reset_link = link_to s_('AccessTokens|reset it'), [:reset, :feed_token, :profile], method: :put, data: { confirm: s_('AccessTokens|Are you sure? Any RSS or calendar URLs currently in use will stop working.') } - - reset_message = s_('AccessTokens|Keep this token secret. Anyone who gets ahold of it can read activity and issue RSS feeds or your calendar feed as if they were you. You should %{link_reset_it} if that ever happens.') % { link_reset_it: reset_link } + - reset_link = link_to s_('AccessTokens|reset this token'), [:reset, :feed_token, :profile], method: :put, data: { confirm: s_('AccessTokens|Are you sure? Any RSS or calendar URLs currently in use will stop working.'), testid: :reset_feed_token_link } + - reset_message = s_('AccessTokens|Keep this token secret. Anyone who has it can read activity and issue RSS feeds or your calendar feed as if they were you. If that happens, %{link_reset_it}.') % { link_reset_it: reset_link } = reset_message.html_safe - if incoming_email_token_enabled? @@ -59,15 +59,15 @@ %h4.gl-mt-0 = s_('AccessTokens|Incoming email token') %p - = s_('AccessTokens|Your incoming email token is used to authenticate you when you create a new issue by email, and is included in your personal project-specific email addresses.') + = s_('AccessTokens|Your incoming email token authenticates you when you create a new issue by email, and is included in your personal project-specific email addresses.') %p = s_('AccessTokens|It cannot be used to access any other data.') .col-lg-8.incoming-email-token-reset = label_tag :incoming_email_token, s_('AccessTokens|Incoming email token'), class: 'label-bold' = text_field_tag :incoming_email_token, current_user.incoming_email_token, class: 'form-control gl-form-input js-select-on-focus', readonly: true %p.form-text.text-muted - - reset_link = link_to s_('AccessTokens|reset it'), [:reset, :incoming_email_token, :profile], method: :put, data: { confirm: s_('AccessTokens|Are you sure? Any issue email addresses currently in use will stop working.') } - - reset_message = s_('AccessTokens|Keep this token secret. Anyone who gets ahold of it can create issues as if they were you. You should %{link_reset_it} if that ever happens.') % { link_reset_it: reset_link } + - reset_link = link_to s_('AccessTokens|reset this token'), [:reset, :incoming_email_token, :profile], method: :put, data: { confirm: s_('AccessTokens|Are you sure? Any issue email addresses currently in use will stop working.'), testid: :reset_email_token_link } + - reset_message = s_('AccessTokens|Keep this token secret. Anyone who has it can create issues as if they were you. If that happens, %{link_reset_it}.') % { link_reset_it: reset_link } = reset_message.html_safe - if static_objects_external_storage_enabled? @@ -78,7 +78,7 @@ %h4.gl-mt-0 = s_('AccessTokens|Static object token') %p - = s_('AccessTokens|Your static object token is used to authenticate you when repository static objects (e.g. archives, blobs, ...) are being served from an external storage.') + = s_('AccessTokens|Your static object token authenticates you when repository static objects (such as archives or blobs) are served from an external storage.') %p = s_('AccessTokens|It cannot be used to access any other data.') .col-lg-8 @@ -88,5 +88,5 @@ - reset_link = url_for [:reset, :static_object_token, :profile] - reset_link_start = '<a data-confirm="%{confirm}" rel="nofollow" data-method="put" href="%{url}">'.html_safe % { confirm: s_('AccessTokens|Are you sure?'), url: reset_link } - reset_link_end = '</a>'.html_safe - - reset_message = s_('AccessTokens|Keep this token secret. Anyone who gets ahold of it can access repository static objects as if they were you. You should %{reset_link_start}reset it%{reset_link_end} if that ever happens.') % { reset_link_start: reset_link_start, reset_link_end: reset_link_end } + - reset_message = s_('AccessTokens|Keep this token secret. Anyone who has it can access repository static objects as if they were you. If that ever happens, %{reset_link_start}reset this token%{reset_link_end}.') % { reset_link_start: reset_link_start, reset_link_end: reset_link_end } = reset_message.html_safe diff --git a/app/views/profiles/show.html.haml b/app/views/profiles/show.html.haml index c3ec2f7bab3..411954aed6a 100644 --- a/app/views/profiles/show.html.haml +++ b/app/views/profiles/show.html.haml @@ -11,7 +11,7 @@ .row.js-search-settings-section .col-lg-4.profile-settings-sidebar %h4.gl-mt-0 - = s_("Profiles|Public Avatar") + = s_("Profiles|Public avatar") %p - if @user.avatar? - if gravatar_enabled? @@ -27,18 +27,17 @@ .md = brand_profile_image_guidelines .col-lg-8 - .clearfix.avatar-image.gl-mb-3 + .avatar-image = link_to avatar_icon_for_user(@user, 400), target: '_blank', rel: 'noopener noreferrer' do - = image_tag avatar_icon_for_user(@user, 160), alt: '', class: 'avatar s160' + = image_tag avatar_icon_for_user(@user, 96), alt: '', class: 'avatar s96' %h5.gl-mt-0= s_("Profiles|Upload new avatar") - .gl-mt-2.gl-mb-3 - %button.gl-button.btn.js-choose-user-avatar-button{ type: 'button' }= s_("Profiles|Choose file...") + .gl-my-3 + %button.gl-button.btn.btn-default.js-choose-user-avatar-button{ type: 'button' }= s_("Profiles|Choose file...") %span.avatar-file-name.gl-ml-3.js-avatar-filename= s_("Profiles|No file chosen.") = f.file_field_without_bootstrap :avatar, class: 'js-user-avatar-input hidden', accept: 'image/*' - .form-text.text-muted= s_("Profiles|The maximum file size allowed is 200KB.") + .gl-text-gray-500= s_("Profiles|The maximum file size allowed is 200KB.") - if @user.avatar? - %hr - = link_to s_("Profiles|Remove avatar"), profile_avatar_path, data: { confirm: s_("Profiles|Avatar will be removed. Are you sure?") }, method: :delete, class: 'gl-button btn btn-danger btn-inverted' + = link_to s_("Profiles|Remove avatar"), profile_avatar_path, data: { confirm: s_("Profiles|Avatar will be removed. Are you sure?") }, method: :delete, class: 'gl-button btn btn-danger-secondary btn-sm gl-mt-5' .col-lg-12 %hr .row.js-search-settings-section @@ -101,6 +100,7 @@ = render 'profiles/name', form: f, user: @user = f.text_field :id, class: 'gl-form-input', readonly: true, label: s_('Profiles|User ID'), wrapper: { class: 'col-md-3' } + = f.text_field :pronouns, class: 'input-md gl-form-input', help: s_("Profiles|Enter your pronouns to let people know how to refer to you") = render_if_exists 'profiles/email_settings', form: f = f.text_field :skype, class: 'input-md gl-form-input', placeholder: s_("Profiles|username") = f.text_field :linkedin, class: 'input-md gl-form-input', help: s_("Profiles|Your LinkedIn profile name from linkedin.com/in/profilename") @@ -124,10 +124,10 @@ = f.check_box :include_private_contributions, label: s_('Profiles|Include private contributions on my profile'), wrapper_class: 'mb-2', inline: true .help-block = s_("Profiles|Choose to show contributions of private projects on your public profile without any project, repository or organization information") - .row.gl-mt-3.gl-mb-3.gl-justify-content-end - .col-lg-8 - = f.submit s_("Profiles|Update profile settings"), class: 'gl-button btn btn-confirm' - = link_to _("Cancel"), user_path(current_user), class: 'gl-button btn btn-cancel' + .row.gl-justify-content-end.gl-mt-5 + .col-lg-8.gl-display-flex + = f.submit s_("Profiles|Update profile settings"), class: 'gl-button btn btn-confirm gl-mr-3' + = link_to _("Cancel"), user_path(current_user), class: 'gl-button btn btn-default btn-cancel' .modal.modal-profile-crop{ data: { cropper_css_path: ActionController::Base.helpers.stylesheet_path('lazy_bundles/cropper.css') } } .modal-dialog @@ -136,7 +136,7 @@ %h4.modal-title = s_("Profiles|Position and size your new avatar") %button.close{ type: "button", "data-dismiss": "modal", "aria-label" => _("Close") } - %span{ "aria-hidden": true } × + %span{ "aria-hidden": "true" } × .modal-body .profile-crop-image-container %img.modal-profile-crop-image{ alt: s_("Profiles|Avatar cropper") } diff --git a/app/views/profiles/two_factor_auths/show.html.haml b/app/views/profiles/two_factor_auths/show.html.haml index 71262f4bcb9..3cd571c23d3 100644 --- a/app/views/profiles/two_factor_auths/show.html.haml +++ b/app/views/profiles/two_factor_auths/show.html.haml @@ -46,7 +46,9 @@ = form_tag profile_two_factor_auth_path, method: :post do |f| - if @error .gl-alert.gl-alert-danger.gl-mb-5 - = @error + .gl-alert-container + .gl-alert-content + = @error .form-group = label_tag :pin_code, _('Pin code'), class: "label-bold" = text_field_tag :pin_code, nil, class: "form-control gl-form-input", required: true, data: { qa_selector: 'pin_code_field' } diff --git a/app/views/projects/_bitbucket_import_modal.html.haml b/app/views/projects/_bitbucket_import_modal.html.haml index c54a4ceb890..1379a339feb 100644 --- a/app/views/projects/_bitbucket_import_modal.html.haml +++ b/app/views/projects/_bitbucket_import_modal.html.haml @@ -4,7 +4,7 @@ .modal-header %h3.modal-title Import projects from Bitbucket %button.close{ type: "button", "data-dismiss": "modal", "aria-label" => _('Close') } - %span{ "aria-hidden": true } × + %span{ "aria-hidden": "true" } × .modal-body To enable importing projects from Bitbucket, - if current_user.admin? diff --git a/app/views/projects/_deletion_failed.html.haml b/app/views/projects/_deletion_failed.html.haml index 7e65f2f1cef..21c799f5bb6 100644 --- a/app/views/projects/_deletion_failed.html.haml +++ b/app/views/projects/_deletion_failed.html.haml @@ -2,7 +2,9 @@ - return unless project.delete_error.present? .project-deletion-failed-message.gl-alert.gl-alert-warning - = sprite_icon('warning', size: 16, css_class: 'gl-icon gl-alert-icon gl-alert-icon-no-title') - .gl-alert-body - This project was scheduled for deletion, but failed with the following message: - = project.delete_error + .gl-alert-container + = sprite_icon('warning', size: 16, css_class: 'gl-icon gl-alert-icon gl-alert-icon-no-title') + .gl-alert-content + .gl-alert-body + This project was scheduled for deletion, but failed with the following message: + = project.delete_error diff --git a/app/views/projects/_files.html.haml b/app/views/projects/_files.html.haml index 8642dc5fc8c..597a22bf34a 100644 --- a/app/views/projects/_files.html.haml +++ b/app/views/projects/_files.html.haml @@ -7,7 +7,7 @@ - add_page_startup_api_call project_blob_path(@project, tree_join(@ref, readme_path), viewer: "rich", format: "json") #tree-holder.tree-holder.clearfix - .nav-block.gl-display-flex.gl-align-items-center + .nav-block.gl-display-flex.gl-xs-flex-direction-column.gl-align-items-stretch = render 'projects/tree/tree_header', tree: @tree #js-last-commit diff --git a/app/views/projects/_gitlab_import_modal.html.haml b/app/views/projects/_gitlab_import_modal.html.haml index 5519415cdc3..689e100ab96 100644 --- a/app/views/projects/_gitlab_import_modal.html.haml +++ b/app/views/projects/_gitlab_import_modal.html.haml @@ -4,7 +4,7 @@ .modal-header %h3.modal-title Import projects from GitLab.com %button.close{ type: "button", "data-dismiss": "modal", "aria-label" => _('Close') } - %span{ "aria-hidden": true } × + %span{ "aria-hidden": "true" } × .modal-body To enable importing projects from GitLab.com, - if current_user.admin? diff --git a/app/views/projects/_home_panel.html.haml b/app/views/projects/_home_panel.html.haml index a70679dab5f..26291c0358e 100644 --- a/app/views/projects/_home_panel.html.haml +++ b/app/views/projects/_home_panel.html.haml @@ -25,14 +25,14 @@ %span.access-request-links.gl-ml-3 = render 'shared/members/access_request_links', source: @project - - if @project.tag_list.present? - = cache_if(cache_enabled, [@project, :tag_list], expires_in: 1.day) do + - if @project.topic_list.present? + = cache_if(cache_enabled, [@project, :topic_list], expires_in: 1.day) do %span.home-panel-topic-list.mt-2.w-100.d-inline-flex.gl-font-base.gl-font-weight-normal.gl-align-items-center = sprite_icon('tag', css_class: 'icon gl-relative gl-mr-2') - @project.topics_to_show.each do |topic| - project_topics_classes = "badge badge-pill badge-secondary gl-mr-2" - - explore_project_topic_path = explore_projects_path(tag: topic) + - explore_project_topic_path = explore_projects_path(topic: topic) - if topic.length > max_project_topic_length %a{ class: "#{ project_topics_classes } str-truncated-30 has-tooltip", data: { container: "body" }, title: topic, href: explore_project_topic_path, itemprop: 'keywords' } = topic.titleize diff --git a/app/views/projects/_import_project_pane.html.haml b/app/views/projects/_import_project_pane.html.haml index c0fe788b56a..e6ded3ad912 100644 --- a/app/views/projects/_import_project_pane.html.haml +++ b/app/views/projects/_import_project_pane.html.haml @@ -83,7 +83,7 @@ .js-toggle-content.toggle-import-form{ class: ('hide' if active_tab != 'import') } - = form_for @project, html: { class: 'new_project gl-show-field-errors' } do |f| + = form_for @project, html: { class: 'new_project' } do |f| %hr = render "shared/import_form", f: f = render 'projects/new_project_fields', f: f, project_name_id: "import-url-name", hide_init_with_readme: true, track_label: track_label diff --git a/app/views/projects/_invite_members.html.haml b/app/views/projects/_invite_members.html.haml index e3a512d6451..ab630d34501 100644 --- a/app/views/projects/_invite_members.html.haml +++ b/app/views/projects/_invite_members.html.haml @@ -3,6 +3,10 @@ track_event: 'render' } } = s_('InviteMember|Invite your team') %p= s_('InviteMember|Add members to this project and start collaborating with your team.') -= link_to s_('InviteMember|Invite members'), project_project_members_path(@project, sort: :access_level_desc), - class: 'gl-button btn btn-confirm gl-mb-8 gl-xs-w-full', - data: { track_event: 'click_button', track_label: 'invite_members_empty_project' } +.js-invite-members-trigger{ data: { variant: 'confirm', + classes: 'gl-mb-8 gl-xs-w-full', + display_text: s_('InviteMember|Invite members'), + event: 'click_button', + label: 'invite_members_empty_project' } } + += render 'shared/issuable/invite_members_trigger', project: @project diff --git a/app/views/projects/_visibility_modal.html.haml b/app/views/projects/_visibility_modal.html.haml index 990ac9fefb9..f75216a71b6 100644 --- a/app/views/projects/_visibility_modal.html.haml +++ b/app/views/projects/_visibility_modal.html.haml @@ -7,7 +7,7 @@ .modal-header %h3.page-title= _('Reduce this project’s visibility?') %button.close{ type: "button", "data-dismiss": "modal", "aria-label" => _('Close') } - %span{ "aria-hidden": true }= sprite_icon("close") + %span{ "aria-hidden": "true" }= sprite_icon("close") .modal-body %p - if @project.group diff --git a/app/views/projects/blob/_blob.html.haml b/app/views/projects/blob/_blob.html.haml index e50b964a253..9fa65f27651 100644 --- a/app/views/projects/blob/_blob.html.haml +++ b/app/views/projects/blob/_blob.html.haml @@ -1,4 +1,6 @@ = render "projects/blob/breadcrumb", blob: blob +- project = @project.present(current_user: current_user) +- ref = local_assigns[:ref] || @ref .info-well.d-none.d-sm-block .well-segment @@ -12,7 +14,12 @@ - if @code_navigation_path #js-code-navigation{ data: { code_navigation_path: @code_navigation_path, blob_path: blob.path, definition_path_prefix: project_blob_path(@project, @ref) } } - if Feature.enabled?(:refactor_blob_viewer, @project, default_enabled: :yaml) - #js-view-blob-app{ data: { blob_path: blob.path, project_path: @project.full_path } } + -# Data info will be removed once we migrate this to use GraphQL + -# Follow-up issue: https://gitlab.com/gitlab-org/gitlab/-/issues/330406 + #js-view-blob-app{ data: { blob_path: blob.path, + project_path: @project.full_path, + target_branch: project.empty_repo? ? ref : @ref, + original_branch: @ref } } .gl-spinner-container = loading_icon(size: 'md') - else diff --git a/app/views/projects/blob/_header_content.html.haml b/app/views/projects/blob/_header_content.html.haml index b310939c5a3..95a5d63e07f 100644 --- a/app/views/projects/blob/_header_content.html.haml +++ b/app/views/projects/blob/_header_content.html.haml @@ -1,4 +1,6 @@ .file-header-content + - if Gitlab::MarkupHelper.gitlab_markdown?(blob.path) + .js-table-contents = blob_icon blob.mode, blob.name %strong.file-title-name.gl-word-break-all{ data: { qa_selector: 'file_name_content' } } diff --git a/app/views/projects/blob/_new_dir.html.haml b/app/views/projects/blob/_new_dir.html.haml index 57477e59167..905dc2a49ec 100644 --- a/app/views/projects/blob/_new_dir.html.haml +++ b/app/views/projects/blob/_new_dir.html.haml @@ -4,7 +4,7 @@ .modal-header %h3.page-title= _('Create New Directory') %button.close{ type: "button", "data-dismiss": "modal", "aria-label" => _('Close') } - %span{ "aria-hidden": true } × + %span{ "aria-hidden": "true" } × .modal-body = form_tag project_create_dir_path(@project, @id), method: :post, remote: false, class: 'js-create-dir-form js-quick-submit js-requires-input' do .form-group.row diff --git a/app/views/projects/blob/_remove.html.haml b/app/views/projects/blob/_remove.html.haml index d3440ee41b5..298a36e28ec 100644 --- a/app/views/projects/blob/_remove.html.haml +++ b/app/views/projects/blob/_remove.html.haml @@ -4,7 +4,7 @@ .modal-header %h3.page-title Delete #{@blob.name} %button.close{ type: "button", "data-dismiss": "modal", "aria-label" => _('Close') } - %span{ "aria-hidden": true } × + %span{ "aria-hidden": "true" } × .modal-body = form_tag project_blob_path(@project, @id), method: :delete, class: 'js-delete-blob-form js-quick-submit js-requires-input' do diff --git a/app/views/projects/blob/_upload.html.haml b/app/views/projects/blob/_upload.html.haml index 28e33e3ac9b..6d2751bb7d4 100644 --- a/app/views/projects/blob/_upload.html.haml +++ b/app/views/projects/blob/_upload.html.haml @@ -4,7 +4,7 @@ .modal-header %h3.page-title= title %button.close{ type: "button", "data-dismiss": "modal", "aria-label" => _('Close') } - %span{ "aria-hidden": true } × + %span{ "aria-hidden": "true" } × .modal-body = form_tag form_path, method: method, class: 'js-quick-submit js-upload-blob-form', data: { method: method } do .dropzone diff --git a/app/views/projects/blob/_viewer.html.haml b/app/views/projects/blob/_viewer.html.haml index a0d82ffd2c7..8713ce79d96 100644 --- a/app/views/projects/blob/_viewer.html.haml +++ b/app/views/projects/blob/_viewer.html.haml @@ -5,6 +5,7 @@ - external_embed = local_assigns.fetch(:external_embed, false) - viewer_url = local_assigns.fetch(:viewer_url) { url_for(safe_params.merge(viewer: viewer.type, format: :json)) } if load_async +- add_page_startup_api_call viewer_url .blob-viewer{ data: { type: viewer.type, rich_type: rich_type, url: viewer_url, path: viewer.blob.path }, class: ('hidden' if hidden) } - if render_error = render 'projects/blob/render_error', viewer: viewer diff --git a/app/views/projects/blob/edit.html.haml b/app/views/projects/blob/edit.html.haml index 9f89981e7ca..ecbef9a11a7 100644 --- a/app/views/projects/blob/edit.html.haml +++ b/app/views/projects/blob/edit.html.haml @@ -5,11 +5,13 @@ - if @conflict .gl-alert.gl-alert-danger.gl-mb-5.gl-mt-5 - = sprite_icon('error', size: 16, css_class: 'gl-icon gl-alert-icon gl-alert-icon-no-title') - .gl-alert-body - Someone edited the file the same time you did. Please check out - = link_to "the file", project_blob_path(@project, tree_join(@branch_name, @file_path)), target: "_blank", rel: 'noopener noreferrer', class: 'gl-link' - and make sure your changes will not unintentionally remove theirs. + .gl-alert-container + = sprite_icon('error', size: 16, css_class: 'gl-icon gl-alert-icon gl-alert-icon-no-title') + .gl-alert-content + .gl-alert-body + Someone edited the file the same time you did. Please check out + = link_to _('the file'), project_blob_path(@project, tree_join(@branch_name, @file_path)), target: "_blank", rel: 'noopener noreferrer', class: 'gl-link' + and make sure your changes will not unintentionally remove theirs. %h3.page-title.blob-edit-page-title Edit file diff --git a/app/views/projects/branches/_branch.html.haml b/app/views/projects/branches/_branch.html.haml index a5414ce7ef2..60cb06f71ba 100644 --- a/app/views/projects/branches/_branch.html.haml +++ b/app/views/projects/branches/_branch.html.haml @@ -46,35 +46,40 @@ title: s_('Branches|Compare') do = s_('Branches|Compare') - = render 'projects/buttons/download', project: @project, ref: branch.name, pipeline: @refs_pipelines[branch.name] + = render 'projects/buttons/download', project: @project, ref: branch.name, pipeline: @refs_pipelines[branch.name], class: 'gl-vertical-align-top' - - if can?(current_user, :push_code, @project) + - if Feature.enabled?(:delete_branch_confirmation_modals, @project, default_enabled: :yaml) + = render 'projects/branches/delete_branch_modal_button', project: @project, branch: branch, merged: merged + + - elsif can?(current_user, :push_code, @project) - if branch.name == @project.repository.root_ref - delete_default_branch_tooltip = s_('Branches|The default branch cannot be deleted') - %span.has-tooltip{ title: delete_default_branch_tooltip } - %button{ class: "gl-button btn btn-danger disabled", disabled: true, 'aria-label' => delete_default_branch_tooltip } - = sprite_icon("remove") + %span.gl-display-inline-block.has-tooltip{ title: delete_default_branch_tooltip } + %button{ class: 'gl-button btn btn-default btn-icon disabled', disabled: true, 'aria-label' => delete_default_branch_tooltip } + = sprite_icon('remove', css_class: 'gl-button-icon gl-icon') - elsif protected_branch?(@project, branch) - if can?(current_user, :push_to_delete_protected_branch, @project) - %button{ class: "gl-button btn btn-danger has-tooltip", - title: s_('Branches|Delete protected branch'), - data: { toggle: "modal", - target: "#modal-delete-branch", + - delete_protected_branch_tooltip = s_('Branches|Delete protected branch') + %button{ class: 'gl-button btn btn-default btn-icon has-tooltip', + title: delete_protected_branch_tooltip, + 'aria-label' => delete_protected_branch_tooltip, + data: { toggle: 'modal', + target: '#modal-delete-branch', delete_path: project_branch_path(@project, branch.name), branch_name: branch.name, - is_merged: ("true" if merged) } } - = sprite_icon("remove") + is_merged: ('true' if merged) } } + = sprite_icon('remove', css_class: 'gl-button-icon gl-icon') - else - - delete_protected_branch_tooltip = s_('Branches|Only a project maintainer or owner can delete a protected branch') - %span.has-tooltip{ title: delete_protected_branch_tooltip } - %button{ class: "gl-button btn btn-danger disabled", disabled: true, 'aria-label' => delete_protected_branch_tooltip } - = sprite_icon("remove") + - delete_protected_branch_disabled_tooltip = s_('Branches|Only a project maintainer or owner can delete a protected branch') + %span.has-tooltip{ title: delete_protected_branch_disabled_tooltip } + %button{ class: 'gl-button btn btn-default btn-icon disabled', disabled: true, 'aria-label' => delete_protected_branch_disabled_tooltip, data: { testid: 'remove-protected-branch' } } + = sprite_icon('remove', css_class: 'gl-button-icon gl-icon') - else = link_to project_branch_path(@project, branch.name), - class: "gl-button btn btn-danger js-remove-row qa-remove-btn js-ajax-loading-spinner has-tooltip", + class: 'gl-button btn btn-default btn-icon js-remove-row qa-remove-btn js-ajax-loading-spinner has-tooltip', title: s_('Branches|Delete branch'), method: :delete, data: { confirm: s_("Branches|Deleting the '%{branch_name}' branch cannot be undone. Are you sure?") % { branch_name: branch.name } }, remote: true, 'aria-label' => s_('Branches|Delete branch') do - = sprite_icon("remove") + = sprite_icon('remove', css_class: 'gl-button-icon gl-icon') diff --git a/app/views/projects/branches/_delete_branch_modal_button.html.haml b/app/views/projects/branches/_delete_branch_modal_button.html.haml new file mode 100644 index 00000000000..829a459ad2c --- /dev/null +++ b/app/views/projects/branches/_delete_branch_modal_button.html.haml @@ -0,0 +1,18 @@ +- if branch.name == @project.repository.root_ref + .js-delete-branch-button{ data: { tooltip: s_('Branches|The default branch cannot be deleted'), + disabled: true.to_s } } +- elsif protected_branch?(@project, branch) + - if can?(current_user, :push_to_delete_protected_branch, @project) + .js-delete-branch-button{ data: { branch_name: branch.name, + is_protected_branch: true.to_s, + merged: merged.to_s, + default_branch_name: @project.repository.root_ref, + delete_path: project_branch_path(@project, branch.name) } } + - else + .js-delete-branch-button{ data: { is_protected_branch: true.to_s, + disabled: true.to_s } } +- else + .js-delete-branch-button{ data: { branch_name: branch.name, + merged: merged.to_s, + default_branch_name: @project.repository.root_ref, + delete_path: project_branch_path(@project, branch.name) } } diff --git a/app/views/projects/branches/_delete_protected_modal.html.haml b/app/views/projects/branches/_delete_protected_modal.html.haml index 5c5653401fb..2b45b4eddcc 100644 --- a/app/views/projects/branches/_delete_protected_modal.html.haml +++ b/app/views/projects/branches/_delete_protected_modal.html.haml @@ -7,7 +7,7 @@ %span.js-branch-name.ref-name>[branch name] = s_("Branches|Delete protected branch '%{branch_name}'?").html_safe % { branch_name: title_branch_name } %button.close{ type: "button", "data-dismiss": "modal", "aria-label" => _('Close') } - %span{ "aria-hidden": true } × + %span{ "aria-hidden": "true" } × .modal-body %p diff --git a/app/views/projects/branches/index.html.haml b/app/views/projects/branches/index.html.haml index 129b207a26f..b1d465d0e75 100644 --- a/app/views/projects/branches/index.html.haml +++ b/app/views/projects/branches/index.html.haml @@ -46,7 +46,7 @@ %ul.content-list.all-branches - @branches.each do |branch| = render "projects/branches/branch", branch: branch, merged: @merged_branch_names.include?(branch.name), commit_status: @branch_pipeline_statuses[branch.name], show_commit_status: @branch_pipeline_statuses.any? - - if Feature.enabled?(:branches_pagination_without_count, @project, default_enabled: true) + - if Feature.enabled?(:branches_pagination_without_count, @project, default_enabled: :yaml) = render('kaminari/gitlab/without_count', previous_path: @prev_path, next_path: @next_path) - else = paginate @branches, theme: 'gitlab' @@ -54,4 +54,7 @@ .nothing-here-block = s_('Branches|No branches to show') -= render 'projects/branches/delete_protected_modal' +- if Feature.enabled?(:delete_branch_confirmation_modals, @project, default_enabled: :yaml) && can?(current_user, :push_code, @project) + .js-delete-branch-modal +- elsif can?(current_user, :push_code, @project) + = render 'projects/branches/delete_protected_modal' diff --git a/app/views/projects/buttons/_clone.html.haml b/app/views/projects/buttons/_clone.html.haml index ee195e69a98..74d10f11898 100644 --- a/app/views/projects/buttons/_clone.html.haml +++ b/app/views/projects/buttons/_clone.html.haml @@ -26,14 +26,19 @@ = clipboard_button(target: '#http_project_clone', title: _("Copy URL"), class: "input-group-text gl-button btn btn-icon btn-default") = render_if_exists 'projects/buttons/geo' %li.divider.mt-2 - %li.pt-2.gl-new-dropdown-item - %label.label-bold{ class: 'gl-px-4!' } - = _('Open in your IDE') + %li.pt-2.gl-new-dropdown-item + %label.label-bold{ class: 'gl-px-4!' } + = _('Open in your IDE') + - if ssh_enabled? + %a.dropdown-item.open-with-link{ href: 'vscode://vscode.git/clone?url=' + CGI.escape(project.ssh_url_to_repo) } + .gl-new-dropdown-item-text-wrapper + = _('Visual Studio Code (SSH)') + - if http_enabled? %a.dropdown-item.open-with-link{ href: 'vscode://vscode.git/clone?url=' + CGI.escape(project.http_url_to_repo) } .gl-new-dropdown-item-text-wrapper - = _('Visual Studio Code') - - if show_xcode_link?(@project) - %a.dropdown-item.open-with-link{ href: xcode_uri_to_repo(@project) } - .gl-new-dropdown-item-text-wrapper - = _("Xcode") + = _('Visual Studio Code (HTTPS)') + - if show_xcode_link?(@project) + %a.dropdown-item.open-with-link{ href: xcode_uri_to_repo(@project) } + .gl-new-dropdown-item-text-wrapper + = _("Xcode") = render_if_exists 'projects/buttons/kerberos_clone_field' diff --git a/app/views/projects/buttons/_download.html.haml b/app/views/projects/buttons/_download.html.haml index 2f89a3f62ed..2d32e07d379 100644 --- a/app/views/projects/buttons/_download.html.haml +++ b/app/views/projects/buttons/_download.html.haml @@ -2,11 +2,11 @@ - if !project.empty_repo? && can?(current_user, :download_code, project) - archive_prefix = "#{project.path}-#{ref.tr('/', '-')}" - .project-action-button.dropdown.inline> - %button.gl-button.btn.btn-default.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', css_class: 'gl-icon') + .project-action-button.dropdown.gl-new-dropdown.inline> + %button.gl-button.btn.btn-default.dropdown-toggle.gl-dropdown-toggle.dropdown-icon-only.has-tooltip{ title: s_('DownloadSource|Download'), 'data-toggle' => 'dropdown', 'aria-label' => s_('DownloadSource|Download'), 'data-display' => 'static', data: { qa_selector: 'download_source_code_button' } } + = sprite_icon('download', css_class: 'gl-icon dropdown-icon') %span.sr-only= _('Select Archive Format') - = sprite_icon('chevron-down', css_class: 'gl-icon') + = sprite_icon('chevron-down', css_class: 'gl-icon dropdown-chevron') .dropdown-menu.dropdown-menu-right{ role: 'menu' } %section %h5.m-0.dropdown-bold-header= _('Download source code') diff --git a/app/views/projects/ci/builds/_build.html.haml b/app/views/projects/ci/builds/_build.html.haml index 0cc595de7be..824e876500b 100644 --- a/app/views/projects/ci/builds/_build.html.haml +++ b/app/views/projects/ci/builds/_build.html.haml @@ -97,7 +97,7 @@ #{job.coverage}% %td - .gl-display-flex + .gl-text-right .btn-group - if can?(current_user, :read_job_artifacts, job) && job.artifacts? = link_to download_project_job_artifacts_path(job.project, job), rel: 'nofollow', download: '', title: _('Download artifacts'), class: 'gl-button btn btn-default btn-icon' do diff --git a/app/views/projects/commits/_commits.html.haml b/app/views/projects/commits/_commits.html.haml index e6c9a7166a9..9e0dd93c683 100644 --- a/app/views/projects/commits/_commits.html.haml +++ b/app/views/projects/commits/_commits.html.haml @@ -35,8 +35,10 @@ - if hidden > 0 %li.gl-alert.gl-alert-warning - = sprite_icon('warning', size: 16, css_class: 'gl-icon gl-alert-icon gl-alert-icon-no-title') - = n_('%s additional commit has been omitted to prevent performance issues.', '%s additional commits have been omitted to prevent performance issues.', hidden) % number_with_delimiter(hidden) + .gl-alert-container + = sprite_icon('warning', size: 16, css_class: 'gl-icon gl-alert-icon gl-alert-icon-no-title') + .gl-alert-content + = n_('%s additional commit has been omitted to prevent performance issues.', '%s additional commits have been omitted to prevent performance issues.', hidden) % number_with_delimiter(hidden) - if project.context_commits_enabled? && can_update_merge_request && context_commits&.empty? %button.gl-button.btn.btn-default.mt-3.add-review-item-modal-trigger{ type: "button", data: { context_commits_empty: 'true' } } diff --git a/app/views/projects/confluences/show.html.haml b/app/views/projects/confluences/show.html.haml index 1eeafac5f1e..cf4e39f9659 100644 --- a/app/views/projects/confluences/show.html.haml +++ b/app/views/projects/confluences/show.html.haml @@ -6,9 +6,9 @@ = s_('WikiEmpty|Confluence is enabled') %p - 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: 'gl-button btn btn-success external-url', title: s_('WikiEmpty|Go to Confluence') do + - wiki_confluence_epic_link_start = format('<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe, url: wiki_confluence_epic_link_url) + = format(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_integration.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 71730da0595..c1f6cfc40c3 100644 --- a/app/views/projects/cycle_analytics/show.html.haml +++ b/app/views/projects/cycle_analytics/show.html.haml @@ -1,6 +1,6 @@ - page_title _("Value Stream Analytics") - add_page_specific_style 'page_bundles/cycle_analytics' - svgs = { empty_state_svg_path: image_path("illustrations/analytics/cycle-analytics-empty-chart.svg"), no_data_svg_path: image_path("illustrations/analytics/cycle-analytics-empty-chart.svg"), no_access_svg_path: image_path("illustrations/analytics/no-access.svg") } -- initial_data = { request_path: project_cycle_analytics_path(@project) }.merge!(svgs) +- initial_data = { request_path: project_cycle_analytics_path(@project), full_path: @project.full_path }.merge!(svgs) #js-cycle-analytics{ data: initial_data } diff --git a/app/views/projects/empty.html.haml b/app/views/projects/empty.html.haml index b76f6b27aa8..027b81d6c68 100644 --- a/app/views/projects/empty.html.haml +++ b/app/views/projects/empty.html.haml @@ -7,7 +7,7 @@ = render "home_panel" = render "archived_notice", project: @project -= render "invite_members" if experiment_enabled?(:invite_members_empty_project_version_a) && can_import_members? += render "invite_members" if can_import_members? %h4.gl-mt-0.gl-mb-3 = _('The repository for this project is empty') @@ -44,6 +44,7 @@ :preserve git clone #{ content_tag(:span, default_url_to_repo, class: 'js-clone')} cd #{h @project.path} + git switch -c #{default_branch_name} touch README.md git add README.md git commit -m "add README" @@ -56,7 +57,7 @@ %pre.bg-light :preserve cd existing_folder - git init + git init --initial-branch=#{default_branch_name} git remote add origin #{ content_tag(:span, default_url_to_repo, class: 'js-clone')} git add . git commit -m "Initial commit" diff --git a/app/views/projects/feature_flags/index.html.haml b/app/views/projects/feature_flags/index.html.haml index 7d48cba74d0..53fe30422ca 100644 --- a/app/views/projects/feature_flags/index.html.haml +++ b/app/views/projects/feature_flags/index.html.haml @@ -14,4 +14,4 @@ "can-user-admin-feature-flag" => can?(current_user, :admin_feature_flag, @project), "new-feature-flag-path" => can?(current_user, :create_feature_flag, @project) ? new_project_feature_flag_path(@project): nil, "rotate-instance-id-path" => can?(current_user, :admin_feature_flags_client, @project) ? reset_token_project_feature_flags_client_path(@project, format: :json) : nil, - "new-user-list-path" => can?(current_user, :admin_feature_flags_user_lists, @project) ? new_project_feature_flags_user_list_path(@project) : nil } } + "user-list-path" => can?(current_user, :admin_feature_flags_user_lists, @project) ? project_feature_flags_user_lists_path(@project) : nil } } diff --git a/app/views/projects/feature_flags_user_lists/edit.html.haml b/app/views/projects/feature_flags_user_lists/edit.html.haml index ea47cc06c0e..1ff488ff0f0 100644 --- a/app/views/projects/feature_flags_user_lists/edit.html.haml +++ b/app/views/projects/feature_flags_user_lists/edit.html.haml @@ -1,4 +1,5 @@ - add_to_breadcrumbs s_('FeatureFlags|Feature Flags'), project_feature_flags_path(@project) +- add_to_breadcrumbs s_('FeatureFlags|User Lists'), project_feature_flags_user_lists_path(@project) - breadcrumb_title s_('FeatureFlags|Edit User List') - page_title s_('FeatureFlags|Edit User List') diff --git a/app/views/projects/feature_flags_user_lists/index.html.haml b/app/views/projects/feature_flags_user_lists/index.html.haml new file mode 100644 index 00000000000..f0e3c36992a --- /dev/null +++ b/app/views/projects/feature_flags_user_lists/index.html.haml @@ -0,0 +1,8 @@ +- add_to_breadcrumbs s_('FeatureFlags|Feature Flags'), project_feature_flags_path(@project) +- breadcrumb_title s_('FeatureFlags|User Lists') +- page_title s_('FeatureFlags|Feature Flag User Lists') + +#js-user-lists{ data: { project_id: @project.id, + feature_flags_help_page_path: help_page_path("operations/feature_flags"), + new_user_list_path: can?(current_user, :create_feature_flag, @project) ? new_project_feature_flags_user_list_path(@project): nil, + error_state_svg_path: image_path('illustrations/feature_flag.svg') } } diff --git a/app/views/projects/feature_flags_user_lists/new.html.haml b/app/views/projects/feature_flags_user_lists/new.html.haml index 3d25453cb66..f2e1ea38d9c 100644 --- a/app/views/projects/feature_flags_user_lists/new.html.haml +++ b/app/views/projects/feature_flags_user_lists/new.html.haml @@ -1,5 +1,6 @@ - @breadcrumb_link = new_project_feature_flags_user_list_path(@project) - add_to_breadcrumbs s_('FeatureFlags|Feature Flags'), project_feature_flags_path(@project) +- add_to_breadcrumbs s_('FeatureFlags|User Lists'), project_feature_flags_user_lists_path(@project) - breadcrumb_title s_('FeatureFlags|New User List') - page_title s_('FeatureFlags|New User List') diff --git a/app/views/projects/feature_flags_user_lists/show.html.haml b/app/views/projects/feature_flags_user_lists/show.html.haml index add256f0190..2c88f3da66b 100644 --- a/app/views/projects/feature_flags_user_lists/show.html.haml +++ b/app/views/projects/feature_flags_user_lists/show.html.haml @@ -1,4 +1,5 @@ - add_to_breadcrumbs s_('FeatureFlags|Feature Flags'), project_feature_flags_path(@project) +- add_to_breadcrumbs s_('FeatureFlags|User Lists'), project_feature_flags_user_lists_path(@project) - breadcrumb_title s_('FeatureFlags|List details') - page_title s_('FeatureFlags|Feature Flag User List Details') diff --git a/app/views/projects/forks/new.html.haml b/app/views/projects/forks/new.html.haml index 267fc3ae986..0716eda79a8 100644 --- a/app/views/projects/forks/new.html.haml +++ b/app/views/projects/forks/new.html.haml @@ -10,7 +10,8 @@ project_name: @project.name, project_path: @project.path, project_description: @project.description, - project_visibility: @project.visibility } } + project_visibility: @project.visibility, + restricted_visibility_levels: Gitlab::CurrentSettings.restricted_visibility_levels.to_json } } - else .row.gl-mt-3 .col-lg-3 diff --git a/app/views/projects/issues/_nav_btns.html.haml b/app/views/projects/issues/_nav_btns.html.haml index 06522d9d434..1289f7aa0c4 100644 --- a/app/views/projects/issues/_nav_btns.html.haml +++ b/app/views/projects/issues/_nav_btns.html.haml @@ -15,8 +15,7 @@ = 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) }), + issue: { milestone_id: finder.milestones.first.try(:id) }), class: "gl-button btn btn-confirm", id: "new_issue_link" diff --git a/app/views/projects/jobs/_table.html.haml b/app/views/projects/jobs/_table.html.haml index 819837a9eff..2d8b7315a29 100644 --- a/app/views/projects/jobs/_table.html.haml +++ b/app/views/projects/jobs/_table.html.haml @@ -12,7 +12,7 @@ = s_('Jobs|Use jobs to automate your tasks') %p = s_('Jobs|Jobs are the building blocks of a GitLab CI/CD pipeline. Each job has a specific task, like testing code. To set up jobs in a CI/CD pipeline, add a CI/CD configuration file to your project.') - = link_to s_('Jobs|Create CI/CD configuration file'), project_ci_pipeline_editor_path(project), class: 'btn gl-button btn-info js-empty-state-button' + = link_to s_('Jobs|Create CI/CD configuration file'), project_ci_pipeline_editor_path(project), class: 'btn gl-button btn-confirm js-empty-state-button' - else .nothing-here-block= s_('Jobs|No jobs to show') - else diff --git a/app/views/projects/merge_requests/_awards_block.html.haml b/app/views/projects/merge_requests/_awards_block.html.haml index 09466ed2244..80a58053ff7 100644 --- a/app/views/projects/merge_requests/_awards_block.html.haml +++ b/app/views/projects/merge_requests/_awards_block.html.haml @@ -1,5 +1,5 @@ -.content-block.content-block-small.emoji-list-container.js-noteable-awards +.content-block.emoji-block.emoji-list-container.js-noteable-awards = render 'award_emoji/awards_block', awardable: @merge_request, inline: true, api_awards_path: award_emoji_merge_request_api_path(@merge_request) do - .ml-auto.mt-auto.mb-auto + .ml-auto.gl-my-2 #js-vue-sort-issue-discussions = render "projects/merge_requests/discussion_filter" diff --git a/app/views/projects/merge_requests/_close_reopen_draft_report_toggle.html.haml b/app/views/projects/merge_requests/_close_reopen_draft_report_toggle.html.haml index 5fa8f908122..f6afac493d5 100644 --- a/app/views/projects/merge_requests/_close_reopen_draft_report_toggle.html.haml +++ b/app/views/projects/merge_requests/_close_reopen_draft_report_toggle.html.haml @@ -1,10 +1,9 @@ - display_issuable_type = issuable_display_type(@merge_request) -- button_action_class = @merge_request.closed? ? 'btn-default' : 'btn-warning btn-warning-secondary' - button_class = "btn gl-button #{!@merge_request.closed? && 'js-draft-toggle-button'}" - toggle_class = "btn gl-button dropdown-toggle" .float-left.btn-group.gl-ml-3.gl-display-none.gl-md-display-flex - = link_to @merge_request.closed? ? reopen_issuable_path(@merge_request) : toggle_draft_merge_request_path(@merge_request), method: :put, class: "#{button_class} #{button_action_class}" do + = link_to @merge_request.closed? ? reopen_issuable_path(@merge_request) : toggle_draft_merge_request_path(@merge_request), method: :put, class: "#{button_class} btn-confirm-secondary" do - if @merge_request.closed? = _('Reopen') = display_issuable_type @@ -12,9 +11,9 @@ = @merge_request.work_in_progress? ? _('Mark as ready') : _('Mark as draft') - if !@merge_request.closed? || !issuable_author_is_current_user(@merge_request) - = button_tag type: 'button', class: "#{toggle_class} #{button_action_class}", data: { 'toggle' => 'dropdown' } do + = button_tag type: 'button', class: "#{toggle_class} btn-confirm-secondary btn-icon", data: { 'toggle' => 'dropdown' } do %span.gl-sr-only= _('Toggle dropdown') - = sprite_icon "angle-down", size: 12 + = sprite_icon "chevron-down", size: 12, css_class: "gl-button-icon" %ul.dropdown-menu.dropdown-menu-right - if @merge_request.open? diff --git a/app/views/projects/merge_requests/_mr_title.html.haml b/app/views/projects/merge_requests/_mr_title.html.haml index e42032fef66..5a983fb5565 100644 --- a/app/views/projects/merge_requests/_mr_title.html.haml +++ b/app/views/projects/merge_requests/_mr_title.html.haml @@ -7,9 +7,11 @@ = cache_if(Feature.enabled?(:cached_mr_title, @project, default_enabled: :yaml), cache_key, expires_in: 1.day) do - if @merge_request.closed_or_merged_without_fork? .gl-alert.gl-alert-danger.gl-mb-5 - = sprite_icon('error', size: 16, css_class: 'gl-icon gl-alert-icon gl-alert-icon-no-title') - .gl-alert-body - The source project of this merge request has been removed. + .gl-alert-container + = sprite_icon('error', size: 16, css_class: 'gl-icon gl-alert-icon gl-alert-icon-no-title') + .gl-alert-content + .gl-alert-body + The source project of this merge request has been removed. .detail-page-header.border-bottom-0.pt-0.pb-0 .detail-page-header-body diff --git a/app/views/projects/merge_requests/_widget.html.haml b/app/views/projects/merge_requests/_widget.html.haml index 606442d71a9..5f2cb1cfcc4 100644 --- a/app/views/projects/merge_requests/_widget.html.haml +++ b/app/views/projects/merge_requests/_widget.html.haml @@ -1,21 +1,22 @@ -- artifacts_endpoint_placeholder = ':pipeline_artifacts_id' += cache_if(Feature.enabled?(:cached_mr_widget, @merge_request.project), [@merge_request.project, @merge_request, current_user], expires_in: 10.minutes) do + - artifacts_endpoint_placeholder = ':pipeline_artifacts_id' -= javascript_tag do - :plain - window.gl = window.gl || {}; - window.gl.mrWidgetData = #{serialize_issuable(@merge_request, serializer: 'widget', issues_links: true)} + = javascript_tag do + :plain + window.gl = window.gl || {}; + window.gl.mrWidgetData = #{serialize_issuable(@merge_request, serializer: 'widget', issues_links: true)} - window.gl.mrWidgetData.artifacts_endpoint = '#{downloadable_artifacts_project_pipeline_path(@project, artifacts_endpoint_placeholder, format: :json)}'; - window.gl.mrWidgetData.artifacts_endpoint_placeholder = '#{artifacts_endpoint_placeholder}'; - window.gl.mrWidgetData.squash_before_merge_help_path = '#{help_page_path("user/project/merge_requests/squash_and_merge")}'; - window.gl.mrWidgetData.ci_troubleshooting_docs_path = '#{help_page_path('ci/troubleshooting.md')}'; - window.gl.mrWidgetData.mr_troubleshooting_docs_path = '#{help_page_path('user/project/merge_requests/reviews/index.md', anchor: 'troubleshooting')}'; - window.gl.mrWidgetData.pipeline_must_succeed_docs_path = '#{help_page_path('user/project/merge_requests/merge_when_pipeline_succeeds.md', anchor: 'only-allow-merge-requests-to-be-merged-if-the-pipeline-succeeds')}'; - window.gl.mrWidgetData.security_approvals_help_page_path = '#{help_page_path('user/application_security/index.md', anchor: 'security-approvals-in-merge-requests')}'; - window.gl.mrWidgetData.license_compliance_docs_path = '#{help_page_path('user/compliance/license_compliance/index.md', anchor: 'policies')}'; - window.gl.mrWidgetData.eligible_approvers_docs_path = '#{help_page_path('user/project/merge_requests/merge_request_approvals', anchor: 'eligible-approvers')}'; - window.gl.mrWidgetData.approvals_help_path = '#{help_page_path("user/project/merge_requests/merge_request_approvals")}'; - window.gl.mrWidgetData.pipelines_empty_svg_path = '#{image_path('illustrations/pipelines_empty.svg')}'; - window.gl.mrWidgetData.codequality_help_path = '#{help_page_path("user/project/merge_requests/code_quality", anchor: "code-quality-reports")}'; + window.gl.mrWidgetData.artifacts_endpoint = '#{downloadable_artifacts_project_pipeline_path(@project, artifacts_endpoint_placeholder, format: :json)}'; + window.gl.mrWidgetData.artifacts_endpoint_placeholder = '#{artifacts_endpoint_placeholder}'; + window.gl.mrWidgetData.squash_before_merge_help_path = '#{help_page_path("user/project/merge_requests/squash_and_merge")}'; + window.gl.mrWidgetData.ci_troubleshooting_docs_path = '#{help_page_path('ci/troubleshooting.md')}'; + window.gl.mrWidgetData.mr_troubleshooting_docs_path = '#{help_page_path('user/project/merge_requests/reviews/index.md', anchor: 'troubleshooting')}'; + window.gl.mrWidgetData.pipeline_must_succeed_docs_path = '#{help_page_path('user/project/merge_requests/merge_when_pipeline_succeeds.md', anchor: 'only-allow-merge-requests-to-be-merged-if-the-pipeline-succeeds')}'; + window.gl.mrWidgetData.security_approvals_help_page_path = '#{help_page_path('user/application_security/index.md', anchor: 'security-approvals-in-merge-requests')}'; + window.gl.mrWidgetData.license_compliance_docs_path = '#{help_page_path('user/compliance/license_compliance/index.md', anchor: 'policies')}'; + window.gl.mrWidgetData.eligible_approvers_docs_path = '#{help_page_path('user/project/merge_requests/merge_request_approvals', anchor: 'eligible-approvers')}'; + window.gl.mrWidgetData.approvals_help_path = '#{help_page_path("user/project/merge_requests/merge_request_approvals")}'; + window.gl.mrWidgetData.pipelines_empty_svg_path = '#{image_path('illustrations/pipelines_empty.svg')}'; + window.gl.mrWidgetData.codequality_help_path = '#{help_page_path("user/project/merge_requests/code_quality", anchor: "code-quality-reports")}'; -#js-vue-mr-widget.mr-widget + #js-vue-mr-widget.mr-widget diff --git a/app/views/projects/merge_requests/edit.html.haml b/app/views/projects/merge_requests/edit.html.haml index 019015a4d86..5fcb5d3f876 100644 --- a/app/views/projects/merge_requests/edit.html.haml +++ b/app/views/projects/merge_requests/edit.html.haml @@ -1,3 +1,5 @@ +- add_to_breadcrumbs _("Merge requests"), project_merge_requests_path(@project) +- breadcrumb_title @merge_request.to_reference - page_title _("Edit"), "#{@merge_request.title} (#{@merge_request.to_reference}", _("Merge requests") %h3.page-title diff --git a/app/views/projects/merge_requests/invalid.html.haml b/app/views/projects/merge_requests/invalid.html.haml index f0bf5af7732..fd1b2328a98 100644 --- a/app/views/projects/merge_requests/invalid.html.haml +++ b/app/views/projects/merge_requests/invalid.html.haml @@ -8,21 +8,23 @@ = render "projects/merge_requests/mr_box" .gl-alert.gl-alert-danger - = sprite_icon('error', size: 16, css_class: 'gl-icon gl-alert-icon gl-alert-icon-no-title') - %p - We cannot render this merge request properly because - - if @merge_request.for_fork? && !@merge_request.source_project - fork project was removed - - elsif !@merge_request.source_branch_exists? - %span{ class: badge_inverse_css_classes }= @merge_request.source_branch - does not exist in - %span{ class: badge_info_css_classes }= @merge_request.source_project_path - - elsif !@merge_request.target_branch_exists? - %span{ class: badge_inverse_css_classes }= @merge_request.target_branch - does not exist in - %span{ class: badge_info_css_classes }= @merge_request.target_project_path - - else - of internal error + .gl-alert-container + = sprite_icon('error', size: 16, css_class: 'gl-icon gl-alert-icon gl-alert-icon-no-title') + .gl-alert-content{ role: 'alert' } + %p + We cannot render this merge request properly because + - if @merge_request.for_fork? && !@merge_request.source_project + fork project was removed + - elsif !@merge_request.source_branch_exists? + %span{ class: badge_inverse_css_classes }= @merge_request.source_branch + does not exist in + %span{ class: badge_info_css_classes }= @merge_request.source_project_path + - elsif !@merge_request.target_branch_exists? + %span{ class: badge_inverse_css_classes }= @merge_request.target_branch + does not exist in + %span{ class: badge_info_css_classes }= @merge_request.target_project_path + - else + of internal error - %strong - Please close merge request or change branches with existing one + %strong + Please close merge request or change branches with existing one diff --git a/app/views/projects/merge_requests/tabs/_tab.html.haml b/app/views/projects/merge_requests/tabs/_tab.html.haml index dcd8db90509..9d942da8098 100644 --- a/app/views/projects/merge_requests/tabs/_tab.html.haml +++ b/app/views/projects/merge_requests/tabs/_tab.html.haml @@ -2,6 +2,8 @@ - tab_class = local_assigns.fetch(:class, nil) - qa_selector = local_assigns.fetch(:qa_selector, nil) - id = local_assigns.fetch(:id, nil) +- attrs = { class: [tab_class, ("active" if params[:tab] == tab_name)], data: { qa_selector: qa_selector } } +- attrs[:id] = id if id.present? -%li{ class: [tab_class, ("active" if params[:tab] == tab_name)], id: id, data: { qa_selector: qa_selector } } +%li{ attrs } = yield diff --git a/app/views/projects/milestones/show.html.haml b/app/views/projects/milestones/show.html.haml index 5a6c2c5faaf..99fe64723d9 100644 --- a/app/views/projects/milestones/show.html.haml +++ b/app/views/projects/milestones/show.html.haml @@ -13,14 +13,18 @@ - if can?(current_user, :read_issue, @project) && @milestone.total_issues_count == 0 .gl-alert.gl-alert-info.gl-mt-3.gl-mb-5{ data: { testid: 'no-issues-alert' } } - = sprite_icon('information-o', size: 16, css_class: 'gl-icon gl-alert-icon gl-alert-icon-no-title') - .gl-alert-body - %span= _('Assign some issues to this milestone.') + .gl-alert-container + = sprite_icon('information-o', size: 16, css_class: 'gl-icon gl-alert-icon gl-alert-icon-no-title') + .gl-alert-content + .gl-alert-body + %span= _('Assign some issues to this milestone.') - elsif @milestone.complete? && @milestone.active? .gl-alert.gl-alert-success.gl-mt-3.gl-mb-5{ data: { testid: 'all-issues-closed-alert' } } - = sprite_icon('check-circle', size: 16, css_class: 'gl-icon gl-alert-icon gl-alert-icon-no-title') - .gl-alert-body - %span= _('All issues for this milestone are closed. You may close this milestone now.') + .gl-alert-container + = sprite_icon('check-circle', size: 16, css_class: 'gl-icon gl-alert-icon gl-alert-icon-no-title') + .gl-alert-content + .gl-alert-body + %span= _('All issues for this milestone are closed. You may close this milestone now.') = render 'shared/milestones/tabs', milestone: @milestone = render 'shared/milestones/sidebar', milestone: @milestone, project: @project, affix_offset: 153 diff --git a/app/views/projects/packages/infrastructure_registry/show.html.haml b/app/views/projects/packages/infrastructure_registry/show.html.haml new file mode 100644 index 00000000000..e5701343b83 --- /dev/null +++ b/app/views/projects/packages/infrastructure_registry/show.html.haml @@ -0,0 +1,15 @@ +- add_to_breadcrumbs _("Infrastructure Registry"), project_infrastructure_registry_index_path(@project) +- add_to_breadcrumbs @package.name, project_infrastructure_registry_index_path(@project) +- breadcrumb_title @package.version +- page_title _("Infrastructure Registry") +- @content_class = "limit-container-width" unless fluid_layout + +.row + .col-12 + #js-vue-packages-detail{ data: { package: package_from_presenter(@package), + can_delete: can?(current_user, :destroy_package, @project).to_s, + svg_path: image_path('illustrations/no-packages.svg'), + project_name: @project.name, + project_path: expose_url(@project.full_path), + terraform_help_path: help_page_path('user/infrastructure/index'), + project_list_url: project_infrastructure_registry_index_path(@project)} } diff --git a/app/views/projects/pages/_access.html.haml b/app/views/projects/pages/_access.html.haml index 5b23234791b..67a2eeb7e7b 100644 --- a/app/views/projects/pages/_access.html.haml +++ b/app/views/projects/pages/_access.html.haml @@ -19,5 +19,3 @@ - link_start = '<a href="%{url}" target="_blank" class="gl-alert-link" rel="noopener noreferrer">'.html_safe % { url: help_page } - link_end = '</a>'.html_safe = html_escape_once(s_('GitLabPages|Access Control is enabled for this Pages website; only authorized users will be able to access it. To make your website publicly available, navigate to your project\'s %{strong_start}Settings > General > Visibility%{strong_end} and select %{strong_start}Everyone%{strong_end} in pages section. Read the %{link_start}documentation%{link_end} for more information.')).html_safe % { link_start: link_start, link_end: link_end, strong_start: '<strong>'.html_safe, strong_end: '</strong>'.html_safe } - .card-footer.gl-alert-info - = s_('GitLabPages|It may take up to 30 minutes before the site is available after the first deployment.') diff --git a/app/views/projects/pipeline_schedules/_form.html.haml b/app/views/projects/pipeline_schedules/_form.html.haml index 628c4780cf2..66aee7dedf3 100644 --- a/app/views/projects/pipeline_schedules/_form.html.haml +++ b/app/views/projects/pipeline_schedules/_form.html.haml @@ -7,7 +7,7 @@ .form-group.row .col-md-9 = f.label :cron, _('Interval Pattern'), class: 'label-bold' - #interval-pattern-input{ data: { initial_interval: @schedule.cron } } + #interval-pattern-input{ data: { initial_interval: @schedule.cron, daily_limit: @schedule.daily_limit } } .form-group.row .col-md-9 = f.label :cron_timezone, _('Cron Timezone'), class: 'label-bold' diff --git a/app/views/projects/pipelines/index.html.haml b/app/views/projects/pipelines/index.html.haml index 42bb8117766..9669b2e72dc 100644 --- a/app/views/projects/pipelines/index.html.haml +++ b/app/views/projects/pipelines/index.html.haml @@ -5,7 +5,10 @@ = render_if_exists "shared/shared_runners_minutes_limit_flash_message" -#pipelines-list-vue{ data: { endpoint: project_pipelines_path(@project, format: :json, code_quality_walkthrough: params[:code_quality_walkthrough]), +- list_url = project_pipelines_path(@project, format: :json, code_quality_walkthrough: params[:code_quality_walkthrough]) +- add_page_startup_api_call list_url + +#pipelines-list-vue{ data: { endpoint: list_url, project_id: @project.id, params: params.to_json, "artifacts-endpoint" => downloadable_artifacts_project_pipeline_path(@project, artifacts_endpoint_placeholder, format: :json), @@ -21,4 +24,5 @@ "has-gitlab-ci" => has_gitlab_ci?(@project).to_s, "add-ci-yml-path" => can?(current_user, :create_pipeline, @project) && @project.present(current_user: current_user).add_ci_yml_path, "suggested-ci-templates" => experiment_suggested_ci_templates.to_json, - "code-quality-page-path" => @project.present(current_user: current_user).add_code_quality_ci_yml_path } } + "code-quality-page-path" => @project.present(current_user: current_user).add_code_quality_ci_yml_path, + "ci-runner-settings-path" => project_settings_ci_cd_path(@project, ci_runner_templates: true, anchor: 'js-runners-settings') } } diff --git a/app/views/projects/pipelines/show.html.haml b/app/views/projects/pipelines/show.html.haml index 93b0a525191..1c134d914e9 100644 --- a/app/views/projects/pipelines/show.html.haml +++ b/app/views/projects/pipelines/show.html.haml @@ -12,7 +12,7 @@ .js-pipeline-container{ data: { controller_action: "#{controller.action_name}" } } #js-pipeline-header-vue.pipeline-header-container{ data: { full_path: @project.full_path, pipeline_iid: @pipeline.iid, pipeline_id: @pipeline.id, pipelines_path: project_pipelines_path(@project) } } - - if @pipeline.failed? && @pipeline.user_not_verified? + - if Gitlab.com? && show_cc_validation_alert?(@pipeline) #js-cc-validation-required-alert - if @pipeline.commit.present? @@ -28,7 +28,6 @@ - lint_link_start = '<a href="%{url}">'.html_safe % { url: lint_link_url } = s_('You can also test your %{gitlab_ci_yml} in %{lint_link_start}CI Lint%{lint_link_end}').html_safe % { gitlab_ci_yml: '.gitlab-ci.yml', lint_link_start: lint_link_start, lint_link_end: '</a>'.html_safe } - #js-pipeline-notification{ data: { dag_doc_path: help_page_path('ci/yaml/README.md', anchor: 'needs') } } = render "projects/pipelines/with_tabs", pipeline: @pipeline, stages: @stages, pipeline_has_errors: pipeline_has_errors .js-pipeline-details-vue{ data: { endpoint: project_pipeline_path(@project, @pipeline, format: :json), metrics_path: namespace_project_ci_prometheus_metrics_histograms_path(namespace_id: @project.namespace, project_id: @project, format: :json), pipeline_project_path: @project.full_path, pipeline_iid: @pipeline.iid, graphql_resource_etag: graphql_etag_pipeline_path(@pipeline) } } diff --git a/app/views/projects/project_members/index.html.haml b/app/views/projects/project_members/index.html.haml index 0fa9fb7079b..d1b6db95392 100644 --- a/app/views/projects/project_members/index.html.haml +++ b/app/views/projects/project_members/index.html.haml @@ -25,8 +25,11 @@ title: _("Import members from another project") - if @project.allowed_to_share_with_group? .js-invite-group-trigger{ data: { classes: 'gl-mt-3 gl-sm-w-auto gl-w-full gl-sm-ml-3', display_text: _('Invite a group') } } - - if !membership_locked? - .js-invite-members-trigger{ data: { variant: 'success', classes: 'gl-mt-3 gl-sm-w-auto gl-w-full gl-sm-ml-3', display_text: _('Invite members') } } + - if can_manage_project_members?(@project) && !membership_locked? + .js-invite-members-trigger{ data: { variant: 'success', + classes: 'gl-mt-3 gl-sm-w-auto gl-w-full gl-sm-ml-3', + trigger_source: 'project-members-page', + display_text: _('Invite members') } } = render 'projects/invite_members_modal', project: @project - else @@ -51,52 +54,15 @@ .tab-pane.active{ id: 'invite-member-pane', role: 'tabpanel' } = render 'shared/members/invite_member', submit_url: project_project_members_path(@project), access_levels: ProjectMember.access_level_roles, default_access_level: @project_member.access_level, can_import_members?: can_import_members?, import_path: import_project_project_members_path(@project) .tab-pane{ id: 'invite-group-pane', role: 'tabpanel', class: ('active' if membership_locked?) } - = render 'shared/members/invite_group', submit_url: project_group_links_path(@project), access_levels: ProjectGroupLink.access_options, default_access_level: ProjectGroupLink.default_access, group_link_field: 'link_group_id', group_access_field: 'link_group_access' + = render 'shared/members/invite_group', submit_url: project_group_links_path(@project), access_levels: ProjectGroupLink.access_options, default_access_level: ProjectGroupLink.default_access, group_link_field: 'link_group_id', group_access_field: 'link_group_access', groups_select_tag_data: { skip_groups: @skip_groups } - elsif !membership_locked? .invite-member= render 'shared/members/invite_member', submit_url: project_project_members_path(@project), access_levels: ProjectMember.access_level_roles, default_access_level: @project_member.access_level, can_import_members?: can_import_members?, import_path: import_project_project_members_path(@project) - 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' - %ul.nav-links.mobile-separator.nav.nav-tabs - %li.nav-item - = link_to '#tab-members', class: ['nav-link', ('active' unless groups_tab_active?)], data: { toggle: 'tab' } do - %span - = _('Members') - %span.badge.gl-tab-counter-badge.badge-muted.badge-pill.gl-badge.sm= @project_members.total_count - - if show_groups?(@group_links) - %li.nav-item - = link_to '#tab-groups', class: ['nav-link', ('active' if groups_tab_active?)] , data: { toggle: 'tab', qa_selector: 'groups_list_tab' } do - %span - = _('Groups') - %span.badge.gl-tab-counter-badge.badge-muted.badge-pill.gl-badge.sm= @group_links.count - - if show_invited_members?(@project, @invited_members) - %li.nav-item - = link_to '#tab-invited-members', class: 'nav-link', data: { toggle: 'tab' } do - %span - = _('Invited') - %span.badge.gl-tab-counter-badge.badge-muted.badge-pill.gl-badge.sm= @invited_members.count - - if show_access_requests?(@project, @requesters) - %li.nav-item - = link_to '#tab-access-requests', class: 'nav-link', data: { toggle: 'tab' } do - %span - = _('Access requests') - %span.badge.gl-tab-counter-badge.badge-muted.badge-pill.gl-badge.sm= @requesters.count - .tab-content - #tab-members.tab-pane{ class: ('active' unless groups_tab_active?) } - .js-project-members-list{ data: { members_data: project_members_list_data_json(@project, @project_members, { param_name: :page, params: { search_groups: nil } }) } } - .loading - .gl-spinner.gl-spinner-md - - if show_groups?(@group_links) - #tab-groups.tab-pane{ class: ('active' if groups_tab_active?) } - .js-project-group-links-list{ data: { members_data: project_group_links_list_data_json(@project, @group_links) } } - .loading - .gl-spinner.gl-spinner-md - - if show_invited_members?(@project, @invited_members) - #tab-invited-members.tab-pane - .js-project-invited-members-list{ data: { members_data: project_members_list_data_json(@project, @invited_members) } } - .loading - .gl-spinner.gl-spinner-md - - if show_access_requests?(@project, @requesters) - #tab-access-requests.tab-pane - .js-project-access-requests-list{ data: { members_data: project_members_list_data_json(@project, @requesters) } } - .loading - .gl-spinner.gl-spinner-md + .invite-group= render 'shared/members/invite_group', access_levels: ProjectGroupLink.access_options, default_access_level: ProjectGroupLink.default_access, submit_url: project_group_links_path(@project), group_link_field: 'link_group_id', group_access_field: 'link_group_access', groups_select_tag_data: { skip_groups: @skip_groups } + .js-project-members-list-app{ data: { members_data: project_members_app_data_json(@project, + members: @project_members, + group_links: @group_links, + invited: @invited_members, + access_requests: @requesters) } } + .loading + .gl-spinner.gl-spinner-md diff --git a/app/views/projects/protected_branches/shared/_branches_list.html.haml b/app/views/projects/protected_branches/shared/_branches_list.html.haml index 2691513c994..b13117960dd 100644 --- a/app/views/projects/protected_branches/shared/_branches_list.html.haml +++ b/app/views/projects/protected_branches/shared/_branches_list.html.haml @@ -8,10 +8,11 @@ .flash-container %table.table.table-bordered %colgroup + %col{ width: "30%" } %col{ width: "20%" } %col{ width: "20%" } - %col{ width: "20%" } - %col{ width: "20%" } + %col{ width: "10%" } + %col{ width: "10%" } - if can_admin_project %col %thead @@ -22,12 +23,10 @@ = s_("ProtectedBranch|Allowed to merge") %th = s_("ProtectedBranch|Allowed to push") - - - if ::Feature.enabled?(:allow_force_push_to_protected_branches, @project, default_enabled: :yaml) - %th - = s_("ProtectedBranch|Allow force push") - %span.has-tooltip{ data: { container: 'body' }, title: s_('ProtectedBranch|Allow force push for all users with push access.'), 'aria-hidden': 'true' } - = sprite_icon('question', size: 16, css_class: 'gl-text-gray-500') + %th + = s_("ProtectedBranch|Allowed to force push") + %span.has-tooltip{ data: { container: 'body' }, title: s_('ProtectedBranch|Allow all users with push access to force push.'), 'aria-hidden': 'true' } + = sprite_icon('question', size: 16, css_class: 'gl-text-gray-500') = render_if_exists 'projects/protected_branches/ee/code_owner_approval_table_head' diff --git a/app/views/projects/protected_branches/shared/_create_protected_branch.html.haml b/app/views/projects/protected_branches/shared/_create_protected_branch.html.haml index 9fdcea96c00..ad131b22924 100644 --- a/app/views/projects/protected_branches/shared/_create_protected_branch.html.haml +++ b/app/views/projects/protected_branches/shared/_create_protected_branch.html.haml @@ -21,13 +21,14 @@ = f.label :push_access_levels_attributes, s_("ProtectedBranch|Allowed to push:"), class: 'col-md-2 text-left text-md-right' .col-md-10 = yield :push_access_levels - - if ::Feature.enabled?(:allow_force_push_to_protected_branches, @project, default_enabled: :yaml) - .form-group.row - = f.label :allow_force_push, s_("ProtectedBranch|Allow force push:"), class: 'col-md-2 gl-text-left text-md-right' - .col-md-10 - = render "shared/buttons/project_feature_toggle", class_list: "js-force-push-toggle project-feature-toggle" - .form-text.gl-text-gray-600.gl-mt-0 - = s_("ProtectedBranch|Allow force push for all users with push access.") + .form-group.row + = f.label :allow_force_push, s_("ProtectedBranch|Allowed to force push:"), class: 'col-md-2 gl-text-left text-md-right' + .col-md-10 + = render "shared/buttons/project_feature_toggle", class_list: "js-force-push-toggle project-feature-toggle" + .form-text.gl-text-gray-600.gl-mt-0 + - force_push_docs_url = help_page_url('topics/git/git_rebase', anchor: 'force-push') + - force_push_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: force_push_docs_url } + = (s_("ProtectedBranch|Allow all users with push access to %{tag_start}force push%{tag_end}.") % { tag_start: force_push_link_start, tag_end: '</a>' }).html_safe = render_if_exists 'projects/protected_branches/ee/code_owner_approval_form', f: f .card-footer = f.submit s_('ProtectedBranch|Protect'), class: 'gl-button btn btn-confirm', disabled: true, data: { qa_selector: 'protect_button' } diff --git a/app/views/projects/protected_branches/shared/_index.html.haml b/app/views/projects/protected_branches/shared/_index.html.haml index c2a5efa7b7c..08246a173d8 100644 --- a/app/views/projects/protected_branches/shared/_index.html.haml +++ b/app/views/projects/protected_branches/shared/_index.html.haml @@ -14,7 +14,7 @@ %ul %li Allow only users with Maintainer #{link_to "permissions", help_page_path("user/permissions")} to create new protected branches. %li Allow only users with Maintainer permissions to push code. - %li Prevent <strong>anyone</strong> from force-pushing to the branch. + %li Prevent <strong>anyone</strong> from #{link_to "force-pushing", help_page_path('topics/git/git_rebase', anchor: 'force-push')} to the branch. %li Prevent <strong>anyone</strong> from deleting the branch. - if can? current_user, :admin_project, @project diff --git a/app/views/projects/registry/repositories/index.html.haml b/app/views/projects/registry/repositories/index.html.haml index f56fd7f557d..bdb5f021b70 100644 --- a/app/views/projects/registry/repositories/index.html.haml +++ b/app/views/projects/registry/repositories/index.html.haml @@ -18,6 +18,8 @@ "project_path": @project.full_path, "gid_prefix": container_repository_gid_prefix, "is_admin": current_user&.admin.to_s, + "show_cleanup_policy_on_alert": show_cleanup_policy_on_alert(@project).to_s, + "cleanup_policies_settings_path": project_settings_packages_and_registries_path(@project), character_error: @character_error.to_s, user_callouts_path: user_callouts_path, user_callout_id: UserCalloutsHelper::UNFINISHED_TAG_CLEANUP_CALLOUT, diff --git a/app/views/projects/runners/_specific_runners.html.haml b/app/views/projects/runners/_specific_runners.html.haml index 88895634990..210cc414007 100644 --- a/app/views/projects/runners/_specific_runners.html.haml +++ b/app/views/projects/runners/_specific_runners.html.haml @@ -7,6 +7,10 @@ = render partial: 'ci/runner/how_to_setup_runner_automatically', locals: { type: 'specific', clusters_path: project_clusters_path(@project) } + - if params[:ci_runner_templates] + %hr + = render partial: 'ci/runner/setup_runner_in_aws', + locals: { registration_token: @project.runners_token } %hr = render partial: 'ci/runner/how_to_setup_runner', locals: { registration_token: @project.runners_token, diff --git a/app/views/projects/services/_form.html.haml b/app/views/projects/services/_form.html.haml index 3c99b4c5e68..724684c9a0a 100644 --- a/app/views/projects/services/_form.html.haml +++ b/app/views/projects/services/_form.html.haml @@ -1,15 +1,15 @@ -- if lookup_context.template_exists?('top', "projects/services/#{@service.to_param}", true) - = render "projects/services/#{@service.to_param}/top" +- if lookup_context.template_exists?('top', "projects/services/#{integration.to_param}", true) + = render "projects/services/#{integration.to_param}/top", integration: integration %h3.page-title - = @service.title - - if @service.operating? + = integration.title + - if integration.operating? = sprite_icon('check', css_class: 'gl-text-green-500') -= form_for(@service, as: :service, url: scoped_integration_path(@service), method: :put, html: { class: 'gl-show-field-errors integration-settings-form js-integration-settings-form', data: { 'test-url' => test_project_service_path(@project, @service) } }) do |form| - = render 'shared/service_settings', form: form, integration: @service - %input{ id: 'services_redirect_to', type: 'hidden', name: 'redirect_to', value: request.referrer } += form_for(integration, as: :service, url: scoped_integration_path(integration), method: :put, html: { class: 'gl-show-field-errors integration-settings-form js-integration-settings-form', data: { 'test-url' => test_project_service_path(@project, integration) } }) do |form| + = render 'shared/service_settings', form: form, integration: integration + %input{ id: 'services_redirect_to', type: 'hidden', name: 'redirect_to', value: request.referer } -- if lookup_context.template_exists?('show', "projects/services/#{@service.to_param}", true) +- if lookup_context.template_exists?('show', "projects/services/#{integration.to_param}", true) %hr - = render "projects/services/#{@service.to_param}/show" + = render "projects/services/#{integration.to_param}/show", integration: integration diff --git a/app/views/projects/services/edit.html.haml b/app/views/projects/services/edit.html.haml index 1aaea50c8d5..a250daafdbb 100644 --- a/app/views/projects/services/edit.html.haml +++ b/app/views/projects/services/edit.html.haml @@ -1,8 +1,9 @@ -- breadcrumb_title @service.title +- breadcrumb_title @integration.title - add_to_breadcrumbs _('Integration Settings'), project_settings_integrations_path(@project) -- page_title @service.title, _('Integrations') +- page_title @integration.title, _('Integrations') - @content_class = 'limit-container-width' unless fluid_layout -= render 'form' += render 'form', integration: @integration + - if @web_hook_logs - = render partial: 'projects/hook_logs/index', locals: { hook: @service.service_hook, hook_logs: @web_hook_logs, project: @project } + = render partial: 'projects/hook_logs/index', locals: { hook: @integration.service_hook, hook_logs: @web_hook_logs, project: @project } diff --git a/app/views/projects/services/mattermost_slash_commands/_detailed_help.html.haml b/app/views/projects/services/mattermost_slash_commands/_detailed_help.html.haml index fe983961657..9d8ce186232 100644 --- a/app/views/projects/services/mattermost_slash_commands/_detailed_help.html.haml +++ b/app/views/projects/services/mattermost_slash_commands/_detailed_help.html.haml @@ -57,7 +57,7 @@ .form-group = label_tag :request_url, s_('MattermostService|Request URL'), class: 'col-12 col-form-label label-bold' .col-12.input-group - = text_field_tag :request_url, service_trigger_url(subject), class: 'form-control form-control-sm', readonly: 'readonly' + = text_field_tag :request_url, service_trigger_url(integration), class: 'form-control form-control-sm', readonly: 'readonly' .input-group-append = clipboard_button(target: '#request_url', class: 'input-group-text') diff --git a/app/views/projects/services/mattermost_slash_commands/_help.html.haml b/app/views/projects/services/mattermost_slash_commands/_help.html.haml index 4a7757daebc..993df389fb0 100644 --- a/app/views/projects/services/mattermost_slash_commands/_help.html.haml +++ b/app/views/projects/services/mattermost_slash_commands/_help.html.haml @@ -10,8 +10,8 @@ %p.inline = s_("MattermostService|After you configure the integration, view your new Mattermost commands by entering") %kbd.inline /<trigger> help - - if !enabled && @service.project_level? - = render 'projects/services/mattermost_slash_commands/detailed_help', subject: @service + - if !enabled && integration.project_level? + = render 'projects/services/mattermost_slash_commands/detailed_help', integration: integration -- if enabled && @service.project_level? - = render 'projects/services/mattermost_slash_commands/installation_info', subject: @service +- if enabled && integration.project_level? + = render 'projects/services/mattermost_slash_commands/installation_info', integration: integration diff --git a/app/views/projects/services/mattermost_slash_commands/_installation_info.html.haml b/app/views/projects/services/mattermost_slash_commands/_installation_info.html.haml index 53ee363de53..38adc69dd5e 100644 --- a/app/views/projects/services/mattermost_slash_commands/_installation_info.html.haml +++ b/app/views/projects/services/mattermost_slash_commands/_installation_info.html.haml @@ -1,5 +1,5 @@ .services-installation-info - - unless @service.activated? + - unless integration.activated? .row .col-sm-9.offset-sm-3 = link_to new_project_mattermost_path(@project), class: 'btn gl-button btn-lg' do diff --git a/app/views/projects/services/prometheus/_configuration_banner.html.haml b/app/views/projects/services/prometheus/_configuration_banner.html.haml index 3786b845692..a34aa22acbb 100644 --- a/app/views/projects/services/prometheus/_configuration_banner.html.haml +++ b/app/views/projects/services/prometheus/_configuration_banner.html.haml @@ -1,26 +1,26 @@ %h4 - = s_('PrometheusService|Auto configuration') + = s_('PrometheusService|Prometheus cluster integration') -- if service.manual_configuration? +- if integration.manual_configuration? .info-well - = s_('PrometheusService|To enable the installation of Prometheus on your clusters, deactivate the manual configuration.') + = s_('PrometheusService|To use a Prometheus installed on a cluster, deactivate the manual configuration.') - else .container-fluid .row - - if service.prometheus_available? + - if integration.prometheus_available? .col-sm-2 .svg-container = image_tag 'illustrations/monitoring/getting_started.svg' .col-sm-10 %p.text-success.gl-mt-3 - = s_('PrometheusService|GitLab is managing Prometheus on your clusters.') + = s_('PrometheusService|You have a cluster with the Prometheus integration enabled.') = link_to s_('PrometheusService|Manage clusters'), project_clusters_path(project), class: 'btn gl-button' - else .col-sm-2 = image_tag 'illustrations/monitoring/loading.svg' .col-sm-10 %p.gl-mt-3 - = s_('PrometheusService|Automatically deploy and configure Prometheus on your clusters to monitor your project’s environments.') - = link_to s_('PrometheusService|Install Prometheus on clusters'), project_clusters_path(project), class: 'btn gl-button btn-confirm' + = s_('PrometheusService|Configure GitLab to query a Prometheus installed in one of your clusters.') + = link_to s_('PrometheusService|Manage clusters'), project_clusters_path(project), class: 'btn gl-button btn-confirm' %hr diff --git a/app/views/projects/services/prometheus/_custom_metrics.html.haml b/app/views/projects/services/prometheus/_custom_metrics.html.haml index a901d5b3575..724950bcb39 100644 --- a/app/views/projects/services/prometheus/_custom_metrics.html.haml +++ b/app/views/projects/services/prometheus/_custom_metrics.html.haml @@ -6,7 +6,7 @@ = link_to s_('PrometheusService|More information'), help_page_path('operations/metrics/index.md', anchor: 'adding-custom-metrics'), target: '_blank', rel: "noopener noreferrer" .col-lg-9 - .card.custom-monitored-metrics.js-panel-custom-monitored-metrics{ data: { qa_selector: 'custom_metrics_container', active_custom_metrics: project_prometheus_metrics_path(project), environments_data: environments_list_data, service_active: "#{@service.active}" } } + .card.custom-monitored-metrics.js-panel-custom-monitored-metrics{ data: { qa_selector: 'custom_metrics_container', active_custom_metrics: project_prometheus_metrics_path(project), environments_data: environments_list_data, service_active: "#{integration.active}" } } .card-header %strong = s_('PrometheusService|Custom metrics') diff --git a/app/views/projects/services/prometheus/_external_alerts.html.haml b/app/views/projects/services/prometheus/_external_alerts.html.haml index b27b1ab8723..168b4853a9a 100644 --- a/app/views/projects/services/prometheus/_external_alerts.html.haml +++ b/app/views/projects/services/prometheus/_external_alerts.html.haml @@ -1,5 +1,5 @@ - return unless can?(current_user, :read_prometheus_alerts, @project) -- return unless @service.manual_configuration? +- return unless integration.manual_configuration? - notify_url = notify_project_prometheus_alerts_url(@project, format: :json) - authorization_key = @project.alerting_setting.try(:token) diff --git a/app/views/projects/services/prometheus/_help.html.haml b/app/views/projects/services/prometheus/_help.html.haml index 04bd800c47a..9b3cb8893c4 100644 --- a/app/views/projects/services/prometheus/_help.html.haml +++ b/app/views/projects/services/prometheus/_help.html.haml @@ -1,5 +1,5 @@ - if @project - = render 'projects/services/prometheus/configuration_banner', project: @project, service: @service + = render 'projects/services/prometheus/configuration_banner', project: @project, integration: integration %h4.gl-mb-3 = s_('PrometheusService|Manual configuration') diff --git a/app/views/projects/services/prometheus/_metrics.html.haml b/app/views/projects/services/prometheus/_metrics.html.haml index 4bafd4d06e0..09fe77b8a9c 100644 --- a/app/views/projects/services/prometheus/_metrics.html.haml +++ b/app/views/projects/services/prometheus/_metrics.html.haml @@ -1,6 +1,6 @@ - project = local_assigns.fetch(:project) -= render 'projects/services/prometheus/custom_metrics', project: project += render 'projects/services/prometheus/custom_metrics', project: project, integration: integration .col-lg-3 %p diff --git a/app/views/projects/services/prometheus/_show.html.haml b/app/views/projects/services/prometheus/_show.html.haml index 9ce61ed5c13..3350ac8a6c5 100644 --- a/app/views/projects/services/prometheus/_show.html.haml +++ b/app/views/projects/services/prometheus/_show.html.haml @@ -4,6 +4,6 @@ = s_('PrometheusService|Metrics') .row.gl-mb-3.prometheus-metrics-monitoring.js-prometheus-metrics-monitoring - = render 'projects/services/prometheus/metrics', project: @project + = render 'projects/services/prometheus/metrics', project: @project, integration: integration -= render 'projects/services/prometheus/external_alerts', project: @project += render 'projects/services/prometheus/external_alerts', project: @project, integration: integration diff --git a/app/views/projects/services/prometheus/_top.html.haml b/app/views/projects/services/prometheus/_top.html.haml index db02ea85865..f7446273a80 100644 --- a/app/views/projects/services/prometheus/_top.html.haml +++ b/app/views/projects/services/prometheus/_top.html.haml @@ -1,4 +1,4 @@ -- return unless @service.manual_configuration? +- return unless integration.manual_configuration? .row .col-lg-12 diff --git a/app/views/projects/services/slack_slash_commands/_help.html.haml b/app/views/projects/services/slack_slash_commands/_help.html.haml index b68addcb093..9702f9b08f2 100644 --- a/app/views/projects/services/slack_slash_commands/_help.html.haml +++ b/app/views/projects/services/slack_slash_commands/_help.html.haml @@ -11,7 +11,7 @@ %p.inline = s_("SlackService|See list of available commands in Slack after setting up this service, by entering") %kbd.inline /<command> help - - if @service.project_level? + - if integration.project_level? %p= _("To set up this service:") %ul.list-unstyled.indent-list %li @@ -39,7 +39,7 @@ .form-group = label_tag :url, 'URL', class: 'col-12 col-form-label label-bold' .col-12.input-group - = text_field_tag :url, service_trigger_url(subject), class: 'form-control form-control-sm', readonly: 'readonly' + = text_field_tag :url, service_trigger_url(integration), class: 'form-control form-control-sm', readonly: 'readonly' .input-group-append = clipboard_button(target: '#url', class: 'input-group-text') diff --git a/app/views/projects/settings/_general.html.haml b/app/views/projects/settings/_general.html.haml index 845fb299b74..0891e3e0526 100644 --- a/app/views/projects/settings/_general.html.haml +++ b/app/views/projects/settings/_general.html.haml @@ -15,8 +15,8 @@ .row .form-group.col-md-9 - = f.label :tag_list, _('Topics (optional)'), class: 'label-bold' - = f.text_field :tag_list, value: @project.tag_list.join(', '), maxlength: 2000, class: "form-control gl-form-input" + = f.label :topics, _('Topics (optional)'), class: 'label-bold' + = f.text_field :topics, value: @project.topic_list.join(', '), maxlength: 2000, class: "form-control gl-form-input" %p.form-text.text-muted= _('Separate topics with commas.') = render_if_exists 'compliance_management/compliance_framework/project_settings', f: f diff --git a/app/views/projects/settings/ci_cd/_form.html.haml b/app/views/projects/settings/ci_cd/_form.html.haml index c4b5c23be13..c89c9879f4b 100644 --- a/app/views/projects/settings/ci_cd/_form.html.haml +++ b/app/views/projects/settings/ci_cd/_form.html.haml @@ -18,7 +18,7 @@ = f.label :auto_cancel_pending_pipelines, class: 'form-check-label' do %strong= _("Auto-cancel redundant pipelines") .form-text.text-muted - = _("New pipelines cause older pending pipelines on the same branch to be cancelled.") + = _("New pipelines cause older pending or running pipelines on the same branch to be cancelled.") = link_to sprite_icon('question-o'), help_page_path('ci/pipelines/settings', anchor: 'auto-cancel-redundant-pipelines'), target: '_blank' .form-group @@ -36,7 +36,7 @@ = f.text_field :ci_config_path, class: 'form-control', placeholder: '.gitlab-ci.yml' %p.form-text.text-muted = html_escape(_("The name of the CI/CD configuration file. A path relative to the root directory is optional (for example %{code_open}my/path/.myfile.yml%{code_close}).")) % { code_open: '<code>'.html_safe, code_close: '</code>'.html_safe } - = link_to sprite_icon('question-o'), help_page_path('ci/pipelines/settings', anchor: 'custom-cicd-configuration-path'), target: '_blank' + = link_to sprite_icon('question-o'), help_page_path('ci/pipelines/settings', anchor: 'custom-cicd-configuration-file'), target: '_blank' %hr .form-group diff --git a/app/views/projects/settings/ci_cd/show.html.haml b/app/views/projects/settings/ci_cd/show.html.haml index d955dabd04c..ade3d40a8df 100644 --- a/app/views/projects/settings/ci_cd/show.html.haml +++ b/app/views/projects/settings/ci_cd/show.html.haml @@ -76,17 +76,7 @@ = render 'projects/triggers/index' - if settings_container_registry_expiration_policy_available?(@project) - %section.settings.no-animate#js-registry-policies{ class: ('expanded' if expanded) } - .settings-header - %h4.settings-title.js-settings-toggle.js-settings-toggle-trigger-only - = _("Clean up image tags") - %button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' } - = expanded ? _('Collapse') : _('Expand') - %p - = _("Save space and find images in the Container Registry. Remove unneeded tags and keep only the ones you want.") - = link_to _('How does cleanup work?'), help_page_path('user/packages/container_registry/index', anchor: 'cleanup-policy'), target: '_blank', rel: 'noopener noreferrer' - .settings-content - = render 'projects/registry/settings/index' + = render 'projects/registry/settings/index' = render_if_exists 'projects/settings/ci_cd/auto_rollback', expanded: expanded diff --git a/app/views/projects/settings/integrations/show.html.haml b/app/views/projects/settings/integrations/show.html.haml index af37795a7c5..84635941436 100644 --- a/app/views/projects/settings/integrations/show.html.haml +++ b/app/views/projects/settings/integrations/show.html.haml @@ -2,18 +2,8 @@ - breadcrumb_title _('Integration Settings') - page_title _('Integrations') -- if show_webhooks_moved_alert? - .gl-alert.gl-alert-info.js-webhooks-moved-alert.gl-mt-3{ role: 'alert', data: { feature_id: UserCalloutsHelper::WEBHOOKS_MOVED, dismiss_endpoint: user_callouts_path } } - = 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 - = _('Webhooks have moved. They can now be found under the Settings menu.') - .gl-alert-actions - = link_to _('Go to Webhooks'), project_hooks_path(@project), class: 'gl-button btn gl-alert-action btn-info' - %h3= _('Integrations') - integrations_link_start = '<a href="%{url}">'.html_safe % { url: help_page_url('user/project/integrations/overview') } - webhooks_link_start = '<a href="%{url}">'.html_safe % { url: project_hooks_path(@project) } %p= _("%{integrations_link_start}Integrations%{link_end} enable you to make third-party applications part of your GitLab workflow. If the available integrations don't meet your needs, consider using a %{webhooks_link_start}webhook%{link_end}.").html_safe % { integrations_link_start: integrations_link_start, webhooks_link_start: webhooks_link_start, link_end: '</a>'.html_safe } -= render 'shared/integrations/index', integrations: @services += render 'shared/integrations/index', integrations: @integrations diff --git a/app/views/projects/settings/operations/_alert_management.html.haml b/app/views/projects/settings/operations/_alert_management.html.haml index 0418d7df42d..34255af9cc6 100644 --- a/app/views/projects/settings/operations/_alert_management.html.haml +++ b/app/views/projects/settings/operations/_alert_management.html.haml @@ -6,7 +6,7 @@ %section.settings.no-animate#js-alert-management-settings{ class: ('expanded' if expanded) } .settings-header %h4.settings-title.js-settings-toggle.js-settings-toggle-trigger-only - = _('Alert integrations') + = _('Alerts') %button.gl-button.btn.btn-default.js-settings-toggle{ type: 'button' } = _('Expand') %p diff --git a/app/views/projects/settings/operations/_configuration_banner.html.haml b/app/views/projects/settings/operations/_configuration_banner.html.haml index 6fa6b23b0da..9803ffc3c4e 100644 --- a/app/views/projects/settings/operations/_configuration_banner.html.haml +++ b/app/views/projects/settings/operations/_configuration_banner.html.haml @@ -1,9 +1,9 @@ %b - = s_('PrometheusService|Auto configuration') + = s_('PrometheusService|Prometheus cluster integration') - if service.manual_configuration? .info-well.p-2.mt-2 - = s_('PrometheusService|To enable the installation of Prometheus on your clusters, deactivate the manual configuration.') + = s_('PrometheusService|To use a Prometheus installed on a cluster, deactivate the manual configuration.') - else .container-fluid .row @@ -13,12 +13,12 @@ = image_tag 'illustrations/monitoring/getting_started.svg' .col-sm-10 %p.text-success.gl-mt-3 - = s_('PrometheusService|GitLab manages Prometheus on your clusters.') + = s_('PrometheusService|You have a cluster with the Prometheus integration enabled.') = link_to s_('PrometheusService|Manage clusters'), project_clusters_path(project), class: 'gl-button btn btn-default' - else .col-sm-2 = image_tag 'illustrations/monitoring/loading.svg' .col-sm-10 %p.gl-mt-3 - = s_('PrometheusService|Monitor your project’s environments by deploying and configuring Prometheus on your clusters.') - = link_to s_('PrometheusService|Install Prometheus on clusters'), project_clusters_path(project), class: 'gl-button btn btn-confirm' + = s_('PrometheusService|Configure GitLab to query a Prometheus installed in one of your clusters.') + = link_to s_('PrometheusService|Manage clusters'), project_clusters_path(project), class: 'btn gl-button btn-confirm' diff --git a/app/views/projects/settings/operations/_tracing.html.haml b/app/views/projects/settings/operations/_tracing.html.haml index a591fa33096..343fd22c051 100644 --- a/app/views/projects/settings/operations/_tracing.html.haml +++ b/app/views/projects/settings/operations/_tracing.html.haml @@ -1,23 +1,13 @@ - setting = tracing_setting -- has_jaeger_url = setting.external_url.present? %section.settings.border-0.no-animate - .settings-header{ :class => "border-top" } + .settings-header{ :class => 'border-top' } %h4.settings-title.js-settings-toggle.js-settings-toggle-trigger-only - = _("Jaeger tracing") + = _('Tracing') %button.btn.btn-default.gl-button.js-settings-toggle{ type: 'button' } = _('Expand') %p - - if has_jaeger_url - - tracing_link = link_to sanitize(setting.external_url, scrubber: Rails::Html::TextOnlyScrubber.new), target: "_blank", rel: 'noopener noreferrer' do - %span - = _('Tracing') - = sprite_icon('external-link', css_class: 'ml-1 vertical-align-middle') - - else - - tracing_link = link_to project_tracing_path(@project) do - %span - = _('Tracing') - = _("To open Jaeger from GitLab to view tracing from the %{link} page, add a URL to your Jaeger server.").html_safe % { link: tracing_link } + = _('Embed an image of your existing Jaeger server in GitLab.') = link_to _('Learn more.'), help_page_path('operations/tracing'), target: '_blank', rel: 'noopener noreferrer' .settings-content = form_for @project, url: project_settings_operations_path(@project), method: :patch do |f| @@ -27,8 +17,8 @@ = form.label :external_url, _('Jaeger URL'), class: 'label-bold' = form.url_field :external_url, class: 'form-control gl-form-input', placeholder: 'https://jaeger.example.com' %p.form-text.text-muted - - jaeger_help_url = "https://www.jaegertracing.io/docs/getting-started/" + - jaeger_help_url = 'https://www.jaegertracing.io/docs/getting-started/' - link_start_tag = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: jaeger_help_url } - - link_end_tag = "#{sprite_icon('external-link', css_class: 'ml-1 vertical-align-middle')}</a>".html_safe - = _("Learn more about %{link_start_tag}Jaeger configuration%{link_end_tag}.").html_safe % { link_start_tag: link_start_tag, link_end_tag: link_end_tag } + - link_end_tag = "#{sprite_icon('external-link', css_class: 'gl-ml-2 gl-vertical-align-middle')}</a>".html_safe + = _('Learn more about %{link_start_tag}Jaeger configuration%{link_end_tag}.').html_safe % { link_start_tag: link_start_tag, link_end_tag: link_end_tag } = f.submit _('Save changes'), class: 'gl-button btn btn-confirm' diff --git a/app/views/projects/settings/operations/show.html.haml b/app/views/projects/settings/operations/show.html.haml index af183046e1e..e2c1a00a587 100644 --- a/app/views/projects/settings/operations/show.html.haml +++ b/app/views/projects/settings/operations/show.html.haml @@ -3,11 +3,11 @@ - page_title title - breadcrumb_title title += render 'projects/settings/operations/metrics_dashboard' += render 'projects/settings/operations/tracing' += render 'projects/settings/operations/error_tracking' = render 'projects/settings/operations/alert_management' = render 'projects/settings/operations/incidents' -= render 'projects/settings/operations/error_tracking' -= render 'projects/settings/operations/prometheus', service: prometheus_service if Feature.enabled?(:settings_operations_prometheus_service) -= render 'projects/settings/operations/metrics_dashboard' = render 'projects/settings/operations/grafana_integration' -= render 'projects/settings/operations/tracing' = render_if_exists 'projects/settings/operations/status_page' += render 'projects/settings/operations/prometheus', service: prometheus_service if Feature.enabled?(:settings_operations_prometheus_service) diff --git a/app/views/projects/settings/packages_and_registries/show.html.haml b/app/views/projects/settings/packages_and_registries/show.html.haml index 561ac7b347d..626ddc20431 100644 --- a/app/views/projects/settings/packages_and_registries/show.html.haml +++ b/app/views/projects/settings/packages_and_registries/show.html.haml @@ -1,16 +1,15 @@ - breadcrumb_title _('Packages & Registries') - page_title _('Packages & Registries') - @content_class = 'limit-container-width' unless fluid_layout -- expanded = true -%section.settings.no-animate#js-registry-policies{ class: ('expanded' if expanded) } - .settings-header - %h4.settings-title.js-settings-toggle.js-settings-toggle-trigger-only - = _("Clean up image tags") - %button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' } - = expanded ? _('Collapse') : _('Expand') - %p - = _("Save space and find images in the Container Registry. Remove unneeded tags and keep only the ones you want.") - = link_to _('How does cleanup work?'), help_page_path('user/packages/container_registry/index', anchor: 'cleanup-policy'), target: '_blank', rel: 'noopener noreferrer' - .settings-content - = render 'projects/registry/settings/index' +#js-registry-settings{ data: { project_id: @project.id, + project_path: @project.full_path, + cadence_options: cadence_options.to_json, + keep_n_options: keep_n_options.to_json, + older_than_options: older_than_options.to_json, + is_admin: current_user&.admin.to_s, + admin_settings_path: ci_cd_admin_application_settings_path(anchor: 'js-registry-settings'), + enable_historic_entries: container_expiration_policies_historic_entry_enabled?(@project).to_s, + help_page_path: help_page_path('user/packages/container_registry/index', anchor: 'cleanup-policy'), + show_cleanup_policy_on_alert: show_cleanup_policy_on_alert(@project).to_s, + tags_regex_help_page_path: help_page_path('user/packages/container_registry/index', anchor: 'regex-pattern-examples') } } diff --git a/app/views/projects/show.html.haml b/app/views/projects/show.html.haml index 90b79fddff1..4757f50739b 100644 --- a/app/views/projects/show.html.haml +++ b/app/views/projects/show.html.haml @@ -2,6 +2,7 @@ - add_page_startup_graphql_call('repository/path_last_commit', { projectPath: @project.full_path, ref: current_ref, path: current_route_path || "" }) - @content_class = "limit-container-width" unless fluid_layout - @skip_current_level_breadcrumb = true +- add_page_specific_style 'page_bundles/project' = content_for :meta_tags do = auto_discovery_link_tag(:atom, project_path(@project, rss_url_options), title: "#{@project.name} activity") diff --git a/app/views/projects/tree/_tree_header.html.haml b/app/views/projects/tree/_tree_header.html.haml index 340f9811f9a..60cc043f813 100644 --- a/app/views/projects/tree/_tree_header.html.haml +++ b/app/views/projects/tree/_tree_header.html.haml @@ -1,4 +1,4 @@ -.tree-ref-container +.tree-ref-container.gl-display-flex.mb-2.mb-md-0 .tree-ref-holder = render 'shared/ref_switcher', destination: 'tree', path: @path, show_create: true @@ -16,5 +16,5 @@ .project-clone-holder.d-none.d-md-inline-block> = render "projects/buttons/clone", dropdown_class: 'dropdown-menu-right' - .project-clone-holder.d-block.d-md-none.mt-sm-2.mt-md-0.ml-sm-2> + .project-clone-holder.d-block.d-md-none.mt-sm-2.mt-md-0.ml-md-2> = render "shared/mobile_clone_panel" diff --git a/app/views/registrations/invites/new.html.haml b/app/views/registrations/invites/new.html.haml index 6e6ff7aaeee..0feae9b17e9 100644 --- a/app/views/registrations/invites/new.html.haml +++ b/app/views/registrations/invites/new.html.haml @@ -13,6 +13,5 @@ url: users_sign_up_invites_path, button_text: _('Continue'), show_omniauth_providers: social_signin_enabled?, - omniauth_providers_placement: :top, - suggestion_path: nil + omniauth_providers_placement: :top = render 'devise/shared/sign_in_link' diff --git a/app/views/search/_results.html.haml b/app/views/search/_results.html.haml index d5fbee34fa0..4ba906dd02f 100644 --- a/app/views/search/_results.html.haml +++ b/app/views/search/_results.html.haml @@ -4,7 +4,7 @@ .gl-md-display-flex - if %w(issues merge_requests).include?(@scope) #js-search-sidebar{ class: search_bar_classes } - .gl-w-full.gl-flex-fill-1.gl-overflow-x-hidden + .gl-w-full.gl-flex-grow-1.gl-overflow-x-hidden = render partial: "search/results/empty" = render_if_exists 'shared/promotions/promote_advanced_search' - else @@ -14,7 +14,7 @@ .results.gl-md-display-flex.gl-mt-3 - if %w(issues merge_requests).include?(@scope) #js-search-sidebar{ class: search_bar_classes } - .gl-w-full.gl-flex-fill-1.gl-overflow-x-hidden + .gl-w-full.gl-flex-grow-1.gl-overflow-x-hidden - if @scope == 'commits' %ul.content-list.commit-list = render partial: "search/results/commit", collection: @search_objects diff --git a/app/views/search/results/_issuable.html.haml b/app/views/search/results/_issuable.html.haml index cb8bab7d0de..da0adba88db 100644 --- a/app/views/search/results/_issuable.html.haml +++ b/app/views/search/results/_issuable.html.haml @@ -5,6 +5,10 @@ = 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} · created %{issuable_created} by %{author} · updated %{issuable_updated}'), { project_name: issuable.project.full_name, issuable_iid: issuable.iid, issuable_created: time_ago_with_tooltip(issuable.created_at, placement: 'bottom'), issuable_updated: time_ago_with_tooltip(issuable.updated_at, placement: 'bottom'), author: link_to_member(@project, issuable.author, avatar: false) }).html_safe + = issuable_project_reference(issuable) + · + = sprintf(s_('created %{issuable_created} by %{author}'), { issuable_created: time_ago_with_tooltip(issuable.created_at, placement: 'bottom'), author: link_to_member(@project, issuable.author, avatar: false) }).html_safe + · + = sprintf(s_('updated %{time_ago}'), { time_ago: time_ago_with_tooltip(issuable.updated_at, placement: 'bottom') }).html_safe .description.term.col-sm-10.gl-px-0 = highlight_and_truncate_issuable(issuable, @search_term, @search_highlight) diff --git a/app/views/shared/_auto_devops_implicitly_enabled_banner.html.haml b/app/views/shared/_auto_devops_implicitly_enabled_banner.html.haml index 6f70c927147..f788bf53a4c 100644 --- a/app/views/shared/_auto_devops_implicitly_enabled_banner.html.haml +++ b/app/views/shared/_auto_devops_implicitly_enabled_banner.html.haml @@ -1,13 +1,14 @@ - if show_auto_devops_implicitly_enabled_banner?(project, current_user) - .qa-auto-devops-banner.auto-devops-implicitly-enabled-banner.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'), class: 'hide-auto-devops-implicitly-enabled-banner alert-link', data: { project_id: project.id } } - = sprite_icon('close', css_class: 'gl-icon') + = render 'shared/global_alert', + variant: :info, + alert_class: 'qa-auto-devops-banner auto-devops-implicitly-enabled-banner', + close_button_class: 'hide-auto-devops-implicitly-enabled-banner', + close_button_data: { project_id: project.id } do .gl-alert-body = s_("AutoDevOps|The Auto DevOps pipeline has been enabled and will be used if no alternative CI configuration file is found.") - - unless Gitlab.config.registry.enabled - %div - = _('Container registry is not enabled on this GitLab instance. Ask an administrator to enable it in order for Auto DevOps to work.') - .gl-alert-actions.gl-mt-3 + - unless Gitlab.config.registry.enabled + %div + = _('Container registry is not enabled on this GitLab instance. Ask an administrator to enable it in order for Auto DevOps to work.') + .gl-alert-actions = link_to _('Settings'), project_settings_ci_cd_path(project), class: 'alert-link btn gl-button btn-info' = link_to _('More information'), help_page_path('topics/autodevops/index.md'), target: '_blank', class: 'alert-link btn gl-button btn-default gl-ml-2' diff --git a/app/views/shared/_confirm_fork_modal.html.haml b/app/views/shared/_confirm_fork_modal.html.haml index ed52aa01047..96b128eb2ec 100644 --- a/app/views/shared/_confirm_fork_modal.html.haml +++ b/app/views/shared/_confirm_fork_modal.html.haml @@ -4,7 +4,7 @@ .modal-header %h3.page-title= _('Fork project?') %button.close{ type: "button", "data-dismiss": "modal", "aria-label" => _('Close') } - %span{ "aria-hidden": true } × + %span{ "aria-hidden": "true" } × .modal-body.p-3 %p= _("You can’t %{tag_start}edit%{tag_end} files directly in this project. Fork this project and submit a merge request with your changes.") % { tag_start: '', tag_end: ''} .modal-footer diff --git a/app/views/shared/_confirm_modal.html.haml b/app/views/shared/_confirm_modal.html.haml index 4e7e5c9d3ba..8b13bb948ee 100644 --- a/app/views/shared/_confirm_modal.html.haml +++ b/app/views/shared/_confirm_modal.html.haml @@ -4,7 +4,7 @@ .modal-header %h3.page-title= _('Confirmation required') %button.close{ type: "button", "data-dismiss": "modal", "aria-label" => _('Close') } - %span{ "aria-hidden": true } × + %span{ "aria-hidden": "true" } × .modal-body %p.text-danger.js-confirm-text diff --git a/app/views/shared/_global_alert.html.haml b/app/views/shared/_global_alert.html.haml new file mode 100644 index 00000000000..bebc72fe428 --- /dev/null +++ b/app/views/shared/_global_alert.html.haml @@ -0,0 +1,20 @@ +- icons = { info: 'information-o', warning: 'warning', success: 'check-circle', danger: 'error', tip: 'bulb' } + +- title = local_assigns.fetch(:title, nil) +- variant = local_assigns.fetch(:variant, :info) +- alert_class = local_assigns.fetch(:alert_class, nil) +- alert_data = local_assigns.fetch(:alert_data, nil) +- close_button_class = local_assigns.fetch(:close_button_class, nil) +- close_button_data = local_assigns.fetch(:close_button_data, nil) +- icon = icons[variant] + +%div{ role: 'alert', class: ["gl-alert-#{variant}", alert_class], data: alert_data } + %div{ class: [container_class, @content_class, 'gl-px-0!'] } + .gl-alert + = sprite_icon(icon, size: 16, css_class: "gl-alert-icon#{' gl-alert-icon-no-title' if title.nil?}") + %button.gl-alert-dismiss.js-close{ type: 'button', aria: { label: _('Close') }, class: close_button_class, data: close_button_data } + = sprite_icon('close', size: 16) + - if title + .gl-alert-title + = title + = yield diff --git a/app/views/shared/_import_form.html.haml b/app/views/shared/_import_form.html.haml index cf9ee1a5231..65e02341936 100644 --- a/app/views/shared/_import_form.html.haml +++ b/app/views/shared/_import_form.html.haml @@ -6,14 +6,8 @@ = f.label :import_url, class: 'label-bold' do %span = _('Git repository URL') - = f.text_field :import_url, - value: import_url.sanitized_url, - autocomplete: 'off', - class: 'form-control gl-form-input', - placeholder: 'https://gitlab.company.com/group/project.git', - required: true, - pattern: '(?:git|https?):\/\/.*/.*\.git$', - title: _('Please provide a valid URL ending with .git') + = f.text_field :import_url, value: import_url.sanitized_url, + autocomplete: 'off', class: 'form-control gl-form-input', placeholder: 'https://gitlab.company.com/group/project.git', required: true .row .form-group.col-md-6 diff --git a/app/views/shared/_search_settings.html.haml b/app/views/shared/_search_settings.html.haml index 2974b2bf4d0..7265f090967 100644 --- a/app/views/shared/_search_settings.html.haml +++ b/app/views/shared/_search_settings.html.haml @@ -1,3 +1,5 @@ +- return if @hide_search_settings + - container_class = local_assigns.fetch(:container_class, 'gl-mt-5') %div{ class: container_class } diff --git a/app/views/shared/_service_settings.html.haml b/app/views/shared/_service_settings.html.haml index 7af356c0820..c70fce7a38f 100644 --- a/app/views/shared/_service_settings.html.haml +++ b/app/views/shared/_service_settings.html.haml @@ -7,7 +7,7 @@ .js-integration-help-html.gl-display-none -# All content below will be repositioned in Vue - if lookup_context.template_exists?('help', "projects/services/#{integration.to_param}", true) - = render "projects/services/#{integration.to_param}/help", subject: integration + = render "projects/services/#{integration.to_param}/help", integration: integration - elsif integration.help.present? .info-well .well-segment diff --git a/app/views/shared/_sidebar_toggle_button.html.haml b/app/views/shared/_sidebar_toggle_button.html.haml index 9d1970093b8..a5a411db8a0 100644 --- a/app/views/shared/_sidebar_toggle_button.html.haml +++ b/app/views/shared/_sidebar_toggle_button.html.haml @@ -1,8 +1,9 @@ %a.toggle-sidebar-button.js-toggle-sidebar.qa-toggle-sidebar.rspec-toggle-sidebar{ role: "button", type: "button", title: "Toggle sidebar" } = sprite_icon('chevron-double-lg-left', css_class: 'icon-chevron-double-lg-left') - = sprite_icon('chevron-double-lg-right', css_class: 'icon-chevron-double-lg-right') - %span.collapse-text= _("Collapse sidebar") + - if sidebar_refactor_disabled? + = sprite_icon('chevron-double-lg-right', css_class: 'icon-chevron-double-lg-right') + %span.collapse-text.gl-ml-3= _("Collapse sidebar") = button_tag class: 'close-nav-button', type: 'button' do = sprite_icon('close') - %span.collapse-text= _("Close sidebar") + %span.collapse-text.gl-ml-3= _("Close sidebar") diff --git a/app/views/shared/boards/components/sidebar/_time_tracker.html.haml b/app/views/shared/boards/components/sidebar/_time_tracker.html.haml index 43081499920..9f230a4a09b 100644 --- a/app/views/shared/boards/components/sidebar/_time_tracker.html.haml +++ b/app/views/shared/boards/components/sidebar/_time_tracker.html.haml @@ -1,7 +1,5 @@ .block.time-tracking - %time-tracker{ ":time-estimate" => "issue.timeEstimate || 0", - ":time-spent" => "issue.timeSpent || 0", - ":human-time-estimate" => "issue.humanTimeEstimate", - ":human-time-spent" => "issue.humanTimeSpent", - ":limit-to-hours" => "timeTrackingLimitToHours", + %time-tracker{ ":limit-to-hours" => "timeTrackingLimitToHours", + ":issuable-iid" => "issue.iid ? issue.iid.toString() : ''", + ":full-path" => "issue.project ? issue.project.fullPath : ''", "root-path" => "#{root_url}" } diff --git a/app/views/shared/file_hooks/_index.html.haml b/app/views/shared/file_hooks/_index.html.haml index cab0adf159b..d48e9f3d02e 100644 --- a/app/views/shared/file_hooks/_index.html.haml +++ b/app/views/shared/file_hooks/_index.html.haml @@ -19,9 +19,6 @@ %li .monospace = File.basename(file) - - if File.dirname(file).ends_with?('plugins') - .text-warning - = _('Plugins directory is deprecated and will be removed in 14.0. Please move this file into /file_hooks directory.') - else .card.bg-light.text-center 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 61c0e5c42f4..ca1d3d53f16 100644 --- a/app/views/shared/form_elements/_apply_template_warning.html.haml +++ b/app/views/shared/form_elements/_apply_template_warning.html.haml @@ -1,7 +1,7 @@ .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") } + %btn.js-close-btn.js-dismiss-btn.close{ type: "button", "aria-hidden": "true", "aria-label": _("Close") } = sprite_icon("close") %p diff --git a/app/views/shared/gitpod/_enable_gitpod_modal.html.haml b/app/views/shared/gitpod/_enable_gitpod_modal.html.haml index dacfbf63db8..6a8ff98a09e 100644 --- a/app/views/shared/gitpod/_enable_gitpod_modal.html.haml +++ b/app/views/shared/gitpod/_enable_gitpod_modal.html.haml @@ -4,7 +4,7 @@ .modal-header %h3.page-title= _('Enable Gitpod?') %button.close{ type: "button", "data-dismiss": "modal", "aria-label" => _('Close') } - %span{ "aria-hidden": true } × + %span{ "aria-hidden": "true" } × .modal-body.p-3 %p= (_("To use Gitpod you must first enable the feature in the integrations section of your %{user_prefs}.") % { user_prefs: link_to(_('user preferences'), profile_preferences_path(anchor: 'gitpod')) }).html_safe .modal-footer diff --git a/app/views/shared/issuable/_form.html.haml b/app/views/shared/issuable/_form.html.haml index de657e39453..e79719d41b0 100644 --- a/app/views/shared/issuable/_form.html.haml +++ b/app/views/shared/issuable/_form.html.haml @@ -24,14 +24,6 @@ = render 'shared/form_elements/description', model: issuable, form: form, project: project -- if issuable.respond_to?(:confidential) - .form-group.row - .offset-sm-2.col-sm-10 - .form-check - = form.check_box :confidential, class: 'form-check-input' - = form.label :confidential, class: 'form-check-label' do - This issue is confidential and should only be visible to team members with at least Reporter access. - = render 'shared/issuable/form/metadata', issuable: issuable, form: form, project: project, presenter: presenter = render_if_exists 'shared/issuable/approvals', issuable: issuable, presenter: presenter, form: form diff --git a/app/views/shared/issuable/_search_bar.html.haml b/app/views/shared/issuable/_search_bar.html.haml index 3e89969f46e..c03697a4076 100644 --- a/app/views/shared/issuable/_search_bar.html.haml +++ b/app/views/shared/issuable/_search_bar.html.haml @@ -23,7 +23,7 @@ - checkbox_id = 'check-all-issues' %label.gl-sr-only{ for: checkbox_id }= _('Select all') = check_box_tag checkbox_id, nil, false, class: "check-all-issues left" - - if Feature.enabled?(:boards_filtered_search, @group) && is_epic_board + - if is_epic_board #js-board-filtered-search{ data: { full_path: @group&.full_path } } - else .issues-other-filters.filtered-search-wrapper.d-flex.flex-column.flex-md-row diff --git a/app/views/shared/issuable/_sidebar.html.haml b/app/views/shared/issuable/_sidebar.html.haml index fb2019bef15..416c788603a 100644 --- a/app/views/shared/issuable/_sidebar.html.haml +++ b/app/views/shared/issuable/_sidebar.html.haml @@ -30,7 +30,8 @@ .block.reviewer.qa-reviewer-block = render "shared/issuable/sidebar_reviewers", issuable_sidebar: issuable_sidebar, reviewers: reviewers, signed_in: signed_in - = render_if_exists 'shared/issuable/sidebar_item_epic', issuable_sidebar: issuable_sidebar + - if @project.group.present? + = render_if_exists 'shared/issuable/sidebar_item_epic', issuable_sidebar: issuable_sidebar, group_path: @project.group.full_path, project_path: issuable_sidebar[:project_full_path], issue_iid: issuable_sidebar[:iid], issuable_type: issuable_type - if issuable_sidebar[:supports_milestone] - milestone = issuable_sidebar[:milestone] || {} @@ -42,7 +43,7 @@ = milestone[:title] - else = _('None') - .title.hide-collapsed + .hide-collapsed.gl-line-height-20.gl-mb-2.gl-text-gray-900{ data: { testid: "milestone_title" } } = _('Milestone') = loading_icon(css_class: 'gl-vertical-align-text-bottom hidden block-loading') - if can_edit_issuable diff --git a/app/views/shared/issuable/_sidebar_assignees.html.haml b/app/views/shared/issuable/_sidebar_assignees.html.haml index 86369b32e98..7416fda6b44 100644 --- a/app/views/shared/issuable/_sidebar_assignees.html.haml +++ b/app/views/shared/issuable/_sidebar_assignees.html.haml @@ -42,22 +42,8 @@ - data['max-select'] = dropdown_options[:data][:'max-select'] if dropdown_options[:data][:'max-select'] - options[:data].merge!(data) - - if directly_invite_members? - - options[:dropdown_class] += ' dropdown-extended-height' - - options[:footer_content] = true - - options[:wrapper_class] = 'js-sidebar-assignee-dropdown' - - options[:toggle_class] += ' js-invite-members-track' - - data['track-event'] = 'show_invite_members' - - options[:data].merge!(data) - - invite_text = _('Invite Members') - - track_label = 'edit_assignee' - - = dropdown_tag(title, options: options) do - %ul.dropdown-footer-list - %li - .js-invite-members-trigger{ data: { trigger_element: 'anchor', - display_text: invite_text, - event: 'click_invite_members', - label: track_label } } - - else - = dropdown_tag(title, options: options) + = render 'shared/issuable/sidebar_user_dropdown', + options: options, + wrapper_class: 'js-sidebar-assignee-dropdown', + track_label: 'edit_assignee', + trigger_source: "#{issuable_type}-assignee-dropdown" diff --git a/app/views/shared/issuable/_sidebar_reviewers.html.haml b/app/views/shared/issuable/_sidebar_reviewers.html.haml index 1a8f1a2639f..bc76d292dd6 100644 --- a/app/views/shared/issuable/_sidebar_reviewers.html.haml +++ b/app/views/shared/issuable/_sidebar_reviewers.html.haml @@ -39,4 +39,8 @@ - data['max-select'] = dropdown_options[:data][:'max-select'] if dropdown_options[:data][:'max-select'] - options[:data].merge!(data) - = dropdown_tag(title, options: options) + = render 'shared/issuable/sidebar_user_dropdown', + options: options, + wrapper_class: 'js-sidebar-reviewer-dropdown', + track_label: 'edit_reviewer', + trigger_source: "#{issuable_type}-reviewer-dropdown" diff --git a/app/views/shared/issuable/_sidebar_user_dropdown.html.haml b/app/views/shared/issuable/_sidebar_user_dropdown.html.haml new file mode 100644 index 00000000000..3a17db5acf8 --- /dev/null +++ b/app/views/shared/issuable/_sidebar_user_dropdown.html.haml @@ -0,0 +1,21 @@ +- options = local_assigns.fetch(:options) +- data = options[:data] + +- if directly_invite_members? + - options[:dropdown_class] += ' dropdown-extended-height' + - options[:footer_content] = true + - options[:wrapper_class] = local_assigns.fetch(:wrapper_class) + - options[:toggle_class] += ' js-invite-members-track' + - data['track-event'] = 'show_invite_members' + - data['track-label'] = local_assigns.fetch(:track_label) + + = dropdown_tag(data['dropdown-title'], options: options) do + %ul.dropdown-footer-list + %li + .js-invite-members-trigger{ data: { trigger_element: 'anchor', + display_text: _('Invite Members'), + event: 'click_invite_members', + trigger_source: local_assigns.fetch(:trigger_source), + label: data['track-label'] } } +- else + = dropdown_tag(data['dropdown-title'], options: options) diff --git a/app/views/shared/issuable/form/_branch_chooser.html.haml b/app/views/shared/issuable/form/_branch_chooser.html.haml index 70e931ac164..1f391e8a321 100644 --- a/app/views/shared/issuable/form/_branch_chooser.html.haml +++ b/app/views/shared/issuable/form/_branch_chooser.html.haml @@ -37,10 +37,12 @@ data: { placeholder: _('Select branch'), endpoint: refs_project_path(@project, sort: 'updated_desc', find: 'branches') }}) - if source_level < target_level - .gl-alert.gl-alert-warning.gl-mt-4 - = sprite_icon('warning', css_class: 'gl-icon gl-alert-icon gl-alert-icon-no-title') - .gl-alert-body - = visibilityMismatchString - %br - = _('Review the target project before submitting to avoid exposing %{source} changes.') % { source: source_visibility } + .gl-alert.gl-alert-warning.gl-alert-not-dismissible.gl-max-content.gl-mt-4 + .gl-alert-container + .gl-alert-content{ role: 'alert' } + = sprite_icon('warning', css_class: 'gl-icon gl-alert-icon gl-alert-icon-no-title') + .gl-alert-body + = visibilityMismatchString + %br + = _('Review the target project before submitting to avoid exposing %{source} changes.') % { source: source_visibility } %hr diff --git a/app/views/shared/issuable/form/_metadata.html.haml b/app/views/shared/issuable/form/_metadata.html.haml index 366e819d252..1043eb49752 100644 --- a/app/views/shared/issuable/form/_metadata.html.haml +++ b/app/views/shared/issuable/form/_metadata.html.haml @@ -2,11 +2,19 @@ - issuable = local_assigns.fetch(:issuable) - presenter = local_assigns.fetch(:presenter) -- return unless can?(current_user, :"admin_#{issuable.to_ability_name}", issuable.project) +- return unless can?(current_user, :"set_#{issuable.to_ability_name}_metadata", issuable) - has_due_date = issuable.has_attribute?(:due_date) - form = local_assigns.fetch(:form) +- if issuable.respond_to?(:confidential) + .form-group.row + .offset-sm-2.col-sm-10 + .form-check + = form.check_box :confidential, class: 'form-check-input' + = form.label :confidential, class: 'form-check-label' do + This issue is confidential and should only be visible to team members with at least Reporter access. + %hr .row %div{ class: (has_due_date ? "col-lg-6" : "col-12") } diff --git a/app/views/shared/issue_type/_emoji_block.html.haml b/app/views/shared/issue_type/_emoji_block.html.haml index ca2749b6bf9..26d30341999 100644 --- a/app/views/shared/issue_type/_emoji_block.html.haml +++ b/app/views/shared/issue_type/_emoji_block.html.haml @@ -4,7 +4,7 @@ .row.gl-m-0.gl-justify-content-space-between .js-noteable-awards = render 'award_emoji/awards_block', awardable: issuable, inline: true, api_awards_path: api_awards_path - .new-branch-col + .new-branch-col.gl-my-2 = 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 } } diff --git a/app/views/shared/members/_group.html.haml b/app/views/shared/members/_group.html.haml index d98ba074687..2aac3a94c49 100644 --- a/app/views/shared/members/_group.html.haml +++ b/app/views/shared/members/_group.html.haml @@ -29,7 +29,7 @@ = group_link.human_access = sprite_icon("chevron-down", css_class: "dropdown-menu-toggle-icon gl-top-3") .dropdown-menu.dropdown-select.dropdown-menu-right.dropdown-menu-selectable - = dropdown_title(_("Change permissions")) + = dropdown_title(_("Change role")) .dropdown-content %ul - Gitlab::Access.options_with_owner.each do |role, role_id| diff --git a/app/views/shared/members/_invite_group.html.haml b/app/views/shared/members/_invite_group.html.haml index d59f2950df6..cefdf825eaa 100644 --- a/app/views/shared/members/_invite_group.html.haml +++ b/app/views/shared/members/_invite_group.html.haml @@ -3,21 +3,25 @@ - submit_url = local_assigns[:submit_url] - group_link_field = local_assigns[:group_link_field] - group_access_field = local_assigns[:group_access_field] +- groups_select_tag_data = local_assigns[:groups_select_tag_data] + .row .col-sm-12 = form_tag submit_url, class: 'invite-group-form js-requires-input', method: :post do .form-group = label_tag group_link_field, _("Select a group to invite"), class: "label-bold" - = groups_select_tag(group_link_field, data: { skip_groups: @skip_groups }, class: 'input-clamp qa-group-select-field', required: true) + = groups_select_tag(group_link_field, data: groups_select_tag_data, class: 'input-clamp qa-group-select-field', required: true) + .form-text.text-muted.gl-mb-3 + = _('Group sharing provides access to all group members (including members who inherited group membership from a parent group).') .form-group - = label_tag group_access_field, _("Max access level"), class: "label-bold" + = label_tag group_access_field, _("Max role"), 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" = 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 } - = _("%{link_start}Read more%{link_end} about role permissions").html_safe % { link_start: link_start, link_end: '</a>'.html_safe } + = _("%{link_start}Learn more%{link_end} about roles.").html_safe % { link_start: link_start, link_end: '</a>'.html_safe } .form-group = label_tag :expires_at, _('Access expiration date'), class: 'label-bold' .clearable-input diff --git a/app/views/shared/members/_invite_member.html.haml b/app/views/shared/members/_invite_member.html.haml index 49111c821b1..e6863ed56a5 100644 --- a/app/views/shared/members/_invite_member.html.haml +++ b/app/views/shared/members/_invite_member.html.haml @@ -10,14 +10,14 @@ = 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') .form-group - = label_tag :access_level, _("Choose a role permission"), class: "label-bold" + = label_tag :access_level, _("Select a role"), 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" = 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 } - = _("%{link_start}Read more%{link_end} about role permissions").html_safe % { link_start: link_start, link_end: '</a>'.html_safe } + = _("%{link_start}Learn more%{link_end} about roles.").html_safe % { link_start: link_start, link_end: '</a>'.html_safe } .form-group = label_tag :expires_at, _('Access expiration date'), class: 'label-bold' .clearable-input diff --git a/app/views/shared/members/_member.html.haml b/app/views/shared/members/_member.html.haml index 88e2a74d235..8f334be0427 100644 --- a/app/views/shared/members/_member.html.haml +++ b/app/views/shared/members/_member.html.haml @@ -81,7 +81,7 @@ = member.human_access = sprite_icon("chevron-down", css_class: "dropdown-menu-toggle-icon gl-top-3") .dropdown-menu.dropdown-select.dropdown-menu-right.dropdown-menu-selectable - = dropdown_title(_("Change permissions")) + = dropdown_title(_("Change role")) .dropdown-content %ul - member.valid_level_roles.each do |role, role_id| diff --git a/app/views/shared/milestones/_issuable.html.haml b/app/views/shared/milestones/_issuable.html.haml index a62ed009552..184904dd7ab 100644 --- a/app/views/shared/milestones/_issuable.html.haml +++ b/app/views/shared/milestones/_issuable.html.haml @@ -3,7 +3,7 @@ - labels = issuable.labels - assignees = issuable.assignees - base_url_args = [project] -- issuable_type_args = base_url_args + [issuable.class.table_name] +- issuable_type_args = base_url_args + [issuable.class.table_name.to_sym] - issuable_url_args = base_url_args + [issuable] %li.issuable-row diff --git a/app/views/shared/milestones/_sidebar.html.haml b/app/views/shared/milestones/_sidebar.html.haml index 0088cd35781..56b2b0d5801 100644 --- a/app/views/shared/milestones/_sidebar.html.haml +++ b/app/views/shared/milestones/_sidebar.html.haml @@ -98,6 +98,7 @@ time_spent: @milestone.total_time_spent, human_time_estimate: @milestone.human_total_time_estimate, human_time_spent: @milestone.human_total_time_spent, + iid: @milestone.iid, limit_to_hours: Gitlab::CurrentSettings.time_tracking_limit_to_hours.to_s } } = render_if_exists 'shared/milestones/weight', milestone: milestone diff --git a/app/views/shared/nav/_scope_menu.html.haml b/app/views/shared/nav/_scope_menu.html.haml index 2f10914ef3d..cbee0e0429c 100644 --- a/app/views/shared/nav/_scope_menu.html.haml +++ b/app/views/shared/nav/_scope_menu.html.haml @@ -1,6 +1,6 @@ -.context-header - = link_to scope_menu.link, **scope_menu.container_html_options do - %span.avatar-container.rect-avatar.s40.project-avatar - = source_icon(scope_menu.container, alt: scope_menu.title, class: 'avatar s40 avatar-tile', width: 40, height: 40) - %span.sidebar-context-title - = scope_menu.title +- if sidebar_refactor_enabled? + = nav_link(**scope_menu.active_routes, html_options: scope_menu.nav_link_html_options) do + = render 'shared/nav/scope_menu_body', scope_menu: scope_menu +- else + .context-header + = render 'shared/nav/scope_menu_body', scope_menu: scope_menu diff --git a/app/views/shared/nav/_scope_menu_body.html.haml b/app/views/shared/nav/_scope_menu_body.html.haml new file mode 100644 index 00000000000..a94c681e2d3 --- /dev/null +++ b/app/views/shared/nav/_scope_menu_body.html.haml @@ -0,0 +1,8 @@ +- avatar_size = sidebar_refactor_disabled? ? 40 : 32 +- avatar_size_class = sidebar_refactor_disabled? ? 's40' : 's32' + += link_to scope_menu.link, **scope_menu.container_html_options, data: { qa_selector: 'project_scope_link' } do + %span{ class: ['avatar-container', 'rect-avatar', 'project-avatar', avatar_size_class] } + = source_icon(scope_menu.container, alt: scope_menu.title, class: ['avatar', 'avatar-tile', avatar_size_class], width: avatar_size, height: avatar_size) + %span.sidebar-context-title + = scope_menu.title diff --git a/app/views/shared/nav/_sidebar.html.haml b/app/views/shared/nav/_sidebar.html.haml index 552dcbfd6fd..54c3b8a281d 100644 --- a/app/views/shared/nav/_sidebar.html.haml +++ b/app/views/shared/nav/_sidebar.html.haml @@ -1,11 +1,13 @@ %aside.nav-sidebar{ class: ('sidebar-collapsed-desktop' if collapsed_sidebar?), **sidebar_tracking_attributes_by_object(sidebar.container), 'aria-label': sidebar.aria_label } .nav-sidebar-inner-scroll - - if sidebar.scope_menu + - if sidebar.scope_menu && sidebar_refactor_disabled? = render partial: 'shared/nav/scope_menu', object: sidebar.scope_menu - elsif sidebar.render_raw_scope_menu_partial = render sidebar.render_raw_scope_menu_partial %ul.sidebar-top-level-items.qa-project-sidebar + - if sidebar.scope_menu && sidebar_refactor_enabled? + = render partial: 'shared/nav/scope_menu', object: sidebar.scope_menu - if sidebar.renderable_menus.any? = render partial: 'shared/nav/sidebar_menu', collection: sidebar.renderable_menus - if sidebar.render_raw_menus_partial diff --git a/app/views/shared/nav/_sidebar_menu.html.haml b/app/views/shared/nav/_sidebar_menu.html.haml index 67c775d1a85..b80bd515a32 100644 --- a/app/views/shared/nav/_sidebar_menu.html.haml +++ b/app/views/shared/nav/_sidebar_menu.html.haml @@ -15,13 +15,13 @@ %ul.sidebar-sub-level-items{ class: ('is-fly-out-only' unless sidebar_menu.has_renderable_items?) } = nav_link(**sidebar_menu.all_active_routes, html_options: { class: 'fly-out-top-item' } ) do - = link_to sidebar_menu.link, **sidebar_menu.collapsed_container_html_options do - %strong.fly-out-top-item-name - = sidebar_menu.title - - if sidebar_menu.has_pill? - %span.badge.badge-pill.count.fly-out-badge{ **sidebar_menu.pill_html_options } - = number_with_delimiter(sidebar_menu.pill_count) + - if sidebar_refactor_disabled? + = link_to sidebar_menu.link, class: "'has-sub-items' if sidebar_menu.has_renderable_items?", **sidebar_menu.collapsed_container_html_options do + = render 'shared/nav/sidebar_menu_collapsed', sidebar_menu: sidebar_menu + - else + %span.fly-out-top-item-container + = render 'shared/nav/sidebar_menu_collapsed', sidebar_menu: sidebar_menu - - if sidebar_menu.has_items? + - if sidebar_menu.has_renderable_items? %li.divider.fly-out-top-item = render partial: 'shared/nav/sidebar_menu_item', collection: sidebar_menu.renderable_items diff --git a/app/views/shared/nav/_sidebar_menu_collapsed.html.haml b/app/views/shared/nav/_sidebar_menu_collapsed.html.haml new file mode 100644 index 00000000000..78567a991df --- /dev/null +++ b/app/views/shared/nav/_sidebar_menu_collapsed.html.haml @@ -0,0 +1,5 @@ +%strong.fly-out-top-item-name + = sidebar_menu.title +- if sidebar_menu.has_pill? + %span.badge.badge-pill.count.fly-out-badge{ **sidebar_menu.pill_html_options } + = number_with_delimiter(sidebar_menu.pill_count) diff --git a/app/views/shared/nav/_sidebar_menu_item.html.haml b/app/views/shared/nav/_sidebar_menu_item.html.haml index 0b0e4c7aec9..674ce593ee2 100644 --- a/app/views/shared/nav/_sidebar_menu_item.html.haml +++ b/app/views/shared/nav/_sidebar_menu_item.html.haml @@ -1,4 +1,4 @@ -= nav_link(**sidebar_menu_item.active_routes) do += nav_link(**sidebar_menu_item.active_routes, html_options: sidebar_menu_item.nav_link_html_options) do = link_to sidebar_menu_item.link, **sidebar_menu_item.container_html_options, data: { qa_selector: 'sidebar_menu_item_link', qa_menu_item: sidebar_menu_item.title } do %span = sidebar_menu_item.title diff --git a/app/views/shared/projects/protected_branches/_update_protected_branch.html.haml b/app/views/shared/projects/protected_branches/_update_protected_branch.html.haml index 6a362866f41..3cbe35e5c15 100644 --- a/app/views/shared/projects/protected_branches/_update_protected_branch.html.haml +++ b/app/views/shared/projects/protected_branches/_update_protected_branch.html.haml @@ -33,6 +33,5 @@ %p.small = _('Members of %{group} can also push to this branch: %{branch}') % { group: (group_push_access_levels.size > 1 ? 'these groups' : 'this group'), branch: group_push_access_levels.map(&:humanize).to_sentence } -- if ::Feature.enabled?(:allow_force_push_to_protected_branches, @project, default_enabled: :yaml) - %td - = render "shared/buttons/project_feature_toggle", is_checked: protected_branch.allow_force_push, label: s_("ProtectedBranch|Toggle allow force push"), class_list: "js-force-push-toggle project-feature-toggle", data: { qa_selector: 'force_push_toggle_button', qa_branch_name: protected_branch.name } +%td + = render "shared/buttons/project_feature_toggle", is_checked: protected_branch.allow_force_push, label: s_("ProtectedBranch|Toggle allowed to force push"), class_list: "js-force-push-toggle project-feature-toggle", data: { qa_selector: 'force_push_toggle_button', qa_branch_name: protected_branch.name } diff --git a/app/views/shared/runners/_runner_type_alert.html.haml b/app/views/shared/runners/_runner_type_alert.html.haml index b83def8b802..e0cc1e924d8 100644 --- a/app/views/shared/runners/_runner_type_alert.html.haml +++ b/app/views/shared/runners/_runner_type_alert.html.haml @@ -5,16 +5,16 @@ = s_('Runners|This runner is available to all groups and projects in your GitLab instance.') .gl-alert-body = s_('Runners|Shared runners are available to every project in a GitLab instance. If you want a runner to build only specific projects, restrict the project in the table below. After you restrict a runner to a project, you cannot change it back to a shared runner.') - = link_to _('Learn more.'), help_page_path('ci/runners/README', anchor: 'shared-runners'), target: '_blank', rel: 'noopener noreferrer' + = link_to _('Learn more.'), help_page_path('ci/runners/runners_scope', anchor: 'shared-runners'), target: '_blank', rel: 'noopener noreferrer' - elsif runner.group_type? %h4.gl-alert-title = s_('Runners|This runner is available to all projects and subgroups in a group.') .gl-alert-body = s_('Runners|Use Group runners when you want all projects in a group to have access to a set of runners.') - = link_to _('Learn more.'), help_page_path('ci/runners/README', anchor: 'group-runners'), target: '_blank', rel: 'noopener noreferrer' + = link_to _('Learn more.'), help_page_path('ci/runners/runners_scope', anchor: 'group-runners'), target: '_blank', rel: 'noopener noreferrer' - else %h4.gl-alert-title = s_('Runners|This runner is associated with specific projects.') .gl-alert-body = s_('Runners|You can set up a specific runner to be used by multiple projects but you cannot make this a shared runner.') - = link_to _('Learn more.'), help_page_path('ci/runners/README', anchor: 'specific-runners'), target: '_blank', rel: 'noopener noreferrer' + = link_to _('Learn more.'), help_page_path('ci/runners/runners_scope', anchor: 'specific-runners'), target: '_blank', rel: 'noopener noreferrer' diff --git a/app/views/shared/wikis/diff.html.haml b/app/views/shared/wikis/diff.html.haml index 19167f04855..0eeceac28c8 100644 --- a/app/views/shared/wikis/diff.html.haml +++ b/app/views/shared/wikis/diff.html.haml @@ -5,7 +5,7 @@ .wiki-page-header.top-area.has-sidebar-toggle.flex-column.flex-lg-row = wiki_sidebar_toggle_button - %h3.page-title.gl-flex-fill-1 + %h3.page-title.gl-flex-grow-1 = link_to_wiki_page @page %span.light · diff --git a/app/views/shared/wikis/edit.html.haml b/app/views/shared/wikis/edit.html.haml index 4bdeee3996f..729646c2731 100644 --- a/app/views/shared/wikis/edit.html.haml +++ b/app/views/shared/wikis/edit.html.haml @@ -7,7 +7,7 @@ .wiki-page-header.top-area.has-sidebar-toggle.flex-column.flex-lg-row = wiki_sidebar_toggle_button - %h3.page-title.gl-flex-fill-1 + %h3.page-title.gl-flex-grow-1 - if @page.persisted? = link_to_wiki_page @page %span.light diff --git a/app/views/shared/wikis/pages.html.haml b/app/views/shared/wikis/pages.html.haml index 1889b6501c9..c1918198594 100644 --- a/app/views/shared/wikis/pages.html.haml +++ b/app/views/shared/wikis/pages.html.haml @@ -5,7 +5,7 @@ - add_page_specific_style 'page_bundles/wiki' .wiki-page-header.top-area.flex-column.flex-lg-row - %h3.page-title.gl-flex-fill-1 + %h3.page-title.gl-flex-grow-1 = s_("Wiki|Wiki Pages") .nav-controls.pb-md-3.pb-lg-0 diff --git a/app/views/users/show.html.haml b/app/views/users/show.html.haml index a5b95883361..effd58ad200 100644 --- a/app/views/users/show.html.haml +++ b/app/views/users/show.html.haml @@ -23,7 +23,7 @@ data: { toggle: 'tooltip', placement: 'bottom', container: 'body' } }> = sprite_icon('error') - else - = link_to new_abuse_report_path(user_id: @user.id, ref_url: request.referrer), class: link_classes + 'btn gl-button btn-default btn-icon', + = link_to new_abuse_report_path(user_id: @user.id, ref_url: request.referer), class: link_classes + 'btn gl-button btn-default btn-icon', title: s_('UserProfile|Report abuse'), data: { toggle: 'tooltip', placement: 'bottom', container: 'body' } do = sprite_icon('error') - if can?(current_user, :read_user_profile, @user) @@ -56,6 +56,9 @@ .user-info .cover-title{ itemprop: 'name' } = @user.name + - if @user.pronouns.present? + %span.gl-font-base.gl-text-gray-500.gl-vertical-align-middle + = "(#{@user.pronouns})" - 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)") |