diff options
author | Phil Hughes <me@iamphill.com> | 2018-01-19 11:49:24 +0300 |
---|---|---|
committer | Robert Speicher <rspeicher@gmail.com> | 2018-01-23 00:45:41 +0300 |
commit | 69487e5cd13ec22db00580e0a77a6ebc2bdb99d8 (patch) | |
tree | 3ea2cc1a323c66407baf1a473cd93d8a295e0745 | |
parent | 30f2dd368be05000ea525883ff6e82b3781c2b6d (diff) |
Merge branch 'fix-description-loss' into 'master'
Add confirm when navigating away from page
Closes #42102
See merge request gitlab-org/gitlab-ce!16518
-rw-r--r-- | app/assets/javascripts/issue_show/components/app.vue | 57 | ||||
-rw-r--r-- | spec/javascripts/issue_show/components/app_spec.js | 33 |
2 files changed, 90 insertions, 0 deletions
diff --git a/app/assets/javascripts/issue_show/components/app.vue b/app/assets/javascripts/issue_show/components/app.vue index fc10a43d1bf..aa2d6aaffa5 100644 --- a/app/assets/javascripts/issue_show/components/app.vue +++ b/app/assets/javascripts/issue_show/components/app.vue @@ -25,9 +25,26 @@ export default { required: true, type: Boolean, }, +<<<<<<< HEAD canDestroy: { required: true, type: Boolean, +======= + computed: { + formState() { + return this.store.formState; + }, + hasUpdated() { + return !!this.state.updatedAt; + }, + issueChanged() { + const descriptionChanged = + this.initialDescriptionText !== this.store.formState.description; + const titleChanged = + this.initialTitleText !== this.store.formState.title; + return descriptionChanged || titleChanged; + }, +>>>>>>> 28bd902980f... Merge branch 'fix-description-loss' into 'master' }, showInlineEditButton: { type: Boolean, @@ -155,6 +172,7 @@ export default { recaptchaModalImplementor, ], +<<<<<<< HEAD methods: { openForm() { if (!this.showForm) { @@ -170,6 +188,45 @@ export default { closeForm() { this.showForm = false; }, +======= + window.addEventListener('beforeunload', this.handleBeforeUnloadEvent); + + eventHub.$on('delete.issuable', this.deleteIssuable); + eventHub.$on('update.issuable', this.updateIssuable); + eventHub.$on('close.form', this.closeForm); + eventHub.$on('open.form', this.openForm); + }, + beforeDestroy() { + eventHub.$off('delete.issuable', this.deleteIssuable); + eventHub.$off('update.issuable', this.updateIssuable); + eventHub.$off('close.form', this.closeForm); + eventHub.$off('open.form', this.openForm); + window.removeEventListener('beforeunload', this.handleBeforeUnloadEvent); + }, + methods: { + handleBeforeUnloadEvent(e) { + const event = e; + if (this.showForm && this.issueChanged) { + event.returnValue = 'Are you sure you want to lose your issue information?'; + } + return undefined; + }, + + openForm() { + if (!this.showForm) { + this.showForm = true; + this.store.setFormState({ + title: this.state.titleText, + description: this.state.descriptionText, + lockedWarningVisible: false, + updateLoading: false, + }); + } + }, + closeForm() { + this.showForm = false; + }, +>>>>>>> 28bd902980f... Merge branch 'fix-description-loss' into 'master' updateIssuable() { return this.service.updateIssuable(this.store.formState) diff --git a/spec/javascripts/issue_show/components/app_spec.js b/spec/javascripts/issue_show/components/app_spec.js index 1454ca52018..9280db072b3 100644 --- a/spec/javascripts/issue_show/components/app_spec.js +++ b/spec/javascripts/issue_show/components/app_spec.js @@ -218,6 +218,39 @@ describe('Issuable output', () => { }); }); + describe('shows dialog when issue has unsaved changed', () => { + it('confirms on title change', (done) => { + vm.showForm = true; + vm.state.titleText = 'title has changed'; + const e = { returnValue: null }; + vm.handleBeforeUnloadEvent(e); + Vue.nextTick(() => { + expect(e.returnValue).not.toBeNull(); + done(); + }); + }); + + it('confirms on description change', (done) => { + vm.showForm = true; + vm.state.descriptionText = 'description has changed'; + const e = { returnValue: null }; + vm.handleBeforeUnloadEvent(e); + Vue.nextTick(() => { + expect(e.returnValue).not.toBeNull(); + done(); + }); + }); + + it('does nothing when nothing has changed', (done) => { + const e = { returnValue: null }; + vm.handleBeforeUnloadEvent(e); + Vue.nextTick(() => { + expect(e.returnValue).toBeNull(); + done(); + }); + }); + }); + describe('error when updating', () => { beforeEach(() => { spyOn(window, 'Flash').and.callThrough(); |