diff options
Diffstat (limited to 'app/views/shared')
24 files changed, 161 insertions, 225 deletions
diff --git a/app/views/shared/_file_picker_button.html.haml b/app/views/shared/_file_picker_button.html.haml index 1d688e7f4b0..8d76e9c1b7d 100644 --- a/app/views/shared/_file_picker_button.html.haml +++ b/app/views/shared/_file_picker_button.html.haml @@ -1,7 +1,8 @@ - classes = local_assigns.fetch(:classes, '') %span.js-filepicker - %button.gl-button.btn.btn-default.js-filepicker-button{ type: 'button', class: classes }= _("Choose file…") + = render Pajamas::ButtonComponent.new(button_options: { class: "js-filepicker-button #{classes}" }) do + = _("Choose file…") %span.file_name.js-filepicker-filename= _("No file chosen.") = f.file_field field, class: "js-filepicker-input hidden" - if help_text.present? diff --git a/app/views/shared/_flash_user_callout.html.haml b/app/views/shared/_flash_user_callout.html.haml index 7b2d59407b4..c549c4e6e4d 100644 --- a/app/views/shared/_flash_user_callout.html.haml +++ b/app/views/shared/_flash_user_callout.html.haml @@ -4,7 +4,7 @@ .flash-container.flash-container-page.user-callout{ data: callout_data } -# We currently only support `alert`, `warning`, `notice`, `success` %div{ class: "flash-#{flash_type}" } - %div{ class: "#{(container_class unless fluid_layout)} #{(extra_flash_class unless @no_container)} #{@content_class}" } + %div{ class: "#{container_class unless fluid_layout} #{extra_flash_class unless @no_container} #{@content_class}" } %span= message %button.btn.gl-button.btn-default.close.js-close{ type: 'button', 'aria-label' => _('Dismiss') } diff --git a/app/views/shared/_label.html.haml b/app/views/shared/_label.html.haml index c0bc50fef5b..1645c2695b5 100644 --- a/app/views/shared/_label.html.haml +++ b/app/views/shared/_label.html.haml @@ -42,7 +42,7 @@ - if current_user %li.gl-display-inline-block.label-subscription.js-label-subscription.gl-ml-3 - if label.can_subscribe_to_label_in_different_levels? - = render Pajamas::ButtonComponent.new(button_options: { class: "js-unsubscribe-button #{('hidden' if status.unsubscribed?)}", data: { url: toggle_subscription_path, toggle: 'tooltip', container: 'body' }, title: tooltip_title } ) do + = render Pajamas::ButtonComponent.new(button_options: { class: "js-unsubscribe-button #{'hidden' if status.unsubscribed?}", data: { url: toggle_subscription_path, toggle: 'tooltip', container: 'body' }, title: tooltip_title } ) do = _('Unsubscribe') .dropdown.dropdown-group-label{ class: ('hidden' unless status.unsubscribed?) } = render Pajamas::ButtonComponent.new(button_options: { class: 'gl-w-full', data: { toggle: 'dropdown' } }) do @@ -51,10 +51,10 @@ .dropdown-menu.dropdown-open-left %ul %li - = render Pajamas::ButtonComponent.new(category: :tertiary, button_options: { class: "js-subscribe-button #{('hidden' unless status.unsubscribed?)}", data: { status: status, url: toggle_subscription_project_label_path(@project, label) } } ) do + = render Pajamas::ButtonComponent.new(category: :tertiary, button_options: { class: "js-subscribe-button #{'hidden' unless status.unsubscribed?}", data: { status: status, url: toggle_subscription_project_label_path(@project, label) } } ) do = _('Subscribe at project level') %li - = render Pajamas::ButtonComponent.new(category: :tertiary, button_options: { class: "js-subscribe-button js-group-level #{('hidden' unless status.unsubscribed?)}", data: { status: status, url: toggle_subscription_group_label_path(label.group, label) } } ) do + = render Pajamas::ButtonComponent.new(category: :tertiary, button_options: { class: "js-subscribe-button js-group-level #{'hidden' unless status.unsubscribed?}", data: { status: status, url: toggle_subscription_group_label_path(label.group, label) } } ) do = _('Subscribe at group level') - else = render Pajamas::ButtonComponent.new(button_options: { class: 'js-subscribe-button gl-w-full', data: { status: status, url: toggle_subscription_path, toggle: 'tooltip', container: 'body' }, title: tooltip_title } ) do diff --git a/app/views/shared/_md_preview.html.haml b/app/views/shared/_md_preview.html.haml index 7314a7ddadc..2fff70cdc74 100644 --- a/app/views/shared/_md_preview.html.haml +++ b/app/views/shared/_md_preview.html.haml @@ -1,6 +1,6 @@ - referenced_users = local_assigns.fetch(:referenced_users, nil) -- if defined?(@merge_request) && @merge_request.discussion_locked? +- if @merge_request&.discussion_locked? .issuable-note-warning = sprite_icon('lock', css_class: 'icon') %span diff --git a/app/views/shared/access_tokens/_created_container.html.haml b/app/views/shared/access_tokens/_created_container.html.haml deleted file mode 100644 index c0aaa46e761..00000000000 --- a/app/views/shared/access_tokens/_created_container.html.haml +++ /dev/null @@ -1,12 +0,0 @@ -.created-personal-access-token-container - %h5.gl-mt-0 - = _('Your new %{type}') % { type: type } - .form-group - .input-group - = text_field_tag 'created-personal-access-token', new_token_value, readonly: true, class: 'form-control js-select-on-focus', data: { qa_selector: 'created_access_token_field' }, 'aria-describedby' => 'created-token-help-block' - %span.input-group-append - = clipboard_button(text: new_token_value, title: _('Copy %{type}') % { type: type }, placement: 'left', class: 'input-group-text btn-default btn-clipboard') - %span#created-token-help-block.form-text.text-muted.text-danger - = _("Make sure you save it - you won't be able to access it again.") - -%hr diff --git a/app/views/shared/access_tokens/_table.html.haml b/app/views/shared/access_tokens/_table.html.haml deleted file mode 100644 index 53c6800f93d..00000000000 --- a/app/views/shared/access_tokens/_table.html.haml +++ /dev/null @@ -1,51 +0,0 @@ -- 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) -- resource = local_assigns.fetch(:resource, false) - -%hr - -%h5 - = _('Active %{type} (%{token_length})') % { type: type_plural, token_length: active_tokens.length } - -- if impersonation - %p.profile-settings-content - = _("To see all the user's personal access tokens you must impersonate them first.") - -- if active_tokens.present? - .table-responsive - %table.table.active-tokens - %thead - %tr - %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', rel: 'noopener noreferrer' - %th= _('Expires') - - if resource - %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? - %span.token-last-used-label= _(time_ago_with_tooltip(token.last_used_at)) - - else - %span.token-never-used-label= _('Never') - %td - - if token.expires? - %span{ class: ('text-warning' if token.expires_soon?) } - = time_ago_with_tooltip(token.expires_at) - - else - %span.token-never-expires-label= _('Never') - - if resource - %td= resource.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 #{'btn-danger-secondary' unless token.expires?}", aria: { label: _('Revoke') }, data: { confirm: _('Are you sure you want to revoke this %{type}? This action cannot be undone.') % { type: type }, 'confirm-btn-variant': 'danger', qa_selector: 'revoke_button' } -- else - .settings-message.text-center - = no_active_tokens_message diff --git a/app/views/shared/deploy_tokens/_form.html.haml b/app/views/shared/deploy_tokens/_form.html.haml index 1b48843eb10..0f290f34a95 100644 --- a/app/views/shared/deploy_tokens/_form.html.haml +++ b/app/views/shared/deploy_tokens/_form.html.haml @@ -3,7 +3,7 @@ - group_deploy_tokens_help_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: group_deploy_tokens_help_link_url } = s_('DeployTokens|Create a new deploy token for all projects in this group. %{link_start}What are deploy tokens?%{link_end}').html_safe % { link_start: group_deploy_tokens_help_link_start, link_end: '</a>'.html_safe } -= gitlab_ui_form_for token, url: create_deploy_token_path(group_or_project, anchor: 'js-deploy-tokens'), method: :post, remote: Feature.enabled?(:ajax_new_deploy_token, group_or_project) do |f| += gitlab_ui_form_for token, url: create_deploy_token_path(group_or_project, anchor: 'js-deploy-tokens'), method: :post, remote: true do |f| .form-group = f.label :name, class: 'label-bold' diff --git a/app/views/shared/deploy_tokens/_index.html.haml b/app/views/shared/deploy_tokens/_index.html.haml index faec379e42b..e5f1fd99125 100644 --- a/app/views/shared/deploy_tokens/_index.html.haml +++ b/app/views/shared/deploy_tokens/_index.html.haml @@ -8,20 +8,13 @@ %p = description .settings-content - - if Feature.enabled?(:ajax_new_deploy_token, group_or_project) - #js-new-deploy-token{ data: { - container_registry_enabled: container_registry_enabled?(group_or_project), - packages_registry_enabled: packages_registry_enabled?(group_or_project), - create_new_token_path: create_deploy_token_path(group_or_project), - token_type: group_or_project.is_a?(Group) ? 'group' : 'project', - deploy_tokens_help_url: help_page_path('user/project/deploy_tokens/index.md') - } + #js-new-deploy-token{ data: { + container_registry_enabled: container_registry_enabled?(group_or_project), + packages_registry_enabled: packages_registry_enabled?(group_or_project), + create_new_token_path: create_deploy_token_path(group_or_project), + token_type: group_or_project.is_a?(Group) ? 'group' : 'project', + deploy_tokens_help_url: help_page_path('user/project/deploy_tokens/index.md') } - - else - - if @created_deploy_token - = render 'shared/deploy_tokens/new_deploy_token', deploy_token: @created_deploy_token - %h5.gl-mt-0 - = s_('DeployTokens|New deploy token') - = render 'shared/deploy_tokens/form', group_or_project: group_or_project, token: @new_deploy_token, presenter: @deploy_tokens + } %hr = render 'shared/deploy_tokens/table', group_or_project: group_or_project, active_tokens: @deploy_tokens diff --git a/app/views/shared/empty_states/_snippets.html.haml b/app/views/shared/empty_states/_snippets.html.haml index a006a3bc0a4..e34166bac6c 100644 --- a/app/views/shared/empty_states/_snippets.html.haml +++ b/app/views/shared/empty_states/_snippets.html.haml @@ -2,8 +2,8 @@ .row.empty-state .col-12 - .svg-content - = image_tag 'illustrations/snippets_empty.svg', data: { qa_selector: 'svg_content' } + .svg-content{ data: { qa_selector: 'svg_content' } } + = image_tag 'illustrations/snippets_empty.svg' .text-content.gl-text-center.gl-pt-0 - if current_user %h4 diff --git a/app/views/shared/issuable/_bulk_update_sidebar.html.haml b/app/views/shared/issuable/_bulk_update_sidebar.html.haml index e6bdefc64d2..da8477f4b2e 100644 --- a/app/views/shared/issuable/_bulk_update_sidebar.html.haml +++ b/app/views/shared/issuable/_bulk_update_sidebar.html.haml @@ -1,5 +1,6 @@ - type = local_assigns.fetch(:type) - is_issue = type == :issues +- move_data = { projects_fetch_path: autocomplete_projects_path(project_id: @project.id), project_full_path: @project.full_path } %aside.issues-bulk-update.js-right-sidebar.right-sidebar{ "aria-live" => "polite", data: { 'signed-in': current_user.present? }, 'aria-label': _('Bulk update') } .issuable-sidebar.hidden @@ -33,7 +34,7 @@ .title = _('Milestone') .filter-item - = dropdown_tag(_("Select milestone"), options: { title: _("Assign milestone"), toggle_class: "js-milestone-select js-extra-options js-filter-submit js-filter-bulk-update", filter: true, dropdown_class: "dropdown-menu-selectable dropdown-menu-milestone", placeholder: _("Search milestones"), data: { show_no: true, field_name: "update[milestone_id]", project_id: @project.id, use_id: true, default_label: _("Milestone") } }) + .js-milestone-dropdown-root{ data: { full_path: @project.full_path, workspace_type: Namespaces::ProjectNamespace.sti_name.downcase } } - if is_issue = render_if_exists 'shared/issuable/iterations_dropdown', parent: @project.group - if is_issue @@ -42,6 +43,9 @@ .title = _('Subscriptions') .js-subscriptions-dropdown + - if is_issue + .block + .js-move-issues{ data: move_data } = hidden_field_tag "update[issuable_ids]", [] = hidden_field_tag :state_event, params[:state_event] diff --git a/app/views/shared/issuable/_form.html.haml b/app/views/shared/issuable/_form.html.haml index 5b7f9c4226c..a325ad5f447 100644 --- a/app/views/shared/issuable/_form.html.haml +++ b/app/views/shared/issuable/_form.html.haml @@ -71,7 +71,10 @@ - else = link_to _('Cancel'), polymorphic_path([@project, issuable]), class: 'gl-button btn btn-default js-reset-autosave' - if can?(current_user, :"destroy_#{issuable.to_ability_name}", @project) - = link_to 'Delete', polymorphic_path([@project, issuable], params: { destroy_confirm: true }), data: { confirm: _('%{issuableType} will be removed! Are you sure?') % { issuableType: issuable.human_class_name } }, method: :delete, class: 'btn gl-button btn-danger btn-danger-secondary gl-float-right js-reset-autosave' + - confirm_title = _('Delete %{issuableType}?') % { issuableType: issuable.human_class_name } + - confirm_body = _('You’re about to permanently delete the %{issuableType} ‘%{strongOpen}%{issuableTitle}%{strongClose}’. To avoid data loss, consider %{strongOpen}closing this %{issuableType}%{strongClose} instead. Once deleted, it cannot be undone or recovered.') % { issuableType: issuable.human_class_name, issuableTitle: issuable.title, strongOpen: '<strong>', strongClose: '</strong>' } + - confirm_primary_btn_text = _('Delete %{issuableType}') % { issuableType: issuable.human_class_name } + = link_to _('Delete'), polymorphic_path([@project, issuable], params: { destroy_confirm: true }), data: { title: confirm_title, confirm: confirm_body, is_html_message: true, confirm_btn_variant: 'danger'}, method: :delete, class: 'btn gl-button btn-danger btn-danger-secondary gl-float-right js-reset-autosave', "aria-label": confirm_primary_btn_text - if issuable.respond_to?(:issue_type) = form.hidden_field :issue_type diff --git a/app/views/shared/issuable/_milestone_dropdown.html.haml b/app/views/shared/issuable/_milestone_dropdown.html.haml index 58108ceeb76..a02d2851c4c 100644 --- a/app/views/shared/issuable/_milestone_dropdown.html.haml +++ b/app/views/shared/issuable/_milestone_dropdown.html.haml @@ -1,19 +1,11 @@ +- name = local_assigns.fetch(:name, nil) - project = @target_project || @project -- extra_class = extra_class || '' -- show_menu_above = show_menu_above || false - selected = local_assigns.fetch(:selected, nil) -- selected_text = selected.try(:title) || params[:milestone_title] -- dropdown_title = local_assigns.fetch(:dropdown_title, _('Filter by milestone')) -- if selected.present? || params[:milestone_title].present? - = hidden_field_tag(name, name == :milestone_title ? selected_text : selected.id) -= dropdown_tag(milestone_dropdown_label(selected_text), options: { title: dropdown_title, toggle_class: "js-milestone-select js-filter-submit #{extra_class}", filter: true, dropdown_class: "dropdown-menu-selectable dropdown-menu-milestone", dropdown_qa_selector: "issuable_milestone_dropdown_content", - placeholder: _('Search milestones'), footer_content: project.present?, data: { show_no: true, show_menu_above: show_menu_above, show_any: show_any, show_upcoming: show_upcoming, show_started: show_started, field_name: name, selected: selected_text, project_id: project.try(:id), default_label: _('Milestone'), qa_selector: "issuable_milestone_dropdown", testid: "issuable-milestone-dropdown" } }) do - - if project - %ul.dropdown-footer-list - %li - = link_to project_milestones_path(project) do - - if can? current_user, :admin_milestone, project - = _('Manage milestones') - - else - = _('View milestones') +.js-milestone-dropdown-root{ data: { can_admin_milestone: can?(current_user, :admin_milestone, project), + full_path: project.full_path, + input_name: name, + milestone_id: selected.try(:id), + milestone_title: selected.try(:title), + project_milestones_path: project_milestones_path(project), + workspace_type: Namespaces::ProjectNamespace.sti_name.downcase } } diff --git a/app/views/shared/issuable/_sidebar.html.haml b/app/views/shared/issuable/_sidebar.html.haml index 4199b7e870b..0fd128df997 100644 --- a/app/views/shared/issuable/_sidebar.html.haml +++ b/app/views/shared/issuable/_sidebar.html.haml @@ -17,14 +17,14 @@ %a.gutter-toggle.float-right.js-sidebar-toggle.has-tooltip{ role: "button", class: "#{'gl-display-block' if moved_sidebar_enabled}", href: "#", "aria-label" => _('Toggle sidebar'), title: sidebar_gutter_tooltip_text, data: { container: 'body', placement: 'left', boundary: 'viewport' } } = sidebar_gutter_toggle_icon - if signed_in && !moved_sidebar_enabled - .js-issuable-todo{ data: { project_path: issuable_sidebar[:project_full_path], iid: issuable_sidebar[:iid], id: issuable_sidebar[:id] } } + .js-sidebar-todo-widget-root{ 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| - .block.assignee.qa-assignee-block{ class: "#{'gl-mt-3' if !signed_in && moved_sidebar_enabled}", data: { qa_selector: 'assignee_block_container' } } + .block.assignee{ class: "#{'gl-mt-3' if !signed_in && moved_sidebar_enabled}", data: { qa_selector: 'assignee_block_container' } } = render "shared/issuable/sidebar_assignees", issuable_sidebar: issuable_sidebar, assignees: assignees, signed_in: signed_in - if issuable_sidebar[:supports_severity] - #js-severity + .js-sidebar-severity-root - if reviewers .block.reviewer{ data: { qa_selector: 'reviewers_block_container' } } @@ -32,17 +32,17 @@ - if issuable_sidebar[:supports_escalation] .block.escalation-status{ data: { testid: 'escalation_status_container' } } - #js-escalation-status{ data: { can_update: issuable_sidebar.dig(:current_user, :can_update_escalation_status).to_s, project_path: issuable_sidebar[:project_full_path], issue_iid: issuable_sidebar[:iid] } } + .js-sidebar-escalation-status-root{ data: { can_update: issuable_sidebar.dig(:current_user, :can_update_escalation_status).to_s, project_path: issuable_sidebar[:project_full_path], issue_iid: issuable_sidebar[:iid] } } = render_if_exists 'shared/issuable/sidebar_escalation_policy', 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 - .js-sidebar-labels{ data: sidebar_labels_data(issuable_sidebar, @project) } + .js-sidebar-labels-widget-root{ data: sidebar_labels_data(issuable_sidebar, @project) } - if issuable_sidebar[:supports_milestone] .block.milestone{ :class => ("gl-border-b-0!" if in_group_context_with_iterations), data: { qa_selector: 'milestone_block', testid: 'sidebar-milestones' } } - .js-milestone-select{ data: { can_edit: can_edit_issuable.to_s, project_path: issuable_sidebar[:project_full_path], issue_iid: issuable_sidebar[:iid] } } + .js-sidebar-milestone-widget-root{ data: { can_edit: can_edit_issuable.to_s, project_path: issuable_sidebar[:project_full_path], issue_iid: issuable_sidebar[:iid] } } - if in_group_context_with_iterations .block.gl-collapse-empty{ data: { qa_selector: 'iteration_container', testid: 'iteration_container' } }< @@ -50,40 +50,40 @@ - if issuable_sidebar[:show_crm_contacts] .block.contact - #js-issue-crm-contacts{ data: { issue_id: issuable_sidebar[:id], group_issues_path: issues_group_path(@project.group) } } + .js-sidebar-crm-contacts-root{ data: { issue_id: issuable_sidebar[:id], group_issues_path: issues_group_path(@project.group) } } = 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.has_key?(:due_date) - #js-due-date-entry-point + .js-sidebar-due-date-widget-root - if issuable_sidebar[:supports_time_tracking] - #issuable-time-tracker.block + .js-sidebar-time-tracking-root.block // Fallback while content is loading .title.hide-collapsed = _('Time tracking') = gl_loading_icon(inline: true) - if issuable_sidebar.dig(:features_available, :health_status) - .js-sidebar-health-status-entry-point{ data: sidebar_status_data(issuable_sidebar, @project) } + .js-sidebar-health-status-widget-root{ data: sidebar_status_data(issuable_sidebar, @project) } - if issuable_sidebar.has_key?(:confidential) -# haml-lint:disable InlineJavaScript %script#js-confidential-issue-data{ type: "application/json" }= { is_confidential: issuable_sidebar[:confidential], is_editable: can_edit_issuable }.to_json.html_safe - #js-confidential-entry-point + .js-sidebar-confidential-widget-root = render_if_exists 'shared/issuable/sidebar_cve_id_request', issuable_sidebar: issuable_sidebar - if !moved_sidebar_enabled - #js-lock-entry-point + .js-sidebar-lock-root - if signed_in - .js-sidebar-subscriptions-entry-point + .js-sidebar-subscriptions-widget-root - .js-sidebar-participants-entry-point + .js-sidebar-participants-widget-root .block.with-sub-blocks - if !moved_sidebar_enabled - #js-reference-entry-point + .js-sidebar-reference-widget-root - if issuable_type == 'merge_request' && !moved_sidebar_enabled .sub-block.js-sidebar-source-branch .sidebar-collapsed-icon.js-dont-change-state @@ -95,7 +95,7 @@ - if show_forwarding_email .block - #issuable-copy-email + .js-sidebar-copy-email-root - if issuable_sidebar.dig(:current_user, :can_move) .block.js-sidebar-move-issue-block .sidebar-collapsed-icon{ data: { toggle: 'tooltip', placement: 'left', container: 'body', boundary: 'viewport' }, title: _('Move issue') } diff --git a/app/views/shared/issuable/_sidebar_assignees.html.haml b/app/views/shared/issuable/_sidebar_assignees.html.haml index 62221fb8218..8ca30d7ca97 100644 --- a/app/views/shared/issuable/_sidebar_assignees.html.haml +++ b/app/views/shared/issuable/_sidebar_assignees.html.haml @@ -1,7 +1,7 @@ - issuable_type = issuable_sidebar[:type] - dropdown_options = assignees_dropdown_options(issuable_type) -#js-vue-sidebar-assignees{ data: { field: issuable_type, +.js-sidebar-assignees-root{ data: { field: issuable_type, signed_in: signed_in, max_assignees: dropdown_options[:data][:"max-select"], directly_invite_members: can_admin_project_member?(@project) } } @@ -39,7 +39,7 @@ - data[:multi_select] = true - data['dropdown-title'] = title - data['dropdown-header'] = dropdown_options[:data][:'dropdown-header'] - - data['max-select'] = dropdown_max_select(dropdown_options[:data], :limit_assignees_per_issuable) + - data['max-select'] = dropdown_max_select(dropdown_options[:data], nil) - options[:data].merge!(data) = render 'shared/issuable/sidebar_user_dropdown', diff --git a/app/views/shared/issuable/_sidebar_reviewers.html.haml b/app/views/shared/issuable/_sidebar_reviewers.html.haml index 771db8af6a8..4df393eeb67 100644 --- a/app/views/shared/issuable/_sidebar_reviewers.html.haml +++ b/app/views/shared/issuable/_sidebar_reviewers.html.haml @@ -1,16 +1,12 @@ - issuable_type = issuable_sidebar[:type] -#js-vue-sidebar-reviewers{ data: { field: issuable_type, signed_in: signed_in } } +.js-sidebar-reviewers-root{ data: { field: issuable_type, signed_in: signed_in } } .title.hide-collapsed = _('Reviewers') = gl_loading_icon(inline: true) .selectbox.hide-collapsed - - if reviewers.none? - = hidden_field_tag "#{issuable_type}[reviewer_ids][]", 0, id: nil - - else - - reviewers.each do |reviewer| - = hidden_field_tag "#{issuable_type}[reviewer_ids][]", reviewer.id, id: nil, data: reviewer_sidebar_data(reviewer, merge_request: @merge_request) + .js-reviewers-inputs - options = { toggle_class: 'js-reviewer-search js-author-search', title: _('Request review from'), @@ -32,10 +28,10 @@ - dropdown_options = reviewers_dropdown_options(issuable_type) - title = dropdown_options[:title] - options[:toggle_class] += ' js-multiselect js-save-user-data' - - data = { field_name: "#{issuable_type}[reviewer_ids][]" } - - data[:multi_select] = true + - data = { multi_select: true } - data['dropdown-title'] = title - data['dropdown-header'] = dropdown_options[:data][:'dropdown-header'] + - data[:suggested_reviewers_help_path] = dropdown_options[:data][:suggested_reviewers_help_path] - data[:suggested_reviewers_header] = dropdown_options[:data][:suggested_reviewers_header] - data[:all_members_header] = dropdown_options[:data][:all_members_header] - data[:show_suggested] = dropdown_options[:data][:show_suggested] diff --git a/app/views/shared/issuable/form/_metadata.html.haml b/app/views/shared/issuable/form/_metadata.html.haml index 76469b34832..9603178f7de 100644 --- a/app/views/shared/issuable/form/_metadata.html.haml +++ b/app/views/shared/issuable/form/_metadata.html.haml @@ -35,7 +35,7 @@ = form.label :milestone_id, _('Milestone'), class: "col-12" .col-12 .issuable-form-select-holder - = render "shared/issuable/milestone_dropdown", selected: issuable.milestone, name: "#{issuable.class.model_name.param_key}[milestone_id]", show_any: false, show_upcoming: false, show_started: false, extra_class: "js-issuable-form-dropdown js-dropdown-keep-input", dropdown_title: _('Select milestone') + = render "shared/issuable/milestone_dropdown", selected: issuable.milestone, name: "#{issuable.class.model_name.param_key}[milestone_id]" .form-group.row = form.label :label_ids, _('Labels'), class: "col-12" @@ -54,3 +54,4 @@ .col-12 .issuable-form-select-holder = form.gitlab_ui_datepicker :due_date, placeholder: _('Select due date'), autocomplete: 'off', id: "issuable-due-date" + = render_if_exists "shared/issuable/form/iteration", form: form, group: project.group diff --git a/app/views/shared/issue_type/_emoji_block.html.haml b/app/views/shared/issue_type/_emoji_block.html.haml index a5c71fb1d24..7eb3c0f5c9f 100644 --- a/app/views/shared/issue_type/_emoji_block.html.haml +++ b/app/views/shared/issue_type/_emoji_block.html.haml @@ -1,8 +1,8 @@ - api_awards_path = local_assigns.fetch(:api_awards_path, nil) -.content-block.emoji-block.emoji-block-sticky +.emoji-block.emoji-block-sticky .row.gl-m-0.gl-justify-content-space-between .js-noteable-awards = render 'award_emoji/awards_block', awardable: issuable, inline: true, api_awards_path: api_awards_path - .new-branch-col.gl-font-size-0 + .new-branch-col.gl-font-size-0.gl-my-2 = render 'new_branch' if show_new_branch_button? diff --git a/app/views/shared/labels/_form.html.haml b/app/views/shared/labels/_form.html.haml index c6932d49d33..9ef4b9e084d 100644 --- a/app/views/shared/labels/_form.html.haml +++ b/app/views/shared/labels/_form.html.haml @@ -29,8 +29,10 @@ = f.submit _('Save changes'), class: 'js-save-button gl-mr-2', pajamas_button: true - else = f.submit _('Create label'), class: 'js-save-button gl-mr-2', data: { qa_selector: 'label_create_button' }, pajamas_button: true - = link_to _('Cancel'), back_path, class: 'btn gl-button btn-default btn-cancel gl-mr-2' + = render Pajamas::ButtonComponent.new(href: back_path) do + = _('Cancel') + - if @label.persisted? - presented_label = @label.present - %button.btn.btn-danger.gl-button.btn-danger-secondary.js-delete-label-modal-button{ type: 'button', data: { label_name: presented_label.name, subject_name: presented_label.subject_name, destroy_path: presented_label.destroy_path } } - %span.gl-button-text= _('Delete') + = render Pajamas::ButtonComponent.new(variant: :danger, category: :secondary, button_options: { class: 'js-delete-label-modal-button', data: { label_name: presented_label.name, subject_name: presented_label.subject_name, destroy_path: presented_label.destroy_path } }) do + = _('Delete') diff --git a/app/views/shared/members/_access_request_links.html.haml b/app/views/shared/members/_access_request_links.html.haml index 7af946377be..0b38b9d7945 100644 --- a/app/views/shared/members/_access_request_links.html.haml +++ b/app/views/shared/members/_access_request_links.html.haml @@ -8,9 +8,10 @@ data: { confirm: leave_confirmation_message(source), confirm_btn_variant: 'danger', qa_selector: 'leave_group_link' }, class: 'js-leave-link' - elsif requester = source.requesters.find_by(user_id: current_user.id) # rubocop: disable CodeReuse/ActiveRecord - = link_to _('Withdraw Access Request'), polymorphic_path([:leave, source, :members]), - method: :delete, - data: { confirm: remove_member_message(requester) } + - if can?(current_user, :withdraw_member_access_request, requester) + = link_to _('Withdraw Access Request'), polymorphic_path([:leave, source, :members]), + method: :delete, + data: { confirm: remove_member_message(requester) } - elsif source.request_access_enabled && can?(current_user, :request_access, source) = link_to _('Request Access'), polymorphic_path([:request_access, source, :members]), method: :post diff --git a/app/views/shared/milestones/_delete_button.html.haml b/app/views/shared/milestones/_delete_button.html.haml index 8a709a36835..432d2efc36e 100644 --- a/app/views/shared/milestones/_delete_button.html.haml +++ b/app/views/shared/milestones/_delete_button.html.haml @@ -1,11 +1,7 @@ - milestone_url = @milestone.project_milestone? ? project_milestone_path(@project, @milestone) : group_milestone_path(@group, @milestone) -%button.js-delete-milestone-button.btn.gl-button.btn-grouped.btn-danger{ data: { milestone_id: @milestone.id, - milestone_title: markdown_field(@milestone, :title), - milestone_url: milestone_url, - milestone_issue_count: @milestone.issues.count, - milestone_merge_request_count: @milestone.merge_requests.count }, - disabled: true } += render Pajamas::ButtonComponent.new(variant: :danger, + button_options: { class: 'js-delete-milestone-button btn-grouped', data: { milestone_id: @milestone.id, milestone_title: markdown_field(@milestone, :title), milestone_url: milestone_url, milestone_issue_count: @milestone.issues.count, milestone_merge_request_count: @milestone.merge_requests.count }, disabled: true }) do = gl_loading_icon(inline: true, css_class: "gl-mr-2 js-loading-icon hidden") = _('Delete') diff --git a/app/views/shared/milestones/_sidebar.html.haml b/app/views/shared/milestones/_sidebar.html.haml index 6a65909b1c2..cc1965945ac 100644 --- a/app/views/shared/milestones/_sidebar.html.haml +++ b/app/views/shared/milestones/_sidebar.html.haml @@ -94,7 +94,7 @@ = milestone.issues_visible_to_user(current_user).closed.count .block - #issuable-time-tracker{ data: { time_estimate: @milestone.total_time_estimate, + .js-sidebar-time-tracking-root{ data: { time_estimate: @milestone.total_time_estimate, time_spent: @milestone.total_time_spent, human_time_estimate: @milestone.human_total_time_estimate, human_time_spent: @milestone.human_total_time_spent, diff --git a/app/views/shared/projects/_list.html.haml b/app/views/shared/projects/_list.html.haml index c39dc561801..43cd2ee4c5b 100644 --- a/app/views/shared/projects/_list.html.haml +++ b/app/views/shared/projects/_list.html.haml @@ -32,7 +32,7 @@ - if any_projects?(projects) - load_pipeline_status(projects) if pipeline_status - load_max_project_member_accesses(projects) # Prime cache used in shared/projects/project view rendered below - %ul.projects-list{ class: css_classes } + %ul.projects-list.gl-text-secondary.gl-w-full.gl-my-2{ class: css_classes } - projects.each_with_index do |project, i| - css_class = (i >= projects_limit) || project.pending_delete? ? 'hide' : nil = render "shared/projects/project", project: project, skip_namespace: skip_namespace, diff --git a/app/views/shared/projects/_project.html.haml b/app/views/shared/projects/_project.html.haml index 81e2e066bd3..908eb2428e8 100644 --- a/app/views/shared/projects/_project.html.haml +++ b/app/views/shared/projects/_project.html.haml @@ -8,102 +8,108 @@ - access = max_project_member_access(project) - compact_mode = false unless local_assigns[:compact_mode] == true - show_last_commit_as_description = false unless local_assigns[:show_last_commit_as_description] == true && can_show_last_commit_in_list?(project) -- css_class = '' unless local_assigns[:css_class] -- css_class += " gl-display-flex!" +- css_class = "gl-sm-display-flex gl-align-items-center gl-vertical-align-middle!" if project.description.blank? && !show_last_commit_as_description - cache_key = project_list_cache_key(project, pipeline_status: pipeline_status) - updated_tooltip = time_ago_with_tooltip(project.last_activity_date) - show_pipeline_status_icon = pipeline_status && can?(current_user, :read_cross_project) && project.pipeline_status.has_status? && can?(current_user, :read_build, project) - last_pipeline = project.last_pipeline if show_pipeline_status_icon -- css_controls_class = compact_mode ? [] : ["flex-lg-row", "justify-content-lg-between"] -- css_controls_class << "with-pipeline-status" if show_pipeline_status_icon && last_pipeline.present? -- avatar_container_class = project.creator && use_creator_avatar ? '' : 'rect-avatar' +- css_controls_class = "with-pipeline-status" if show_pipeline_status_icon && last_pipeline.present? +- css_controls_container_class = compact_mode ? "" : "gl-lg-flex-direction-row gl-justify-content-space-between" +- css_metadata_classes = "gl-display-flex gl-align-items-center gl-mr-5 gl-reset-color! icon-wrapper has-tooltip" -%li.project-row.gl-align-items-center{ class: css_class } +%li.project-row = cache(cache_key) do - if avatar - .flex-grow-0.flex-shrink-0{ class: avatar_container_class } + .project-cell.gl-w-11 = link_to project_path(project), class: dom_class(project) do - if project.creator && use_creator_avatar = render Pajamas::AvatarComponent.new(project.creator, size: 48, alt: '', class: 'gl-mr-5') - else = render Pajamas::AvatarComponent.new(project, size: 48, alt: '', class: 'gl-mr-5') - .project-details.d-sm-flex.flex-sm-fill.align-items-center{ data: { qa_selector: 'project_content', qa_project_name: project.name } } - .flex-wrapper - .d-flex.align-items-center.flex-wrap.project-title - %h2.d-flex.gl-mt-3 - = link_to project_path(project), class: 'text-plain js-prefetch-document' do - %span.project-full-name.gl-mr-3>< - %span.namespace-name - - if project.namespace && !skip_namespace - = project.namespace.human_name - \/ - %span.project-name< - = project.name + .project-cell{ class: css_class } + .project-details.gl-pr-9.gl-sm-pr-0.gl-w-full.gl-display-flex.gl-flex-direction-column{ data: { qa_selector: 'project_content', qa_project_name: project.name } } + .gl-display-flex.gl-align-items-center.gl-flex-wrap-wrap + %h2.gl-font-base.gl-line-height-20.gl-my-0 + = link_to project_path(project), class: 'text-plain gl-mr-3 js-prefetch-document' do + %span.namespace-name.gl-font-weight-normal + - if project.namespace && !skip_namespace + = project.namespace.human_name + \/ + %span.project-name< + = project.name - %span.metadata-info.visibility-icon.gl-mr-3.gl-mt-3.text-secondary.has-tooltip{ data: { container: 'body', placement: 'top' }, title: visibility_icon_description(project) } - = visibility_level_icon(project.visibility_level) + %span.gl-mr-3.has-tooltip{ data: { container: 'body', placement: 'top' }, title: visibility_icon_description(project) } + = visibility_level_icon(project.visibility_level) - - if explore_projects_tab? && project_license_name(project) - %span.metadata-info.d-inline-flex.align-items-center.gl-mr-3.gl-mt-3 - = sprite_icon('scale', size: 14, css_class: 'gl-mr-2') - = project_license_name(project) + - if explore_projects_tab? && project_license_name(project) + %span.gl-display-inline-flex.gl-align-items-center.gl-mr-3 + = sprite_icon('scale', size: 14, css_class: 'gl-mr-2') + = project_license_name(project) - - if !explore_projects_tab? && access&.nonzero? - -# haml-lint:disable UnnecessaryStringOutput - = ' ' # prevent haml from eating the space between elements - .metadata-info.gl-mt-3 - %span.user-access-role.gl-display-block{ data: { qa_selector: 'user_role_content' } }= localized_project_human_access(access) + - if !explore_projects_tab? && access&.nonzero? + -# haml-lint:disable UnnecessaryStringOutput + = ' ' # prevent haml from eating the space between elements + %span.user-access-role.gl-display-block.gl-m-0{ data: { qa_selector: 'user_role_content' } }= Gitlab::Access.human_access(access) - - if !explore_projects_tab? - .metadata-info.gl-mt-3 - = render_if_exists 'compliance_management/compliance_framework/compliance_framework_badge', project: project + - if !explore_projects_tab? + = render_if_exists 'compliance_management/compliance_framework/compliance_framework_badge', project: project - - if show_last_commit_as_description - .description.d-none.d-sm-block.gl-mr-3 - = link_to_markdown(project.commit.title, project_commit_path(project, project.commit), class: "commit-row-message") - - elsif project.description.present? - .description.d-none.d-sm-block.gl-mr-3 - = markdown_field(project, :description) + - if show_last_commit_as_description + .description.gl-display-none.gl-sm-display-block.gl-overflow-hidden.gl-mr-3.gl-mt-2 + = link_to_markdown(project.commit.title, project_commit_path(project, project.commit), class: "commit-row-message") + - elsif project.description.present? + .description.gl-display-none.gl-sm-display-block.gl-overflow-hidden.gl-mr-3.gl-mt-2 + = markdown_field(project, :description) - - if project.topics.any? - .gl-mt-2 - = render "shared/projects/topics", project: project.present(current_user: current_user) + - if project.topics.any? + .gl-mt-2 + = render "shared/projects/topics", project: project.present(current_user: current_user) - = render_if_exists 'shared/projects/removed', project: project + = render_if_exists 'shared/projects/removed', project: project - .controls.d-flex.flex-sm-column.align-items-center.align-items-sm-end.flex-wrap.flex-shrink-0.text-secondary{ class: css_controls_class.join(" ") } - .icon-container.d-flex.align-items-center + .gl-display-flex.gl-mt-3{ class: "#{css_class} gl-sm-display-none!" } + .controls.gl-display-flex.gl-align-items-center - if show_pipeline_status_icon && last_pipeline.present? - pipeline_path = pipelines_project_commit_path(project.pipeline_status.project, project.pipeline_status.sha, ref: project.pipeline_status.ref) - %span.icon-wrapper.pipeline-status + %span.icon-wrapper.pipeline-status.gl-mr-5 = render 'ci/status/icon', status: last_pipeline.detailed_status(current_user), tooltip_placement: 'top', path: pipeline_path = render_if_exists 'shared/projects/archived', project: project - if stars - = link_to project_starrers_path(project), - class: "d-flex align-items-center icon-wrapper stars has-tooltip", - title: _('Stars'), data: { container: 'body', placement: 'top' } do - = sprite_icon('star', size: 14, css_class: 'gl-mr-2') - = number_with_delimiter(project.star_count) - - if forks - = link_to project_forks_path(project), - class: "align-items-center icon-wrapper forks has-tooltip", - title: _('Forks'), data: { container: 'body', placement: 'top' } do - = sprite_icon('fork', size: 14, css_class: 'gl-mr-2') - = number_with_delimiter(project.forks_count) - - if show_merge_request_count?(disabled: !merge_requests, compact_mode: compact_mode) - = link_to project_merge_requests_path(project), - class: "d-none d-xl-flex align-items-center icon-wrapper merge-requests has-tooltip", - title: _('Merge requests'), data: { container: 'body', placement: 'top' } do - = sprite_icon('git-merge', size: 14, css_class: 'gl-mr-2') - = number_with_delimiter(project.open_merge_requests_count) - - if show_issue_count?(disabled: !issues, compact_mode: compact_mode) - = link_to project_issues_path(project), - class: "d-none d-xl-flex align-items-center icon-wrapper issues has-tooltip", - title: _('Issues'), data: { container: 'body', placement: 'top' } do - = sprite_icon('issues', size: 14, css_class: 'gl-mr-2') - = number_with_delimiter(project.open_issues_count) - .updated-note + = link_to project_starrers_path(project), class: "#{css_metadata_classes} stars", title: _('Stars'), data: { container: 'body', placement: 'top' } do + = sprite_icon('star-o', size: 14, css_class: 'gl-mr-2') + = badge_count(project.star_count) + .updated-note.gl-ml-3.gl-sm-ml-0 %span = _('Updated') = updated_tooltip + + .project-cell{ class: "#{css_class} gl-xs-display-none!" } + .project-controls.gl-display-flex.gl-flex-direction-column.gl-w-full{ class: css_controls_container_class, data: { testid: 'project_controls'} } + .controls.gl-display-flex.gl-align-items-center{ class: css_controls_class } + - if show_pipeline_status_icon && last_pipeline.present? + - pipeline_path = pipelines_project_commit_path(project.pipeline_status.project, project.pipeline_status.sha, ref: project.pipeline_status.ref) + %span.icon-wrapper.pipeline-status.gl-mr-5 + = render 'ci/status/icon', status: last_pipeline.detailed_status(current_user), tooltip_placement: 'top', path: pipeline_path + + = render_if_exists 'shared/projects/archived', project: project + - if stars + = link_to project_starrers_path(project), class: "#{css_metadata_classes} stars", title: _('Stars'), data: { container: 'body', placement: 'top' } do + = sprite_icon('star-o', size: 14, css_class: 'gl-mr-2') + = badge_count(project.star_count) + - if forks + = link_to project_forks_path(project), class: "#{css_metadata_classes} forks", title: _('Forks'), data: { container: 'body', placement: 'top' } do + = sprite_icon('fork', size: 14, css_class: 'gl-mr-2') + = badge_count(project.forks_count) + - if show_merge_request_count?(disabled: !merge_requests, compact_mode: compact_mode) + = link_to project_merge_requests_path(project), class: "#{css_metadata_classes} merge-requests", title: _('Merge requests'), data: { container: 'body', placement: 'top' } do + = sprite_icon('git-merge', size: 14, css_class: 'gl-mr-2') + = badge_count(project.open_merge_requests_count) + - if show_issue_count?(disabled: !issues, compact_mode: compact_mode) + = link_to project_issues_path(project), class: "#{css_metadata_classes} issues", title: _('Issues'), data: { container: 'body', placement: 'top' } do + = sprite_icon('issues', size: 14, css_class: 'gl-mr-2') + = badge_count(project.open_issues_count) + .updated-note.gl-white-space-nowrap.gl-justify-content-end + %span + = _('Updated') + = updated_tooltip diff --git a/app/views/shared/web_hooks/_form.html.haml b/app/views/shared/web_hooks/_form.html.haml index c95e63bdc83..ecb736dac4f 100644 --- a/app/views/shared/web_hooks/_form.html.haml +++ b/app/views/shared/web_hooks/_form.html.haml @@ -10,21 +10,25 @@ = s_('Webhooks|URL must be percent-encoded if it contains one or more special characters.') .form-group = form.label :token, s_('Webhooks|Secret token'), class: 'label-bold' - = form.text_field :token, class: 'form-control gl-form-input', placeholder: '' + = form.password_field :token, value: hook.masked_token, autocomplete: 'new-password', class: 'form-control gl-form-input' %p.form-text.text-muted - code_start = '<code>'.html_safe - code_end = '</code>'.html_safe - = s_('Webhooks|Used to validate received payloads. Sent with the request in the %{code_start}X-Gitlab-Token HTTP%{code_end} header.').html_safe % { code_start: code_start, code_end: code_end } + = s_('Webhooks|Used to validate received payloads. Sent with the request in the %{code_start}X-Gitlab-Token%{code_end} HTTP header.').html_safe % { code_start: code_start, code_end: code_end } .form-group = form.label :url, s_('Webhooks|Trigger'), class: 'label-bold' %ul.list-unstyled %li.gl-pb-5 - = form.gitlab_ui_checkbox_component :push_events, s_('Webhooks|Push events') - .gl-pl-6 - = form.text_field :push_events_branch_filter, class: 'form-control gl-form-input', - placeholder: 'Branch name or wildcard pattern to trigger on (leave blank for all)' - %p.form-text.text-muted.custom-control - = s_('Webhooks|Push to the repository.') + - if Feature.enabled?(:enhanced_webhook_support_regex) + - is_new_hook = hook.id.nil? + .js-vue-push-events{ data: { push_events: hook.push_events.to_s, strategy: hook.branch_filter_strategy, is_new_hook: is_new_hook.to_s, push_events_branch_filter: hook.push_events_branch_filter } } + - else + = form.gitlab_ui_checkbox_component :push_events, s_('Webhooks|Push events') + .gl-pl-6 + = form.text_field :push_events_branch_filter, class: 'form-control gl-form-input', + placeholder: 'Branch name or wildcard pattern to trigger on (leave blank for all)' + %p.form-text.text-muted.custom-control + = s_('Webhooks|Push to the repository.') %li.gl-pb-5 = form.gitlab_ui_checkbox_component :tag_push_events, s_('Webhooks|Tag push events'), |