diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2021-07-20 09:55:51 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2021-07-20 09:55:51 +0000 |
commit | e8d2c2579383897a1dd7f9debd359abe8ae8373d (patch) | |
tree | c42be41678c2586d49a75cabce89322082698334 /app/views/shared | |
parent | fc845b37ec3a90aaa719975f607740c22ba6a113 (diff) | |
download | gitlab-ce-e8d2c2579383897a1dd7f9debd359abe8ae8373d.tar.gz |
Add latest changes from gitlab-org/gitlab@14-1-stable-eev14.1.0-rc42
Diffstat (limited to 'app/views/shared')
45 files changed, 188 insertions, 320 deletions
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 f788bf53a4c..35a3835a522 100644 --- a/app/views/shared/_auto_devops_implicitly_enabled_banner.html.haml +++ b/app/views/shared/_auto_devops_implicitly_enabled_banner.html.haml @@ -10,5 +10,5 @@ %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' + = link_to _('Settings'), project_settings_ci_cd_path(project), class: 'alert-link btn gl-button btn-confirm' + = link_to _('More information'), help_page_path('topics/autodevops/index.md'), target: '_blank', class: 'alert-link btn gl-button btn-default gl-ml-3' diff --git a/app/views/shared/_confirm_your_email_alert.html.haml b/app/views/shared/_confirm_your_email_alert.html.haml new file mode 100644 index 00000000000..b9906a89ce4 --- /dev/null +++ b/app/views/shared/_confirm_your_email_alert.html.haml @@ -0,0 +1,7 @@ +.js-vue-alert{ 'v-cloak': true, + data: { dismissible: 'true', + title: _('Please confirm your email address'), + primary_button_text: _('Resend confirmation email'), + primary_button_link: new_user_confirmation_path, + variant: 'warning'} } + = (_("To continue, you need to select the link in the confirmation email we sent to verify your email address. If you didn't get our email, select %{strongStart}Resend confirmation email.%{strongEnd}") % { strongStart: '<strong>', strongEnd: '</strong>' }).html_safe diff --git a/app/views/shared/_global_alert.html.haml b/app/views/shared/_global_alert.html.haml index bebc72fe428..ea83f5c1656 100644 --- a/app/views/shared/_global_alert.html.haml +++ b/app/views/shared/_global_alert.html.haml @@ -2,19 +2,23 @@ - title = local_assigns.fetch(:title, nil) - variant = local_assigns.fetch(:variant, :info) +- dismissible = local_assigns.fetch(:dismissible, true) - 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] +- alert_root_class = 'gl-alert-layout-limited' if fluid_layout +- alert_container_class = [container_class, @content_class] unless fluid_layout || local_assigns.fetch(:is_contained, false) -%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 } +%div{ role: 'alert', class: [alert_root_class, 'gl-alert-max-content', 'gl-alert', "gl-alert-#{variant}", alert_class], data: alert_data } + .gl-alert-container{ class: alert_container_class } + = sprite_icon(icon, size: 16, css_class: "gl-alert-icon#{' gl-alert-icon-no-title' if title.nil?}") + - if dismissible + %button.btn.gl-dismiss-btn.btn-default.btn-sm.gl-button.btn-default-tertiary.btn-icon.js-close{ type: 'button', aria: { label: _('Dismiss') }, class: close_button_class, data: close_button_data } = sprite_icon('close', size: 16) + .gl-alert-content{ role: 'alert' } - if title - .gl-alert-title + %h4.gl-alert-title = title = yield diff --git a/app/views/shared/_group_form.html.haml b/app/views/shared/_group_form.html.haml index 7055dc8142a..e96372a29db 100644 --- a/app/views/shared/_group_form.html.haml +++ b/app/views/shared/_group_form.html.haml @@ -28,8 +28,7 @@ title: _('Please choose a group URL with no special characters.'), "data-bind-in" => "#{'create_chat_team' if Gitlab.config.mattermost.enabled}" %p.validation-error.gl-field-error.field-validation.hide - = _('Group path is already taken. Suggestions: ') - %span.gl-path-suggestions + = _("Group path is already taken. We've suggested one that is available.") %p.validation-success.gl-field-success.field-validation.hide= _('Group path is available.') %p.validation-pending.gl-field-error-ignore.field-validation.hide= _('Checking group URL availability...') diff --git a/app/views/shared/_import_form.html.haml b/app/views/shared/_import_form.html.haml index 65e02341936..f03314563cb 100644 --- a/app/views/shared/_import_form.html.haml +++ b/app/views/shared/_import_form.html.haml @@ -8,7 +8,18 @@ = _('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 + = render 'shared/global_alert', + variant: :warning, + alert_class: 'gl-mt-3 js-import-url-warning hide', + dismissible: false, + close_button_class: 'js-close-2fa-enabled-success-alert' do + .gl-alert-body + = s_('Import|A repository URL usually ends in a .git suffix, although this is not required. Double check to make sure your repository URL is correct.') + .gl-alert.gl-alert-not-dismissible.gl-alert-warning.gl-mt-3.hide#project_import_url_warning + .gl-alert-container + = sprite_icon('warning-solid', css_class: 'gl-icon s16 gl-alert-icon gl-alert-icon-no-title') + .gl-alert-content{ role: 'alert' } .row .form-group.col-md-6 = f.label :import_url_user, class: 'label-bold' do diff --git a/app/views/shared/_new_project_item_select.html.haml b/app/views/shared/_new_project_item_select.html.haml index 3817ff8a56d..d5f4add2796 100644 --- a/app/views/shared/_new_project_item_select.html.haml +++ b/app/views/shared/_new_project_item_select.html.haml @@ -1,5 +1,5 @@ - if any_projects?(@projects) - .project-item-select-holder.btn-group.gl-ml-auto.gl-mr-auto.gl-py-3.gl-relative.gl-display-flex.gl-overflow-hidden + .project-item-select-holder.btn-group.gl-ml-auto.gl-mr-auto.gl-relative.gl-overflow-hidden{ class: 'gl-display-flex!' } %a.btn.gl-button.btn-confirm.new-project-item-link.block-truncated.qa-new-project-item-link{ href: '', data: { label: local_assigns[:label], type: local_assigns[:type] }, class: "gl-m-0!" } = loading_icon(color: 'light') = project_select_tag :project_path, class: "project-item-select gl-absolute! gl-visibility-hidden", data: { include_groups: local_assigns[:include_groups], order_by: 'last_activity_at', relative_path: local_assigns[:path], with_shared: local_assigns[:with_shared], include_projects_in_subgroups: local_assigns[:include_projects_in_subgroups] }, with_feature_enabled: local_assigns[:with_feature_enabled] diff --git a/app/views/shared/_project_limit.html.haml b/app/views/shared/_project_limit.html.haml index 9110f5a7f31..90612ba623f 100644 --- a/app/views/shared/_project_limit.html.haml +++ b/app/views/shared/_project_limit.html.haml @@ -1,8 +1,10 @@ - if cookies[:hide_project_limit_message].blank? && !current_user.hide_project_limit && !current_user.can_create_project? && current_user.projects_limit > 0 - .project-limit-message.gl-alert.gl-alert-warning.gl-display-none.gl-sm-display-block - = _("You won't be able to create new projects because you have reached your project limit.") - - .float-right - = link_to _("Don't show again"), profile_path(user: {hide_project_limit: true}), method: :put, class: 'alert-link' - | - = link_to _('Remind later'), '#', class: 'hide-project-limit-message alert-link' + = render 'shared/global_alert', + variant: :warning, + dismissible: false, + alert_class: 'project-limit-message' do + .gl-alert-body + = _("You won't be able to create new projects because you have reached your project limit.") + .gl-alert-actions + = link_to _('Remind later'), '#', class: 'alert-link hide-project-limit-message btn gl-button btn-confirm' + = link_to _("Don't show again"), profile_path(user: {hide_project_limit: true}), method: :put, class: 'alert-link btn gl-button btn-default gl-ml-3' diff --git a/app/views/shared/_ping_consent.html.haml b/app/views/shared/_service_ping_consent.html.haml index d0f1e4d7221..77597124e5c 100644 --- a/app/views/shared/_ping_consent.html.haml +++ b/app/views/shared/_service_ping_consent.html.haml @@ -1,5 +1,5 @@ - if session[:ask_for_usage_stats_consent] - .ping-consent-message.gl-alert.gl-alert-info + .service-ping-consent-message.gl-alert.gl-alert-info = sprite_icon('information-o', css_class: 'gl-icon gl-alert-icon gl-alert-icon-no-title') %button.js-close.gl-alert-dismiss{ type: 'button', 'aria-label' => _('Dismiss') } = sprite_icon('close', css_class: 'gl-icon') @@ -8,7 +8,7 @@ - settings_link = link_to _('your settings'), metrics_and_profiling_admin_application_settings_path(anchor: 'js-usage-settings'), class: 'gl-link' = s_('To help improve GitLab, we would like to periodically %{docs_link}. This can be changed at any time in %{settings_link}.').html_safe % { docs_link: docs_link, settings_link: settings_link } .gl-alert-actions.gl-mt-3 - - send_usage_data_path = admin_application_settings_path(application_setting: { version_check_enabled: 1, usage_ping_enabled: 1 }) + - send_service_data_path = admin_application_settings_path(application_setting: { version_check_enabled: 1, usage_ping_enabled: 1 }) - not_now_path = admin_application_settings_path(application_setting: { version_check_enabled: 0, usage_ping_enabled: 0 }) - = link_to _("Send usage data"), send_usage_data_path, 'data-url' => admin_application_settings_path, method: :put, 'data-check-enabled': true, 'data-ping-enabled': true, class: 'js-usage-consent-action alert-link btn gl-button btn-info' - = link_to _("Don't send usage data"), not_now_path, 'data-url' => admin_application_settings_path, method: :put, 'data-check-enabled': false, 'data-ping-enabled': false, class: 'js-usage-consent-action alert-link btn gl-button btn-default gl-ml-2' + = link_to _("Send service data"), send_service_data_path, 'data-url' => admin_application_settings_path, method: :put, 'data-check-enabled': true, 'data-service-ping-enabled': true, class: 'js-service-ping-consent-action alert-link btn gl-button btn-info' + = link_to _("Don't send service data"), not_now_path, 'data-url' => admin_application_settings_path, method: :put, 'data-check-enabled': false, 'data-service-ping-enabled': false, class: 'js-service-ping-consent-action alert-link btn gl-button btn-default gl-ml-2' diff --git a/app/views/shared/_sidebar_toggle_button.html.haml b/app/views/shared/_sidebar_toggle_button.html.haml index a5a411db8a0..b3d6c4c327b 100644 --- a/app/views/shared/_sidebar_toggle_button.html.haml +++ b/app/views/shared/_sidebar_toggle_button.html.haml @@ -1,7 +1,5 @@ %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') - - 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 diff --git a/app/views/shared/access_tokens/_form.html.haml b/app/views/shared/access_tokens/_form.html.haml index 88c24a27497..6435475a9a3 100644 --- a/app/views/shared/access_tokens/_form.html.haml +++ b/app/views/shared/access_tokens/_form.html.haml @@ -1,5 +1,9 @@ - title = local_assigns.fetch(:title, _('Add a %{type}') % { type: type }) - prefix = local_assigns.fetch(:prefix, :personal_access_token) +- help_path = local_assigns.fetch(:help_path) +- project = local_assigns.fetch(:project, false) +- access_levels = local_assigns.fetch(:access_levels, false) +- default_access_level = local_assigns.fetch(:default_access_level, false) %h5.gl-mt-0 = title @@ -11,13 +15,16 @@ = form_errors(token) .row - .form-group.col-md-6 - = f.label :name, _('Name'), class: 'label-bold' - = f.text_field :name, class: 'form-control gl-form-input', required: true, data: { qa_selector: 'access_token_name_field' } + .form-group.col + .row + = f.label :name, _('Token name'), class: 'label-bold col-md-12' + .col-md-6 + = f.text_field :name, class: 'form-control gl-form-input', required: true, data: { qa_selector: 'access_token_name_field' }, :'aria-describedby' => 'access_token_help_text' + %span.form-text.text-muted.col-md-12#access_token_help_text= _('For example, the application using the token or the purpose of the token.') .row .form-group.col-md-6 - = f.label :expires_at, _('Expires at'), class: 'label-bold' + = f.label :expires_at, _('Expiration date'), class: 'label-bold' .input-icon-wrapper = render_if_exists 'personal_access_tokens/callout_max_personal_access_token_lifetime' @@ -25,8 +32,20 @@ .js-access-tokens-expires-at = f.text_field :expires_at, class: 'datepicker gl-datepicker-input form-control gl-form-input', placeholder: 'YYYY-MM-DD', autocomplete: 'off', data: { js_name: 'expiresAt' } + - if project + .row + .form-group.col-md-6 + = label_tag :access_level, _("Select a role"), class: "label-bold" + .select-wrapper + = select_tag :"#{prefix}[access_level]", options_for_select(access_levels, default_access_level), class: "form-control project-access-select select-control", data: { qa_selector: 'access_token_access_level' } + = sprite_icon('chevron-down', css_class: "gl-icon gl-absolute gl-top-3 gl-right-3 gl-text-gray-200") + .form-group - = f.label :scopes, _('Scopes'), class: 'label-bold' + %b{ :'aria-describedby' => 'select_scope_help_text' } + = s_('Tokens|Select scopes') + %p.text-secondary#select_scope_help_text + = s_('Tokens|Scopes set the permission levels granted to the token.') + = link_to "Learn more.", help_path, target: '_blank' = render 'shared/tokens/scopes_form', prefix: prefix, token: token, scopes: scopes - if prefix == :personal_access_token && Feature.enabled?(:personal_access_tokens_scoped_to_projects, current_user) diff --git a/app/views/shared/access_tokens/_table.html.haml b/app/views/shared/access_tokens/_table.html.haml index 9c59d5ae1fa..1f08bff9858 100644 --- a/app/views/shared/access_tokens/_table.html.haml +++ b/app/views/shared/access_tokens/_table.html.haml @@ -1,10 +1,15 @@ - no_active_tokens_message = local_assigns.fetch(:no_active_tokens_message, _('This user has no active %{type}.') % { type: type_plural }) - impersonation = local_assigns.fetch(:impersonation, false) +- project = local_assigns.fetch(:project, false) +- personal = !impersonation && !project %hr %h5 = _('Active %{type} (%{token_length})') % { type: type_plural, token_length: active_tokens.length } +- if personal && !personal_access_token_expiration_enforced? + %p.profile-settings-content + = _("Personal access tokens are not revoked upon expiration.") - if impersonation %p.profile-settings-content = _("To see all the user's personal access tokens you must impersonate them first.") @@ -14,18 +19,21 @@ %table.table.active-tokens %thead %tr - %th= _('Name') + %th= _('Token name') + %th= _('Scopes') %th= s_('AccessTokens|Created') %th = _('Last Used') = link_to sprite_icon('question-o'), help_page_path('user/profile/personal_access_tokens.md', anchor: 'view-the-last-time-a-token-was-used'), target: '_blank' %th= _('Expires') - %th= _('Scopes') + - if project + %th= _('Role') %th %tbody - active_tokens.each do |token| %tr %td= token.name + %td= token.scopes.present? ? token.scopes.join(', ') : _('no scopes selected') %td= token.created_at.to_date.to_s(:medium) %td - if token.last_used_at? @@ -42,8 +50,9 @@ = _('In %{time_to_now}') % { time_to_now: distance_of_time_in_words_to_now(token.expires_at) } - else %span.token-never-expires-label= _('Never') - %td= token.scopes.present? ? token.scopes.join(', ') : _('no scopes selected') - %td= link_to _('Revoke'), revoke_route_helper.call(token), method: :put, class: 'gl-button btn btn-danger btn-sm float-right qa-revoke-button', data: { confirm: _('Are you sure you want to revoke this %{type}? This action cannot be undone.') % { type: type } } + - if project + %td= project.project_member(token.user).human_access + %td= link_to _('Revoke'), revoke_route_helper.call(token), method: :put, class: "gl-button btn btn-danger btn-sm float-right qa-revoke-button #{'btn-danger-secondary' unless token.expires?}", data: { confirm: _('Are you sure you want to revoke this %{type}? This action cannot be undone.') % { type: type } } - else .settings-message.text-center = no_active_tokens_message diff --git a/app/views/shared/boards/_show.html.haml b/app/views/shared/boards/_show.html.haml index c1a50cfe718..9ccd5655fb0 100644 --- a/app/views/shared/boards/_show.html.haml +++ b/app/views/shared/boards/_show.html.haml @@ -2,6 +2,7 @@ - group = local_assigns.fetch(:group, false) - @no_breadcrumb_container = true - @no_container = true +- @content_wrapper_class = "#{@content_wrapper_class} gl-relative" - @content_class = "issue-boards-content js-focus-mode-board" - if board.to_type == "EpicBoard" - breadcrumb_title _("Epic Boards") @@ -9,6 +10,9 @@ - breadcrumb_title _("Issue Boards") = render 'shared/alerts/positioning_disabled' += content_for :after_content do + #js-right-sidebar-portal + - page_title("#{board.name}", _("Boards")) - add_page_specific_style 'page_bundles/boards' diff --git a/app/views/shared/deploy_keys/_form.html.haml b/app/views/shared/deploy_keys/_form.html.haml index 452e54f9cd4..bf2514f8b0d 100644 --- a/app/views/shared/deploy_keys/_form.html.haml +++ b/app/views/shared/deploy_keys/_form.html.haml @@ -13,7 +13,7 @@ = form.label :key, class: 'col-form-label col-sm-2' .col-sm-10 %p.light - - link_start = "<a href='#{help_page_path('ssh/README')}' target='_blank' rel='noreferrer noopener'>".html_safe + - link_start = "<a href='#{help_page_path('ssh/index')}' target='_blank' rel='noreferrer noopener'>".html_safe - link_end = '</a>' = _('Paste a public key here. %{link_start}How do I generate it?%{link_end}').html_safe % { link_start: link_start, link_end: link_end.html_safe } = form.text_area :key, class: 'form-control gl-form-input thin_area', rows: 5, data: { qa_selector: 'deploy_key_field' } diff --git a/app/views/shared/deploy_keys/_project_group_form.html.haml b/app/views/shared/deploy_keys/_project_group_form.html.haml index 0c671b4a1c0..8da48a7936a 100644 --- a/app/views/shared/deploy_keys/_project_group_form.html.haml +++ b/app/views/shared/deploy_keys/_project_group_form.html.haml @@ -9,7 +9,7 @@ .form-group.row %p.light.gl-mb-0 = _('Paste a public key here.') - = link_to _('How do I generate it?'), help_page_path("ssh/README") + = link_to _('How do I generate it?'), help_page_path("ssh/index") = f.fields_for :deploy_keys_projects do |deploy_keys_project_form| .form-group.row diff --git a/app/views/shared/deploy_tokens/_form.html.haml b/app/views/shared/deploy_tokens/_form.html.haml index 976776ccc62..5d351bd11fd 100644 --- a/app/views/shared/deploy_tokens/_form.html.haml +++ b/app/views/shared/deploy_tokens/_form.html.haml @@ -38,7 +38,7 @@ - if packages_registry_enabled?(group_or_project) %fieldset.form-group.form-check - = f.check_box :read_package_registry, class: 'form-check-input' + = f.check_box :read_package_registry, class: 'form-check-input', data: { qa_selector: 'deploy_token_read_package_registry_checkbox' } = f.label :read_package_registry, 'read_package_registry', class: 'label-bold form-check-label' .text-secondary= s_('DeployTokens|Allows read access to the package registry.') diff --git a/app/views/shared/empty_states/_issues.html.haml b/app/views/shared/empty_states/_issues.html.haml index 13d9d71d58e..9842457a2eb 100644 --- a/app/views/shared/empty_states/_issues.html.haml +++ b/app/views/shared/empty_states/_issues.html.haml @@ -47,7 +47,7 @@ = link_to _('New issue'), button_path, class: 'gl-button btn btn-confirm', id: 'new_issue_link' - if show_import_button - .js-csv-import-export-buttons{ data: { show_import_button: show_import_button.to_s, issuable_type: issuable_type, import_csv_issues_path: import_csv_namespace_project_issues_path, can_edit: can_edit.to_s, project_import_jira_path: project_import_jira_path(@project), max_attachment_size: number_to_human_size(Gitlab::CurrentSettings.max_attachment_size.megabytes), container_class: 'gl-display-inline-flex gl-vertical-align-middle', show_label: 'true' } } + .js-csv-import-export-buttons{ data: { show_import_button: 'true', issuable_type: issuable_type, import_csv_issues_path: import_csv_namespace_project_issues_path, can_edit: can_edit.to_s, project_import_jira_path: project_import_jira_path(@project), max_attachment_size: number_to_human_size(Gitlab::CurrentSettings.max_attachment_size.megabytes), container_class: 'gl-display-inline-flex gl-vertical-align-middle', show_label: 'true' } } %hr %p.gl-text-center.gl-mb-0 %strong diff --git a/app/views/shared/issuable/_bulk_update_sidebar.html.haml b/app/views/shared/issuable/_bulk_update_sidebar.html.haml index bbbb728d048..3a526a9f306 100644 --- a/app/views/shared/issuable/_bulk_update_sidebar.html.haml +++ b/app/views/shared/issuable/_bulk_update_sidebar.html.haml @@ -6,21 +6,13 @@ = form_tag [:bulk_update, @project, type], method: :post, class: "bulk-update" do .block.issuable-sidebar-header .filter-item.inline.update-issues-btn.float-left - = button_tag _('Update all'), class: "gl-button btn update-selected-issues btn-confirm", disabled: true + = button_tag _('Update all'), class: "gl-button btn js-update-selected-issues btn-confirm", disabled: true = button_tag _('Cancel'), class: "gl-button btn btn-default js-bulk-update-menu-hide float-right" - if params[:state] != 'merged' .block .title = _('Status') - .filter-item - = dropdown_tag(_("Select status"), options: { toggle_class: "js-issue-status", title: _("Change status"), dropdown_class: "dropdown-menu-status dropdown-menu-selectable", data: { field_name: "update[state_event]", default_label: _("Status") } } ) do - %ul - %li - %a{ href: "#", data: { id: "reopen" } } - = _('Open') - %li - %a{ href: "#", data: { id: "close" } } - = _('Closed') + .js-issue-status .block .title = _('Assignee') diff --git a/app/views/shared/issuable/_form.html.haml b/app/views/shared/issuable/_form.html.haml index e79719d41b0..6aa80e6808d 100644 --- a/app/views/shared/issuable/_form.html.haml +++ b/app/views/shared/issuable/_form.html.haml @@ -6,11 +6,16 @@ = form_errors(issuable) - if @conflict - .gl-alert.gl-alert-danger.gl-mb-5 - Someone edited the #{issuable.class.model_name.human.downcase} the same time you did. - Please check out - = link_to "the #{issuable.class.model_name.human.downcase}", polymorphic_path([@project, issuable]), target: "_blank", rel: 'noopener noreferrer' - and make sure your changes will not unintentionally remove theirs + = render 'shared/global_alert', + variant: :danger, + dismissible: false, + is_contained: true, + alert_class: 'gl-mb-5' do + .gl-alert-body + Someone edited the #{issuable.class.model_name.human.downcase} the same time you did. + Please check out + = link_to "the #{issuable.class.model_name.human.downcase}", polymorphic_path([@project, issuable]), target: "_blank", rel: 'noopener noreferrer' + and make sure your changes will not unintentionally remove theirs = render 'shared/issuable/form/branch_chooser', issuable: issuable, form: form diff --git a/app/views/shared/issuable/_invite_members_trigger.html.haml b/app/views/shared/issuable/_invite_members_trigger.html.haml deleted file mode 100644 index 5dd6ec0addf..00000000000 --- a/app/views/shared/issuable/_invite_members_trigger.html.haml +++ /dev/null @@ -1,8 +0,0 @@ -- return unless can_import_members? - -.js-invite-members-modal{ data: { id: project.id, - name: project.name, - is_project: 'true', - access_levels: ProjectMember.access_level_roles.to_json, - default_access_level: Gitlab::Access::GUEST, - help_link: help_page_url('user/permissions') } } diff --git a/app/views/shared/issuable/_search_bar.html.haml b/app/views/shared/issuable/_search_bar.html.haml index c03697a4076..737a0ff8c5b 100644 --- a/app/views/shared/issuable/_search_bar.html.haml +++ b/app/views/shared/issuable/_search_bar.html.haml @@ -25,6 +25,8 @@ = check_box_tag checkbox_id, nil, false, class: "check-all-issues left" - if is_epic_board #js-board-filtered-search{ data: { full_path: @group&.full_path } } + - elsif Feature.enabled?(:issue_boards_filtered_search, board&.resource_parent) && board + #js-issue-board-filtered-search - else .issues-other-filters.filtered-search-wrapper.d-flex.flex-column.flex-md-row .filtered-search-box diff --git a/app/views/shared/issuable/_sidebar.html.haml b/app/views/shared/issuable/_sidebar.html.haml index 416c788603a..c76aa176696 100644 --- a/app/views/shared/issuable/_sidebar.html.haml +++ b/app/views/shared/issuable/_sidebar.html.haml @@ -10,19 +10,13 @@ %aside.right-sidebar.js-right-sidebar.js-issuable-sidebar{ data: { signed: { in: signed_in }, issuable_type: issuable_type }, class: sidebar_gutter_collapsed_class, 'aria-live' => 'polite', 'aria-label': issuable_type } .issuable-sidebar - .block.issuable-sidebar-header - - if signed_in - %span.issuable-header-text.hide-collapsed.float-left - = _('To Do') + .issuable-sidebar-header.gl-py-3 %a.gutter-toggle.float-right.js-sidebar-toggle.has-tooltip{ role: "button", href: "#", "aria-label" => _('Toggle sidebar'), title: sidebar_gutter_tooltip_text, data: { container: 'body', placement: 'left', boundary: 'viewport' } } = sidebar_gutter_toggle_icon - if signed_in - = render "shared/issuable/sidebar_todo", issuable_sidebar: issuable_sidebar + .js-issuable-todo{ data: { project_path: issuable_sidebar[:project_full_path], iid: issuable_sidebar[:iid], id: issuable_sidebar[:id] } } = form_for issuable_type, url: issuable_sidebar[:issuable_json_path], remote: true, html: { class: 'issuable-context-form inline-update js-issuable-update' } do |f| - - if signed_in - .block.todo.hide-expanded - = render "shared/issuable/sidebar_todo", issuable_sidebar: issuable_sidebar, is_collapsed: true .block.assignee.qa-assignee-block = render "shared/issuable/sidebar_assignees", issuable_sidebar: issuable_sidebar, assignees: assignees, signed_in: signed_in @@ -34,34 +28,11 @@ = 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] || {} .block.milestone{ :class => ("gl-border-b-0!" if issuable_sidebar[:supports_iterations]), data: { qa_selector: 'milestone_block' } } - .sidebar-collapsed-icon.has-tooltip{ title: sidebar_milestone_tooltip_label(milestone), data: { container: 'body', html: 'true', placement: 'left', boundary: 'viewport' } } - = sprite_icon('clock') - %span.milestone-title.collapse-truncated-title - - if milestone.present? - = milestone[:title] - - else - = _('None') - .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 - = link_to _('Edit'), '#', class: 'js-sidebar-dropdown-toggle edit-link float-right', data: { qa_selector: "edit_milestone_link", track_label: "right_sidebar", track_property: "milestone", track_event: "click_edit_button", track_value: "" } - .value.hide-collapsed - - if milestone.present? - - milestone_title = milestone[:expired] ? _("%{milestone_name} (Past due)").html_safe % { milestone_name: milestone[:title] } : milestone[:title] - = link_to milestone_title, milestone[:web_url], class: "bold has-tooltip", title: sidebar_milestone_remaining_days(milestone), data: { container: "body", html: 'true', boundary: 'viewport', qa_selector: 'milestone_link', qa_title: milestone[:title] } - - else - %span.no-value - = _('None') - - .selectbox.hide-collapsed - = f.hidden_field 'milestone_id', value: milestone[:id], id: nil - = dropdown_tag('Milestone', options: { title: _('Assign milestone'), toggle_class: 'js-milestone-select js-extra-options', filter: true, dropdown_class: 'dropdown-menu-selectable', placeholder: _('Search milestones'), data: { show_no: true, field_name: "#{issuable_type}[milestone_id]", project_id: issuable_sidebar[:project_id], issuable_id: issuable_sidebar[:id], ability_name: issuable_type, issue_update: issuable_sidebar[:issuable_json_path], use_id: true, default_no: true, selected: milestone[:title], null_default: true, display: 'static' }}) + .js-milestone-select{ data: { can_edit: can_edit_issuable.to_s, project_path: issuable_sidebar[:project_full_path], issue_iid: issuable_sidebar[:iid] } } - if @project.group.present? && issuable_sidebar[:supports_iterations] - .block{ class: 'gl-pt-0!' } + .block{ class: 'gl-pt-0!', data: { qa_selector: 'iteration_container' } } = render_if_exists 'shared/issuable/iteration_select', can_edit: can_edit_issuable.to_s, group_path: @project.group.full_path, project_path: issuable_sidebar[:project_full_path], issue_iid: issuable_sidebar[:iid], issuable_type: issuable_type - if issuable_sidebar[:supports_time_tracking] @@ -75,13 +46,13 @@ .js-sidebar-labels{ data: sidebar_labels_data(issuable_sidebar, @project) } - = render_if_exists 'shared/issuable/sidebar_weight', issuable_sidebar: issuable_sidebar + = render_if_exists 'shared/issuable/sidebar_weight', issuable_sidebar: issuable_sidebar, can_edit: can_edit_issuable.to_s, project_path: issuable_sidebar[:project_full_path], issue_iid: issuable_sidebar[:iid] - if issuable_sidebar[:supports_severity] #js-severity - if issuable_sidebar.dig(:features_available, :health_status) - .js-sidebar-status-entry-point + .js-sidebar-status-entry-point{ data: sidebar_status_data(issuable_sidebar, @project) } - if issuable_sidebar.has_key?(:confidential) %script#js-confidential-issue-data{ type: "application/json" }= { is_confidential: issuable_sidebar[:confidential], is_editable: can_edit_issuable }.to_json.html_safe diff --git a/app/views/shared/issuable/_sidebar_todo.html.haml b/app/views/shared/issuable/_sidebar_todo.html.haml deleted file mode 100644 index a867421298b..00000000000 --- a/app/views/shared/issuable/_sidebar_todo.html.haml +++ /dev/null @@ -1,15 +0,0 @@ -- is_collapsed = local_assigns.fetch(:is_collapsed, false) -- has_todo = !!issuable_sidebar.dig(:current_user, :todo, :id) - -- todo_button_data = issuable_todo_button_data(issuable_sidebar, is_collapsed) -- button_title = has_todo ? todo_button_data[:mark_text] : todo_button_data[:todo_text] -- button_icon = has_todo ? todo_button_data[:mark_icon] : todo_button_data[:todo_icon] - -%button.issuable-todo-btn.js-issuable-todo{ type: 'button', - class: (is_collapsed ? 'btn-blank sidebar-collapsed-icon dont-change-state has-tooltip' : 'gl-button btn btn-default issuable-header-btn float-right'), - title: button_title, - 'aria-label' => button_title, - data: todo_button_data } - %span.issuable-todo-inner.js-issuable-todo-inner< - = is_collapsed ? button_icon : button_title - = loading_icon(css_class: is_collapsed ? '' : 'gl-ml-3') diff --git a/app/views/shared/issuable/_sort_dropdown.html.haml b/app/views/shared/issuable/_sort_dropdown.html.haml index 9e3caf62d77..caf271e9ee9 100644 --- a/app/views/shared/issuable/_sort_dropdown.html.haml +++ b/app/views/shared/issuable/_sort_dropdown.html.haml @@ -1,6 +1,7 @@ - sort_value = @sort - sort_title = issuable_sort_option_title(sort_value) - viewing_issues = controller.controller_name == 'issues' || controller.action_name == 'issues' +- viewing_merge_requests = controller.controller_name == 'merge_requests' .dropdown.inline.gl-ml-3.issue-sort-dropdown .btn-group{ role: 'group' } @@ -17,6 +18,7 @@ = sortable_item(sort_title_due_date, page_filter_path(sort: sort_value_due_date), sort_title) if viewing_issues = sortable_item(sort_title_popularity, page_filter_path(sort: sort_value_popularity), sort_title) = sortable_item(sort_title_label_priority, page_filter_path(sort: sort_value_label_priority), sort_title) + = sortable_item(sort_title_merged_date, page_filter_path(sort: sort_value_merged_date), sort_title) if viewing_merge_requests = sortable_item(sort_title_relative_position, page_filter_path(sort: sort_value_relative_position), sort_title) if viewing_issues = render_if_exists('shared/ee/issuable/sort_dropdown', viewing_issues: viewing_issues, sort_title: sort_title) = issuable_sort_direction_button(sort_value) diff --git a/app/views/shared/issue_type/_details_content.html.haml b/app/views/shared/issue_type/_details_content.html.haml index ceedb5e5c59..0bf002fbbc5 100644 --- a/app/views/shared/issue_type/_details_content.html.haml +++ b/app/views/shared/issue_type/_details_content.html.haml @@ -20,6 +20,9 @@ #js-related-merge-requests{ data: { endpoint: expose_path(api_v4_projects_issues_related_merge_requests_path(id: @project.id, issue_iid: issuable.iid)), project_namespace: @project.namespace.path, project_path: @project.path } } + - if can?(current_user, :admin_feature_flags_issue_links, @project) + = render_if_exists 'projects/issues/related_feature_flags' + - if can?(current_user, :download_code, @project) - add_page_startup_api_call related_branches_path #related-branches{ data: { url: related_branches_path } } diff --git a/app/views/shared/members/_group.html.haml b/app/views/shared/members/_group.html.haml deleted file mode 100644 index 2aac3a94c49..00000000000 --- a/app/views/shared/members/_group.html.haml +++ /dev/null @@ -1,50 +0,0 @@ -- group_link = local_assigns[:group_link] -- group = group_link.shared_with_group -- can_admin_member = local_assigns[:can_admin_member] -- group_link_path = local_assigns[:group_link_path] -- dom_id = "group_member_#{group_link.id}" - --# Note this is just for groups. For individual members please see shared/members/_member - -%li.member.js-member.group_member.py-2.px-3.d-flex.flex-column.flex-md-row{ id: dom_id, data: { qa_selector: 'group_row' } } - %span.list-item-name.mb-2.m-md-0 - = group_icon(group, class: "avatar s40 flex-shrink-0 flex-grow-0", alt: '') - .user-info - = link_to group.full_name, group_path(group), class: 'member' - .cgray - Given access #{time_ago_with_tooltip(group_link.created_at)} - %span.js-expires-in{ class: ('gl-display-none' unless group_link.expires?) } - · - %span.js-expires-in-text{ class: ('text-warning' if group_link.expires_soon?) } - - if group_link.expires? - = _("Expires in %{expires_at}").html_safe % { expires_at: distance_of_time_in_words_to_now(group_link.expires_at) } - .controls.member-controls.align-items-center - = form_tag group_link_path, method: :put, remote: true, class: 'js-edit-member-form form-group d-sm-flex' do - = hidden_field_tag "group_link[group_access]", group_link.group_access - .member-form-control.dropdown.mr-sm-2.d-sm-inline-block - %button.dropdown-menu-toggle.js-member-permissions-dropdown{ type: "button", - disabled: !can_admin_member, - data: { toggle: "dropdown", field_name: "group_link[group_access]" } } - %span.dropdown-toggle-text - = 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 role")) - .dropdown-content - %ul - - Gitlab::Access.options_with_owner.each do |role, role_id| - %li - = link_to role, '#', - class: ("is-active" if group_link.group_access == role_id), - data: { id: role_id, el_id: dom_id } - .clearable-input.member-form-control.d-sm-inline-block - = text_field_tag 'group_link[expires_at]', group_link.expires_at, class: 'form-control js-access-expiration-date js-member-update-control', placeholder: _('Expiration date'), id: "member_expires_at_#{group.id}", disabled: !can_admin_member - = sprite_icon('close', size: 16, css_class: 'clear-icon js-clear-input gl-text-gray-200') - - if can_admin_member - = link_to group_link_path, - method: :delete, - data: { confirm: _("Are you sure you want to remove %{group_name}?") % { group_name: group.name }, qa_selector: 'delete_group_access_link' }, - class: 'gl-button btn btn-danger m-0 ml-sm-2 align-self-center' do - %span.d-block.d-sm-none - = _("Delete") - = sprite_icon('remove', css_class: 'd-none d-sm-block') diff --git a/app/views/shared/members/_manage_access_button.html.haml b/app/views/shared/members/_manage_access_button.html.haml new file mode 100644 index 00000000000..13509a7480a --- /dev/null +++ b/app/views/shared/members/_manage_access_button.html.haml @@ -0,0 +1,7 @@ +- path = local_assigns.fetch(:path, nil) + +.gl-float-right + = link_to path, class: 'btn btn-default btn-sm gl-button' do + = sprite_icon('pencil-square', css_class: 'gl-icon gl-button-icon') + %span.gl-button-text + = _('Manage access') diff --git a/app/views/shared/members/_member.html.haml b/app/views/shared/members/_member.html.haml index 8f334be0427..ba0e5e492f4 100644 --- a/app/views/shared/members/_member.html.haml +++ b/app/views/shared/members/_member.html.haml @@ -1,5 +1,4 @@ - show_roles = local_assigns.fetch(:show_roles, true) -- show_controls = local_assigns.fetch(:show_controls, true) - force_mobile_view = local_assigns.fetch(:force_mobile_view, false) - member = local_assigns.fetch(:member) - current_user_is_group_owner = local_assigns.fetch(:current_user_is_group_owner, false) @@ -7,11 +6,10 @@ - group = local_assigns.fetch(:group) - user = local_assigns.fetch(:user, member.user) - source = member.source -- override = member.try(:override) -# Note this is just for individual members. For groups please see shared/members/_group -%li.member.js-member.py-2.px-3.d-flex.flex-column{ class: [dom_class(member), ("is-overridden" if override), ("flex-md-row" unless force_mobile_view)], id: dom_id(member), data: { qa_selector: 'member_row' } } +%li.member.js-member.py-2.px-3.d-flex.flex-column{ class: [dom_class(member), ("flex-md-row" unless force_mobile_view)], id: dom_id(member), data: { qa_selector: 'member_row' } } %span.list-item-name.mb-2.m-md-0 - if user = image_tag avatar_icon_for_user(user, 40), class: "avatar s40 flex-shrink-0 flex-grow-0", alt: '' @@ -62,70 +60,4 @@ - if show_roles .controls.member-controls.align-items-center = render_if_exists 'shared/members/ee/ldap_tag', can_override: member.can_override? - - if show_controls && member.source == membership_source - - - if member.can_resend_invite? - = link_to sprite_icon('paper-airplane'), polymorphic_path([:resend_invite, member]), - method: :post, - class: 'gl-button btn btn-default align-self-center mr-sm-2', - title: _('Resend invite') - - - if user != current_user && member.can_update? - = form_for member, remote: true, html: { class: "js-edit-member-form form-group #{'d-sm-flex' unless force_mobile_view}" } do |f| - = f.hidden_field :access_level - .member-form-control.dropdown{ class: [("mr-sm-2 d-sm-inline-block" unless force_mobile_view)] } - %button.dropdown-menu-toggle.js-member-permissions-dropdown{ type: "button", - disabled: member.can_override? && !override, - data: { toggle: "dropdown", field_name: "#{f.object_name}[access_level]", qa_selector: "access_level_dropdown" } } - %span.dropdown-toggle-text - = 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 role")) - .dropdown-content - %ul - - member.valid_level_roles.each do |role, role_id| - %li - = link_to role, '#', - class: ("is-active" if member.access_level == role_id), - data: { id: role_id, el_id: dom_id(member), qa_selector: "#{role.downcase}_access_level_link" } - = render_if_exists 'shared/members/ee/revert_ldap_group_sync_option', - group: group, - member: member, - can_override: member.can_override? - .clearable-input.member-form-control{ class: [("d-sm-inline-block" unless force_mobile_view)] } - = f.text_field :expires_at, - disabled: member.can_override? && !override, - class: 'form-control js-access-expiration-date js-member-update-control', - placeholder: _('Expiration date'), - id: "member_expires_at_#{member.id}", - data: { el_id: dom_id(member) } - = sprite_icon('close', size: 16, css_class: 'clear-icon js-clear-input gl-text-gray-200') - - else - %span.member-access-text.user-access-role= member.human_access - - - if member.can_approve? - = link_to polymorphic_path([:approve_access_request, member]), - method: :post, - class: "btn btn-confirm btn-icon gl-button align-self-center m-0 mb-2 #{'mb-sm-0 ml-sm-2' unless force_mobile_view}", - title: _('Grant access') do - %span{ class: ('d-block d-sm-none' unless force_mobile_view) } - = _('Grant access') - - unless force_mobile_view - = sprite_icon('check', css_class: 'd-none d-sm-block') - - - if member.can_remove? - - if current_user == user - = link_to polymorphic_path([:leave, member.source, :members]), method: :delete, data: { confirm: leave_confirmation_message(member.source) }, class: "btn gl-button btn-svg btn-danger align-self-center m-0 #{'ml-sm-2' unless force_mobile_view}" do - = sprite_icon('leave', css_class: 'gl-icon') - = _('Leave') - - else - %button{ data: { member_path: member_path(member.member), member_type: member.type, message: remove_member_message(member), is_access_request: member.request?.to_s, qa_selector: 'delete_member_button' }, - class: "js-remove-member-button btn gl-button btn-danger align-self-center m-0 #{'ml-sm-2 btn-icon' unless force_mobile_view}", - title: remove_member_title(member) } - %span{ class: ('d-block d-sm-none' unless force_mobile_view) } - = _("Delete") - - unless force_mobile_view - = sprite_icon('remove', css_class: 'd-none d-sm-block gl-icon') - - else - %span.member-access-text.user-access-role= member.human_access + %span.member-access-text.user-access-role= member.human_access diff --git a/app/views/shared/members/_requests.html.haml b/app/views/shared/members/_requests.html.haml index 3aa43ed1922..8b0a85656dc 100644 --- a/app/views/shared/members/_requests.html.haml +++ b/app/views/shared/members/_requests.html.haml @@ -1,20 +1,19 @@ - membership_source = local_assigns.fetch(:membership_source) - requesters = local_assigns.fetch(:requesters) -- force_mobile_view = local_assigns.fetch(:force_mobile_view, false) - group = local_assigns.fetch(:group) - current_user_is_group_owner = group && group.has_owner?(current_user) - return if requesters.empty? -.card.gl-mt-3{ class: ('card-mobile' if force_mobile_view ) } +.card.gl-mt-3{ data: { testid: 'access-requests' } } .card-header = _("Users requesting access to") %strong= membership_source.name %span.badge.badge-pill= requesters.size + = render 'shared/members/manage_access_button', path: membership_source.is_a?(Project) ? project_project_members_path(@project, tab: 'access_requests') : group_group_members_path(@group, tab: 'access_requests') %ul.content-list.members-list = render partial: 'shared/members/member', collection: requesters, as: :member, locals: { membership_source: membership_source, group: group, - force_mobile_view: force_mobile_view, current_user_is_group_owner: current_user_is_group_owner } diff --git a/app/views/shared/members/_search_field.html.haml b/app/views/shared/members/_search_field.html.haml deleted file mode 100644 index b1e3134f7aa..00000000000 --- a/app/views/shared/members/_search_field.html.haml +++ /dev/null @@ -1,6 +0,0 @@ -- name = local_assigns.fetch(:name, :search) - -.search-control-wrap.gl-relative - = search_field_tag name, params[name], { placeholder: _('Search'), class: 'form-control', spellcheck: false } - %button.user-search-btn.border-left.gl-display-flex.gl-align-items-center.gl-justify-content-center{ type: 'submit', 'aria': { label: _('Submit search') }, data: { testid: 'user-search-submit' } } - = sprite_icon('search') diff --git a/app/views/shared/members/_sort_dropdown.html.haml b/app/views/shared/members/_sort_dropdown.html.haml deleted file mode 100644 index 682e3a0433b..00000000000 --- a/app/views/shared/members/_sort_dropdown.html.haml +++ /dev/null @@ -1,19 +0,0 @@ -.dropdown.inline.qa-user-sort-dropdown{ data: { testid: 'user-sort-dropdown' } } - = dropdown_toggle(member_sort_options_hash[@sort], { toggle: 'dropdown', testid: 'dropdown-toggle' }) - %ul.dropdown-menu.dropdown-menu-right.dropdown-menu-selectable - %li.dropdown-header - = _("Sort by") - - member_sort_options_hash.each do |value, title| - %li - = link_to filter_group_project_member_path(sort: value), class: ("is-active" if @sort == value) do - = title - %li.divider - %li{ data: { testid: 'filter-members-with-inherited-permissions' } } - = link_to filter_group_project_member_path(with_inherited_permissions: nil), class: ("is-active" unless params[:with_inherited_permissions].present?) do - = _("Show all members") - %li{ data: { testid: 'filter-members-with-inherited-permissions' } } - = link_to filter_group_project_member_path(with_inherited_permissions: 'exclude'), class: ("is-active" if params[:with_inherited_permissions] == 'exclude') do - = _("Show only direct members") - %li{ data: { testid: 'filter-members-with-inherited-permissions' } } - = link_to filter_group_project_member_path(with_inherited_permissions: 'only'), class: ("is-active" if params[:with_inherited_permissions] == 'only') do - = _("Show only inherited members") diff --git a/app/views/shared/milestones/_form_dates.html.haml b/app/views/shared/milestones/_form_dates.html.haml index e0664c1feba..7a41e381a96 100644 --- a/app/views/shared/milestones/_form_dates.html.haml +++ b/app/views/shared/milestones/_form_dates.html.haml @@ -1,13 +1,11 @@ -.col-md-6 - .form-group.row - .col-form-label.col-sm-2 - = f.label :start_date, _('Start Date') - .col-sm-10 - = f.text_field :start_date, class: "datepicker form-control gl-form-input", data: { qa_selector: "start_date_field" }, placeholder: _('Select start date'), autocomplete: 'off' - %a.inline.float-right.gl-mt-2.js-clear-start-date{ href: "#" }= _('Clear start date') - .form-group.row - .col-form-label.col-sm-2 - = f.label :due_date, _('Due Date') - .col-sm-10 - = f.text_field :due_date, class: "datepicker form-control gl-form-input", data: { qa_selector: "due_date_field" }, placeholder: _('Select due date'), autocomplete: 'off' - %a.inline.float-right.gl-mt-2.js-clear-due-date{ href: "#" }= _('Clear due date') +.form-group.row + .col-form-label.col-sm-2 + = f.label :start_date, _('Start Date') + .col-sm-4 + = f.text_field :start_date, class: "datepicker form-control gl-form-input", data: { qa_selector: "start_date_field" }, placeholder: _('Select start date'), autocomplete: 'off' + %a.inline.float-right.gl-mt-2.js-clear-start-date{ href: "#" }= _('Clear start date') + .col-form-label.col-sm-2 + = f.label :due_date, _('Due Date') + .col-sm-4 + = f.text_field :due_date, class: "datepicker form-control gl-form-input", data: { qa_selector: "due_date_field" }, placeholder: _('Select due date'), autocomplete: 'off' + %a.inline.float-right.gl-mt-2.js-clear-due-date{ href: "#" }= _('Clear due date') diff --git a/app/views/shared/milestones/_issuable.html.haml b/app/views/shared/milestones/_issuable.html.haml index 184904dd7ab..12380d4c34e 100644 --- a/app/views/shared/milestones/_issuable.html.haml +++ b/app/views/shared/milestones/_issuable.html.haml @@ -25,3 +25,5 @@ = link_to polymorphic_path(issuable_type_args, { milestone_title: @milestone.title, assignee_id: assignee.id, state: 'all' }), class: 'has-tooltip', title: _("Assigned to %{assignee_name}") % { assignee_name: assignee.name }, data: { container: 'body' } do - image_tag(avatar_icon_for_user(assignee, 16), class: "avatar s16", alt: '') + + = render_if_exists "shared/milestones/issuable_weight", issuable: issuable diff --git a/app/views/shared/milestones/_issuables.html.haml b/app/views/shared/milestones/_issuables.html.haml index 9147e1c50e3..460ddd0897c 100644 --- a/app/views/shared/milestones/_issuables.html.haml +++ b/app/views/shared/milestones/_issuables.html.haml @@ -4,11 +4,15 @@ .card .card-header{ class: panel_class } - .title - = title - - if show_counter - .counter - = number_with_delimiter(issuables.length) + .header.gl-mb-2 + .title + = title + .issuable-count-weight.gl-ml-3 + - if show_counter + %span.counter + = sprite_icon('issues', css_class: 'gl-vertical-align-text-bottom') + = number_with_delimiter(issuables.length) + = render_if_exists "shared/milestones/issuables_weight", issuables: issuables - class_prefix = dom_class(issuables).pluralize %ul{ class: "content-list milestone-#{class_prefix}-list", id: "#{class_prefix}-list-#{id}" } diff --git a/app/views/shared/milestones/_milestone_complete_alert.html.haml b/app/views/shared/milestones/_milestone_complete_alert.html.haml new file mode 100644 index 00000000000..1c25fae747e --- /dev/null +++ b/app/views/shared/milestones/_milestone_complete_alert.html.haml @@ -0,0 +1,10 @@ +- milestone = local_assigns[:milestone] + +- if milestone.complete? && milestone.active? + = render 'shared/global_alert', + variant: :success, + is_contained: true, + alert_data: { testid: 'all-issues-closed-alert' }, + dismissible: false do + .gl-alert-body + = yield diff --git a/app/views/shared/milestones/_top.html.haml b/app/views/shared/milestones/_top.html.haml index c37fdf0c98f..2709a39c475 100644 --- a/app/views/shared/milestones/_top.html.haml +++ b/app/views/shared/milestones/_top.html.haml @@ -5,11 +5,8 @@ = render 'shared/milestones/header', milestone: milestone = render 'shared/milestones/description', milestone: milestone - -- if milestone.complete? && milestone.active? - .gl-alert.gl-alert-success.gl-mt-3 - %span - = _('All issues for this milestone are closed.') - = group ? _('You may close the milestone now.') : _('Navigate to the project to close the milestone.') += render 'shared/milestones/milestone_complete_alert', milestone: milestone do + = _('All issues for this milestone are closed.') + = group ? _('You may close the milestone now.') : _('Navigate to the project to close the milestone.') = render_if_exists 'shared/milestones/burndown', milestone: milestone, project: @project diff --git a/app/views/shared/namespaces/cascading_settings/_enforcement_checkbox.html.haml b/app/views/shared/namespaces/cascading_settings/_enforcement_checkbox.html.haml index ab4d8816ec9..cfa87351689 100644 --- a/app/views/shared/namespaces/cascading_settings/_enforcement_checkbox.html.haml +++ b/app/views/shared/namespaces/cascading_settings/_enforcement_checkbox.html.haml @@ -1,9 +1,10 @@ - attribute = local_assigns.fetch(:attribute, nil) +- group = local_assigns.fetch(:group, nil) - form = local_assigns.fetch(:form, nil) - setting_locked = local_assigns.fetch(:setting_locked, false) - help_text = local_assigns.fetch(:help_text, s_('CascadingSettings|Subgroups cannot change this setting.')) -- return unless attribute && group && form && cascading_namespace_settings_enabled? +- return unless attribute && group && form - return if setting_locked - lock_attribute = "lock_#{attribute}" diff --git a/app/views/shared/namespaces/cascading_settings/_setting_label_checkbox.html.haml b/app/views/shared/namespaces/cascading_settings/_setting_label_checkbox.html.haml index d27b3641637..83d602aba21 100644 --- a/app/views/shared/namespaces/cascading_settings/_setting_label_checkbox.html.haml +++ b/app/views/shared/namespaces/cascading_settings/_setting_label_checkbox.html.haml @@ -1,10 +1,11 @@ - attribute = local_assigns.fetch(:attribute, nil) +- group = local_assigns.fetch(:group, nil) - settings_path_helper = local_assigns.fetch(:settings_path_helper, nil) - form = local_assigns.fetch(:form, nil) - setting_locked = local_assigns.fetch(:setting_locked, false) - help_text = local_assigns.fetch(:help_text, nil) -- return unless attribute && form && settings_path_helper +- return unless attribute && group && form && settings_path_helper = form.label attribute, class: 'custom-control-label', aria: { disabled: setting_locked } do = render 'shared/namespaces/cascading_settings/setting_label_container' do diff --git a/app/views/shared/namespaces/cascading_settings/_setting_label_fieldset.html.haml b/app/views/shared/namespaces/cascading_settings/_setting_label_fieldset.html.haml index 4a2ec9f30fd..66c760b466c 100644 --- a/app/views/shared/namespaces/cascading_settings/_setting_label_fieldset.html.haml +++ b/app/views/shared/namespaces/cascading_settings/_setting_label_fieldset.html.haml @@ -1,9 +1,10 @@ - attribute = local_assigns.fetch(:attribute, nil) +- group = local_assigns.fetch(:group, nil) - settings_path_helper = local_assigns.fetch(:settings_path_helper, nil) - setting_locked = local_assigns.fetch(:setting_locked, false) - help_text = local_assigns.fetch(:help_text, nil) -- return unless attribute && settings_path_helper +- return unless attribute && group && settings_path_helper %legend.h5.gl-border-none.gl-m-0 = render 'shared/namespaces/cascading_settings/setting_label_container' do diff --git a/app/views/shared/nav/_scope_menu.html.haml b/app/views/shared/nav/_scope_menu.html.haml index cbee0e0429c..1a7089fb570 100644 --- a/app/views/shared/nav/_scope_menu.html.haml +++ b/app/views/shared/nav/_scope_menu.html.haml @@ -1,6 +1,6 @@ -- 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 += nav_link(**scope_menu.active_routes, html_options: scope_menu.nav_link_html_options) do + = link_to scope_menu.link, **scope_menu.container_html_options, data: { qa_selector: 'sidebar_menu_link', qa_menu_item: scope_qa_menu_item(scope_menu.container) } do + %span{ class: scope_avatar_classes(scope_menu.container) } + = source_icon(scope_menu.container, alt: scope_menu.title, class: ['avatar', 'avatar-tile', 's32'], width: 32, height: 32) + %span.sidebar-context-title + = scope_menu.title diff --git a/app/views/shared/nav/_scope_menu_body.html.haml b/app/views/shared/nav/_scope_menu_body.html.haml deleted file mode 100644 index a94c681e2d3..00000000000 --- a/app/views/shared/nav/_scope_menu_body.html.haml +++ /dev/null @@ -1,8 +0,0 @@ -- 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 54c3b8a281d..915352996d9 100644 --- a/app/views/shared/nav/_sidebar.html.haml +++ b/app/views/shared/nav/_sidebar.html.haml @@ -1,15 +1,14 @@ %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 && 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? + %ul.sidebar-top-level-items{ data: { qa_selector: sidebar_qa_selector(sidebar.container) } } + - if sidebar.render_raw_scope_menu_partial + = render sidebar.render_raw_scope_menu_partial + - elsif sidebar.scope_menu = 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 = render 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 b80bd515a32..9a04139d2f2 100644 --- a/app/views/shared/nav/_sidebar_menu.html.haml +++ b/app/views/shared/nav/_sidebar_menu.html.haml @@ -15,12 +15,12 @@ %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 - - 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 + %span.fly-out-top-item-container + %strong.fly-out-top-item-name + = sidebar_menu.title + - if sidebar_menu.has_pill? + %span.badge.badge-pill.count.fly-out-badge{ **sidebar_menu.pill_html_options } + = number_with_delimiter(sidebar_menu.pill_count) - if sidebar_menu.has_renderable_items? %li.divider.fly-out-top-item diff --git a/app/views/shared/nav/_sidebar_menu_collapsed.html.haml b/app/views/shared/nav/_sidebar_menu_collapsed.html.haml deleted file mode 100644 index 78567a991df..00000000000 --- a/app/views/shared/nav/_sidebar_menu_collapsed.html.haml +++ /dev/null @@ -1,5 +0,0 @@ -%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/snippets/_embed.html.haml b/app/views/shared/snippets/_embed.html.haml index f698e1a301b..b5abd00b8fd 100644 --- a/app/views/shared/snippets/_embed.html.haml +++ b/app/views/shared/snippets/_embed.html.haml @@ -4,12 +4,12 @@ = external_snippet_icon('doc-text') %strong.file-title-name - %a.gitlab-embedded-snippets-title{ href: url_for(only_path: false, overwrite_params: nil) } + %a.gitlab-embedded-snippets-title{ href: url_for(only_path: false, overwrite_params: nil), target: '_blank', rel: 'noopener noreferrer' } = blob.name %small = number_to_human_size(blob.size) - %a.gitlab-logo-wrapper{ href: url_for(only_path: false, overwrite_params: nil), title: 'view on gitlab' } + %a.gitlab-logo-wrapper{ href: url_for(only_path: false, overwrite_params: nil), title: 'View on GitLab', target: '_blank', rel: 'noopener noreferrer' } %img.gitlab-logo{ src: image_url('ext_snippet_icons/logo.svg'), alt: "GitLab logo" } .file-actions.d-none.d-sm-block diff --git a/app/views/shared/wikis/edit.html.haml b/app/views/shared/wikis/edit.html.haml index 729646c2731..15710f0df49 100644 --- a/app/views/shared/wikis/edit.html.haml +++ b/app/views/shared/wikis/edit.html.haml @@ -18,7 +18,7 @@ .nav-controls.pb-md-3.pb-lg-0 - if @page.persisted? - - if can?(current_user, :admin_wiki, @wiki.container) + - if can?(current_user, :create_wiki, @wiki.container) #delete-wiki-modal-wrapper{ data: { delete_wiki_url: wiki_page_path(@wiki, @page), page_title: @page.human_title } } = render 'shared/wikis/form', uploads_path: wiki_attachment_upload_url |