mirror of
https://github.com/TryGhost/Ghost.git
synced 2024-11-30 01:42:29 +03:00
2f849c431f
no issue - depending on when the newsletter settings route is accessed we would sometimes show an empty newsletter list - the problem stems from the use of a non-reactive fixed list of displayed newsletters where we manually update the list when we know the list should change. On initial load we were using `await store.findAll('newsletter')` then updating the displayed list, however the default behaviour for `store.findAll()` is to immediately return a live array - this doesn't work for our use-case because we'd then potentially update our displayed list from incomplete data - added the `{reload: true}` option to the `findAll()` call to force a wait for the API request to finish before updating the displayed list of newsletters
153 lines
4.4 KiB
JavaScript
153 lines
4.4 KiB
JavaScript
import Component from '@glimmer/component';
|
|
import ConfirmArchiveModal from '../../modals/edit-newsletter/confirm-archive';
|
|
import ConfirmUnarchiveModal from '../../modals/edit-newsletter/confirm-unarchive';
|
|
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;
|
|
|
|
@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.members-email-labs.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
|
|
unarchiveNewsletter(newsletter) {
|
|
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.findAll('newsletter', {reload: true});
|
|
|
|
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;
|
|
}
|
|
}
|
|
}
|