mirror of
https://github.com/TryGhost/Ghost.git
synced 2024-12-22 18:31:57 +03:00
5b09cd5bef
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
129 lines
3.6 KiB
JavaScript
129 lines
3.6 KiB
JavaScript
import Browser from 'mobiledoc-kit/utils/browser';
|
|
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';
|
|
|
|
export default class KoenigCardEmailCtaComponent extends Component {
|
|
@tracked isFocused = false;
|
|
|
|
get formattedHtml() {
|
|
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;
|
|
}
|
|
|
|
return {
|
|
items: [{
|
|
buttonClass: 'fw4 flex items-center white',
|
|
icon: 'koenig/kg-edit',
|
|
iconClass: 'fill-white',
|
|
title: 'Edit',
|
|
text: '',
|
|
action: run.bind(this, this.args.editCard)
|
|
}]
|
|
};
|
|
}
|
|
|
|
constructor() {
|
|
super(...arguments);
|
|
this.args.registerComponent(this);
|
|
|
|
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
|
|
updateHtml(html) {
|
|
this._updatePayloadAttr('html', html);
|
|
}
|
|
|
|
@action
|
|
setSegment(segment) {
|
|
this._updatePayloadAttr('segment', segment.filter);
|
|
}
|
|
|
|
@action
|
|
registerEditor(textReplacementEditor) {
|
|
let commands = {
|
|
'META+ENTER': run.bind(this, this._enter, 'meta'),
|
|
'CTRL+ENTER': run.bind(this, this._enter, 'ctrl')
|
|
};
|
|
|
|
Object.keys(commands).forEach((str) => {
|
|
textReplacementEditor.registerKeyCommand({
|
|
str,
|
|
run() {
|
|
return commands[str](textReplacementEditor, str);
|
|
}
|
|
});
|
|
});
|
|
|
|
this._textReplacementEditor = textReplacementEditor;
|
|
|
|
run.scheduleOnce('afterRender', this, this._placeCursorAtEnd);
|
|
}
|
|
|
|
@action
|
|
leaveEditMode() {
|
|
if (isBlank(this.args.payload.html)) {
|
|
// afterRender is required to avoid double modification of `isSelected`
|
|
// TODO: see if there's a way to avoid afterRender
|
|
run.scheduleOnce('afterRender', this, this.args.deleteCard);
|
|
}
|
|
}
|
|
|
|
_updatePayloadAttr(attr, value) {
|
|
let payload = this.args.payload;
|
|
|
|
set(payload, attr, value);
|
|
|
|
// update the mobiledoc and stay in edit mode
|
|
this.args.saveCard?.(payload, false);
|
|
}
|
|
|
|
/* key commands ----------------------------------------------------------*/
|
|
|
|
_enter(modifier) {
|
|
if (this.isEditing && (modifier === 'meta' || (modifier === 'crtl' && Browser.isWin()))) {
|
|
this.args.editCard?.();
|
|
}
|
|
}
|
|
|
|
_placeCursorAtEnd() {
|
|
if (!this._textReplacementEditor) {
|
|
return;
|
|
}
|
|
|
|
let tailPosition = this._textReplacementEditor.post.tailPosition();
|
|
let rangeToSelect = tailPosition.toRange();
|
|
this._textReplacementEditor.selectRange(rangeToSelect);
|
|
}
|
|
}
|