Switched tag unsaved changes modal to new modal pattern

refs https://github.com/TryGhost/Team/issues/1734
refs https://github.com/TryGhost/Team/issues/559
refs https://github.com/TryGhost/Ghost/issues/14101

- switches to newer modal patterns ready for later Ember upgrades
This commit is contained in:
Kevin Ansfield 2022-09-09 14:48:16 +01:00
parent 04f3ac37d3
commit e17d24358e
3 changed files with 42 additions and 66 deletions

View File

@ -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;

View File

@ -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;
}
}

View File

@ -27,12 +27,4 @@
</button>
</div>
{{/unless}}
</section>
{{#if this.showUnsavedChangesModal}}
<GhFullscreenModal
@modal="leave-settings"
@confirm={{this.leaveScreen}}
@close={{this.toggleUnsavedChangesModal}}
@modifier="action wide" />
{{/if}}
</section>