diff --git a/app/assets/stylesheets/pages/projects.scss b/app/assets/stylesheets/pages/projects.scss index 8cf0bebfc4eaca4816710416051b7ae0cf3d234f..8c0a0c766b24ca84234b8ea15266e64f4c4ff792 100644 --- a/app/assets/stylesheets/pages/projects.scss +++ b/app/assets/stylesheets/pages/projects.scss @@ -493,8 +493,7 @@ } } -.protected-branches-list, -.protected-tags-list { +.protected-branches-list { margin-bottom: 32px; .settings-message { diff --git a/app/views/projects/protected_tags/shared/_create_protected_tag.html.haml b/app/views/projects/protected_tags/shared/_create_protected_tag.html.haml index d67c3dc19d7ad502950a913a994692ea3b08041a..8dcc59a09d092b89b277183fe9bed8ec70154dea 100644 --- a/app/views/projects/protected_tags/shared/_create_protected_tag.html.haml +++ b/app/views/projects/protected_tags/shared/_create_protected_tag.html.haml @@ -1,23 +1,20 @@ = gitlab_ui_form_for [@project, @protected_tag], html: { class: 'new-protected-tag js-new-protected-tag' } do |f| %input{ type: 'hidden', name: 'update_section', value: 'js-protected-tags-settings' } - = render Pajamas::CardComponent.new(card_options: { class: 'gl-mb-5' }) do |c| - - c.with_header do - = _('Protect a tag') - - c.with_body do - = form_errors(@protected_tag) - .form-group.row - = f.label :name, _('Tag:'), class: 'col-md-2 text-left text-md-right' - .col-md-10.protected-tags-dropdown - = render partial: "projects/protected_tags/shared/dropdown", locals: { f: f } - .form-text.text-muted - - wildcards_url = help_page_path('user/project/protected_tags', anchor: 'wildcard-protected-tags') - - wildcards_link_start = ''.html_safe % { url: wildcards_url } - = html_escape(_("%{wildcards_link_start}Wildcards%{wildcards_link_end} such as %{code_tag_start}v*%{code_tag_end} or %{code_tag_start}*-release%{code_tag_end} are supported.")) % { wildcards_link_start: wildcards_link_start, wildcards_link_end: ''.html_safe, code_tag_start: ''.html_safe, code_tag_end: ''.html_safe } - .form-group.row - = f.label :create_access_levels_attributes, _('Allowed to create:'), class: 'col-md-2 text-left text-md-right' - .col-md-10 - .create_access_levels-container - = yield :create_access_levels + = form_errors(@protected_tag) + .form-group + = f.label :name, _('Tag') + .protected-tags-dropdown + = render partial: "projects/protected_tags/shared/dropdown", locals: { f: f } + .form-text.text-muted + - wildcards_url = help_page_path('user/project/protected_tags', anchor: 'wildcard-protected-tags') + - wildcards_link_start = ''.html_safe % { url: wildcards_url } + = html_escape(_("%{wildcards_link_start}Wildcards%{wildcards_link_end} such as %{code_tag_start}v*%{code_tag_end} or %{code_tag_start}*-release%{code_tag_end} are supported.")) % { wildcards_link_start: wildcards_link_start, wildcards_link_end: ''.html_safe, code_tag_start: ''.html_safe, code_tag_end: ''.html_safe } + .form-group + = f.label :create_access_levels_attributes, _('Allowed to create') + .create_access_levels-container + = yield :create_access_levels + + = f.submit _('Protect'), pajamas_button: true, disabled: true, data: { qa_selector: 'protect_tag_button' } + = render Pajamas::ButtonComponent.new(button_options: { type: 'reset', class: 'gl-ml-2 js-toggle-button' }) do + = _('Cancel') - - c.with_footer do - = f.submit _('Protect'), pajamas_button: true, disabled: true, data: { qa_selector: 'protect_tag_button' } diff --git a/app/views/projects/protected_tags/shared/_dropdown.html.haml b/app/views/projects/protected_tags/shared/_dropdown.html.haml index 9d5d649bc40af7cef43adf03859d0b68539d2414..758df7b3c1eb9706dc1deb0606dc6616c55b101c 100644 --- a/app/views/projects/protected_tags/shared/_dropdown.html.haml +++ b/app/views/projects/protected_tags/shared/_dropdown.html.haml @@ -1,7 +1,7 @@ = f.hidden_field(:name) = dropdown_tag(s_('ProtectedBranch|Select tag or create wildcard'), - options: { toggle_class: 'js-protected-tag-select js-filter-submit wide monospace', + options: { toggle_class: 'js-protected-tag-select js-filter-submit wide monospace gl-w-auto!', filter: true, dropdown_class: "dropdown-menu-selectable capitalize-header git-revision-dropdown", placeholder: s_("ProtectedBranch|Search protected tags"), footer_content: true, data: { show_no: true, show_any: true, show_upcoming: true, diff --git a/app/views/projects/protected_tags/shared/_index.html.haml b/app/views/projects/protected_tags/shared/_index.html.haml index a016ccf865694a1a283523f7879b2aa65d8c61d8..81361d90eedc4e4da4531aed19d3c9b70e55c188 100644 --- a/app/views/projects/protected_tags/shared/_index.html.haml +++ b/app/views/projects/protected_tags/shared/_index.html.haml @@ -14,7 +14,22 @@ = s_("ProtectedTag|By default, protected tags restrict who can modify the tag.") = link_to s_("ProtectedTag|Learn more."), help_page_path("user/project/protected_tags", anchor: "who-can-modify-a-protected-tag") - - if can? current_user, :admin_project, @project - = yield :create_protected_tag - - = yield :tag_list + = render Pajamas::CardComponent.new(card_options: { class: 'gl-new-card js-toggle-container' }, header_options: { class: 'gl-new-card-header' }, body_options: { class: 'gl-new-card-body gl-px-0' }) do |c| + - c.with_header do + .gl-new-card-title-wrapper + %h3.gl-new-card-title + = _('Protected tags') + .gl-new-card-count + = sprite_icon('tag', css_class: 'gl-mr-2') + = @protected_tags_count + - if can? current_user, :admin_project, @project + .gl-new-card-actions + = render Pajamas::ButtonComponent.new(size: :small, button_options: { class: "js-toggle-button js-toggle-content" }) do + = _('Add tag') + - c.with_body do + - if can? current_user, :admin_project, @project + .gl-new-card-add-form.gl-m-3.gl-mb-4.gl-display-none.js-toggle-content + %h4.gl-mt-0 + = _('Protect a tag') + = yield :create_protected_tag + = yield :tag_list diff --git a/app/views/projects/protected_tags/shared/_protected_tag.html.haml b/app/views/projects/protected_tags/shared/_protected_tag.html.haml index 4fe1c8bd3cb0c2e5220b4fa77dfaf7f1095b1232..11e8d3a81c24ef9e35d11665b2d62cde10c988e9 100644 --- a/app/views/projects/protected_tags/shared/_protected_tag.html.haml +++ b/app/views/projects/protected_tags/shared/_protected_tag.html.haml @@ -1,10 +1,10 @@ %tr.js-protected-tag-edit-form{ data: { url: project_protected_tag_path(@project, protected_tag) } } - %td + %td{ data: { label: s_('ProtectedBranch|Tag') }, class: 'gl-vertical-align-middle!' } %span.ref-name= protected_tag.name - if @project.root_ref?(protected_tag.name) = gl_badge_tag s_('ProtectedTags|default'), variant: :info, class: 'gl-ml-2' - %td + %td{ data: { label: s_('ProtectedBranch|Last commit') }, class: 'gl-vertical-align-middle!' } - if protected_tag.wildcard? - matching_tags = protected_tag.matching(repository.tag_names) = link_to pluralize(matching_tags.count, "matching tag"), project_protected_tag_path(@project, protected_tag) @@ -18,5 +18,5 @@ = yield - if can? current_user, :admin_project, @project - %td - = link_button_to 'Unprotect', [@project, protected_tag, { update_section: 'js-protected-tags-settings' }], aria: { label: s_('ProtectedTags|Unprotect tag') }, data: { confirm: 'Tag will be writable for developers. Are you sure?', confirm_btn_variant: 'danger' }, method: :delete, variant: :danger, category: :secondary + %td{ data: { label: _('Actions') }, class: 'gl-vertical-align-middle!' } + = link_button_to 'Unprotect', [@project, protected_tag, { update_section: 'js-protected-tags-settings' }], aria: { label: s_('ProtectedTags|Unprotect tag') }, data: { confirm: 'Tag will be writable for developers. Are you sure?', confirm_btn_variant: 'danger' }, method: :delete, variant: :danger, category: :secondary, size: :small diff --git a/app/views/projects/protected_tags/shared/_tags_list.html.haml b/app/views/projects/protected_tags/shared/_tags_list.html.haml index 0a85a353e27e3b639eb58beb0e4db3dcb9fbae8d..66b030a194b416a7b0c5e67a67dd7617e2d4215c 100644 --- a/app/views/projects/protected_tags/shared/_tags_list.html.haml +++ b/app/views/projects/protected_tags/shared/_tags_list.html.haml @@ -1,31 +1,27 @@ .protected-tags-list.js-protected-tags-list - if @protected_tags.empty? - .card-header - = s_('ProtectedBranch|Protected tags (%{tags_count})') % { tags_count: 0 } - %p.settings-message.text-center + .gl-new-card-empty.gl-px-5.gl-py-4 = s_('ProtectedBranch|No tags are protected.') - else - can_admin_project = can?(current_user, :admin_project, @project) - %table.table.table-bordered + %table.table.b-table.gl-table.b-table-stacked-md %colgroup %col{ width: "25%" } %col{ width: "25%" } %col{ width: "50%" } - if can_admin_project %col - %thead + %thead.d-none.d-md-table-header-group %tr %th - = s_('ProtectedBranch|Protected tags (%{tags_count})') % { tags_count: @protected_tags_count } + = s_('ProtectedBranch|Tag') %th = s_('ProtectedBranch|Last commit') %th = s_('ProtectedBranch|Allowed to create') - if can_admin_project %th - %tbody - %tr - = yield + %tbody= yield = paginate @protected_tags, theme: 'gitlab' diff --git a/ee/app/views/projects/protected_tags/ee/_protected_tag_access_summary.html.haml b/ee/app/views/projects/protected_tags/ee/_protected_tag_access_summary.html.haml index 15c853707829aa2381c877356d6a08ee860f6e99..62cfe3db0b824720899f052bcc55e211dccc18f0 100644 --- a/ee/app/views/projects/protected_tags/ee/_protected_tag_access_summary.html.haml +++ b/ee/app/views/projects/protected_tags/ee/_protected_tag_access_summary.html.haml @@ -1,2 +1,2 @@ -%td - = render partial: 'projects/settings/ee/access_level_dropdown', locals: { protected_tag: protected_tag, access_levels: protected_tag.create_access_levels, level_frequencies: access_level_frequencies(protected_tag.create_access_levels), input_basic_name: 'create_access_levels', toggle_class: 'js-allowed-to-create' } +%td{ data: { label: s_('ProtectedBranch|Allowed to create') } } + = render partial: 'projects/settings/ee/access_level_dropdown', locals: { protected_tag: protected_tag, access_levels: protected_tag.create_access_levels, level_frequencies: access_level_frequencies(protected_tag.create_access_levels), input_basic_name: 'create_access_levels', toggle_class: 'js-allowed-to-create gl-w-full! gl-form-input-lg' } diff --git a/ee/spec/support/protected_tags/access_control_shared_examples.rb b/ee/spec/support/protected_tags/access_control_shared_examples.rb index 8bc2fd27e1b9b7c0fe36516cce38bdf9b0d4da24..a667725ebdfaa7317b0f4f1da2293fbe5770e194 100644 --- a/ee/spec/support/protected_tags/access_control_shared_examples.rb +++ b/ee/spec/support/protected_tags/access_control_shared_examples.rb @@ -18,6 +18,7 @@ def access_levels it "allows creating protected tags that roles, users, and groups can create" do visit project_protected_tags_path(project) + click_button('Add tag') set_protected_tag_name('v1.0') set_allowed_to('create', users.map(&:name)) @@ -36,6 +37,7 @@ def access_levels it "allows updating protected tags so that roles and users can create it" do visit project_protected_tags_path(project) + click_button('Add tag') set_protected_tag_name('v1.0') set_allowed_to('create') @@ -57,6 +59,7 @@ def access_levels it "allows updating protected tags so that roles and users cannot create it" do visit project_protected_tags_path(project) + click_button('Add tag') set_protected_tag_name('v1.0') @@ -81,6 +84,7 @@ def access_levels users.each { |user| project.add_developer(user) } visit project_protected_tags_path(project) + click_button('Add tag') # Create Protected Tag set_protected_tag_name('v1.0') @@ -119,6 +123,7 @@ def access_levels context 'When updating a protected tag' do it 'discards other roles when choosing "No one"' do visit project_protected_tags_path(project) + click_button('Add tag') set_protected_tag_name('fix') set_allowed_to('create', roles.values) @@ -148,6 +153,7 @@ def access_levels context 'When creating a protected tag' do it 'discards other roles when choosing "No one"' do visit project_protected_tags_path(project) + click_button('Add tag') set_protected_tag_name('v1.0') set_allowed_to('create', ProtectedRef::AccessLevel.human_access_levels.values) diff --git a/locale/gitlab.pot b/locale/gitlab.pot index 5fa3eb92259ec9af85c2004c315221cff78aa8f8..3f9e51ef9f8b1cb7e7a5b4c9acf0940946380f93 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -2944,6 +2944,9 @@ msgstr "" msgid "Add suggestion to batch" msgstr "" +msgid "Add tag" +msgstr "" + msgid "Add text to the sign-in page. Markdown enabled." msgstr "" @@ -4804,7 +4807,7 @@ msgstr "" msgid "Allowed email domain restriction only permitted for top-level groups" msgstr "" -msgid "Allowed to create:" +msgid "Allowed to create" msgstr "" msgid "Allowed to delete projects" @@ -37621,6 +37624,9 @@ msgstr "" msgid "Protected paths" msgstr "" +msgid "Protected tags" +msgstr "" + msgid "ProtectedBranch|%{wildcards_link_start}Wildcards%{wildcards_link_end} such as %{code_tag_start}*-stable%{code_tag_end} or %{code_tag_start}production/*%{code_tag_end} are supported." msgstr "" @@ -37714,9 +37720,6 @@ msgstr "" msgid "ProtectedBranch|Protected branches" msgstr "" -msgid "ProtectedBranch|Protected tags (%{tags_count})" -msgstr "" - msgid "ProtectedBranch|Reject code pushes that change files listed in the CODEOWNERS file." msgstr "" @@ -37729,6 +37732,9 @@ msgstr "" msgid "ProtectedBranch|Select tag or create wildcard" msgstr "" +msgid "ProtectedBranch|Tag" +msgstr "" + msgid "ProtectedBranch|There are currently no protected branches, protect a branch with the form above." msgstr "" @@ -45850,9 +45856,6 @@ msgstr "" msgid "Tag this commit." msgstr "" -msgid "Tag:" -msgstr "" - msgid "Tagged this commit to %{tag_name} with \"%{message}\"." msgstr "" diff --git a/spec/features/protected_tags_spec.rb b/spec/features/protected_tags_spec.rb index 45315f53fd6b0b4855596da8523f1777a294a408..f5b463d63fadcc2b6db010d5bec803e650d100e1 100644 --- a/spec/features/protected_tags_spec.rb +++ b/spec/features/protected_tags_spec.rb @@ -15,6 +15,8 @@ describe "explicit protected tags" do it "allows creating explicit protected tags" do visit project_protected_tags_path(project) + click_button('Add tag') + set_protected_tag_name('some-tag') set_allowed_to('create') click_on_protect @@ -29,6 +31,7 @@ project.repository.add_tag(user, 'some-tag', commit.id) visit project_protected_tags_path(project) + click_button('Add tag') set_protected_tag_name('some-tag') set_allowed_to('create') click_on_protect @@ -38,6 +41,7 @@ it "displays an error message if the named tag does not exist" do visit project_protected_tags_path(project) + click_button('Add tag') set_protected_tag_name('some-tag') set_allowed_to('create') click_on_protect @@ -49,6 +53,7 @@ describe "wildcard protected tags" do it "allows creating protected tags with a wildcard" do visit project_protected_tags_path(project) + click_button('Add tag') set_protected_tag_name('*-stable') set_allowed_to('create') click_on_protect @@ -63,12 +68,16 @@ project.repository.add_tag(user, 'staging-stable', 'master') visit project_protected_tags_path(project) + click_button('Add tag') set_protected_tag_name('*-stable') set_allowed_to('create') click_on_protect + within("#js-protected-tags-settings .gl-new-card-count") do + expect(page).to have_content("2") + end + within(".protected-tags-list") do - expect(page).to have_content("Protected tags (2)") expect(page).to have_content("2 matching tags") end end @@ -79,11 +88,13 @@ project.repository.add_tag(user, 'development', 'master') visit project_protected_tags_path(project) + click_button('Add tag') set_protected_tag_name('*-stable') set_allowed_to('create') click_on_protect visit project_protected_tags_path(project) + click_button('Add tag') click_on "2 matching tags" within(".protected-tags-list") do diff --git a/spec/support/shared_examples/features/protected_tags_with_deploy_keys_examples.rb b/spec/support/shared_examples/features/protected_tags_with_deploy_keys_examples.rb index cc0984b62262de7d0663fdc401ee27230657d45c..703ba5b018a06db29a1c84935ef0f3432b9192ec 100644 --- a/spec/support/shared_examples/features/protected_tags_with_deploy_keys_examples.rb +++ b/spec/support/shared_examples/features/protected_tags_with_deploy_keys_examples.rb @@ -14,6 +14,7 @@ it "shows all dropdown sections in the 'Allowed to create' main dropdown, with only one deploy key" do visit project_protected_tags_path(project) + click_button('Add tag') find(".js-allowed-to-create").click wait_for_requests @@ -31,6 +32,7 @@ create(:protected_tag, :no_one_can_create, project: project, name: 'v1.0.0') visit project_protected_tags_path(project) + click_button('Add tag') within(".js-protected-tag-edit-form") do find(".js-allowed-to-create").click @@ -46,6 +48,7 @@ context 'when no deploy key can push' do it "just shows all sections but not deploy keys in the 'Allowed to create' dropdown" do visit project_protected_tags_path(project) + click_button('Add tag') find(".js-allowed-to-create").click wait_for_requests diff --git a/spec/support/shared_examples/protected_tags/access_control_ce_shared_examples.rb b/spec/support/shared_examples/protected_tags/access_control_ce_shared_examples.rb index f308b4ad372b1c9c00bbacfcb195a5d017ada77b..371f33f2b29decabd235443bac1551aacaf50123 100644 --- a/spec/support/shared_examples/protected_tags/access_control_ce_shared_examples.rb +++ b/spec/support/shared_examples/protected_tags/access_control_ce_shared_examples.rb @@ -4,6 +4,7 @@ ProtectedRef::AccessLevel.human_access_levels.each do |(access_type_id, access_type_name)| it "allows creating protected tags that #{access_type_name} can create" do visit project_protected_tags_path(project) + click_button('Add tag') set_protected_tag_name('master') set_allowed_to('create', access_type_name) @@ -15,6 +16,7 @@ it "allows updating protected tags so that #{access_type_name} can create them" do visit project_protected_tags_path(project) + click_button('Add tag') set_protected_tag_name('master') set_allowed_to('create', 'No one')