diff --git a/ghost/admin/app/controllers/tag.js b/ghost/admin/app/controllers/tag.js index 52a16a102d..9b44800e66 100644 --- a/ghost/admin/app/controllers/tag.js +++ b/ghost/admin/app/controllers/tag.js @@ -3,15 +3,12 @@ import DeleteTagModal from '../components/tags/delete-tag-modal'; import {action} from '@ember/object'; import {inject as service} from '@ember/service'; import {task} from 'ember-concurrency'; -import {tracked} from '@glimmer/tracking'; export default class TagController extends Controller { @service modals; @service notifications; @service router; - @tracked showUnsavedChangesModal; - get tag() { return this.model; } @@ -23,37 +20,6 @@ export default class TagController extends Controller { }); } - @action - toggleUnsavedChangesModal(transition) { - let leaveTransition = this.leaveScreenTransition; - - if (!transition && this.showUnsavedChangesModal) { - this.leaveScreenTransition = null; - this.showUnsavedChangesModal = false; - return; - } - - if (!leaveTransition || transition.targetName === leaveTransition.targetName) { - this.leaveScreenTransition = transition; - - // if a save is running, wait for it to finish then transition - if (this.saveTask.isRunning) { - return this.saveTask.last.then(() => { - transition.retry(); - }); - } - - // we genuinely have unsaved data, show the modal - this.showUnsavedChangesModal = true; - } - } - - @action - leaveScreen() { - this.tag.rollbackAttributes(); - return this.leaveScreenTransition.retry(); - } - @task({drop: true}) *saveTask() { let {tag} = this; diff --git a/ghost/admin/app/routes/tag.js b/ghost/admin/app/routes/tag.js index 6bde28c780..ada63bba91 100644 --- a/ghost/admin/app/routes/tag.js +++ b/ghost/admin/app/routes/tag.js @@ -1,7 +1,10 @@ import AuthenticatedRoute from 'ghost-admin/routes/authenticated'; +import ConfirmUnsavedChangesModal from '../components/modals/confirm-unsaved-changes'; +import {action} from '@ember/object'; import {inject as service} from '@ember/service'; export default class TagRoute extends AuthenticatedRoute { + @service modals; @service router; @service session; @@ -9,14 +12,6 @@ export default class TagRoute extends AuthenticatedRoute { // and refresh in the background _requiresBackgroundRefresh = true; - constructor() { - super(...arguments); - - this.router.on('routeWillChange', (transition) => { - this.showUnsavedChangesModal(transition); - }); - } - beforeModel() { super.beforeModel(...arguments); @@ -48,26 +43,49 @@ export default class TagRoute extends AuthenticatedRoute { } deactivate() { - super.deactivate(...arguments); - - // clean up newly created records and revert unsaved changes to existing - this.controller.tag.rollbackAttributes(); - this._requiresBackgroundRefresh = true; + + this.confirmModal = null; + this.hasConfirmed = false; } - showUnsavedChangesModal(transition) { - if (transition.from && transition.from.name === this.routeName && transition.targetName) { - let {controller} = this; + @action + async willTransition(transition) { + if (this.hasConfirmed) { + return true; + } - // tag.changedAttributes is always true for new tags but number of changed attrs is reliable - let isChanged = Object.keys(controller.tag.changedAttributes()).length > 0; + transition.abort(); - if (!controller.tag.isDeleted && isChanged) { - transition.abort(); - controller.toggleUnsavedChangesModal(transition); - return; - } + // wait for any existing confirm modal to be closed before allowing transition + if (this.confirmModal) { + return; + } + + if (this.controller.saveTask?.isRunning) { + await this.controller.saveTask.last; + } + + const shouldLeave = await this.confirmUnsavedChanges(); + + if (shouldLeave) { + this.controller.model.rollbackAttributes(); + this.hasConfirmed = true; + return transition.retry(); } } + + async confirmUnsavedChanges() { + if (this.controller.model?.hasDirtyAttributes) { + this.confirmModal = this.modals + .open(ConfirmUnsavedChangesModal) + .finally(() => { + this.confirmModal = null; + }); + + return this.confirmModal; + } + + return true; + } } diff --git a/ghost/admin/app/templates/tag.hbs b/ghost/admin/app/templates/tag.hbs index 5c2728190f..3d36a17d86 100644 --- a/ghost/admin/app/templates/tag.hbs +++ b/ghost/admin/app/templates/tag.hbs @@ -27,12 +27,4 @@ {{/unless}} - - -{{#if this.showUnsavedChangesModal}} - -{{/if}} \ No newline at end of file + \ No newline at end of file