Updated newsletter model and form for latest schema

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

- `senderEmail` is now nullable with a fallback to `noreply@{site domain}`
- `senderName` is not nullable and has no fallback
  - updated preview and input placeholder to match real-world behaviour
  - inserted site title as the default value when creating a new newsletter to avoid friction with the sender name needing to be filled in when saving
- switched `senderReplyTo` input field to a select with "newsletter" and "support" options
  - added basic `<Inputs::Select>` component as `<OneWaySelect>` had re-rendering issues causing loss of selected value when the label of the newsletter email changed to reflect a custom newsletter email value
This commit is contained in:
Kevin Ansfield 2022-04-12 14:01:27 +01:00
parent 3a26f07379
commit 95d7e3ddf2
9 changed files with 44 additions and 30 deletions

View File

@ -0,0 +1,6 @@
<select
...attributes
{{on "change" (pick "target.value" @onChange)}}
>
{{yield (hash option=(component "inputs/select/option" currentValue=@value))}}
</select>

View File

@ -0,0 +1,7 @@
<option value={{@value}} selected={{if (eq @currentValue @value) true false}}>
{{#if (has-block)}}
{{yield}}
{{else}}
{{@label}}
{{/if}}
</option>

View File

@ -2,7 +2,7 @@
<div class="gh-members-emailpreview-container">
<div class="gh-members-emailpreview-faux">
<p>
<span class="strong">{{or @newsletter.senderName this.config.blogTitle}}</span> &lt;{{full-email-address (or @newsletter.senderEmail this.settings.membersFromAddress)}}&gt;
<span class="strong">{{@newsletter.senderName}}</span> &lt;{{full-email-address (or @newsletter.senderEmail "noreply")}}&gt;
</p>
<p><span class="dark">To:</span> Jamie Larson &lt;jamie@example.com&gt;</p>
</div>

View File

@ -8,7 +8,7 @@
type="text"
class="gh-input miw-100 form-text"
value={{@newsletter.name}}
placeholder={{this.config.blogTitle}}
placeholder={{this.settings.title}}
{{on "input" (fn this.onInput "name")}}
/>
<GhErrorMessage @errors={{@newsletter.errors}} @property="name" />
@ -33,7 +33,6 @@
type="text"
class="gh-input miw-100 form-text"
value={{@newsletter.senderName}}
placeholder={{this.config.blogTitle}}
{{on "input" (fn this.onInput "senderName")}}
/>
<GhErrorMessage @errors={{@newsletter.errors}} @property="senderName" />
@ -46,22 +45,23 @@
type="text"
class="gh-input miw-100 form-text"
value={{@newsletter.senderEmail}}
placeholder={{full-email-address this.settings.membersFromAddress}}
placeholder={{full-email-address "noreply"}}
{{on "input" (fn this.onInput "senderEmail")}}
/>
<GhErrorMessage @errors={{@newsletter.errors}} @property="senderEmail" />
</GhFormGroup>
<GhFormGroup @classNames="vertical" @errors={{@newsletter.errors}} @hasValidated={{@newsletter.hasValidated}} @property="senderReplyTo">
<label for="newsletter-reply-to" class="modal-fullsettings-title">Reply-to address</label>
<input
<label for="newsletter-reply-to" class="modal-fullsettings-title">Reply-to email address</label>
<Inputs::Select
id="newsletter-reply-to"
type="text"
class="gh-input miw-100 form-text"
value={{@newsletter.senderReplyTo}}
placeholder={{full-email-address this.settings.membersFromAddress}}
{{on "input" (fn this.onInput "senderReplyTo")}}
/>
@value={{@newsletter.senderReplyTo}}
@onChange={{fn this.onValueChange "senderReplyTo"}}
as |select|
>
<select.option @value="newsletter">Newsletter ({{full-email-address (or @newsletter.senderEmail "noreply")}})</select.option>
<select.option @value="support">Support ({{full-email-address this.settings.membersSupportAddress}})</select.option>
</Inputs::Select>
<GhErrorMessage @errors={{@newsletter.errors}} @property="senderReplyTo" />
</GhFormGroup>
</div>
@ -75,7 +75,7 @@
type="checkbox"
id="subscribe-on-signup"
checked={{@newsletter.subscribeOnSignup}}
{{on "change" (fn this.onChange "subscribeOnSignup")}}
{{on "change" (fn this.onCheckboxChange "subscribeOnSignup")}}
>
<button type="button" class="input-toggle-component" {{on "click" (fn this.toggleProperty "subscribeOnSignup")}}></button>
</div>

View File

@ -3,11 +3,10 @@ import {action} from '@ember/object';
import {inject as service} from '@ember/service';
export default class EditNewsletterSettingsForm extends Component {
@service config;
@service settings;
@action
onChange(property, event) {
onCheckboxChange(property, event) {
this.args.newsletter[property] = event.target.checked;
}
@ -20,4 +19,9 @@ export default class EditNewsletterSettingsForm extends Component {
onInput(property, event) {
this.args.newsletter[property] = event.target.value;
}
@action
onValueChange(property, value) {
this.args.newsletter[property] = value;
}
}

View File

@ -10,7 +10,7 @@ export default class Newsletter extends Model.extend(ValidationEngine) {
@attr senderName;
@attr senderEmail;
@attr senderReplyTo;
@attr({defaultValue: 'newsletter'}) senderReplyTo;
@attr({defaultValue: 'active'}) status;
@attr({defaultValue: ''}) recipientFilter;

View File

@ -6,12 +6,15 @@ import {inject as service} from '@ember/service';
export default class NewNewsletterRoute extends AdminRoute {
@service modals;
@service router;
@service settings;
@service store;
newsletterModal = null;
model() {
return this.store.createRecord('newsletter');
return this.store.createRecord('newsletter', {
senderName: this.settings.get('title')
});
}
setupController(controller, model) {

View File

@ -12,7 +12,7 @@ export default BaseValidator.create({
}
if (!validator.isLength(model.name || '', 0, 191)) {
model.errors.add('name', 'Name cannot be longer than 191 characters.');
model.errors.add('name', 'Cannot be longer than 191 characters.');
this.invalidate();
}
@ -26,7 +26,7 @@ export default BaseValidator.create({
}
if (!validator.isLength(model.senderName || '', 0, 191)) {
model.errors.add('senderName', 'Sender name cannot be longer than 191 characters.');
model.errors.add('senderName', 'Cannot be longer than 191 characters.');
this.invalidate();
}
@ -34,16 +34,13 @@ export default BaseValidator.create({
},
senderEmail(model) {
if (isBlank(model.senderEmail)) {
model.errors.add('senderEmail', 'Please enter a newsletter email address.');
this.invalidate();
} else if (!validator.isEmail(model.senderEmail)) {
if (model.senderEmail && !validator.isEmail(model.senderEmail)) {
model.errors.add('senderEmail', 'Invalid email.');
this.invalidate();
}
if (!validator.isLength(model.senderEmail || '', 0, 191)) {
model.errors.add('senderEmail', 'Sender email cannot be longer than 191 characters.');
model.errors.add('senderEmail', 'Cannot be longer than 191 characters.');
this.invalidate();
}
@ -54,13 +51,10 @@ export default BaseValidator.create({
if (isBlank(model.senderReplyTo)) {
model.errors.add('senderReplyTo', 'Please enter a reply-to email address.');
this.invalidate();
} else if (!validator.isEmail(model.senderReplyTo)) {
model.errors.add('senderReplyTo', 'Invalid email.');
this.invalidate();
}
if (!validator.isLength(model.senderReplyTo || '', 0, 191)) {
model.errors.add('senderReplyTo', 'Reply-to email cannot be longer than 191 characters.');
if (!validator.isIn(model.senderReplyTo, ['newsletter', 'support'])) {
model.errors.add('senderReplyTo', 'Can only be set to "newsletter" or "support".');
this.invalidate();
}

View File

@ -117,7 +117,7 @@ module.exports = function (defaults) {
includePolyfill: false
},
'ember-composable-helpers': {
only: ['optional', 'toggle', 'toggle-action']
only: ['optional', 'pick', 'toggle', 'toggle-action']
},
'ember-promise-modals': {
excludeCSS: true