0
Fork 0
mirror of https://github.com/TryGhost/Ghost.git synced 2025-02-10 23:36:14 -05:00

Added Tips & Donations link to Button, Header and Email CTA cards suggestions (#17614)

closes https://github.com/TryGhost/Product/issues/3665

- added link suggestion feature to the Header card in Mobiledoc (missing
feature)
- Tips & Donations link is behind a feature flag atm, to be cleaned up
once the feature is ready to be released
This commit is contained in:
Sag 2023-08-07 17:16:29 +02:00 committed by GitHub
parent c201e4eb4f
commit 3254b8e149
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 128 additions and 13 deletions

View file

@ -585,3 +585,4 @@ remove|ember-template-lint|no-action|369|46|369|46|1d7de8deaee7bfe5bd051e900e988
remove|ember-template-lint|no-action|401|46|401|46|df19e5858021b80de54052c953e70e3b4606a8f5|1688342400000|1698714000000|1703898000000|app/components/gh-portal-links.hbs remove|ember-template-lint|no-action|401|46|401|46|df19e5858021b80de54052c953e70e3b4606a8f5|1688342400000|1698714000000|1703898000000|app/components/gh-portal-links.hbs
remove|ember-template-lint|no-action|433|46|433|46|3afa41e4d86dd7e5c049a762f0f761c2464a5f96|1688342400000|1698714000000|1703898000000|app/components/gh-portal-links.hbs remove|ember-template-lint|no-action|433|46|433|46|3afa41e4d86dd7e5c049a762f0f761c2464a5f96|1688342400000|1698714000000|1703898000000|app/components/gh-portal-links.hbs
remove|ember-template-lint|no-action|465|46|465|46|f2f0f3f512f141fdd821333c873f5052813bb491|1688342400000|1698714000000|1703898000000|app/components/gh-portal-links.hbs remove|ember-template-lint|no-action|465|46|465|46|f2f0f3f512f141fdd821333c873f5052813bb491|1688342400000|1698714000000|1703898000000|app/components/gh-portal-links.hbs
remove|ember-template-lint|no-unused-block-params|1|0|1|0|e25f7866ab4ee682b08edf3b29a1351e4079538e|1688342400000|1698714000000|1703898000000|lib/koenig-editor/addon/components/koenig-card-header.hbs

View file

@ -282,7 +282,22 @@ export default class KoenigLexicalEditor extends Component {
return links; return links;
}; };
return [...defaults, ...offersLinks, ...memberLinks()];
const donationLink = () => {
// TODO: remove feature condition once Tips & Donations have been released
if (this.feature.tipsAndDonations) {
if (this.settings.donationsEnabled) {
return [{
label: `Support ${this.settings.title}`,
value: this.config.getSiteUrl('/#/portal/support')
}];
}
}
return [];
};
return [...defaults, ...offersLinks, ...memberLinks(), ...donationLink()];
}; };
const fetchLabels = async () => { const fetchLabels = async () => {

View file

@ -11,6 +11,7 @@ import {tracked} from '@glimmer/tracking';
export default class KoenigCardButtonComponent extends Component { export default class KoenigCardButtonComponent extends Component {
@service feature; @service feature;
@service store; @service store;
@service settings;
@service membersUtils; @service membersUtils;
@service ui; @service ui;
@ -81,6 +82,16 @@ export default class KoenigCardButtonComponent extends Component {
}); });
} }
// TODO: remove feature condition once Tips & Donations have been released
if (this.feature.tipsAndDonations) {
if (this.settings.donationsEnabled) {
urls.push({
name: `Support ${this.settings.title}`,
url: this.config.getSiteUrl('/#/portal/support')
});
}
}
return urls; return urls;
} }

View file

@ -15,6 +15,7 @@ import {tracked} from '@glimmer/tracking';
export default class KoenigCardEmailCtaComponent extends Component { export default class KoenigCardEmailCtaComponent extends Component {
@service feature; @service feature;
@service store; @service store;
@service settings;
@service membersUtils; @service membersUtils;
@service ui; @service ui;
@ -105,6 +106,16 @@ export default class KoenigCardEmailCtaComponent extends Component {
}); });
} }
// TODO: remove feature condition once Tips & Donations have been released
if (this.feature.tipsAndDonations) {
if (this.settings.donationsEnabled) {
urls.push({
name: `Support ${this.settings.title}`,
url: this.config.getSiteUrl('/#/portal/support')
});
}
}
return urls; return urls;
} }

View file

