Commit 35864591 authored by Jarek Ostrowski's avatar Jarek Ostrowski Committed by Natalia Tepluhina

Update badge list row modal to gl-modal

MR: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/44495
parent 2128a652
<script>
import { mapActions, mapState } from 'vuex';
import { GlLoadingIcon, GlButton } from '@gitlab/ui';
import { GlLoadingIcon, GlButton, GlModalDirective } from '@gitlab/ui';
import { s__ } from '~/locale';
import { PROJECT_BADGE } from '../constants';
import Badge from './badge.vue';
......@@ -12,6 +12,9 @@ export default {
GlLoadingIcon,
GlButton,
},
directives: {
GlModal: GlModalDirective,
},
props: {
badge: {
type: Object,
......@@ -61,13 +64,13 @@ export default {
@click="editBadge(badge)"
/>
<gl-button
v-gl-modal.delete-badge-modal
:disabled="badge.isDeleting"
variant="danger"
data-toggle="modal"
data-target="#delete-badge-modal"
icon="remove"
size="medium"
:aria-label="__('Delete')"
data-testid="delete-badge"
@click="updateBadgeInModal(badge)"
/>
<gl-loading-icon v-show="badge.isDeleting" :inline="true" />
......
<script>
import { mapState, mapActions } from 'vuex';
import { GlSprintf } from '@gitlab/ui';
import { GlSprintf, GlModal } from '@gitlab/ui';
import { deprecatedCreateFlash as createFlash } from '~/flash';
import { s__ } from '~/locale';
import DeprecatedModal2 from '~/vue_shared/components/deprecated_modal_2.vue';
import Badge from './badge.vue';
import BadgeForm from './badge_form.vue';
import BadgeList from './badge_list.vue';
......@@ -14,7 +13,7 @@ export default {
Badge,
BadgeForm,
BadgeList,
GlModal: DeprecatedModal2,
GlModal,
GlSprintf,
},
i18n: {
......@@ -24,6 +23,17 @@ export default {
},
computed: {
...mapState(['badgeInModal', 'isEditing']),
primaryProps() {
return {
text: s__('Delete badge'),
attributes: [{ category: 'primary' }, { variant: 'danger' }],
};
},
cancelProps() {
return {
text: s__('Cancel'),
};
},
},
methods: {
...mapActions(['deleteBadge']),
......@@ -44,11 +54,11 @@ export default {
<template>
<div class="badge-settings">
<gl-modal
id="delete-badge-modal"
:header-title-text="s__('Badges|Delete badge?')"
:footer-primary-button-text="s__('Badges|Delete badge')"
footer-primary-button-variant="danger"
@submit="onSubmitModal"
modal-id="delete-badge-modal"
:title="s__('Badges|Delete badge?')"
:action-primary="primaryProps"
:action-cancel="cancelProps"
@primary="onSubmitModal"
>
<div class="well">
<badge
......@@ -65,9 +75,9 @@ export default {
</p>
</gl-modal>
<badge-form v-show="isEditing" :is-editing="true" />
<badge-form v-show="isEditing" :is-editing="true" data-testid="edit-badge" />
<badge-form v-show="!isEditing" :is-editing="false" />
<badge-form v-show="!isEditing" :is-editing="false" data-testid="add-new-badge" />
<badge-list v-show="!isEditing" />
</div>
</template>
---
title: Update delete badge modal to gl-modal
merge_request: 44495
author:
type: changed
......@@ -14557,9 +14557,9 @@ CREATE TABLE plan_limits (
nuget_max_file_size bigint DEFAULT 524288000 NOT NULL,
pypi_max_file_size bigint DEFAULT '3221225472'::bigint NOT NULL,
generic_packages_max_file_size bigint DEFAULT '5368709120'::bigint NOT NULL,
project_feature_flags integer DEFAULT 200 NOT NULL,
golang_max_file_size bigint DEFAULT 104857600 NOT NULL,
debian_max_file_size bigint DEFAULT '3221225472'::bigint NOT NULL,
project_feature_flags integer DEFAULT 200 NOT NULL,
ci_max_artifact_size_api_fuzzing integer DEFAULT 0 NOT NULL
);
......
......@@ -4028,9 +4028,6 @@ msgstr ""
msgid "Badges|Badge image preview"
msgstr ""
msgid "Badges|Delete badge"
msgstr ""
msgid "Badges|Delete badge?"
msgstr ""
......@@ -8561,6 +8558,9 @@ msgstr ""
msgid "Delete artifacts"
msgstr ""
msgid "Delete badge"
msgstr ""
msgid "Delete board"
msgstr ""
......
import Vue from 'vue';
import { mountComponentWithStore } from 'helpers/vue_mount_component_helper';
import Vuex from 'vuex';
import { shallowMount, createLocalVue } from '@vue/test-utils';
import { GlModal } from '@gitlab/ui';
import store from '~/badges/store';
import BadgeSettings from '~/badges/components/badge_settings.vue';
import BadgeList from '~/badges/components/badge_list.vue';
import BadgeListRow from '~/badges/components/badge_list_row.vue';
import { createDummyBadge } from '../dummy_badge';
describe('BadgeSettings component', () => {
const Component = Vue.extend(BadgeSettings);
let vm;
const localVue = createLocalVue();
localVue.use(Vuex);
beforeEach(() => {
setFixtures(`
<div id="dummy-element"></div>
<button
id="dummy-modal-button"
type="button"
data-toggle="modal"
data-target="#delete-badge-modal"
>Show modal</button>
`);
describe('BadgeSettings component', () => {
let wrapper;
const badge = createDummyBadge();
// Can be removed once GlLoadingIcon no longer throws a warning
jest.spyOn(global.console, 'warn').mockImplementation(() => jest.fn());
const createComponent = (isEditing = false) => {
store.state.badges = [badge];
store.state.kind = 'project';
store.state.isEditing = isEditing;
vm = mountComponentWithStore(Component, {
el: '#dummy-element',
wrapper = shallowMount(BadgeSettings, {
store,
localVue,
stubs: {
'badge-list': BadgeList,
'badge-list-row': BadgeListRow,
},
});
};
beforeEach(() => {
createComponent();
});
afterEach(() => {
vm.$destroy();
wrapper.destroy();
});
it('displays modal if button is clicked', done => {
const badge = createDummyBadge();
store.state.badgeInModal = badge;
const modal = vm.$el.querySelector('#delete-badge-modal');
const button = document.getElementById('dummy-modal-button');
it('displays modal if button for deleting a badge is clicked', async () => {
const button = wrapper.find('[data-testid="delete-badge"]');
button.click();
button.vm.$emit('click');
await wrapper.vm.$nextTick();
Vue.nextTick()
.then(() => {
expect(modal.innerText).toMatch('Delete badge?');
const badgeElement = modal.querySelector('img.project-badge');
expect(badgeElement).not.toBe(null);
expect(badgeElement.getAttribute('src')).toBe(badge.renderedImageUrl);
})
.then(done)
.catch(done.fail);
const modal = wrapper.find(GlModal);
expect(modal.isVisible()).toBe(true);
});
it('displays a form to add a badge', () => {
const form = vm.$el.querySelector('form:nth-of-type(2)');
expect(form).not.toBe(null);
const button = form.querySelector('.btn-success');
expect(button).not.toBe(null);
expect(button).toHaveText(/Add badge/);
expect(wrapper.find('[data-testid="add-new-badge"]').isVisible()).toBe(true);
});
it('displays badge list', () => {
const badgeListElement = vm.$el.querySelector('.card');
expect(badgeListElement).not.toBe(null);
expect(badgeListElement).toBeVisible();
expect(badgeListElement.innerText).toMatch('Your badges');
expect(wrapper.find(BadgeList).isVisible()).toBe(true);
});
describe('when editing', () => {
beforeEach(done => {
store.state.isEditing = true;
Vue.nextTick()
.then(done)
.catch(done.fail);
beforeEach(() => {
createComponent(true);
});
it('displays a form to edit a badge', () => {
const form = vm.$el.querySelector('form:nth-of-type(1)');
expect(form).not.toBe(null);
const cancelButton = form.querySelector('[data-testid="cancelEditing"]');
expect(cancelButton).not.toBe(null);
expect(cancelButton).toHaveText(/Cancel/);
const submitButton = form.querySelector('[data-testid="saveEditing"]');
expect(submitButton).not.toBe(null);
expect(submitButton).toHaveText(/Save changes/);
expect(wrapper.find('[data-testid="edit-badge"]').isVisible()).toBe(true);
});
it('displays no badge list', () => {
const badgeListElement = vm.$el.querySelector('.card');
expect(badgeListElement).toBeHidden();
});
});
describe('methods', () => {
describe('onSubmitModal', () => {
it('triggers ', () => {
jest.spyOn(vm, 'deleteBadge').mockImplementation(() => Promise.resolve());
const modal = vm.$el.querySelector('#delete-badge-modal');
const deleteButton = modal.querySelector('.btn-danger');
deleteButton.click();
const badge = store.state.badgeInModal;
expect(vm.deleteBadge).toHaveBeenCalledWith(badge);
});
expect(wrapper.find(BadgeList).isVisible()).toBe(false);
});
});
});
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment