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')