@ -18,7 +18,6 @@
@moveCursorToNextSection={{@moveCursorToNextSection}} @moveCursorToNextSection={{@moveCursorToNextSection}}
@editor={{@editor}} @editor={{@editor}}
{{did-insert this.registerElement}} {{did-insert this.registerElement}}
as |card|
> >
{{#if @isEditing}} {{#if @isEditing}}
<div class="kg-header-card kg-size-{{@payload.size}} kg-style-{{@payload.style}}" style="{{if (eq @payload.style "image") this.backgroundImageStyle}}"> <div class="kg-header-card kg-size-{{@payload.size}} kg-style-{{@payload.style}}" style="{{if (eq @payload.style "image") this.backgroundImageStyle}}">
@ -151,16 +150,24 @@
<div class="kg-settings-panel-control"> <div class="kg-settings-panel-control">
<label class="kg-settings-panel-control-label" for="header-url-input">URL</label> <label class="kg-settings-panel-control-label" for="header-url-input">URL</label>
<div class="kg-settings-panel-control-input"> <div class="kg-settings-panel-control-input">
<input <GhInputWithSelect
type="text" @value={{@payload.buttonUrl}}
class="gh-input" @options={{this.suggestedUrls}}
id="header-url-input" @valueField="url"
name="header-url" @searchField="url"
value={{@payload.buttonUrl}} @placeholder=""
placeholder="Add URL" @searchMessage={{null}}
{{on "input" this.setButtonUrl}} @onInput={{this.setButtonUrl}}
{{on-key "Enter" (fn this.focusElement "#header-url-input")}} @openOnFocus={{true}}
@closeWhenEmpty={{true}}
@triggerClass="header-url-input"
@triggerId="header-url-input"
@renderInPlace={{false}} {{!-- avoid dropdown inheriting editor styles --}}
as |suggestion|
> >
<span class="kg-settings-link-title" title="{{suggestion.name}}">{{suggestion.name}}</span>
<span class="kg-settings-link-url" {{on "mouseenter" this.enterLinkURL}} {{on "mouseleave" this.leaveLinkURL}}><span>{{suggestion.url}}</span></span>
</GhInputWithSelect>
</div> </div>
</div> </div>
{{/if}} {{/if}}

View file

@ -11,6 +11,7 @@ import {set} from '@ember/object';
export default class KoenigCardHeaderComponent extends Component { export default class KoenigCardHeaderComponent extends Component {
@service feature; @service feature;
@service store; @service store;
@service settings;
@service membersUtils; @service membersUtils;
@service ui; @service ui;
@ -64,6 +65,49 @@ export default class KoenigCardHeaderComponent extends Component {
return ''; return '';
} }
get suggestedUrls() {
const urls = [];
urls.push(...[{
name: `Homepage`,
url: this.config.getSiteUrl('/')
}, {
name: 'Free signup',
url: this.config.getSiteUrl('/#/portal/signup/free')
}]);
if (this.membersUtils.paidMembersEnabled) {
urls.push(...[{
name: 'Paid signup',
url: this.config.getSiteUrl('/#/portal/signup')
}, {
name: 'Upgrade or change plan',
url: this.config.getSiteUrl('/#/portal/account/plans')
}]);
}
if (this.offers) {
this.offers.forEach((offer) => {
urls.push(...[{
name: `Offer - ${offer.name}`,
url: this.config.getSiteUrl(offer.code)
}]);
});
}
// TODO: remove feature condition once Tips & Donations have been released
if (this.feature.tipsAndDonations) {
if (this.settings.donationsEnabled) {
urls.push({
name: `Support ${this.settings.title}`,
url: this.config.getSiteUrl('/#/portal/support')
});
}
}
return urls;
}
constructor() { constructor() {
super(...arguments); super(...arguments);
this.args.registerComponent(this); this.args.registerComponent(this);
@ -157,8 +201,8 @@ export default class KoenigCardHeaderComponent extends Component {
} }
@action @action
setButtonUrl(event) { setButtonUrl(url) {
this._updatePayloadAttr('buttonUrl', event.target.value); this._updatePayloadAttr('buttonUrl', url);
if (!this.args.payload.buttonEnabled) { if (!this.args.payload.buttonEnabled) {
this._updatePayloadAttr('buttonEnabled', true); this._updatePayloadAttr('buttonEnabled', true);
} }
@ -172,6 +216,32 @@ export default class KoenigCardHeaderComponent extends Component {
} }
} }
@action
enterLinkURL(event) {
event.stopPropagation();
const parent = event.target;
const child = event.target.querySelector('span');
clearTimeout(this.linkScrollerTimeout);
if (child.offsetWidth > parent.offsetWidth) {
this.linkScrollerTimeout = setTimeout(() => {
parent.classList.add('scroller');
child.style.transform = `translateX(-${(child.offsetWidth - parent.offsetWidth) + 8}px)`;
}, 100);
}
}
@action
leaveLinkURL(event) {
event.stopPropagation();
clearTimeout(this.linkScrollerTimeout);
const parent = event.target;
const child = event.target.querySelector('span');
child.style.transform = 'translateX(0)';
parent.classList.remove('scroller');
}
@action @action
leaveEditMode() { leaveEditMode() {
if (this.isEmpty) { if (this.isEmpty) {