Commit 9cad09d3 authored by Savas Vedova's avatar Savas Vedova

Improve modal interaction

Restore previous state when the modal is closed without being
saved. Otherwise, it's confusing for the user as it seems like
the action was saved.
parent 0b096a99
...@@ -54,9 +54,11 @@ export default { ...@@ -54,9 +54,11 @@ export default {
}, },
data() { data() {
return { return {
previouslySelectedProject: {},
selectedProject: { ...this.assignedPolicyProject }, selectedProject: { ...this.assignedPolicyProject },
hasSelectedNewProject: false, hasSelectedNewProject: false,
shouldShowUnlinkWarning: false, shouldShowUnlinkWarning: false,
savingChanges: false,
}; };
}, },
computed: { computed: {
...@@ -94,6 +96,8 @@ export default { ...@@ -94,6 +96,8 @@ export default {
throw new Error(data.securityPolicyProjectAssign.errors); throw new Error(data.securityPolicyProjectAssign.errors);
} }
this.previouslySelectedProject = this.selectedProject;
this.$emit('project-updated', { this.$emit('project-updated', {
text: this.$options.i18n.save.okLink, text: this.$options.i18n.save.okLink,
variant: 'success', variant: 'success',
...@@ -122,7 +126,7 @@ export default { ...@@ -122,7 +126,7 @@ export default {
} }
this.shouldShowUnlinkWarning = false; this.shouldShowUnlinkWarning = false;
this.selectedProject = {}; this.previouslySelectedProject = {};
this.$emit('project-updated', { this.$emit('project-updated', {
text: this.$options.i18n.save.okUnlink, text: this.$options.i18n.save.okUnlink,
variant: 'success', variant: 'success',
...@@ -136,6 +140,7 @@ export default { ...@@ -136,6 +140,7 @@ export default {
}, },
async saveChanges() { async saveChanges() {
this.savingChanges = true;
this.$emit('updating-project'); this.$emit('updating-project');
if (this.shouldShowUnlinkWarning) { if (this.shouldShowUnlinkWarning) {
...@@ -144,7 +149,7 @@ export default { ...@@ -144,7 +149,7 @@ export default {
await this.linkProject(); await this.linkProject();
} }
this.hasSelectedNewProject = false; this.savingChanges = false;
}, },
setSelectedProject(data) { setSelectedProject(data) {
this.shouldShowUnlinkWarning = false; this.shouldShowUnlinkWarning = false;
...@@ -154,8 +159,18 @@ export default { ...@@ -154,8 +159,18 @@ export default {
}, },
confirmDeletion() { confirmDeletion() {
this.shouldShowUnlinkWarning = !this.shouldShowUnlinkWarning; this.shouldShowUnlinkWarning = !this.shouldShowUnlinkWarning;
this.selectedProject = {};
this.hasSelectedNewProject = true;
},
restoreProject() {
this.selectedProject = this.previouslySelectedProject;
}, },
closeModal() { closeModal() {
if (this.hasSelectedNewProject && !this.savingChanges) {
this.restoreProject();
}
this.hasSelectedNewProject = false;
this.shouldShowUnlinkWarning = false; this.shouldShowUnlinkWarning = false;
this.$emit('close'); this.$emit('close');
}, },
...@@ -211,7 +226,7 @@ export default { ...@@ -211,7 +226,7 @@ export default {
/> />
</gl-dropdown> </gl-dropdown>
<gl-button <gl-button
v-if="selectedProjectId" v-if="selectedProjectId || shouldShowUnlinkWarning"
icon="remove" icon="remove"
class="gl-ml-3" class="gl-ml-3"
:aria-label="$options.i18n.unlinkButtonLabel" :aria-label="$options.i18n.unlinkButtonLabel"
......
...@@ -27,16 +27,20 @@ describe('ScanNewPolicyModal Component', () => { ...@@ -27,16 +27,20 @@ describe('ScanNewPolicyModal Component', () => {
const findAlert = () => wrapper.findComponent(GlAlert); const findAlert = () => wrapper.findComponent(GlAlert);
const findModal = () => wrapper.findComponent(GlModal); const findModal = () => wrapper.findComponent(GlModal);
const selectProject = async ( const selectProject = async ({
project = { project = {
id: 'gid://gitlab/Project/1', id: 'gid://gitlab/Project/1',
name: 'Test 1', name: 'Test 1',
}, },
) => { shouldSubmit = true,
} = {}) => {
findInstanceProjectSelector().vm.$emit('projectClicked', project); findInstanceProjectSelector().vm.$emit('projectClicked', project);
await wrapper.vm.$nextTick(); await wrapper.vm.$nextTick();
if (shouldSubmit) {
findModal().vm.$emit('ok'); findModal().vm.$emit('ok');
await wrapper.vm.$nextTick(); await wrapper.vm.$nextTick();
}
}; };
const createWrapper = ({ const createWrapper = ({
...@@ -100,11 +104,17 @@ describe('ScanNewPolicyModal Component', () => { ...@@ -100,11 +104,17 @@ describe('ScanNewPolicyModal Component', () => {
}); });
}); });
it('emits close event when gl-modal emits change event', () => { it('emits close event when gl-modal emits change event', async () => {
createWrapper(); createWrapper();
findModal().vm.$emit('change'); await selectProject({ shouldSubmit: false });
findModal().vm.$emit('change');
expect(wrapper.emitted('close')).toEqual([[]]); expect(wrapper.emitted('close')).toEqual([[]]);
expect(findInstanceProjectSelector().props('selectedProjects')[0].name).toBe('Test 1');
// should restore the previous state when action is not submitted
await wrapper.vm.$nextTick();
expect(findInstanceProjectSelector().props('selectedProjects')[0].name).toBeUndefined();
}); });
describe('unlinking project', () => { describe('unlinking project', () => {
...@@ -169,6 +179,10 @@ describe('ScanNewPolicyModal Component', () => { ...@@ -169,6 +179,10 @@ describe('ScanNewPolicyModal Component', () => {
text: 'Security policy project was linked successfully', text: 'Security policy project was linked successfully',
variant: 'success', variant: 'success',
}); });
expect(findInstanceProjectSelector().props('selectedProjects')).toEqual([
{ id: 'gid://gitlab/Project/1', name: 'Test 1' },
]);
}); });
it('emits an event with an error message', async () => { it('emits an event with an error message', async () => {
......
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