Extracted PSM email settings into separate component

This commit is contained in:
Kevin Ansfield 2019-11-08 15:56:56 +07:00
parent 3fd2a8d62c
commit 2777856a29
4 changed files with 174 additions and 139 deletions

View File

@ -3,7 +3,6 @@ import SettingsMenuMixin from 'ghost-admin/mixins/settings-menu-component';
import boundOneWay from 'ghost-admin/utils/bound-one-way';
import formatMarkdown from 'ghost-admin/utils/format-markdown';
import moment from 'moment';
import validator from 'validator';
import {alias, or} from '@ember/object/computed';
import {computed} from '@ember/object';
import {run} from '@ember/runloop';
@ -29,8 +28,6 @@ export default Component.extend(SettingsMenuMixin, {
_showSettingsMenu: false,
_showThrobbers: false,
emailTestScratch: '',
sendTestEmailError: '',
canonicalUrlScratch: alias('post.canonicalUrlScratch'),
customExcerptScratch: alias('post.customExcerptScratch'),
codeinjectionFootScratch: alias('post.codeinjectionFootScratch'),
@ -41,7 +38,6 @@ export default Component.extend(SettingsMenuMixin, {
ogTitleScratch: alias('post.ogTitleScratch'),
twitterDescriptionScratch: alias('post.twitterDescriptionScratch'),
twitterTitleScratch: alias('post.twitterTitleScratch'),
emailSubjectScratch: alias('post.emailSubjectScratch'),
slugValue: boundOneWay('post.slug'),
facebookDescription: or('ogDescriptionScratch', 'customExcerptScratch', 'seoDescription'),
@ -50,7 +46,6 @@ export default Component.extend(SettingsMenuMixin, {
twitterDescription: or('twitterDescriptionScratch', 'customExcerptScratch', 'seoDescription'),
twitterImage: or('post.twitterImage', 'post.featureImage'),
twitterTitle: or('twitterTitleScratch', 'seoTitle'),
emailSubject: or('emailSubjectScratch', 'post.title'),
showVisibilityInput: or('session.user.isOwner', 'session.user.isAdmin', 'session.user.isEditor'),
@ -103,10 +98,6 @@ export default Component.extend(SettingsMenuMixin, {
}
}),
mailgunError: computed('settings.memberSubscriptionSettings', function () {
return !this._isMailgunConfigured();
}),
didReceiveAttrs() {
this._super(...arguments);
@ -176,10 +167,6 @@ export default Component.extend(SettingsMenuMixin, {
});
},
toggleEmailPreview() {
this.toggleEmailPreviewModal();
},
/**
* triggered by user manually changing slug
*/
@ -419,29 +406,6 @@ export default Component.extend(SettingsMenuMixin, {
});
},
setEmailSubject(emailSubject) {
// Grab the post and current stored email subject
let post = this.post;
let currentEmailSubject = post.get('emailSubject');
// If the subject entered matches the stored email subject, do nothing
if (currentEmailSubject === emailSubject) {
return;
}
// If the subject entered is different, set it as the new email subject
post.set('emailSubject', emailSubject);
// Make sure the email subject is valid and if so, save it into the post
return post.validate({property: 'emailSubject'}).then(() => {
if (post.get('isNew')) {
return;
}
return this.savePost.perform();
});
},
setCoverImage(image) {
this.set('post.featureImage', image);
@ -554,47 +518,10 @@ export default Component.extend(SettingsMenuMixin, {
this.set('_showThrobbers', true);
}).restartable(),
sendTestEmail: task(function* () {
try {
const resourceId = this.post.id;
const testEmail = this.emailTestScratch.trim();
if (!validator.isEmail(testEmail)) {
this.set('sendTestEmailError', 'Please enter a valid email');
return false;
}
if (!this.isMailgunConfigured()) {
this.set('sendTestEmailError', 'Please configure Mailgun in Labs → Members');
return false;
}
this.set('sendTestEmailError', '');
const url = this.get('ghostPaths.url').api('/email_preview/posts', resourceId);
const data = {emails: [testEmail]};
const options = {
data,
dataType: 'json'
};
return yield this.ajax.post(url, options);
} catch (error) {
if (error) {
this.notifications.showAPIError(error, {key: 'send.previewEmail'});
}
}
}).drop(),
showError(error) {
// TODO: remove null check once ValidationEngine has been removed
if (error) {
this.notifications.showAPIError(error);
}
},
// TODO: put this on settings model
_isMailgunConfigured: function () {
let subSettingsValue = this.get('settings.membersSubscriptionSettings');
let subscriptionSettings = subSettingsValue ? JSON.parse(subSettingsValue) : {};
if (Object.keys(subscriptionSettings).includes('mailgunApiKey')) {
return (subscriptionSettings.mailgunApiKey && subscriptionSettings.mailgunDomain);
}
return true;
}
});

View File

@ -0,0 +1,98 @@
import Component from '@ember/component';
import validator from 'validator';
import {alias, or} from '@ember/object/computed';
import {computed} from '@ember/object';
import {inject as service} from '@ember/service';
import {task} from 'ember-concurrency';
export default Component.extend({
ajax: service(),
ghostPaths: service(),
notifications: service(),
settings: service(),
post: null,
emailTestScratch: '',
sendTestEmailError: '',
savePost: null,
close() {},
toggleEmailPreviewModal() {},
emailSubject: or('emailSubjectScratch', 'post.title'),
emailSubjectScratch: alias('post.emailSubjectScratch'),
mailgunError: computed('settings.memberSubscriptionSettings', function () {
return !this._isMailgunConfigured();
}),
actions: {
setEmailSubject(emailSubject) {
// Grab the post and current stored email subject
let post = this.post;
let currentEmailSubject = post.get('emailSubject');
// If the subject entered matches the stored email subject, do nothing
if (currentEmailSubject === emailSubject) {
return;
}
// If the subject entered is different, set it as the new email subject
post.set('emailSubject', emailSubject);
// Make sure the email subject is valid and if so, save it into the post
return post.validate({property: 'emailSubject'}).then(() => {
if (post.get('isNew')) {
return;
}
return this.savePost.perform();
});
},
toggleEmailPreview() {
this.toggleEmailPreviewModal();
},
discardEnter() {
return false;
}
},
sendTestEmail: task(function* () {
try {
const resourceId = this.post.id;
const testEmail = this.emailTestScratch.trim();
if (!validator.isEmail(testEmail)) {
this.set('sendTestEmailError', 'Please enter a valid email');
return false;
}
if (!this._isMailgunConfigured()) {
this.set('sendTestEmailError', 'Please configure Mailgun in Labs → Members');
return false;
}
this.set('sendTestEmailError', '');
const url = this.ghostPaths.url.api('/email_preview/posts', resourceId);
const data = {emails: [testEmail]};
const options = {
data,
dataType: 'json'
};
return yield this.ajax.post(url, options);
} catch (error) {
if (error) {
this.notifications.showAPIError(error, {key: 'send.previewEmail'});
}
}
}).drop(),
// TODO: put this on settings model
_isMailgunConfigured() {
let subSettingsValue = this.settings.get('membersSubscriptionSettings');
let subscriptionSettings = subSettingsValue ? JSON.parse(subSettingsValue) : {};
if (Object.keys(subscriptionSettings).includes('mailgunApiKey')) {
return (subscriptionSettings.mailgunApiKey && subscriptionSettings.mailgunDomain);
}
return true;
}
});

View File

@ -315,72 +315,12 @@
{{/if}}
{{#if (eq subview "email-settings")}}
<div class="settings-menu-header subview">
<button {{action "closeSubview"}} class="back settings-menu-header-action" data-test-button="close-psm-subview">{{svg-jar "arrow-left"}}<span class="hidden">Back</span></button>
<h4>Email newsletter</h4>
<div style="width:23px;"></div>
</div>
<div class="settings-menu-content settings-menu-email">
{{#if mailgunError}}
<p class="gh-box gh-box-warning settings-menu-mailgun-warning">
{{svg-jar "info" class="w5 h5 fill-yellow nl1"}}
You need to configure Mailgun in {{#link-to "settings.labs" data-test-nav="labs"}}Labs → Members settings{{/link-to}} to enable email newsletters.
</p>
{{/if}}
<form {{action "discardEnter" on="submit"}}>
{{#gh-form-group errors=post.errors hasValidated=post.hasValidated property="emailSubject"}}
<label for="og-title">Subject</label>
{{gh-text-input
class="post-setting-email-subject"
id="email-subject"
name="post-setting-email-subject"
placeholder=(truncate emailSubject 40)
value=(readonly emailSubjectScratch)
input=(action (mut emailSubjectScratch) value="target.value")
focus-out=(action "setEmailSubject" emailSubjectScratch)
stopEnterKeyDownPropagation=true
disabled=deliveredAction
data-test-field="email-subject"}}
{{gh-error-message errors=post.errors property="emailSubject" data-test-error="email-subject"}}
{{/gh-form-group}}
<div class="form-group">
<div class="flex">
<label class="nowrap flex-auto">Test email</label>
<button type="button" class="gh-btn gh-btn-link settings-menu-email-button" onclick={{action "toggleEmailPreview"}}
data-test-button="toggle-email-preview">
<span class="blue">
Preview in browser
</span>
</button>
</div>
<div class="{{if mailgunError "disabled"}}">
{{gh-text-input
class="post-setting-email-test"
id="email-test"
name="post-setting-email-test"
placeholder=(truncate 'noreply@example.com' 40)
value=(readonly emailTestScratch)
input=(action (mut emailTestScratch) value="target.value")
stopEnterKeyDownPropagation=true
disabled=mailgunError
data-test-field="email-test"}}
{{#if sendTestEmailError}}
<div class="error"><p class="response">{{sendTestEmailError}}</p></div>
{{/if}}
{{gh-task-button "Send test email"
task=sendTestEmail
successText="Email sent"
runningText="Sending..."
class="gh-btn w-100 mt2 gh-btn-icon"
disabled=mailgunError
data-test-send-test-mail=true
}}
</div>
</div>
</form>
</div>
<GhPostSettingsMenu::Email
@post={{this.post}}
@savePostTask={{this.savePost}}
@toggleEmailPreviewModal={{this.toggleEmailPreviewModal}}
@close={{action "closeSubview"}}
/>
{{/if}}
{{#if (eq subview "facebook-data")}}

View File

@ -0,0 +1,70 @@
<div class="settings-menu-header subview">
<button {{on "click" this.close}} class="back settings-menu-header-action" data-test-button="close-psm-subview">{{svg-jar "arrow-left"}}<span class="hidden">Back</span></button>
<h4>Email newsletter</h4>
<div style="width:23px;"></div>
</div>
<div class="settings-menu-content settings-menu-email">
{{#if mailgunError}}
<p class="gh-box gh-box-warning settings-menu-mailgun-warning">
{{svg-jar "info" class="w5 h5 fill-yellow nl1"}}
You need to configure Mailgun in {{#link-to "settings.labs" data-test-nav="labs"}}Labs → Members settings{{/link-to}} to
enable sending posts in email.
</p>
{{/if}}
<form {{action "discardEnter" on="submit"}}>
{{#gh-form-group errors=post.errors hasValidated=post.hasValidated property="emailSubject"}}
<label for="og-title">Subject</label>
{{gh-text-input
class="post-setting-email-subject"
id="email-subject"
name="post-setting-email-subject"
placeholder=(truncate emailSubject 40)
value=(readonly emailSubjectScratch)
input=(action (mut emailSubjectScratch) value="target.value")
focus-out=(action "setEmailSubject" emailSubjectScratch)
stopEnterKeyDownPropagation=true
disabled=deliveredAction
data-test-field="email-subject"}}
{{gh-error-message errors=post.errors property="emailSubject" data-test-error="email-subject"}}
{{/gh-form-group}}
<div class="form-group">
<div class="flex">
<label class="nowrap flex-auto">Test email</label>
<button type="button" class="gh-btn gh-btn-link settings-menu-email-button" onclick={{action "toggleEmailPreview"}}
data-test-button="toggle-email-preview">
<span class="blue">
Preview in browser
</span>
</button>
</div>
<div class="{{if mailgunError "disabled"}}">
{{gh-text-input
class="post-setting-email-test"
id="email-test"
name="post-setting-email-test"
placeholder=(truncate 'noreply@example.com' 40)
value=(readonly emailTestScratch)
input=(action (mut emailTestScratch) value="target.value")
stopEnterKeyDownPropagation=true
disabled=mailgunError
data-test-field="email-test"}}
{{#if sendTestEmailError}}
<div class="error"><p class="response">{{sendTestEmailError}}</p></div>
{{/if}}
{{gh-task-button "Send test email"
task=sendTestEmail
successText="Email sent"
runningText="Sending..."
class="gh-btn w-100 mt2 gh-btn-icon"
disabled=mailgunError
data-test-send-test-mail=true
}}
</div>
</div>
</form>
</div>