0
Fork 0
mirror of https://github.com/TryGhost/Ghost.git synced 2025-03-11 02:12:21 -05:00

Switched member 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 15:05:35 +01:00
parent e17d24358e
commit 543c44415d
3 changed files with 44 additions and 60 deletions

View file

@ -20,12 +20,9 @@ export default class MemberController extends Controller {
@tracked isLoading = false; @tracked isLoading = false;
@tracked showDeleteMemberModal = false; @tracked showDeleteMemberModal = false;
@tracked showImpersonateMemberModal = false; @tracked showImpersonateMemberModal = false;
@tracked showUnsavedChangesModal = false;
@tracked modalLabel = null; @tracked modalLabel = null;
@tracked showLabelModal = false; @tracked showLabelModal = false;
leaveScreenTransition = null;
constructor() { constructor() {
super(...arguments); super(...arguments);
this._availableLabels = this.store.peekAll('label'); this._availableLabels = this.store.peekAll('label');
@ -135,37 +132,6 @@ export default class MemberController 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.save.isRunning) {
return this.save.last.then(() => {
transition.retry();
});
}
// we genuinely have unsaved data, show the modal
this.showUnsavedChangesModal = true;
}
}
@action
leaveScreen() {
this.member.rollbackAttributes();
return this.leaveScreenTransition.retry();
}
// Tasks ------------------------------------------------------------------- // Tasks -------------------------------------------------------------------
@task({drop: true}) @task({drop: true})

View file

@ -1,9 +1,11 @@
import AdminRoute from 'ghost-admin/routes/admin'; import AdminRoute from 'ghost-admin/routes/admin';
import ConfirmUnsavedChangesModal from '../components/modals/confirm-unsaved-changes';
import {action} from '@ember/object'; import {action} from '@ember/object';
import {inject as service} from '@ember/service'; import {inject as service} from '@ember/service';
export default class MembersRoute extends AdminRoute { export default class MembersRoute extends AdminRoute {
@service feature; @service feature;
@service modals;
@service router; @service router;
_requiresBackgroundRefresh = true; _requiresBackgroundRefresh = true;
@ -11,7 +13,6 @@ export default class MembersRoute extends AdminRoute {
constructor() { constructor() {
super(...arguments); super(...arguments);
this.router.on('routeWillChange', (transition) => { this.router.on('routeWillChange', (transition) => {
this.showUnsavedChangesModal(transition);
this.closeImpersonateModal(transition); this.closeImpersonateModal(transition);
}); });
} }
@ -36,10 +37,10 @@ export default class MembersRoute extends AdminRoute {
} }
deactivate() { deactivate() {
super.deactivate(...arguments);
// clean up newly created records and revert unsaved changes to existing
this.controller.member.rollbackAttributes();
this._requiresBackgroundRefresh = true; this._requiresBackgroundRefresh = true;
this.confirmModal = null;
this.hasConfirmed = false;
} }
@action @action
@ -47,27 +48,48 @@ export default class MembersRoute extends AdminRoute {
this.controller.save(); this.controller.save();
} }
titleToken() { @action
return this.controller.member.name; async willTransition(transition) {
} if (this.hasConfirmed) {
return true;
}
showUnsavedChangesModal(transition) { transition.abort();
if (transition.from && transition.from.name === this.routeName && transition.targetName) {
let {controller} = this;
// member.changedAttributes is always true for new members but number of changed attrs is reliable // wait for any existing confirm modal to be closed before allowing transition
let isChanged = Object.keys(controller.member.changedAttributes()).length > 0; if (this.confirmModal) {
return;
}
if (!controller.member.isDeleted && isChanged) { if (this.controller.saveTask?.isRunning) {
transition.abort(); await this.controller.saveTask.last;
controller.toggleUnsavedChangesModal(transition); }
return;
} 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;
}
closeImpersonateModal(transition) { closeImpersonateModal(transition) {
// If user navigates away with forward or back button, ensure returning to page // If user navigates away with forward or back button, ensure returning to page
// hides modal // hides modal
if (transition.from && transition.from.name === this.routeName && transition.targetName) { if (transition.from && transition.from.name === this.routeName && transition.targetName) {
let {controller} = this; let {controller} = this;
@ -75,4 +97,8 @@ export default class MembersRoute extends AdminRoute {
controller.closeImpersonateMemberModal(transition); controller.closeImpersonateMemberModal(transition);
} }
} }
titleToken() {
return this.controller.member.name;
}
} }

View file

@ -68,14 +68,6 @@
</div> </div>
</section> </section>
{{#if this.showUnsavedChangesModal}}
<GhFullscreenModal
@modal="leave-settings"
@confirm={{this.leaveScreen}}
@close={{this.toggleUnsavedChangesModal}}
@modifier="action wide" />
{{/if}}
{{#if this.showDeleteMemberModal}} {{#if this.showDeleteMemberModal}}
<GhFullscreenModal <GhFullscreenModal
@modal="delete-member" @modal="delete-member"