Added member counts to newsletter publish menu (#1760)

refs 6140a98351

- Adds free/paid member counts to newsletter option in publish menu
- Updates default state for newsletter sending option based on number of members for free/paid
- Updates styling for checkboxes based on enabled/disabled state
This commit is contained in:
Rishabh Garg 2020-11-11 22:38:43 +05:30 committed by GitHub
parent 1640ee25b6
commit 7191fe1558
7 changed files with 108 additions and 8 deletions

View File

@ -38,7 +38,7 @@
<div class="gh-publishmenu-email-label {{if this.disableEmailOption "pe-none"}}">
<label class="gh-publishmenu-radio-label mb3 {{if this.disableEmailOption "midgrey"}}">Deliver to</label>
<div class="form-group for-checkbox mb0">
<label class="checkbox" for="free-members" {{action "toggleSendEmailWhenPublished" "free" bubbles="false"}}>
<label class="checkbox {{if this.disableFreeMemberCheckbox "gh-publishmenu-checkbox-disabled"}}" for="free-members" {{action "toggleSendEmailWhenPublished" "free" bubbles="false"}}>
<input
type="checkbox"
checked={{this.sendEmailToFreeMembersWhenPublished}}
@ -48,9 +48,9 @@
data-test-checkbox="free-members"
>
<span class="input-toggle-component"></span>
<p>Free members</p>
<p>Free members <span class="gh-publishmenu-emailcount">{{this.freeMemberCountLabel}}</span></p>
</label>
<label class="checkbox" for="paid-members" {{action "toggleSendEmailWhenPublished" "paid" bubbles="false"}}>
<label class="checkbox {{if this.disablePaidMemberCheckbox "gh-publishmenu-checkbox-disabled"}}" for="paid-members" {{action "toggleSendEmailWhenPublished" "paid" bubbles="false"}}>
<input
type="checkbox"
checked={{this.sendEmailToPaidMembersWhenPublished}}
@ -60,7 +60,7 @@
data-test-checkbox="paid-members"
>
<span class="input-toggle-component"></span>
<p>Paid members</p>
<p>Paid members <span class="gh-publishmenu-emailcount">{{this.paidMemberCountLabel}}</span></p>
</label>
</div>
</div>

View File

@ -1,6 +1,7 @@
import Component from '@ember/component';
import moment from 'moment';
import {computed} from '@ember/object';
import {formatNumber} from 'ghost-admin/helpers/format-number';
import {isEmpty} from '@ember/utils';
import {or} from '@ember/object/computed';
import {inject as service} from '@ember/service';
@ -24,6 +25,28 @@ export default Component.extend({
return (this.get('session.user.isOwnerOrAdmin') && this.memberCount === 0);
}),
disableFreeMemberCheckbox: computed('freeMemberCount', function () {
return (this.get('session.user.isOwnerOrAdmin') && this.freeMemberCount === 0);
}),
disablePaidMemberCheckbox: computed('paidMemberCount', function () {
return (this.get('session.user.isOwnerOrAdmin') && this.paidMemberCount === 0);
}),
freeMemberCountLabel: computed('freeMemberCount', function () {
if (this.get('freeMemberCount') !== undefined) {
return `(${formatNumber(this.get('freeMemberCount'))})`;
}
return '';
}),
paidMemberCountLabel: computed('freeMemberCount', function () {
if (this.get('freeMemberCount') !== undefined) {
return `(${formatNumber(this.get('paidMemberCount'))})`;
}
return '';
}),
canSendEmail: computed('feature.labs.members', 'post.{displayName,email}', 'settings.{mailgunApiKey,mailgunDomain,mailgunBaseUrl}', 'config.mailgunIsConfigured', function () {
let membersEnabled = this.feature.get('labs.members');
let mailgunIsConfigured = this.get('settings.mailgunApiKey') && this.get('settings.mailgunDomain') && this.get('settings.mailgunBaseUrl') || this.get('config.mailgunIsConfigured');

View File

@ -38,7 +38,7 @@
<div class="gh-publishmenu-email-label">
<label class="gh-publishmenu-radio-label mb3 midgrey pe-none">Deliver to</label>
<div class="form-group for-checkbox mb0">
<label class="checkbox" for="free-members">
<label class="checkbox gh-publishmenu-checkbox-disabled" for="free-members">
<input
type="checkbox"
checked={{this.sendEmailToFreeMembersWhenPublished}}
@ -47,9 +47,9 @@
data-test-checkbox="free-members"
>
<span class="input-toggle-component"></span>
<p>Free members</p>
<p>Free members <span class="gh-publishmenu-emailcount">{{this.freeMemberCountLabel}}</span></p>
</label>
<label class="checkbox" for="paid-members">
<label class="checkbox gh-publishmenu-checkbox-disabled" for="paid-members">
<input
type="checkbox"
checked={{this.sendEmailToPaidMembersWhenPublished}}
@ -58,7 +58,7 @@
data-test-checkbox="paid-members"
>
<span class="input-toggle-component"></span>
<p>Paid members</p>
<p>Paid members <span class="gh-publishmenu-emailcount">{{this.paidMemberCountLabel}}</span></p>
</label>
</div>
</div>

View File

@ -2,6 +2,7 @@ import Component from '@ember/component';
import moment from 'moment';
import {computed} from '@ember/object';
import {equal, or} from '@ember/object/computed';
import {formatNumber} from 'ghost-admin/helpers/format-number';
import {inject as service} from '@ember/service';
export default Component.extend({
@ -23,6 +24,28 @@ export default Component.extend({
disableEmailOption: equal('memberCount', 0),
showSendEmail: or('session.user.isOwner', 'session.user.isAdmin', 'session.user.isEditor'),
disableFreeMemberCheckbox: computed('freeMemberCount', function () {
return (this.get('session.user.isOwnerOrAdmin') && this.freeMemberCount === 0);
}),
disablePaidMemberCheckbox: computed('paidMemberCount', function () {
return (this.get('session.user.isOwnerOrAdmin') && this.paidMemberCount === 0);
}),
freeMemberCountLabel: computed('freeMemberCount', function () {
if (this.get('freeMemberCount') !== undefined) {
return `(${formatNumber(this.get('freeMemberCount'))})`;
}
return '';
}),
paidMemberCountLabel: computed('freeMemberCount', function () {
if (this.get('freeMemberCount') !== undefined) {
return `(${formatNumber(this.get('paidMemberCount'))})`;
}
return '';
}),
canSendEmail: computed('feature.labs.members', 'post.{displayName,email}', 'settings.{mailgunApiKey,mailgunDomain,mailgunBaseUrl}', 'config.mailgunIsConfigured', function () {
let membersEnabled = this.feature.get('labs.members');
let mailgunIsConfigured = this.get('settings.mailgunApiKey') && this.get('settings.mailgunDomain') && this.get('settings.mailgunBaseUrl') || this.get('config.mailgunIsConfigured');

View File

@ -17,6 +17,8 @@
@saveType={{this.saveType}}
@isClosing={{this.isClosing}}
@memberCount={{this.memberCount}}
@paidMemberCount={{this.paidMemberCount}}
@freeMemberCount={{this.freeMemberCount}}
@setSaveType={{action "setSaveType"}}
@setTypedDateError={{action (mut this.typedDateError)}} />
@ -29,6 +31,8 @@
@setSendEmailWhenPublished={{action "setSendEmailWhenPublished"}}
@backgroundTask={{this.backgroundTask}}
@memberCount={{this.memberCount}}
@paidMemberCount={{this.paidMemberCount}}
@freeMemberCount={{this.freeMemberCount}}
@sendEmailWhenPublished={{this.sendEmailWhenPublished}} />
{{/if}}

View File

@ -14,6 +14,8 @@ export default Component.extend({
feature: service(),
settings: service(),
config: service(),
session: service(),
store: service(),
backgroundTask: null,
classNames: 'gh-publishmenu',
@ -153,6 +155,7 @@ export default Component.extend({
this.set('sendEmailWhenPublished', 'paid');
}
}
this.countPaidMembers();
},
actions: {
@ -206,6 +209,39 @@ export default Component.extend({
}
},
countPaidMembers: action(function () {
// TODO: remove editor conditional once editors can query member counts
if (!this.session.get('user.isEditor') && this.canSendEmail) {
this.countPaidMembersTask.perform();
}
}),
countPaidMembersTask: task(function* () {
const result = yield this.store.query('member', {filter: 'subscribed:true', paid: true, limit: 1, page: 1});
const paidMemberCount = result.meta.pagination.total;
const freeMemberCount = this.memberCount - paidMemberCount;
this.set('paidMemberCount', paidMemberCount);
this.set('freeMemberCount', freeMemberCount);
if (this.postStatus === 'draft' && this.canSendEmail) {
// Set default newsletter recipients
if (this.post.visibility === 'public' || this.post.visibility === 'members') {
if (paidMemberCount > 0 && freeMemberCount > 0) {
this.set('sendEmailWhenPublished', 'all');
} else if (!paidMemberCount && freeMemberCount > 0) {
this.set('sendEmailWhenPublished', 'free');
} else if (!freeMemberCount && paidMemberCount > 0) {
this.set('sendEmailWhenPublished', 'paid');
} else if (!freeMemberCount && !paidMemberCount) {
this.set('sendEmailWhenPublished', 'none');
}
} else {
const type = paidMemberCount > 0 ? 'paid' : 'none';
this.set('sendEmailWhenPublished', type);
}
}
}),
// action is required because <GhFullscreenModal> only uses actions
confirmEmailSend: action(function () {
return this._confirmEmailSend.perform();

View File

@ -255,4 +255,18 @@
.gh-publishmenu-email-info {
margin: 15px 0;
color: var(--midgrey);
}
.gh-publishmenu-emailcount {
color: var(--midlightgrey);
}
.gh-publishmenu-checkbox-disabled {
color: var(--midlightgrey);
opacity: 0.75;
pointer-events: none;
}
.gh-publishmenu-checkbox-disabled p {
color: var(--midlightgrey) !important;
}