Updated publishing with renamed newsletter and email_segment options (#2380)

refs https://github.com/TryGhost/Team/issues/1596

This commit updates admin to align with the changes in the backend in https://github.com/TryGhost/Ghost/pull/14798

- `post.email_recipient_filter` option and property is renamed to `email_segment`
- `newsletter_id` option is renamed to `newsletter` (and now uses slug instead of id)
- Sending a post via email, means you need to set the `newsletter` option. The `email_segment` option is optional now and defaults to `all`. Not setting `newsletter` means not sending an email, setting `email_segment` is ignored if `newsletter` is missing.
- We can no longer use `email_recipient_filter` (now renamed to `email_segment`) to know whether a post is published/scheduled to be sent as an email. We need to rely on the newsletter relation now. The `email_segment` `none` value has been dropped and will be `all` even if no email will be sent (newsletter will be null). 
- `sendEmailWhenPublished` option is no longer supported in the backend.
This commit is contained in:
Simon Backx 2022-05-16 10:18:46 +02:00 committed by GitHub
parent 3e8c5403b6
commit 3a11faf0b6
9 changed files with 37 additions and 47 deletions

View File

@ -6,22 +6,21 @@ export default class Post extends ApplicationAdapter {
const url = this.buildURL(modelName, id, snapshot, requestType, query); const url = this.buildURL(modelName, id, snapshot, requestType, query);
const parsedUrl = new URL(url); const parsedUrl = new URL(url);
if (snapshot?.adapterOptions?.newsletter) {
const newsletter = snapshot.adapterOptions.newsletter;
parsedUrl.searchParams.append('newsletter', newsletter);
// TODO: cleanup sendEmailWhenPublished when removing publishingFlow flag // TODO: cleanup sendEmailWhenPublished when removing publishingFlow flag
let emailRecipientFilter = snapshot?.adapterOptions?.emailRecipientFilter let emailSegment = snapshot?.adapterOptions?.emailSegment
|| snapshot?.adapterOptions?.sendEmailWhenPublished; || snapshot?.adapterOptions?.sendEmailWhenPublished;
if (emailRecipientFilter) { if (emailSegment) {
if (emailRecipientFilter === 'status:free,status:-free') { if (emailSegment === 'status:free,status:-free') {
emailRecipientFilter = 'all'; emailSegment = 'all';
} }
parsedUrl.searchParams.append('email_recipient_filter', emailRecipientFilter); parsedUrl.searchParams.append('email_segment', emailSegment);
} }
if (snapshot?.adapterOptions?.newsletter) {
// TODO: rename newsletter_id to newsletter once changed in the backend
const newsletterId = snapshot.adapterOptions.newsletter;
parsedUrl.searchParams.append('newsletter_id', newsletterId);
} }
return parsedUrl.toString(); return parsedUrl.toString();

View File

@ -33,7 +33,7 @@
{{#if {{#if
(or post.isSent (or post.isSent
(and post.isPublished post.email) (and post.isPublished post.email)
(and post.isScheduled post.emailRecipientFilter (not post.email)) post.willEmail
) )
}} }}
{{#if post.emailOnly}} {{#if post.emailOnly}}

View File

@ -23,7 +23,7 @@
Scheduled Scheduled
{{#if this.isHovered}} {{#if this.isHovered}}
to be published to be published
{{#if (and @post.emailRecipientFilter (not @post.email))}} {{#if (and @post.newsletter (not @post.email))}}
and sent to <GhRecipientFilterCount @filter={{@post.fullRecipientFilter}} @newsletter={{@post.newsletter}} /> and sent to <GhRecipientFilterCount @filter={{@post.fullRecipientFilter}} @newsletter={{@post.newsletter}} />
{{/if}} {{/if}}
{{this.scheduledTime}} {{this.scheduledTime}}

View File

@ -51,14 +51,12 @@
{{#if (and this.feature.emailAnalytics (eq @post.displayName "post"))}} {{#if (and this.feature.emailAnalytics (eq @post.displayName "post"))}}
<LinkTo @route="editor.edit" @models={{array @post.displayName @post.id}} class="permalink gh-list-data gh-post-list-recipients"> <LinkTo @route="editor.edit" @models={{array @post.displayName @post.id}} class="permalink gh-list-data gh-post-list-recipients">
<div class="flex fw4"> <div class="flex fw4">
{{#if (or @post.email @post.willEmail)}}
{{#if (eq @post.email.status "submitted")}} {{#if (eq @post.email.status "submitted")}}
<span class="flex" data-tooltip="{{capitalize @post.email.recipientFilter}} members"> <span class="flex" data-tooltip="{{capitalize @post.email.recipientFilter}} members">
<span class="darkgrey fw5 gh-content-email-stats">{{format-number @post.email.emailCount}}</span> <span class="darkgrey fw5 gh-content-email-stats">{{format-number @post.email.emailCount}}</span>
<span class="midgrey-l2 fw4 gh-content-email-stats-mobile">{{gh-pluralize @post.email.emailCount "send"}}</span> <span class="midgrey-l2 fw4 gh-content-email-stats-mobile">{{gh-pluralize @post.email.emailCount "send"}}</span>
</span> </span>
{{/if}} {{/if}}
{{/if}}
</div> </div>
</LinkTo> </LinkTo>
@ -84,9 +82,9 @@
<a href={{@post.url}} class="permalink gh-list-data gh-post-list-status" target="_blank" rel="noopener noreferrer"> <a href={{@post.url}} class="permalink gh-list-data gh-post-list-status" target="_blank" rel="noopener noreferrer">
<div class="flex items-center"> <div class="flex items-center">
{{#if @post.isScheduled}} {{#if @post.isScheduled}}
<span class="gh-content-status-scheduled gh-badge nowrap" title="Scheduled" data-tooltip="{{capitalize this.scheduledText}} to {{@post.emailRecipientFilter}} members"> <span class="gh-content-status-scheduled gh-badge nowrap" title="Scheduled" data-tooltip="{{capitalize this.scheduledText}} to {{@post.emailSegment}} members">
Scheduled Scheduled
{{#if @post.emailRecipientFilter}} {{#if @post.newsletter}}
{{svg-jar "email-stroke"}} {{svg-jar "email-stroke"}}
{{/if}} {{/if}}
</span> </span>
@ -118,9 +116,9 @@
<LinkTo @route="editor.edit" @models={{array @post.displayName @post.id}} class="permalink gh-list-data gh-post-list-status"> <LinkTo @route="editor.edit" @models={{array @post.displayName @post.id}} class="permalink gh-list-data gh-post-list-status">
<div class="flex items-center"> <div class="flex items-center">
{{#if @post.isScheduled}} {{#if @post.isScheduled}}
<span class="gh-content-status-scheduled gh-badge nowrap" title="Scheduled" data-tooltip="{{capitalize this.scheduledText}} to {{@post.emailRecipientFilter}} members"> <span class="gh-content-status-scheduled gh-badge nowrap" title="Scheduled" data-tooltip="{{capitalize this.scheduledText}} to {{@post.emailSegment}} members">
Scheduled Scheduled
{{#if @post.emailRecipientFilter}} {{#if @post.newsletter}}
{{svg-jar "email-stroke"}} {{svg-jar "email-stroke"}}
{{/if}} {{/if}}
</span> </span>

View File

@ -11,11 +11,6 @@ export default class GhPostsListItemComponent extends Component {
@tracked isHovered = false; @tracked isHovered = false;
get sendEmailWhenPublished() {
let {post} = this.args;
return post.emailRecipientFilter && post.emailRecipientFilter !== 'none';
}
get scheduledText() { get scheduledText() {
let {post} = this.args; let {post} = this.args;
let text = []; let text = [];

View File

@ -335,7 +335,7 @@ export default Component.extend({
// Set default newsletter recipients // Set default newsletter recipients
this.set('sendEmailWhenPublished', this.defaultEmailRecipients); this.set('sendEmailWhenPublished', this.defaultEmailRecipients);
} else { } else {
this.set('sendEmailWhenPublished', this.post.emailRecipientFilter); this.set('sendEmailWhenPublished', this.post.emailSegment);
} }
}, },
@ -476,7 +476,7 @@ export default Component.extend({
try { try {
// will show alert for non-date related failed validations // will show alert for non-date related failed validations
post = yield this.saveTask.perform({sendEmailWhenPublished, newsletter: this.selectedNewsletter?.id, emailOnly}); post = yield this.saveTask.perform({sendEmailWhenPublished, newsletter: this.selectedNewsletter?.slug, emailOnly});
this._cachePublishedAtBlogTZ(); this._cachePublishedAtBlogTZ();

View File

@ -1069,7 +1069,6 @@ export default class EditorController extends Controller {
async _showScheduledNotification(delayed) { async _showScheduledNotification(delayed) {
let { let {
publishedAtUTC, publishedAtUTC,
emailRecipientFilter,
previewUrl, previewUrl,
emailOnly, emailOnly,
newsletter newsletter
@ -1079,7 +1078,7 @@ export default class EditorController extends Controller {
let title = 'Scheduled'; let title = 'Scheduled';
let description = emailOnly ? ['Will be sent'] : ['Will be published']; let description = emailOnly ? ['Will be sent'] : ['Will be published'];
if (emailRecipientFilter && emailRecipientFilter !== 'none') { if (newsletter) {
const recipientCount = await this.membersCountCache.countString(this.post.fullRecipientFilter, {newsletter}); const recipientCount = await this.membersCountCache.countString(this.post.fullRecipientFilter, {newsletter});
description.push(`${!emailOnly ? 'and delivered ' : ''}to <span><strong>${recipientCount}</strong></span>`); description.push(`${!emailOnly ? 'and delivered ' : ''}to <span><strong>${recipientCount}</strong></span>`);
} }

View File

@ -104,7 +104,7 @@ export default Model.extend(Comparable, ValidationEngine, {
updatedBy: attr('number'), updatedBy: attr('number'),
url: attr('string'), url: attr('string'),
uuid: attr('string'), uuid: attr('string'),
emailRecipientFilter: attr('members-segment-string', {defaultValue: null}), emailSegment: attr('members-segment-string', {defaultValue: null}),
emailOnly: attr('boolean', {defaultValue: false}), emailOnly: attr('boolean', {defaultValue: false}),
featureImage: attr('string'), featureImage: attr('string'),
@ -160,9 +160,8 @@ export default Model.extend(Comparable, ValidationEngine, {
hasEmail: computed('email', 'emailOnly', function () { hasEmail: computed('email', 'emailOnly', function () {
return this.email !== null || this.emailOnly; return this.email !== null || this.emailOnly;
}), }),
willEmail: computed('isScheduled', 'newsletter', 'email', function () {
willEmail: computed('emailRecipientFilter', 'email', function () { return this.isScheduled && !!this.newsletter && !this.email;
return this.emailRecipientFilter !== null && !this.email;
}), }),
previewUrl: computed('uuid', 'ghostPaths.url', 'config.blogUrl', function () { previewUrl: computed('uuid', 'ghostPaths.url', 'config.blogUrl', function () {
@ -201,12 +200,12 @@ export default Model.extend(Comparable, ValidationEngine, {
} }
}), }),
fullRecipientFilter: computed('newsletter.recipientFilter', 'emailRecipientFilter', function () { fullRecipientFilter: computed('newsletter.recipientFilter', 'emailSegment', function () {
if (!this.newsletter) { if (!this.newsletter) {
return this.emailRecipientFilter; return this.emailSegment;
} }
return `${this.newsletter.recipientFilter}+(${this.emailRecipientFilter})`; return `${this.newsletter.recipientFilter}+(${this.emailSegment})`;
}), }),
// check every second to see if we're past the scheduled time // check every second to see if we're past the scheduled time

View File

@ -273,8 +273,8 @@ export default class PublishOptions {
const adapterOptions = {}; const adapterOptions = {};
if (willEmail) { if (willEmail) {
adapterOptions.newsletter = this.newsletter.id; adapterOptions.newsletter = this.newsletter.slug;
adapterOptions.emailRecipientFilter = this.recipientFilter; adapterOptions.emailSegment = this.recipientFilter;
} }
try { try {