Ghost/ghost/admin/app/components/modal-confirm-email-send.js
Kevin Ansfield bd60c8089b 🐛 Fixed confusing member count shown in save notification and editor header
closes https://github.com/TryGhost/Team/issues/776

Since switching to using a real NQL filter in the `posts.email_recipient_filter` field where we used to show `free members`, `paid members`, or `all members` we were showing `status:free`, `status:-free`, and `status:free,status:-free` respectively. If labels are used in a filter the text became even longer.

- added a `membersCountCache` service
  - `.count(filter)` fetches a numeric count from the members API, if the filter has been counted in the last minute it returns the count directly from a cache instead to avoid hammering the members API when we show counts in multiple places across the UI
  - `.countString(filter)` fetches a count but returns a humanized string with the logic extracted from what we displayed in the confirm email sending modal
- added a `<GhRecipientFilterCount @filter="" />` component that acts as a wrapper around the async count from `membersCountCache`
- updated confirm email send modal, plus save notification and editor status displays for scheduled posts to use the new service and component
2021-06-11 11:44:50 +01:00

81 lines
2.3 KiB
JavaScript

import ModalComponent from 'ghost-admin/components/modal-base';
import {action} from '@ember/object';
import {inject as service} from '@ember/service';
import {task} from 'ember-concurrency';
export default ModalComponent.extend({
membersCountCache: service(),
session: service(),
store: service(),
errorMessage: null,
memberCount: null,
// Allowed actions
confirm: () => {},
actions: {
confirm() {
if (this.errorMessage) {
return this.retryEmailTask.perform();
} else {
if (!this.countRecipientsTask.isRunning) {
return this.confirmAndCheckErrorTask.perform();
}
}
}
},
countRecipients: action(function () {
this.countRecipientsTask.perform();
}),
countRecipientsTask: task(function* () {
const {sendEmailWhenPublished} = this.model;
const filter = `subscribed:true+(${sendEmailWhenPublished})`;
const result = sendEmailWhenPublished ? yield this.membersCountCache.countString(filter) : 'no members';
this.set('memberCount', result);
}),
confirmAndCheckErrorTask: task(function* () {
try {
yield this.confirm();
this.closeModal();
return true;
} catch (e) {
// switch to "failed" state if email fails
if (e && e.name === 'EmailFailedError') {
this.set('errorMessage', e.message);
return;
}
// close modal and continue with normal error handling if it was
// a non-email-related error
this.closeModal();
if (e) {
throw e;
}
}
}),
retryEmailTask: task(function* () {
try {
yield this.model.retryEmailSend();
this.closeModal();
return true;
} catch (e) {
// update "failed" state if email fails again
if (e && e.name === 'EmailFailedError') {
this.set('errorMessage', e.message);
return;
}
// TODO: test a non-email failure - maybe this needs to go through
// the notifications service
if (e) {
throw e;
}
}
})
});