Ghost/ghost/admin/app/routes/member.js

124 lines
3.4 KiB
JavaScript
Raw Normal View History

import * as Sentry from '@sentry/ember';
Refactored away CurrentUserSettings mixin (#2200) no issue Mixins are deprecated in Ember so we want to remove their usage. The `CurrentUserSettings` mixin was used in Route files to provide `transitionAuthor()` (that also transitions contributors) and `transitionEditor()` methods so the the consuming route could use them to prevent access to authors/editors. In practice the only reason this was used was to prevent access to admin-only routes. - added an `AdminRoute` class that inherits from our `AuthenticatedRoute` class - when any route inherits from this class it will only allow access to admins and owners, any other user will be redirected to the home screen (dashboard or site depending on permissions) - updated all of our admin-only routes to use the new `AdminRoute` - allowed for removal of `CurrentUserSettings` mixin usage - allowed for `beforeModel()` hooks to be removed from consuming routes in many cases - some admin-only routes were extending/inheriting directly from Ember's `Route` based on the assumption that the router hierarchy would have a parent route perform the redirect. Those have also been switched to `AdminRoute` for consistency and to prevent accidentally making them available if the router hierarchy changes - `/#/settings` does not use the `AdminRoute` so that it can redirect to the current user's setting page for non-admin users - removed `CurrentUserSettings` mixin file - cleaned up unnecessary computed property and function used for redirect-when-disabled in the Zapier route
2022-01-17 13:05:27 +03:00
import AdminRoute from 'ghost-admin/routes/admin';
import ConfirmUnsavedChangesModal from '../components/modals/confirm-unsaved-changes';
import {action} from '@ember/object';
import {inject as service} from '@ember/service';
Refactored away CurrentUserSettings mixin (#2200) no issue Mixins are deprecated in Ember so we want to remove their usage. The `CurrentUserSettings` mixin was used in Route files to provide `transitionAuthor()` (that also transitions contributors) and `transitionEditor()` methods so the the consuming route could use them to prevent access to authors/editors. In practice the only reason this was used was to prevent access to admin-only routes. - added an `AdminRoute` class that inherits from our `AuthenticatedRoute` class - when any route inherits from this class it will only allow access to admins and owners, any other user will be redirected to the home screen (dashboard or site depending on permissions) - updated all of our admin-only routes to use the new `AdminRoute` - allowed for removal of `CurrentUserSettings` mixin usage - allowed for `beforeModel()` hooks to be removed from consuming routes in many cases - some admin-only routes were extending/inheriting directly from Ember's `Route` based on the assumption that the router hierarchy would have a parent route perform the redirect. Those have also been switched to `AdminRoute` for consistency and to prevent accidentally making them available if the router hierarchy changes - `/#/settings` does not use the `AdminRoute` so that it can redirect to the current user's setting page for non-admin users - removed `CurrentUserSettings` mixin file - cleaned up unnecessary computed property and function used for redirect-when-disabled in the Zapier route
2022-01-17 13:05:27 +03:00
export default class MembersRoute extends AdminRoute {
@service feature;
@service modals;
@service router;
queryParams = {
postAnalytics: {refreshModel: false}
};
_requiresBackgroundRefresh = true;
constructor() {
super(...arguments);
this.router.on('routeWillChange', (transition) => {
this.closeImpersonateModal(transition);
});
}
model(params) {
this._requiresBackgroundRefresh = false;
if (params.member_id) {
return this.store.queryRecord('member', {id: params.member_id, include: 'tiers'});
} else {
return this.store.createRecord('member');
}
}
setupController(controller, member, transition) {
super.setupController(...arguments);
controller.setInitialRelationshipValues();
if (this._requiresBackgroundRefresh) {
controller.fetchMemberTask.perform(member.id);
}
controller.directlyFromAnalytics = false;
if (transition.from?.name === 'posts.analytics') {
controller.directlyFromAnalytics = true;
}
}
resetController(controller, isExiting) {
super.resetController(...arguments);
// Make sure we clear
if (isExiting && controller.postAnalytics) {
controller.set('postAnalytics', null);
controller.set('directlyFromAnalytics', false);
}
}
deactivate() {
this._requiresBackgroundRefresh = true;
this.confirmModal = null;
this.hasConfirmed = false;
}
@action
save() {
this.controller.save();
}
@action
async willTransition(transition) {
let hasDirtyAttributes = this.controller.dirtyAttributes;
// wait for any existing confirm modal to be closed before allowing transition
if (this.confirmModal) {
return;
}
if (!this.hasConfirmed && hasDirtyAttributes) {
transition.abort();
if (this.controller.saveTask?.isRunning) {
await this.controller.saveTask.last;
transition.retry();
}
const shouldLeave = await this.confirmUnsavedChanges();
if (shouldLeave) {
this.controller.model.rollbackAttributes();
this.hasConfirmed = true;
return transition.retry();
}
}
}
async confirmUnsavedChanges() {
Sentry.captureMessage('showing unsaved changes modal for members route');
this.confirmModal = this.modals
.open(ConfirmUnsavedChangesModal)
.finally(() => {
this.confirmModal = null;
});
return this.confirmModal;
}
closeImpersonateModal(transition) {
// If user navigates away with forward or back button, ensure returning to page
// hides modal
if (transition.from && transition.from.name === this.routeName && transition.targetName) {
let {controller} = this;
controller.closeImpersonateMemberModal(transition);
}
}
titleToken() {
return this.controller.member.name;
}
}