mirror of
https://github.com/TryGhost/Ghost.git
synced 2024-11-29 07:09:48 +03:00
86751f902c
no issue - in future Ember build tooling components must be imported directly rather than passing a name at runtime
169 lines
5.0 KiB
JavaScript
169 lines
5.0 KiB
JavaScript
import Component from '@glimmer/component';
|
|
import ConfirmArchiveModal from '../../modals/newsletters/confirm-archive';
|
|
import ConfirmUnarchiveModal from '../../modals/newsletters/confirm-unarchive';
|
|
import MultipleNewslettersLimitModal from '../../modals/limits/multiple-newsletters';
|
|
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 NewsletterManagementComponent extends Component {
|
|
@service modals;
|
|
@service router;
|
|
@service store;
|
|
@service limit;
|
|
|
|
@tracked statusFilter = 'active';
|
|
@tracked filteredNewsletters = [];
|
|
|
|
statusFilters = ['active', 'archived'];
|
|
newsletters = this.store.peekAll('newsletter');
|
|
|
|
constructor() {
|
|
super(...arguments);
|
|
this.loadNewslettersTask.perform();
|
|
|
|
this.router.on('routeDidChange', this.handleNewRouteChange);
|
|
}
|
|
|
|
willDestroy() {
|
|
super.willDestroy(...arguments);
|
|
this.router.off('routeDidChange', this.handleNewRouteChange);
|
|
|
|
this.confirmArchiveModal?.close();
|
|
this.confirmUnarchiveModal?.close();
|
|
}
|
|
|
|
get activeNewsletters() {
|
|
return this.newsletters.filter(n => n.status === 'active');
|
|
}
|
|
|
|
get archivedNewsletters() {
|
|
return this.newsletters.filter(n => n.status === 'archived');
|
|
}
|
|
|
|
get displayingDefault() {
|
|
return this.statusFilter === 'active' && this.filteredNewsletters.length === 1;
|
|
}
|
|
|
|
@action
|
|
changeStatusFilter(status) {
|
|
this.statusFilter = status;
|
|
this.updateFilteredNewsletters();
|
|
}
|
|
|
|
@action
|
|
updateFilteredNewsletters() {
|
|
this.filteredNewsletters = this.newsletters.filter((n) => {
|
|
return n.status === this.statusFilter
|
|
&& !n.isNew
|
|
&& !n.isDestroyed;
|
|
});
|
|
}
|
|
|
|
@action
|
|
handleNewRouteChange(transition) {
|
|
// NOTE: this is necessary because ember-drag-drop has forced us into using
|
|
// an explicit tracked filteredNewsletters property rather than using a reactive
|
|
// getter that automatically displays newly added newsletters
|
|
|
|
if (transition.from.name === 'settings.newsletters.new-newsletter') {
|
|
this.updateFilteredNewsletters();
|
|
}
|
|
}
|
|
|
|
@action
|
|
archiveNewsletter(newsletter) {
|
|
this.confirmArchiveModal = this.modals.open(ConfirmArchiveModal, {
|
|
newsletter,
|
|
archiveNewsletterTask: this.archiveNewsletterTask
|
|
});
|
|
}
|
|
|
|
@task
|
|
*archiveNewsletterTask(newsletter) {
|
|
newsletter.status = 'archived';
|
|
const result = yield newsletter.save();
|
|
|
|
this.updateFilteredNewsletters();
|
|
|
|
this.confirmArchiveModal?.close();
|
|
|
|
return result;
|
|
}
|
|
|
|
@action
|
|
async unarchiveNewsletter(newsletter) {
|
|
try {
|
|
await this.limit.limiter.errorIfWouldGoOverLimit('newsletters');
|
|
} catch (error) {
|
|
if (error.errorType === 'HostLimitError') {
|
|
// Not allowed: we reached the limit here
|
|
this.modals.open(MultipleNewslettersLimitModal, {
|
|
message: error.message
|
|
});
|
|
return;
|
|
}
|
|
|
|
throw error;
|
|
}
|
|
|
|
this.confirmUnarchiveModal = this.modals.open(ConfirmUnarchiveModal, {
|
|
newsletter,
|
|
unarchiveNewsletterTask: this.unarchiveNewsletterTask
|
|
});
|
|
}
|
|
|
|
@task
|
|
*unarchiveNewsletterTask(newsletter) {
|
|
newsletter.status = 'active';
|
|
const result = yield newsletter.save();
|
|
|
|
if (this.statusFilter === 'archived' && !this.archivedNewsletters.length) {
|
|
this.statusFilter = 'active';
|
|
}
|
|
|
|
this.updateFilteredNewsletters();
|
|
|
|
this.confirmUnarchiveModal?.close();
|
|
|
|
return result;
|
|
}
|
|
|
|
@task
|
|
*loadNewslettersTask() {
|
|
const newsletters = yield this.store.query('newsletter', {include: 'count.members,count.posts', limit: 'all'});
|
|
|
|
this.updateFilteredNewsletters();
|
|
|
|
return newsletters;
|
|
}
|
|
|
|
@task
|
|
*reorderNewslettersTask() {
|
|
// filteredNewsletters is the array that gets updated by <SortableObjects> whilst dragging.
|
|
// we only want to update ordering when _active_ newsletters are re-ordered to make sure
|
|
// archived newsletters don't end up with a lower sort order than active ones
|
|
|
|
if (this.statusFilter !== 'active') {
|
|
return;
|
|
}
|
|
|
|
// use filteredNewsletters rather than activeNewsletters so we're using'the ordered array
|
|
const activeNewsletters = this.filteredNewsletters;
|
|
|
|
const otherNewsletters = this.newsletters
|
|
.filter(n => !activeNewsletters.includes(n))
|
|
.sort(({sortOrder: a}, {sortOrder: b}) => b - a);
|
|
|
|
let sortOrder = 0;
|
|
|
|
for (const n of [...activeNewsletters, ...otherNewsletters]) {
|
|
n.sortOrder = sortOrder;
|
|
yield n.save();
|
|
|
|
sortOrder += 1;
|
|
}
|
|
}
|
|
}
|