diff --git a/app/assets/javascripts/badges/components/badge_form.vue b/app/assets/javascripts/badges/components/badge_form.vue index 06fc00891c3fff81887e2ea012f1f29ce6553042..6a919f6024c1f109962b4c941bc7ff94ddedd6c4 100644 --- a/app/assets/javascripts/badges/components/badge_form.vue +++ b/app/assets/javascripts/badges/components/badge_form.vue @@ -208,7 +208,7 @@ export default { <form ref="form" :class="{ 'was-validated': wasValidated }" - class="gl-mt-3 gl-mb-3 needs-validation" + class="needs-validation" novalidate @submit.prevent.stop="onSubmit" > @@ -264,14 +264,13 @@ export default { </p> </div> - <div v-if="!inModal" class="form-group" data-testid="action-buttons"> + <div v-if="!inModal" class="gl-flex gl-gap-3" data-testid="action-buttons"> <gl-button :loading="isSaving" type="submit" variant="confirm" category="primary" data-testid="add-badge-button" - class="gl-mr-3" > {{ saveText }} </gl-button> diff --git a/app/assets/javascripts/badges/components/badge_list.vue b/app/assets/javascripts/badges/components/badge_list.vue index 45a3d7ba2b92b21460af68ce1f9be0a856a35bbf..7c307a5d280b084a53c65cef7cacdf263ed6c27e 100644 --- a/app/assets/javascripts/badges/components/badge_list.vue +++ b/app/assets/javascripts/badges/components/badge_list.vue @@ -31,6 +31,8 @@ export default { GlTooltip: GlTooltipDirective, }, i18n: { + edit: __('Edit'), + delete: __('Delete'), emptyGroupMessage: s__('Badges|This group has no badges. Add an existing badge or create one.'), emptyProjectMessage: s__('Badges|This project has no badges. Start by adding a new badge.'), }, @@ -138,24 +140,26 @@ export default { data-testid="badge-actions" > <gl-button + v-gl-tooltip v-gl-modal.edit-badge-modal :disabled="item.isDeleting" - variant="default" category="tertiary" icon="pencil" size="medium" - :aria-label="__('Edit')" + :title="$options.i18n.edit" + :aria-label="$options.i18n.edit" data-testid="edit-badge-button" @click="editBadge(item)" /> <gl-button + v-gl-tooltip v-gl-modal.delete-badge-modal :disabled="item.isDeleting" category="tertiary" - variant="danger" icon="remove" size="medium" - :aria-label="__('Delete')" + :title="$options.i18n.delete" + :aria-label="$options.i18n.delete" data-testid="delete-badge" @click="updateBadgeInModal(item)" /> diff --git a/app/assets/javascripts/badges/components/badge_settings.vue b/app/assets/javascripts/badges/components/badge_settings.vue index 1892213a233d8f4ee64e23c3d3e644593795c4a9..ebf71d6a5af55ef6230388ee9f5658defc2b15fc 100644 --- a/app/assets/javascripts/badges/components/badge_settings.vue +++ b/app/assets/javascripts/badges/components/badge_settings.vue @@ -1,5 +1,5 @@ <script> -import { GlButton, GlModal, GlSprintf } from '@gitlab/ui'; +import { GlModal, GlSprintf } from '@gitlab/ui'; // eslint-disable-next-line no-restricted-imports import { mapState, mapActions } from 'vuex'; import { createAlert, VARIANT_INFO } from '~/alert'; @@ -12,13 +12,12 @@ import BadgeList from './badge_list.vue'; export default { name: 'BadgeSettings', components: { + CrudComponent, Badge, BadgeForm, BadgeList, - GlButton, GlModal, GlSprintf, - CrudComponent, }, i18n: { title: s__('Badges|Your badges'), @@ -28,11 +27,6 @@ export default { 'Badges|If you delete this badge, you %{strongStart}cannot%{strongEnd} restore it.', ), }, - data() { - return { - addFormVisible: false, - }; - }, computed: { ...mapState(['badges', 'badgeInModal', 'isEditing']), saveProps() { @@ -55,11 +49,8 @@ export default { }, methods: { ...mapActions(['deleteBadge']), - showAddForm() { - this.addFormVisible = !this.addFormVisible; - }, closeAddForm() { - this.addFormVisible = false; + this.$refs.badgesCrud.hideForm(); }, onSubmitEditModal() { this.$refs.editForm.onSubmit(); @@ -85,25 +76,19 @@ export default { <template> <crud-component + ref="badgesCrud" :title="$options.i18n.title" icon="labels" :count="badges.length" - class="badge-settings" + :toggle-text="$options.i18n.addFormTitle" + data-testid="badge-settings" > - <template #actions> - <gl-button - v-if="!addFormVisible" - size="small" - data-testid="show-badge-add-form" - @click="showAddForm" - >{{ $options.i18n.addButton }}</gl-button - > - </template> - - <div v-if="addFormVisible" class="gl-new-card-add-form gl-m-5"> + <template #form> <h4 class="gl-mt-0">{{ $options.i18n.addFormTitle }}</h4> <badge-form :is-editing="false" @close-add-form="closeAddForm" /> - </div> + </template> + + <badge-list /> <gl-modal modal-id="edit-badge-modal" @@ -136,6 +121,5 @@ export default { </gl-sprintf> </p> </gl-modal> - <badge-list /> </crud-component> </template> diff --git a/app/assets/javascripts/vue_shared/components/crud_component.vue b/app/assets/javascripts/vue_shared/components/crud_component.vue index 22826c8582f868588340db1d7db83624f44c88b2..5028e804ea6f5af9553a0acf636114da86dc1b10 100644 --- a/app/assets/javascripts/vue_shared/components/crud_component.vue +++ b/app/assets/javascripts/vue_shared/components/crud_component.vue @@ -88,7 +88,7 @@ export default { </div> <div class="gl-flex gl-items-baseline gl-gap-3" data-testid="crud-actions"> <gl-button - v-if="toggleText" + v-if="toggleText && !isFormVisible" size="small" data-testid="crud-form-toggle" @click="toggleForm" diff --git a/qa/qa/page/component/badges.rb b/qa/qa/page/component/badges.rb index 118e5072f0f1aa5464d3c0da52ea99af30ce394c..a97c3ae8d66f82c250ec7981fda105d0bd7e2861 100644 --- a/qa/qa/page/component/badges.rb +++ b/qa/qa/page/component/badges.rb @@ -4,10 +4,6 @@ module QA module Page module Component class Badges < Page::Base - view 'app/assets/javascripts/badges/components/badge_settings.vue' do - element 'show-badge-add-form' - end - view 'app/assets/javascripts/badges/components/badge_form.vue' do element 'badge-name-field' element 'badge-link-url-field' @@ -25,7 +21,7 @@ class Badges < Page::Base end def show_badge_add_form - click_element 'show-badge-add-form' + click_element 'crud-form-toggle' end def fill_name(name) diff --git a/spec/features/groups/settings/group_badges_spec.rb b/spec/features/groups/settings/group_badges_spec.rb index 1ae61853748f896817258a3e82a1083924c7ff78..51a003e18315eeb4fc18d15271a0383cb9467ad2 100644 --- a/spec/features/groups/settings/group_badges_spec.rb +++ b/spec/features/groups/settings/group_badges_spec.rb @@ -21,10 +21,10 @@ end it 'shows a list of badges', :js do - page.within '.badge-settings' do + within_testid('badge-settings') do wait_for_requests - rows = all('.gl-card-body tbody tr') + rows = all('tbody tr') expect(rows.length).to eq 2 expect(rows[0]).to have_content badge_1.link_url expect(rows[1]).to have_content badge_2.link_url @@ -33,8 +33,8 @@ context 'adding a badge', :js do it 'user can preview a badge' do - click_button 'Add badge' - page.within '.badge-settings form' do + click_button 'Add new badge' + within_testid('crud-form') do fill_in 'badge-link-url', with: badge_link_url fill_in 'badge-image-url', with: badge_image_url within '#badge-preview' do @@ -45,15 +45,15 @@ end it do - click_button 'Add badge' - page.within '.badge-settings' do + click_button 'Add new badge' + within_testid('badge-settings') do fill_in 'badge-link-url', with: badge_link_url fill_in 'badge-image-url', with: badge_image_url click_button 'Add badge' wait_for_requests - within '.gl-card-body' do + within_testid('crud-body') do expect(find('a')[:href]).to eq badge_link_url expect(find('a img')[:src]).to eq badge_image_url end @@ -63,9 +63,9 @@ context 'editing a badge', :js do it 'form is shown when clicking edit button in list' do - page.within '.badge-settings' do + within_testid('badge-settings') do wait_for_requests - rows = all('.gl-card-body tbody tr') + rows = all('tbody tr') expect(rows.length).to eq 2 rows[1].find('[aria-label="Edit"]').click end @@ -77,9 +77,9 @@ end it 'updates a badge when submitting the edit form' do - page.within '.badge-settings' do + within_testid('badge-settings') do wait_for_requests - rows = all('.gl-card-body tbody tr') + rows = all('tbody tr') expect(rows.length).to eq 2 rows[1].find('[aria-label="Edit"]').click end @@ -92,8 +92,8 @@ wait_for_requests end - page.within '.badge-settings' do - rows = all('.gl-card-body tbody tr') + within_testid('badge-settings') do + rows = all('tbody tr') expect(rows.length).to eq 2 expect(rows[1]).to have_content badge_link_url end @@ -107,7 +107,7 @@ def click_delete_button(badge_row) it 'shows a modal when deleting a badge' do wait_for_requests - rows = all('.gl-card-body tbody tr') + rows = all('tbody tr') expect(rows.length).to eq 2 click_delete_button(rows[1]) @@ -117,14 +117,14 @@ def click_delete_button(badge_row) it 'deletes a badge when confirming the modal' do wait_for_requests - rows = all('.gl-card-body tbody tr') + rows = all('tbody tr') expect(rows.length).to eq 2 click_delete_button(rows[1]) find('.modal .btn-danger').click wait_for_requests - rows = all('.gl-card-body tbody tr') + rows = all('tbody tr') expect(rows.length).to eq 1 expect(rows[0]).to have_content badge_1.link_url end diff --git a/spec/features/projects/settings/project_badges_spec.rb b/spec/features/projects/settings/project_badges_spec.rb index ee02f648dec2e69d0845bea3b16fc3bc2ef74e46..36fbdce40180353ae6b08d0f78a7e0b97a2bbaef 100644 --- a/spec/features/projects/settings/project_badges_spec.rb +++ b/spec/features/projects/settings/project_badges_spec.rb @@ -22,10 +22,10 @@ end it 'shows a list of badges', :js do - page.within '.badge-settings' do + within_testid('badge-settings') do wait_for_requests - rows = all('.gl-card-body tbody tr') + rows = all('tbody tr') expect(rows.length).to eq 2 expect(rows[0]).to have_content group_badge.link_url expect(rows[1]).to have_content project_badge.link_url @@ -34,8 +34,8 @@ context 'adding a badge', :js do it 'user can preview a badge' do - click_button 'Add badge' - page.within '.badge-settings form' do + click_button 'Add new badge' + within_testid('crud-form') do fill_in 'badge-link-url', with: badge_link_url fill_in 'badge-image-url', with: badge_image_url within '#badge-preview' do @@ -46,15 +46,15 @@ end it do - click_button 'Add badge' - page.within '.badge-settings' do + click_button 'Add new badge' + within_testid('badge-settings') do fill_in 'badge-link-url', with: badge_link_url fill_in 'badge-image-url', with: badge_image_url click_button 'Add badge' wait_for_requests - within '.gl-card-body' do + within_testid('crud-body') do expect(find('a')[:href]).to eq badge_link_url expect(find('a img')[:src]).to eq badge_image_url end @@ -64,9 +64,9 @@ context 'editing a badge', :js do it 'form is shown when clicking edit button in list' do - page.within '.badge-settings' do + within_testid('badge-settings') do wait_for_requests - rows = all('.gl-card-body tbody tr') + rows = all('tbody tr') expect(rows.length).to eq 2 rows[1].find('[aria-label="Edit"]').click end @@ -78,9 +78,9 @@ end it 'updates a badge when submitting the edit form' do - page.within '.badge-settings' do + within_testid('badge-settings') do wait_for_requests - rows = all('.gl-card-body tbody tr') + rows = all('tbody tr') expect(rows.length).to eq 2 rows[1].find('[aria-label="Edit"]').click end @@ -93,8 +93,8 @@ wait_for_requests end - page.within '.badge-settings' do - rows = all('.gl-card-body tbody tr') + within_testid('badge-settings') do + rows = all('tbody tr') expect(rows.length).to eq 2 expect(rows[1]).to have_content badge_link_url end @@ -108,7 +108,7 @@ def click_delete_button(badge_row) it 'shows a modal when deleting a badge' do wait_for_requests - rows = all('.gl-card-body tbody tr') + rows = all('tbody tr') expect(rows.length).to eq 2 click_delete_button(rows[1]) @@ -118,14 +118,14 @@ def click_delete_button(badge_row) it 'deletes a badge when confirming the modal' do wait_for_requests - rows = all('.gl-card-body tbody tr') + rows = all('tbody tr') expect(rows.length).to eq 2 click_delete_button(rows[1]) find('.modal .btn-danger').click wait_for_requests - rows = all('.gl-card-body tbody tr') + rows = all('tbody tr') expect(rows.length).to eq 1 expect(rows[0]).to have_content group_badge.link_url end diff --git a/spec/frontend/badges/components/badge_settings_spec.js b/spec/frontend/badges/components/badge_settings_spec.js index 5a904857f8912d9dc61dd596054fdfe6368ce842..e88cc09f6337a9bc0f4659ffdc144465d110b83b 100644 --- a/spec/frontend/badges/components/badge_settings_spec.js +++ b/spec/frontend/badges/components/badge_settings_spec.js @@ -1,8 +1,8 @@ -import { GlCard, GlTable } from '@gitlab/ui'; -import { shallowMount } from '@vue/test-utils'; +import { GlTable } from '@gitlab/ui'; import Vue from 'vue'; // eslint-disable-next-line no-restricted-imports import Vuex from 'vuex'; +import { shallowMountExtended } from 'helpers/vue_test_utils_helper'; import CrudComponent from '~/vue_shared/components/crud_component.vue'; import BadgeSettings from '~/badges/components/badge_settings.vue'; import BadgeList from '~/badges/components/badge_list.vue'; @@ -21,10 +21,10 @@ describe('BadgeSettings component', () => { store.state.kind = 'project'; store.state.isEditing = isEditing; - wrapper = shallowMount(BadgeSettings, { + wrapper = shallowMountExtended(BadgeSettings, { store, stubs: { - GlCard, + CrudComponent, GlTable, 'badge-list': BadgeList, 'badge-form': BadgeForm, @@ -38,11 +38,11 @@ describe('BadgeSettings component', () => { it('renders a header with the badge count', () => { createComponent(); - const findCrudComponent = () => wrapper.findComponent(CrudComponent); + const cardTitle = wrapper.findByTestId('crud-title'); + const cardCount = wrapper.findByTestId('crud-count'); - expect(findCrudComponent().props('title')).toBe('Your badges'); - expect(findCrudComponent().props('icon')).toBe('labels'); - expect(findCrudComponent().props('count')).toBe(1); + expect(cardTitle.text()).toContain('Your badges'); + expect(cardCount.text()).toContain('1'); }); it('displays a table', () => { diff --git a/spec/frontend/vue_shared/components/crud_component_spec.js b/spec/frontend/vue_shared/components/crud_component_spec.js index 1d6eed62d6d5c57ecd93f60f97cceb49712f39a4..3e052ffcd668f406912aa05741d6db323016c0af 100644 --- a/spec/frontend/vue_shared/components/crud_component_spec.js +++ b/spec/frontend/vue_shared/components/crud_component_spec.js @@ -77,6 +77,7 @@ describe('CRUD Component', () => { findFormToggle().vm.$emit('click'); await nextTick(); + expect(findFormToggle().exists()).toBe(false); expect(findForm().text()).toBe('Form slot'); });