mirror of
https://github.com/TryGhost/Ghost.git
synced 2024-12-25 20:03:12 +03:00
Updated members count to use selected newsletter when publishing
refs https://github.com/TryGhost/Team/issues/1576 - Passes the selected newsletter to the recipient selector - Added a `recipientFilter` getter to the newsletter model to make changes easier in the future - Updates the `fullRecipientFilter` in the new publishing flow to use the newsletter's recipientFilter - Already takes future paid only newsletters into account - The counts in the status message after publishing is not updated yet (requires https://github.com/TryGhost/Team/issues/1569) - The counts in the scheduled notification is not updated yet (requires https://github.com/TryGhost/Team/issues/1569)
This commit is contained in:
parent
03ba0da1a7
commit
1f5f9645e6
@ -162,7 +162,7 @@ export class PublishOptions {
|
||||
}
|
||||
|
||||
get fullRecipientFilter() {
|
||||
let filter = `newsletters:${this.newsletter.slug}`;
|
||||
let filter = this.newsletter.recipientFilter;
|
||||
|
||||
if (this.recipientFilter) {
|
||||
filter += `+(${this.recipientFilter})`;
|
||||
|
@ -24,9 +24,10 @@
|
||||
|
||||
<GhMembersRecipientSelect
|
||||
@filter={{@publishOptions.recipientFilter}}
|
||||
@newsletter={{@publishOptions.newsletter}}
|
||||
@onChange={{@publishOptions.setRecipientFilter}}
|
||||
@renderInPlace={{false}}
|
||||
@dropdownClass="gh-publishmenu-newsletter-dropdown"
|
||||
/>
|
||||
</div>
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
|
@ -1,4 +1,4 @@
|
||||
<div class="gh-publishmenu-send-to-option">
|
||||
<div class="gh-publishmenu-send-to-option" {{did-update this.onUpdateNewsletter @newsletter }}>
|
||||
<p>Free members <span class="gh-publishmenu-emailcount" data-test-email-count="free-members">{{this.freeMemberCountLabel}}</span></p>
|
||||
<div class="for-switch x-small {{if @disabled "disabled"}}">
|
||||
<label class="switch" for="send-email-to-free">
|
||||
|
@ -78,6 +78,11 @@ export default class GhMembersRecipientSelect extends Component {
|
||||
return '';
|
||||
}
|
||||
|
||||
@action
|
||||
onUpdateNewsletter() {
|
||||
this.fetchMemberCountsTask.perform();
|
||||
}
|
||||
|
||||
@action
|
||||
toggleFilter(filter) {
|
||||
if (this.args.disabled) {
|
||||
@ -202,15 +207,15 @@ export default class GhMembersRecipientSelect extends Component {
|
||||
*fetchMemberCountsTask() {
|
||||
const user = yield this.session.user;
|
||||
|
||||
if (!user.isAdmin) {
|
||||
if (!user.isAdmin || !this.args.newsletter) {
|
||||
return;
|
||||
}
|
||||
|
||||
yield Promise.all([
|
||||
this.store.query('member', {filter: 'newsletters.status:active+status:free', limit: 1}).then((res) => {
|
||||
this.store.query('member', {filter: this.args.newsletter.recipientFilter + '+status:free', limit: 1}).then((res) => {
|
||||
this.freeMemberCount = res.meta.pagination.total;
|
||||
}),
|
||||
this.store.query('member', {filter: 'newsletters.status:active+status:-free', limit: 1}).then((res) => {
|
||||
this.store.query('member', {filter: this.args.newsletter.recipientFilter + '+status:-free', limit: 1}).then((res) => {
|
||||
this.paidMemberCount = res.meta.pagination.total;
|
||||
})
|
||||
]);
|
||||
|
@ -80,6 +80,7 @@
|
||||
|
||||
<GhMembersRecipientSelect
|
||||
@filter={{@recipientsFilter}}
|
||||
@newsletter={{@selectedNewsletter}}
|
||||
@onChange={{@setSendEmailWhenPublished}}
|
||||
/>
|
||||
</div>
|
||||
@ -90,4 +91,4 @@
|
||||
</div>
|
||||
{{/if}}
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -59,6 +59,7 @@
|
||||
<div class="form-group">
|
||||
<GhMembersRecipientSelect
|
||||
@filter={{@recipientsFilter}}
|
||||
@newsletter={{this.selectedNewsletter}}
|
||||
@disabled={{true}}
|
||||
/>
|
||||
</div>
|
||||
@ -68,4 +69,4 @@
|
||||
</section>
|
||||
{{/if}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -401,7 +401,7 @@ export default Component.extend({
|
||||
post: this.post,
|
||||
emailOnly: this.emailOnly,
|
||||
sendEmailWhenPublished: this.sendEmailWhenPublished,
|
||||
newsletterId: this.newsletterId,
|
||||
newsletter: this.selectedNewsletter,
|
||||
isScheduled: saveType === 'schedule',
|
||||
confirm: this.saveWithConfirmedPublish.perform,
|
||||
retryEmailSend: this.retryEmailSendTask.perform
|
||||
@ -449,17 +449,15 @@ export default Component.extend({
|
||||
}),
|
||||
|
||||
fetchNewslettersTask: task(function* () {
|
||||
if (this.feature.multipleNewsletters) {
|
||||
const newsletters = yield this.store.query('newsletter', {
|
||||
filter: 'status:active',
|
||||
order: 'sort_order ASC'
|
||||
});
|
||||
const newsletters = yield this.store.query('newsletter', {
|
||||
filter: 'status:active',
|
||||
order: 'sort_order ASC'
|
||||
});
|
||||
|
||||
const defaultNewsletter = newsletters.toArray()[0];
|
||||
const defaultNewsletter = newsletters.toArray()[0];
|
||||
|
||||
this.defaultNewsletter = defaultNewsletter;
|
||||
this.set('selectedNewsletter', defaultNewsletter);
|
||||
}
|
||||
this.defaultNewsletter = defaultNewsletter;
|
||||
this.set('selectedNewsletter', defaultNewsletter);
|
||||
}),
|
||||
|
||||
_saveTask: task(function* () {
|
||||
|
@ -59,8 +59,8 @@ export default class ConfirmPublishModal extends Component {
|
||||
|
||||
@task
|
||||
*countRecipientsTask() {
|
||||
const {sendEmailWhenPublished} = this.args.data;
|
||||
const filter = `newsletters.status:active+(${sendEmailWhenPublished})`;
|
||||
const {sendEmailWhenPublished,newsletter} = this.args.data;
|
||||
const filter = `${newsletter.recipientFilter}+(${sendEmailWhenPublished})`;
|
||||
|
||||
this.memberCount = sendEmailWhenPublished ? (yield this.membersCountCache.count(filter)) : 0;
|
||||
this.memberCountString = sendEmailWhenPublished ? (yield this.membersCountCache.countString(filter)) : '0 members';
|
||||
|
@ -1079,6 +1079,7 @@ export default class EditorController extends Controller {
|
||||
let description = emailOnly ? ['Will be sent'] : ['Will be published'];
|
||||
|
||||
if (emailRecipientFilter && emailRecipientFilter !== 'none') {
|
||||
// TODO: replace active filter with newsletter.recipientFilter (requires https://github.com/TryGhost/Team/issues/1569)
|
||||
const recipientCount = await this.membersCountCache.countString(`newsletters.status:active+(${emailRecipientFilter})`);
|
||||
description.push(`${!emailOnly ? 'and delivered ' : ''}to <span><strong>${recipientCount}</strong></span>`);
|
||||
}
|
||||
|
@ -13,7 +13,6 @@ export default class Newsletter extends Model.extend(ValidationEngine) {
|
||||
@attr({defaultValue: 'newsletter'}) senderReplyTo;
|
||||
|
||||
@attr({defaultValue: 'active'}) status;
|
||||
@attr({defaultValue: ''}) recipientFilter;
|
||||
@attr({defaultValue: true}) subscribeOnSignup;
|
||||
@attr({defaultValue: 'members'}) visibility;
|
||||
@attr({defaultValue: 0}) sortOrder;
|
||||
@ -34,4 +33,15 @@ export default class Newsletter extends Model.extend(ValidationEngine) {
|
||||
// HACK - not a real model attribute but a workaround for Ember Data not
|
||||
// exposing meta from save responses
|
||||
@attr _meta;
|
||||
|
||||
/**
|
||||
* The filter that we should use to filter out members that are subscribed to this newsletter
|
||||
*/
|
||||
get recipientFilter() {
|
||||
const idFilter = 'newsletters.id:' + this.id;
|
||||
if (this.visibility === 'paid') {
|
||||
return idFilter + '+status:-free';
|
||||
}
|
||||
return idFilter;
|
||||
}
|
||||
}
|
||||
|
@ -6,6 +6,7 @@ import {authenticateSession, invalidateSession} from 'ember-simple-auth/test-sup
|
||||
import {beforeEach, describe, it} from 'mocha';
|
||||
import {blur, click, currentRouteName, currentURL, fillIn, find, findAll, triggerEvent} from '@ember/test-helpers';
|
||||
import {datepickerSelect} from 'ember-power-datepicker/test-support';
|
||||
import {enableLabsFlag} from '../helpers/labs-flag';
|
||||
import {enableMailgun} from '../helpers/mailgun';
|
||||
import {enableNewsletters} from '../helpers/newsletters';
|
||||
import {enableStripe} from '../helpers/stripe';
|
||||
@ -845,6 +846,7 @@ describe('Acceptance: Editor', function () {
|
||||
const role = this.server.create('role', {name: 'Administrator'});
|
||||
user = this.server.create('user', {roles: [role]});
|
||||
this.server.loadFixtures('settings');
|
||||
enableLabsFlag(this.server, 'multipleNewsletters');
|
||||
return await authenticateSession();
|
||||
});
|
||||
|
||||
@ -876,7 +878,8 @@ describe('Acceptance: Editor', function () {
|
||||
// Enable stripe to also show paid members breakdown
|
||||
enableStripe(this.server);
|
||||
|
||||
const newsletter = this.server.create('newsletter', {status: 'active'});
|
||||
// Note: we need to set the ID of a newsletter to some string value because of how NQL filters work.
|
||||
const newsletter = this.server.create('newsletter', {status: 'active', name: 'test newsletter', id: 'test-newsletter'});
|
||||
this.server.createList('member', 4, {status: 'free', newsletters: [newsletter]});
|
||||
this.server.createList('member', 2, {status: 'paid', newsletters: [newsletter]});
|
||||
|
||||
@ -889,8 +892,8 @@ describe('Acceptance: Editor', function () {
|
||||
await selectChoose('[data-test-distribution-action-select]', 'send');
|
||||
await click('[data-test-publishmenu-scheduled-option]');
|
||||
await datepickerSelect('[data-test-publishmenu-draft] [data-test-date-time-picker-datepicker]', new Date(scheduledTime.format().replace(/\+.*$/, '')));
|
||||
|
||||
// Expect 4 free and 2 paid recipients here
|
||||
|
||||
// Expect 4 free and 2 paid recipients here
|
||||
expect(find('[data-test-email-count="free-members"]')).to.contain.text('4');
|
||||
expect(find('[data-test-email-count="paid-members"]')).to.contain.text('2');
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user