import Controller from '@ember/controller'; import EmberObject from '@ember/object'; import boundOneWay from 'ghost-admin/utils/bound-one-way'; import moment from 'moment'; import windowProxy from 'ghost-admin/utils/window-proxy'; import {alias} from '@ember/object/computed'; import {computed, defineProperty} from '@ember/object'; import {inject as controller} from '@ember/controller'; import {inject as service} from '@ember/service'; import {task} from 'ember-concurrency'; const SCRATCH_PROPS = ['name', 'email', 'note']; export default Controller.extend({ members: controller(), notifications: service(), router: service(), store: service(), member: alias('model'), scratchMember: computed('member', function () { let scratchMember = EmberObject.create({member: this.member}); SCRATCH_PROPS.forEach(prop => defineProperty(scratchMember, prop, boundOneWay(`member.${prop}`))); return scratchMember; }), subscribedAt: computed('member.createdAtUTC', function () { let memberSince = moment(this.member.createdAtUTC).from(moment()); let createdDate = moment(this.member.createdAtUTC).format('MMM DD, YYYY'); return `${createdDate} (${memberSince})`; }), actions: { setProperty(propKey, value) { this._saveMemberProperty(propKey, value); }, toggleDeleteMemberModal() { this.toggleProperty('showDeleteMemberModal'); }, save() { return this.save.perform(); }, deleteMember() { return this.member.destroyRecord().then(() => { return this.transitionToRoute('members'); }, (error) => { return this.notifications.showAPIError(error, {key: 'member.delete'}); }); }, toggleUnsavedChangesModal(transition) { let leaveTransition = this.leaveScreenTransition; if (!transition && this.showUnsavedChangesModal) { this.set('leaveScreenTransition', null); this.set('showUnsavedChangesModal', false); return; } if (!leaveTransition || transition.targetName === leaveTransition.targetName) { this.set('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.set('showUnsavedChangesModal', true); } }, leaveScreen() { this.member.rollbackAttributes(); return this.leaveScreenTransition.retry(); } }, save: task(function* () { let {member, scratchMember} = this; // if Cmd+S is pressed before the field loses focus make sure we're // saving the intended property values let scratchProps = scratchMember.getProperties(SCRATCH_PROPS); member.setProperties(scratchProps); try { yield member.save(); // replace 'member.new' route with 'member' route this.replaceRoute('member', member); return member; } catch (error) { if (error) { this.notifications.showAPIError(error, {key: 'member.save'}); } } }).drop(), fetchMember: task(function* (memberId) { this.set('isLoading', true); yield this.store.findRecord('member', memberId, { reload: true }).then((member) => { this.set('member', member); this.set('isLoading', false); return member; }); }), _saveMemberProperty(propKey, newValue) { let member = this.member; member.set(propKey, newValue); } });