Added segment selection to email-cta card

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

- updated `<KoenigEditor>` so it creates default card payloads as TrackedObject instances so that getters in glimmer component based cards can track changes to payload properties
- added dropdown free/paid selector to email-cta card that sets the `segment` payload property to the respective filter
- updated design to show the footer outside of edit mode too so that the selected segment is always visible
This commit is contained in:
Kevin Ansfield 2021-07-21 18:39:21 +01:00
parent 105c76b2e8
commit 2b1ccc9c37
4 changed files with 61 additions and 5 deletions

View File

@ -311,3 +311,10 @@
.gh-labs-mailgun-region .ember-power-select-selected-item {
margin-left: 0;
}
/* Inline input */
.ember-power-select-inline {
display: inline-block;
vertical-align: middle;
margin-bottom: 4px;
}

View File

@ -32,12 +32,36 @@
/>
<div class="kg-card-help">
<p>
<span>Only visible when delivered by email, this card will not be published on your site.</span>
<a href="https://ghost.org/help/email-newsletters/#email-cards" class="dib lh-zero v-mid kg-card-help-icon-link" target="_blank" rel="noreferer nopener">{{svg-jar "help" class="stroke-midgrey"}}</a>
<span>
Only visible to
<PowerSelect
@options={{this.segments}}
@selected={{this.selectedSegment}}
@onChange={{this.setSegment}}
@searchEnabled={{false}}
@triggerComponent="gh-power-select/trigger"
@triggerClass="ember-power-select-inline"
as |segment|
>
{{segment.name}}
</PowerSelect>
when delievered by email.
</span>
<br>
<span>This card will not be published on your site.</span>
</p>
</div>
{{else}}
<p>{{{this.formattedHtml}}}</p>
<div class="kg-card-help">
<p>
<span>
Only visible to <strong>{{this.selectedSegment.name}}</strong> when delievered by email.
</span>
<br>
<span>This card will not be published on your site.</span>
</p>
</div>
<div class="koenig-card-click-overlay"></div>
{{/if}}
</KoenigCard>

View File

@ -3,6 +3,7 @@ import Component from '@glimmer/component';
import {action} from '@ember/object';
import {formatTextReplacementHtml} from './koenig-text-replacement-html-input';
import {isBlank} from '@ember/utils';
import {notifyPropertyChange} from '@ember/object';
import {run} from '@ember/runloop';
import {set} from '@ember/object';
import {tracked} from '@glimmer/tracking';
@ -14,6 +15,20 @@ export default class KoenigCardEmailCtaComponent extends Component {
return formatTextReplacementHtml(this.args.payload.html);
}
get segments() {
return [{
name: 'Free members',
filter: 'status:free'
}, {
name: 'Paid members',
filter: 'status:-free'
}];
}
get selectedSegment() {
return this.segments.find(segment => segment.filter === this.args.payload.segment);
}
get toolbar() {
if (this.args.isEditing) {
return false;
@ -38,6 +53,10 @@ export default class KoenigCardEmailCtaComponent extends Component {
if (!this.args.payload.html) {
this._updatePayloadAttr('html', '<p>Hey {first_name, "there"},</p>');
}
if (!this.args.payload.segment) {
this._updatePayloadAttr('segment', 'status:free');
}
}
@action
@ -45,6 +64,11 @@ export default class KoenigCardEmailCtaComponent extends Component {
this._updatePayloadAttr('html', html);
}
@action
setSegment(segment) {
this._updatePayloadAttr('segment', segment.filter);
}
@action
registerEditor(textReplacementEditor) {
let commands = {

View File

@ -17,6 +17,7 @@ import registerKeyCommands from '../options/key-commands';
import registerTextExpansions from '../options/text-expansions';
import validator from 'validator';
import {A} from '@ember/array';
import {TrackedObject} from 'tracked-built-ins';
import {action} from '@ember/object';
import {assign} from '@ember/polyfills';
import {camelize, capitalize} from '@ember/string';
@ -320,11 +321,11 @@ export default Component.extend({
let cardName = env.name;
let componentName = CARD_COMPONENT_MAP[cardName];
// the payload must be copied to avoid sharing the reference
// the payload must be copied to avoid sharing the reference.
// `payload.files` is special because it's set by paste/drag-n-drop
// events and can't be copied for security reasons
let {files} = payload;
let payloadCopy = JSON.parse(JSON.stringify(payload || null));
let payloadCopy = new TrackedObject(JSON.parse(JSON.stringify(payload || null)));
payloadCopy.files = files;
// all of the properties that will be passed through to the
@ -979,7 +980,7 @@ export default Component.extend({
if (range && range.isCollapsed && range.headSection.isBlank && !range.headSection.isListItem) {
if (!this._modifierKeys.shift) {
editor.run((postEditor) => {
let payload = {url: text, linkOnError: true, isDirectUrl: true};
let payload = new TrackedObject({url: text, linkOnError: true, isDirectUrl: true});
let card = postEditor.builder.createCardSection('embed', payload);
let nextSection = range.headSection.next;