mirror of
https://github.com/TryGhost/Ghost.git
synced 2024-11-28 14:03:48 +03:00
Added settings for newsletter header, title style, and feature image (#1993)
refs https://github.com/TryGhost/Team/issues/755 reqs https://github.com/TryGhost/Ghost/pull/13006 - updated settings model to match new server-side settings - updated email customisation modal behind the dev experiments flag - adjusted layout to move to a fixed top bar and scrollable sidebar - added image upload, toggles and selections for new settings - updated preview to match selected settings Co-authored-by: Sanne de Vries <sannedv@protonmail.com>
This commit is contained in:
parent
230058d6ec
commit
b2b66490b7
@ -4,6 +4,10 @@ import XFileInput from 'emberx-file-input/components/x-file-input';
|
||||
// upgraded to emberx-file-input@1.2.0
|
||||
|
||||
export default XFileInput.extend({
|
||||
didInsertElement() {
|
||||
this.onInsert?.(this.element.querySelector('input[type="file"]'));
|
||||
},
|
||||
|
||||
change(e) {
|
||||
let action = this.action;
|
||||
let files = this.files(e);
|
||||
|
@ -4,5 +4,11 @@
|
||||
files=this.files
|
||||
isUploading=this._uploadFiles.isRunning
|
||||
progressBar=(component "gh-progress-bar" percentage=this.uploadPercentage)
|
||||
setFiles=(action 'setFiles')
|
||||
setFiles=(action "setFiles")
|
||||
registerFileInput=(action "registerFileInput")
|
||||
triggerFileDialog=(action "triggerFileDialog")
|
||||
imageExtensions=this.imageExtensions
|
||||
imageMimeTypes=this.imageMimeTypes
|
||||
iconExtensions=this.iconExtensions
|
||||
iconMimeTypes=this.iconMimeTypes
|
||||
)}}
|
||||
|
@ -1,6 +1,12 @@
|
||||
import Component from '@ember/component';
|
||||
import EmberObject from '@ember/object';
|
||||
import ghostPaths from 'ghost-admin/utils/ghost-paths';
|
||||
import {
|
||||
ICON_EXTENSIONS,
|
||||
ICON_MIME_TYPES,
|
||||
IMAGE_EXTENSIONS,
|
||||
IMAGE_MIME_TYPES
|
||||
} from 'ghost-admin/components/gh-image-uploader';
|
||||
import {all, task} from 'ember-concurrency';
|
||||
import {get} from '@ember/object';
|
||||
import {isArray} from '@ember/array';
|
||||
@ -89,6 +95,11 @@ export default Component.extend({
|
||||
if (!this.paramsHash) {
|
||||
this.set('paramsHash', {purpose: 'image'});
|
||||
}
|
||||
|
||||
this.set('imageExtensions', IMAGE_EXTENSIONS);
|
||||
this.set('imageMimeTypes', IMAGE_MIME_TYPES);
|
||||
this.set('iconExtensions', ICON_EXTENSIONS);
|
||||
this.set('iconMimeTypes', ICON_MIME_TYPES);
|
||||
},
|
||||
|
||||
didReceiveAttrs() {
|
||||
@ -105,6 +116,20 @@ export default Component.extend({
|
||||
},
|
||||
|
||||
actions: {
|
||||
registerFileInput(input) {
|
||||
this.fileInput = input;
|
||||
},
|
||||
|
||||
triggerFileDialog() {
|
||||
if (!this.fileInput) {
|
||||
// eslint-disable-next-line
|
||||
console.error('When using uploader.triggerFileDialog you must call uploader.registerFileInput first');
|
||||
return;
|
||||
}
|
||||
|
||||
this.fileInput.click();
|
||||
},
|
||||
|
||||
setFiles(files, resetInput) {
|
||||
this._setFiles(files);
|
||||
|
||||
|
300
ghost/admin/app/components/modal-email-design-settings-labs.hbs
Normal file
300
ghost/admin/app/components/modal-email-design-settings-labs.hbs
Normal file
@ -0,0 +1,300 @@
|
||||
<div class="modal-body modal-fullsettings labs-newsletter-settings">
|
||||
<div class="flex items-center justify-between w-100 modal-fullsettings-topbar">
|
||||
<h2 class="modal-fullsettings-heading">Email newsletter design</h2>
|
||||
<div class="flex items-center">
|
||||
<button
|
||||
class="gh-btn mr3"
|
||||
{{on "click" (action "closeModal")}}
|
||||
{{!-- disable mouseDown so it does not trigger focus-out validations --}}
|
||||
{{on "mousedown" (optional this.noop)}}
|
||||
data-test-button="cancel-custom-view-form"
|
||||
>
|
||||
<span>Cancel</span>
|
||||
</button>
|
||||
|
||||
<GhTaskButton
|
||||
@buttonText="Save and close"
|
||||
@successText="Saved"
|
||||
@task={{this.saveSettings}}
|
||||
@idleClass="gh-btn-primary"
|
||||
@class="gh-btn gh-btn-icon"
|
||||
data-test-button="save-members-modal-setting"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-fullsettings-body">
|
||||
<div class="modal-fullsettings-sidebar with-footer">
|
||||
<div>
|
||||
<fieldset class="modal-fullsettings-form">
|
||||
<div class="modal-fullsettings-section first">
|
||||
<GhFormGroup @classNames="vertical">
|
||||
<h4 class="modal-fullsettings-title">Header image</h4>
|
||||
|
||||
<GhUploader
|
||||
@extensions={{this.imageExtensions}}
|
||||
@paramsHash={{hash purpose="image"}}
|
||||
@onComplete={{fn this.imageUploaded "headerImage"}}
|
||||
as |uploader|
|
||||
>
|
||||
<div class="modal-fullsettings-uploader">
|
||||
{{#if uploader.isUploading}}
|
||||
<div class="gh-portal-button-icon">
|
||||
<div class="gh-loading-spinner"></div>
|
||||
</div>
|
||||
{{else if this.headerImage}}
|
||||
<div class="gh-header-img-container">
|
||||
<img
|
||||
class="gh-header-img-thumbnail"
|
||||
src={{this.headerImage}}
|
||||
alt="header image"
|
||||
data-test-img="header"
|
||||
>
|
||||
<button type="button" class="gh-btn gh-header-img-deleteicon" {{on "click" (fn this.changeSetting "headerImage" null)}}>
|
||||
<span> {{svg-jar "trash" class="w5 h5"}} </span>
|
||||
</button>
|
||||
</div>
|
||||
{{else}}
|
||||
<button type="button" class="gh-btn gh-header-img-uploadicon" data-tooltip="Upload image" {{on "click" uploader.triggerFileDialog}} data-test-image-upload-btn="header-image">
|
||||
<span>{{svg-jar "upload-fill" class="w5 h5"}}</span>
|
||||
</button>
|
||||
<div style="display:none">
|
||||
<GhFileInput
|
||||
@multiple={{false}}
|
||||
@action={{uploader.setFiles}}
|
||||
@accept={{uploader.imageMimeTypes}}
|
||||
@onInsert={{uploader.registerFileInput}}
|
||||
data-test-file-input="icon" />
|
||||
</div>
|
||||
{{/if}}
|
||||
<div>
|
||||
<h4>An optional branded image</h4>
|
||||
<p>For best result use 1200x600 PNG image</p>
|
||||
</div>
|
||||
</div>
|
||||
</GhUploader>
|
||||
</GhFormGroup>
|
||||
|
||||
<GhFormGroup>
|
||||
<h4 class="modal-fullsettings-title">Show publication icon</h4>
|
||||
<div class="for-switch small {{if (not this.settings.icon) "disabled"}}">
|
||||
<label class="switch" for="show-header">
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={{and this.showHeaderIcon this.settings.icon}}
|
||||
id="show-header"
|
||||
name="show-header"
|
||||
disabled={{not this.settings.icon}}
|
||||
{{on "click" (fn this.toggleSetting "showHeaderIcon")}}
|
||||
>
|
||||
<span class="input-toggle-component"></span>
|
||||
</label>
|
||||
</div>
|
||||
</GhFormGroup>
|
||||
<GhFormGroup>
|
||||
<h4 class="modal-fullsettings-title">Show publication title</h4>
|
||||
<div class="for-switch small">
|
||||
<label class="switch" for="show-title">
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={{this.showHeaderTitle}}
|
||||
id="show-title"
|
||||
name="show-title"
|
||||
{{on "click" (fn this.toggleSetting "showHeaderTitle")}}
|
||||
>
|
||||
<span class="input-toggle-component"></span>
|
||||
</label>
|
||||
</div>
|
||||
</GhFormGroup>
|
||||
</div>
|
||||
<div class="modal-fullsettings-section divider-top">
|
||||
<GhFormGroup>
|
||||
<h4 class="modal-fullsettings-title">Show post feature image</h4>
|
||||
<div class="for-switch small">
|
||||
<label class="switch" for="show-feature-image">
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={{this.showFeatureImage}}
|
||||
id="show-feature-image"
|
||||
name="show-feature-image"
|
||||
{{on "click" (fn this.toggleSetting "showFeatureImage")}}
|
||||
>
|
||||
<span class="input-toggle-component"></span>
|
||||
</label>
|
||||
</div>
|
||||
</GhFormGroup>
|
||||
<GhFormGroup @classNames="vertical">
|
||||
<h4 class="modal-fullsettings-title gh-email-design-alignment">
|
||||
<span>Post title style</span>
|
||||
<div class="gh-btn-group icons">
|
||||
<button type="button" class="gh-btn gh-btn-icon {{if (eq this.titleAlignment "left") "gh-btn-group-selected"}}" {{on "click" (fn this.changeSetting "titleAlignment" "left")}}><span>{{svg-jar "align-left"}}</span></button>
|
||||
<button type="button" class="gh-btn gh-btn-icon {{if (eq this.titleAlignment "center") "gh-btn-group-selected"}}" {{on "click" (fn this.changeSetting "titleAlignment" "center")}}><span>{{svg-jar "align-center"}}</span></button>
|
||||
</div>
|
||||
</h4>
|
||||
<div class="modal-fullsettings-radiogroup gh-email-design-typography">
|
||||
<div class="gh-radio {{if (eq this.titleFontCategory "serif") "active"}}"
|
||||
{{on "click" (fn this.changeSetting "titleFontCategory" "serif")}}
|
||||
>
|
||||
<div class="gh-radio-content serif">
|
||||
<div class="gh-radio-label">
|
||||
<span class="sample title">Aa</span>
|
||||
<div class="description">
|
||||
<h4>Elegant serif</h4>
|
||||
<p>Beautiful lines with great readability</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="gh-radio-button"></div>
|
||||
</div>
|
||||
<div class="gh-radio {{if (eq this.titleFontCategory "sans_serif") "active"}}"
|
||||
{{on "click" (fn this.changeSetting "titleFontCategory" "sans_serif")}}
|
||||
>
|
||||
<div class="gh-radio-content sans-serif">
|
||||
<div class="gh-radio-label">
|
||||
<span class="sample title">Aa</span>
|
||||
<div class="description">
|
||||
<h4>Clean sans-serif</h4>
|
||||
<p>A more minimal style with sharp lines</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="gh-radio-button"></div>
|
||||
</div>
|
||||
</div>
|
||||
{{!-- <p>Font style for the email title</p> --}}
|
||||
</GhFormGroup>
|
||||
</div>
|
||||
<div class="modal-fullsettings-section">
|
||||
<GhFormGroup @classNames="vertical">
|
||||
<h4 class="modal-fullsettings-title">Body style</h4>
|
||||
<div class="modal-fullsettings-radiogroup gh-email-design-typography">
|
||||
<div class="gh-radio {{if (eq this.bodyFontCategory "serif") "active"}}"
|
||||
{{on "click" (fn this.changeSetting "bodyFontCategory" "serif")}}
|
||||
>
|
||||
<div class="gh-radio-content serif">
|
||||
<div class="gh-radio-label">
|
||||
<span class="sample">Aa</span>
|
||||
<div class="description">
|
||||
<h4>Elegant serif</h4>
|
||||
<p>Beautiful lines with great readability</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="gh-radio-button"></div>
|
||||
</div>
|
||||
<div class="gh-radio {{if (eq this.bodyFontCategory "sans_serif") "active"}}"
|
||||
{{on "click" (fn this.changeSetting "bodyFontCategory" "sans_serif")}}
|
||||
>
|
||||
<div class="gh-radio-content sans-serif">
|
||||
<div class="gh-radio-label">
|
||||
<span class="sample">Aa</span>
|
||||
<div class="description">
|
||||
<h4>Clean sans-serif</h4>
|
||||
<p>A more minimal style with sharp lines</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="gh-radio-button"></div>
|
||||
</div>
|
||||
</div>
|
||||
{{!-- <p>Font style for the email body content</p> --}}
|
||||
</GhFormGroup>
|
||||
</div>
|
||||
<div class="modal-fullsettings-section divider-top">
|
||||
<GhFormGroup @classNames="vertical">
|
||||
<h4 class="modal-fullsettings-title">Email footer</h4>
|
||||
<KoenigBasicHtmlInput
|
||||
@name="footer"
|
||||
@html={{this.footerContent}}
|
||||
@class="miw-100 form-text gh-members-emailsettings-footer-input"
|
||||
@placeholder="Any extra information or legal text"
|
||||
@onChange={{fn this.changeSetting "footerContent"}}
|
||||
@onFocus={{this.handleInputFocus}}
|
||||
@onBlur={{this.handleInputBlur}}
|
||||
/>
|
||||
</GhFormGroup>
|
||||
</div>
|
||||
</fieldset>
|
||||
</div>
|
||||
<div class="modal-fullsettings-section gh-members-emailsettings-footer">
|
||||
<GhFormGroup>
|
||||
<div class="gh-members-emailsettings-promotelabel">
|
||||
<span>{{svg-jar "heart"}}</span>
|
||||
<div>
|
||||
<h4 class="modal-fullsettings-title">Promote independent publishing</h4>
|
||||
<p>Show you’re a part of the indie publishing movement with a small badge in the footer</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="for-switch small">
|
||||
<label
|
||||
class="switch"
|
||||
for="promote-ghost"
|
||||
>
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={{this.showBadge}}
|
||||
id="promote-ghost"
|
||||
name="promote-ghost"
|
||||
{{on "click" (fn this.toggleSetting "showBadge")}}
|
||||
>
|
||||
<span class="input-toggle-component"></span>
|
||||
</label>
|
||||
</div>
|
||||
</GhFormGroup>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-fullsettings-main">
|
||||
<div class="modal-fullsettings-preview-container gh-members-emailpreview">
|
||||
<div class="gh-members-emailpreview-container">
|
||||
<div class="gh-members-emailpreview-faux">
|
||||
<p>
|
||||
<span class="strong">{{this.config.blogTitle}}</span> <{{this.settings.membersFromAddress}}>
|
||||
</p>
|
||||
<p><span class="dark">To:</span> Jamie Larson <jamie@example.com></p>
|
||||
</div>
|
||||
<div class="gh-members-emailpreview-contents">
|
||||
{{#if this.headerImage}}
|
||||
<div class="gh-members-emailpreview-header-image">
|
||||
<img src={{this.headerImage}}>
|
||||
</div>
|
||||
{{/if}}
|
||||
{{#if this.showHeader}}
|
||||
<div class="gh-members-emailpreview-header">
|
||||
{{#if (and this.settings.icon this.showHeaderIcon)}}
|
||||
<img src={{this.settings.icon}} />
|
||||
{{/if}}
|
||||
{{#if this.showHeaderTitle}}
|
||||
<h4>{{this.config.blogTitle}}</h4>
|
||||
{{/if}}
|
||||
</div>
|
||||
{{/if}}
|
||||
<div class="gh-members-emailpreview-title {{if (eq this.titleAlignment "left") "gh-members-emailpreview-title-left"}}">
|
||||
<h2 class="{{if (eq this.titleFontCategory "serif") "serif"}}">Your email newsletter</h2>
|
||||
<p>
|
||||
<span>By {{if this.session.user.name this.session.user.name this.session.user.email}} – {{this.currentDate}} – </span> <a href="javascript:">View online →</a>
|
||||
</p>
|
||||
</div>
|
||||
{{#if this.showFeatureImage}}
|
||||
<div class="gh-members-emailpreview-featureimage" style={{this.featureImageStyle}}></div>
|
||||
{{/if}}
|
||||
<div class="gh-members-emailpreview-content {{if (eq this.bodyFontCategory "sans_serif") "sans-serif"}}">
|
||||
<p>This is what your content will look like when you send one of your posts as an email newsletter to your subscribers.</p>
|
||||
<p>Over there on the left you’ll see some settings that allow you to customise the look and feel of this template to make it perfectly suited to your brand. Email templates are exceptionally finnicky to make, but we’ve spent a long time optimising this one to make it work beautifully across devices, email clients and content types.</p>
|
||||
<p>So, you can trust that every email you send with Ghost will look great and work well. Just like the rest of your site.</p>
|
||||
</div>
|
||||
<div class="gh-members-emailpreview-footer">
|
||||
<div class="gh-members-emailpreview-footercontent">
|
||||
{{{this.footerContent}}}
|
||||
</div>
|
||||
<div class="gh-members-emailpreview-footersite">
|
||||
<span>{{this.config.blogTitle}} © – </span> <a href="javascript:">Unsubscribe</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="gh-members-emailpreview-badge {{if (not this.showBadge) "hide"}}">
|
||||
<a href="javascript:"><svg viewBox="0 0 156 156"><g fill="none" fill-rule="evenodd"><rect fill="#15212B" width="156" height="156" rx="27"></rect><g transform="translate(36 36)" fill="#F6F8FA"><path d="M0 71.007A4.004 4.004 0 014 67h26a4 4 0 014 4.007v8.986A4.004 4.004 0 0130 84H4a4 4 0 01-4-4.007v-8.986zM50 71.007A4.004 4.004 0 0154 67h26a4 4 0 014 4.007v8.986A4.004 4.004 0 0180 84H54a4 4 0 01-4-4.007v-8.986z"></path><rect y="34" width="84" height="17" rx="4"></rect><path d="M0 4.007A4.007 4.007 0 014.007 0h41.986A4.003 4.003 0 0150 4.007v8.986A4.007 4.007 0 0145.993 17H4.007A4.003 4.003 0 010 12.993V4.007z"></path><rect x="67" width="17" height="17" rx="4"></rect></g></g></svg> <span>Publish with Ghost</span></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
@ -0,0 +1,92 @@
|
||||
import ModalComponent from 'ghost-admin/components/modal-base';
|
||||
import moment from 'moment';
|
||||
// TODO: expose this via a helper
|
||||
import {IMAGE_EXTENSIONS} from 'ghost-admin/components/gh-image-uploader';
|
||||
import {action} from '@ember/object';
|
||||
import {htmlSafe} from '@ember/template';
|
||||
import {inject as service} from '@ember/service';
|
||||
import {task} from 'ember-concurrency-decorators';
|
||||
import {tracked} from '@glimmer/tracking';
|
||||
|
||||
export default class ModalEmailDesignSettings extends ModalComponent {
|
||||
@service config;
|
||||
@service ghostPaths;
|
||||
@service session;
|
||||
@service settings;
|
||||
|
||||
@tracked headerImage = this.settings.get('newsletterHeaderImage');
|
||||
@tracked showHeaderIcon = this.settings.get('newsletterShowHeaderIcon');
|
||||
@tracked showHeaderTitle = this.settings.get('newsletterShowHeaderTitle');
|
||||
@tracked titleFontCategory = this.settings.get('newsletterTitleFontCategory');
|
||||
@tracked titleAlignment = this.settings.get('newsletterTitleAlignment');
|
||||
@tracked showFeatureImage = this.settings.get('newsletterShowFeatureImage');
|
||||
@tracked bodyFontCategory = this.settings.get('newsletterBodyFontCategory');
|
||||
@tracked footerContent = this.settings.get('newsletterFooterContent');
|
||||
@tracked showBadge = this.settings.get('newsletterShowBadge');
|
||||
|
||||
currentDate = moment().format('D MMM YYYY');
|
||||
imageExtensions = IMAGE_EXTENSIONS;
|
||||
|
||||
get showHeader() {
|
||||
return (this.showHeaderIcon && this.settings.get('icon')) || this.showHeaderTitle;
|
||||
}
|
||||
|
||||
get featureImageUrl() {
|
||||
// keep path separate so asset rewriting correctly picks it up
|
||||
let imagePath = '/img/user-cover.png';
|
||||
let fullPath = this.ghostPaths.assetRoot.replace(/\/$/, '') + imagePath;
|
||||
return fullPath;
|
||||
}
|
||||
|
||||
get featureImageStyle() {
|
||||
return htmlSafe(`background-image: url(${this.featureImageUrl})`);
|
||||
}
|
||||
|
||||
@action
|
||||
toggleSetting(setting, event) {
|
||||
this[setting] = event.target.checked;
|
||||
}
|
||||
|
||||
@action
|
||||
changeSetting(setting, value) {
|
||||
this[setting] = value;
|
||||
}
|
||||
|
||||
@action
|
||||
imageUploaded(setting, images) {
|
||||
if (images[0]) {
|
||||
this[setting] = images[0].url;
|
||||
}
|
||||
}
|
||||
|
||||
@action
|
||||
handleInputFocus() {
|
||||
this._removeShortcuts();
|
||||
}
|
||||
|
||||
@action
|
||||
handleInputBlur() {
|
||||
this._setupShortcuts();
|
||||
}
|
||||
|
||||
@action
|
||||
confirm() {
|
||||
this.saveSettings.perform();
|
||||
}
|
||||
|
||||
@task({drop: true})
|
||||
*saveSettings() {
|
||||
this.settings.set('newsletterHeaderImage', this.headerImage);
|
||||
this.settings.set('newsletterShowHeaderIcon', this.showHeaderIcon);
|
||||
this.settings.set('newsletterShowHeaderTitle', this.showHeaderTitle);
|
||||
this.settings.set('newsletterTitleFontCategory', this.titleFontCategory);
|
||||
this.settings.set('newsletterTitleAlignment', this.titleAlignment);
|
||||
this.settings.set('newsletterShowFeatureImage', this.showFeatureImage);
|
||||
this.settings.set('newsletterBodyFontCategory', this.bodyFontCategory);
|
||||
this.settings.set('newsletterFooterContent', this.footerContent);
|
||||
this.settings.set('newsletterShowBadge', this.showBadge);
|
||||
|
||||
yield this.settings.save();
|
||||
this.closeModal();
|
||||
}
|
||||
}
|
@ -145,7 +145,7 @@
|
||||
<div class="gh-members-emailpreview-title">
|
||||
<h2>Your email newsletter</h2>
|
||||
<p>
|
||||
<span>By {{if this.session.user.name this.session.user.name this.session.user.email}} – {{this.currentDate}} – </span> <a href="javascript:">View online →</a>
|
||||
<span>By {{if this.session.user.name this.session.user.name this.session.user.email}} – {{this.currentDate}} – </span> <a href="javascript:">View online →</a>
|
||||
</p>
|
||||
</div>
|
||||
<div class="gh-members-emailpreview-content {{if (eq this.bodyFontCategory "sans_serif") "sans-serif"}}">
|
||||
|
@ -77,9 +77,15 @@ export default Model.extend(ValidationEngine, {
|
||||
* Newsletter settings
|
||||
*/
|
||||
newsletterShowHeader: attr('boolean'),
|
||||
newsletterHeaderImage: attr('string'),
|
||||
newsletterShowHeaderIcon: attr('boolean'),
|
||||
newsletterShowHeaderTitle: attr('boolean'),
|
||||
newsletterTitleFontCategory: attr('string'),
|
||||
newsletterTitleAlignment: attr('string'),
|
||||
newsletterShowFeatureImage: attr('boolean'),
|
||||
newsletterBodyFontCategory: attr('string'),
|
||||
newsletterShowBadge: attr('boolean'),
|
||||
newsletterFooterContent: attr('string'),
|
||||
newsletterShowBadge: attr('boolean'),
|
||||
/**
|
||||
* OAuth settings
|
||||
*/
|
||||
|
@ -227,7 +227,7 @@
|
||||
}
|
||||
|
||||
|
||||
/* Full screen setting modal with preview. Used in e.g. Portal
|
||||
/* Full screen setting modal with preview. Used in e.g. Portal
|
||||
/* settings, Email design settings etc.
|
||||
/* ---------------------------------------------------------- */
|
||||
.modal-fullsettings {
|
||||
@ -241,6 +241,9 @@
|
||||
padding: 0;
|
||||
flex-grow: 1;
|
||||
}
|
||||
.labs-newsletter-settings .modal-fullsettings-body {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.modal-fullsettings-body .form-group.space-l {
|
||||
margin-bottom: 1.9em;
|
||||
@ -266,6 +269,10 @@
|
||||
padding: 0px 24px 20px;
|
||||
width: 362px;
|
||||
}
|
||||
.labs-newsletter-settings .modal-fullsettings-sidebar {
|
||||
width: 400px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.modal-fullsettings-sidebar.with-footer {
|
||||
justify-content: space-between;
|
||||
@ -275,6 +282,9 @@
|
||||
height: 66px;
|
||||
padding: 0 24px;
|
||||
}
|
||||
.labs-newsletter-settings .modal-fullsettings-topbar {
|
||||
border-bottom: 1px solid var(--whitegrey);
|
||||
}
|
||||
|
||||
.modal-fullsettings-heading {
|
||||
display: flex;
|
||||
@ -284,6 +294,9 @@
|
||||
padding: 0 24px;
|
||||
margin: 0 -24px 1px;
|
||||
}
|
||||
.labs-newsletter-settings .modal-fullsettings-heading {
|
||||
height: 66px;
|
||||
}
|
||||
|
||||
.modal-fullsettings-form {
|
||||
min-width: 292px;
|
||||
@ -294,14 +307,22 @@
|
||||
padding: 0 24px;
|
||||
}
|
||||
|
||||
/* labs-newsletter-settings - delete all when removing flag */
|
||||
.modal-fullsettings-section.first {
|
||||
margin-top: 8px;
|
||||
}
|
||||
.labs-newsletter-settings .modal-fullsettings-section.first {
|
||||
margin-top: 24px;
|
||||
}
|
||||
/* end delete all */
|
||||
|
||||
.modal-fullsettings-section.divider-top {
|
||||
border-top: 1px solid var(--whitegrey);
|
||||
padding-top: 16px;
|
||||
}
|
||||
.labs-newsletter-settings .modal-fullsettings-section.divider-top {
|
||||
padding-top: 24px;
|
||||
}
|
||||
|
||||
.modal-fullsettings-sectionheading {
|
||||
font-size: 1.2rem;
|
||||
@ -319,6 +340,9 @@
|
||||
padding: 0;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
.labs-newsletter-settings .modal-fullsettings-section .form-group {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.modal-fullsettings-section .form-group > p {
|
||||
font-size: 1.25rem !important;
|
||||
@ -365,6 +389,99 @@
|
||||
margin: 0 12px 0 0;
|
||||
}
|
||||
|
||||
.labs-newsletter-settings .modal-fullsettings-uploader {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin: 18px 0 0;
|
||||
padding: 3px;
|
||||
border: 1px solid var(--whitegrey);
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.labs-newsletter-settings .gh-header-img-uploadicon,
|
||||
.labs-newsletter-settings .gh-header-img-uploadicon:hover,
|
||||
.labs-newsletter-settings .gh-header-img-uploadicon:focus {
|
||||
width: 56px;
|
||||
height: 44px;
|
||||
margin-right: 11px;
|
||||
border: 1px dashed var(--lightgrey);
|
||||
background: transparent;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.labs-newsletter-settings .gh-header-img-uploadicon span {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.labs-newsletter-settings .gh-header-img-uploadicon span svg {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
fill: var(--darkgrey);
|
||||
}
|
||||
|
||||
.labs-newsletter-settings .gh-header-img-uploadicon:hover span svg {
|
||||
fill: var(--darkgrey);
|
||||
}
|
||||
|
||||
.labs-newsletter-settings .gh-header-img-container {
|
||||
height: 44px;
|
||||
}
|
||||
|
||||
.labs-newsletter-settings .gh-header-img-thumbnail {
|
||||
display: inline-block;
|
||||
width: 56px;
|
||||
height: 44px;
|
||||
margin: 0 11px 0 0;
|
||||
border: 1px solid var(--whitegrey);
|
||||
cursor: pointer;
|
||||
background-position: center;
|
||||
object-fit: cover;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.labs-newsletter-settings .gh-header-img-thumbnail svg path {
|
||||
stroke: var(--midlightgrey-d1);
|
||||
}
|
||||
|
||||
.labs-newsletter-settings .gh-header-img-deleteicon {
|
||||
position: absolute;
|
||||
left: 4px;
|
||||
width: 56px;
|
||||
height: 44px;
|
||||
background: var(--black) !important;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.labs-newsletter-settings .gh-header-img-deleteicon:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.labs-newsletter-settings .gh-header-img-deleteicon span {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.labs-newsletter-settings .gh-header-img-deleteicon span svg {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
}
|
||||
|
||||
.modal-fullsettings-uploader h4 {
|
||||
margin: 0 !important;
|
||||
padding: 0;
|
||||
font-size: 1.3rem;
|
||||
line-height: 1.4em;
|
||||
}
|
||||
|
||||
.modal-fullsettings-uploader p {
|
||||
margin: 0 !important;
|
||||
padding: 0;
|
||||
font-size: 1.2rem !important;
|
||||
}
|
||||
|
||||
.modal-fullsettings-main {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
@ -379,6 +496,9 @@
|
||||
height: calc(100vh - 126px);
|
||||
overflow-y: scroll;
|
||||
}
|
||||
.labs-newsletter-settings .modal-fullsettings-preview-container {
|
||||
height: 100vh;
|
||||
}
|
||||
|
||||
.modal-fullsettings-preview-hidescrollbar {
|
||||
overflow: hidden;
|
||||
@ -387,6 +507,9 @@
|
||||
border: 1px solid var(--whitegrey);
|
||||
border-radius: 5px;
|
||||
}
|
||||
.labs-newsletter-settings .modal-fullsettings-preview-hidescrollbar {
|
||||
height: 100vh;
|
||||
}
|
||||
|
||||
.modal-fullsettings-preview-hidescrollbar .modal-fullsettings-preview-container {
|
||||
border: none;
|
||||
@ -448,4 +571,4 @@
|
||||
flex: 1;
|
||||
margin-right: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -58,7 +58,7 @@
|
||||
|
||||
@media (max-width: 1100px) {
|
||||
.members-list {
|
||||
border-bottom: none
|
||||
border-bottom: none
|
||||
}
|
||||
}
|
||||
|
||||
@ -780,7 +780,7 @@ textarea.gh-member-details-textarea {
|
||||
}
|
||||
|
||||
.gh-member-btn-expandfeed {
|
||||
margin: 8px 0;
|
||||
margin: 8px 0;
|
||||
}
|
||||
|
||||
|
||||
@ -1180,6 +1180,13 @@ p.gh-members-import-errordetail:first-of-type {
|
||||
|
||||
/* Email newsletter design settings
|
||||
/* -------------------------------------------------------- */
|
||||
.labs-newsletter-settings .gh-email-design-alignment {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin: -4px 0 0 0;
|
||||
}
|
||||
|
||||
.gh-email-design-typography .gh-radio {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@ -1188,18 +1195,44 @@ p.gh-members-import-errordetail:first-of-type {
|
||||
padding: 0;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
.labs-newsletter-settings .gh-email-design-typography .gh-radio {
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
|
||||
.gh-email-design-typography .gh-radio-content {
|
||||
border: 1px solid var(--whitegrey);
|
||||
border-radius: 3px;
|
||||
border-radius: 3px; /* labs-newsletter-settings - delete line when removing flag */
|
||||
margin: 0 -32px 0 0;
|
||||
}
|
||||
/* labs-newsletter-settings - delete all when removing flag */
|
||||
.labs-newsletter-settings .gh-email-design-typography .gh-radio-content {
|
||||
border-radius: inherit;
|
||||
}
|
||||
/* end delete all */
|
||||
|
||||
.labs-newsletter-settings .gh-email-design-typography .gh-radio-content.serif {
|
||||
border-top-left-radius: 3px;
|
||||
border-top-right-radius: 3px;
|
||||
}
|
||||
|
||||
.labs-newsletter-settings .gh-email-design-typography .gh-radio-content.sans-serif {
|
||||
border-bottom-left-radius: 3px;
|
||||
border-bottom-right-radius: 3px;
|
||||
}
|
||||
|
||||
.labs-newsletter-settings .gh-email-design-typography .active {
|
||||
margin: 0 2px 2px;
|
||||
}
|
||||
|
||||
.gh-email-design-typography .active .gh-radio-content {
|
||||
border: 1px solid transparent;
|
||||
box-shadow: 0px 0px 0px 2px var(--green);
|
||||
}
|
||||
|
||||
.labs-newsletter-settings .gh-email-design-typography .active .gh-radio-label {
|
||||
margin: 0 -2px;
|
||||
}
|
||||
|
||||
.gh-email-design-typography .gh-radio-button {
|
||||
margin-right: 12px;
|
||||
opacity: 0;
|
||||
@ -1219,6 +1252,13 @@ p.gh-members-import-errordetail:first-of-type {
|
||||
width: 44px;
|
||||
text-align: center;
|
||||
}
|
||||
.labs-newsletter-settings .gh-email-design-typography .gh-radio-label .sample {
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
.labs-newsletter-settings .gh-email-design-typography .gh-radio-label .sample.title {
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.gh-email-design-typography .gh-radio-label .description h4 {
|
||||
font-size: 1.3rem;
|
||||
@ -1227,7 +1267,8 @@ p.gh-members-import-errordetail:first-of-type {
|
||||
line-height: 1.4em;
|
||||
}
|
||||
|
||||
.gh-email-design-typography .gh-radio-label.serif .description h4 {
|
||||
.gh-email-design-typography .gh-radio-label.serif .description h4,
|
||||
.labs-newsletter-settings .gh-email-design-typography .gh-radio-content.serif .description h4 {
|
||||
font-family: Georgia, 'Times New Roman', Times, serif;
|
||||
font-size: 1.3rem;
|
||||
}
|
||||
@ -1238,7 +1279,8 @@ p.gh-members-import-errordetail:first-of-type {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.gh-email-design-typography .gh-radio-label.serif .description p {
|
||||
.gh-email-design-typography .gh-radio-label.serif .description p,
|
||||
.labs-newsletter-settings .gh-email-design-typography .gh-radio-content.serif .description p {
|
||||
font-size: 1.25rem !important;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
@ -1253,7 +1295,7 @@ p.gh-members-import-errordetail:first-of-type {
|
||||
|
||||
.gh-members-emailsettings-footer-input p {
|
||||
height: 108px;
|
||||
overflow-y: scroll;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.gh-members-emailsettings-footer-input p {
|
||||
@ -1266,6 +1308,10 @@ p.gh-members-import-errordetail:first-of-type {
|
||||
padding-top: 20px;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
.labs-newsletter-settings .gh-members-emailsettings-footer {
|
||||
padding: inherit;
|
||||
margin: 0px -24px 4px;
|
||||
}
|
||||
|
||||
.gh-members-emailsettings-footer .form-group {
|
||||
align-items: flex-start;
|
||||
@ -1406,6 +1452,9 @@ p.gh-members-import-errordetail:first-of-type {
|
||||
align-items: center;
|
||||
padding: 50px 0 40px;
|
||||
}
|
||||
.labs-newsletter-settings .gh-members-emailpreview-title-left {
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
.gh-members-emailpreview-title h2 {
|
||||
font-size: 4.2rem;
|
||||
@ -1438,6 +1487,15 @@ p.gh-members-import-errordetail:first-of-type {
|
||||
color: #15212A;
|
||||
}
|
||||
|
||||
.labs-newsletter-settings .gh-members-emailpreview-featureimage {
|
||||
width: 100%;
|
||||
max-width: 600px;
|
||||
height: 300px;
|
||||
margin-bottom: 1.7em;
|
||||
background: #fafafa no-repeat 50%;
|
||||
background-size: cover;
|
||||
}
|
||||
|
||||
.gh-members-emailpreview-content {
|
||||
padding-bottom: 20px;
|
||||
border-bottom: 1px solid #e5eff5;
|
||||
@ -1713,4 +1771,4 @@ p.gh-members-import-errordetail:first-of-type {
|
||||
|
||||
.gh-member-product-form-block .form-group:last-of-type {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
@ -421,7 +421,7 @@ Usage: CTA buttons grouped together horizontally.
|
||||
border-radius: 0;
|
||||
height: 30px;
|
||||
line-height: 30px;
|
||||
border-radius: 2px;
|
||||
border-radius: 3px;
|
||||
background: transparent !important;
|
||||
font-weight: 500 !important;
|
||||
}
|
||||
@ -438,6 +438,31 @@ Usage: CTA buttons grouped together horizontally.
|
||||
fill: var(--black);
|
||||
}
|
||||
|
||||
.gh-btn-group.icons .gh-btn {
|
||||
margin: 3px;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.gh-btn-group.icons .gh-btn span {
|
||||
height: 28px;
|
||||
padding: 0 10px;
|
||||
}
|
||||
|
||||
.gh-btn-group.icons .gh-btn-icon svg {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
margin-right: 0;
|
||||
fill: var(--midgrey);
|
||||
}
|
||||
|
||||
.gh-btn-group.icons .gh-btn-group-selected svg {
|
||||
fill: var(--black);
|
||||
}
|
||||
|
||||
.gh-btn-group.icons .gh-btn-icon svg path {
|
||||
stroke: none;
|
||||
}
|
||||
|
||||
.gh-btn-block + .gh-btn-block {
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
@ -45,8 +45,14 @@
|
||||
|
||||
{{#if this.showEmailDesignSettings}}
|
||||
<GhFullscreenModal @modifier="full-overlay portal-settings">
|
||||
<ModalEmailDesignSettings
|
||||
@closeModal={{this.toggleEmailDesignSettings}}
|
||||
/>
|
||||
{{#if (enable-developer-experiments)}}
|
||||
<ModalEmailDesignSettingsLabs
|
||||
@closeModal={{this.toggleEmailDesignSettings}}
|
||||
/>
|
||||
{{else}}
|
||||
<ModalEmailDesignSettings
|
||||
@closeModal={{this.toggleEmailDesignSettings}}
|
||||
/>
|
||||
{{/if}}
|
||||
</GhFullscreenModal>
|
||||
{{/if}}
|
3
ghost/admin/public/assets/icons/align-center.svg
Normal file
3
ghost/admin/public/assets/icons/align-center.svg
Normal file
@ -0,0 +1,3 @@
|
||||
<svg width="24" height="24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M1 6a1 1 0 011-1h20a1 1 0 110 2H2a1 1 0 01-1-1zM6 12.5a1 1 0 011-1h10a1 1 0 110 2H7a1 1 0 01-1-1zM1 19a1 1 0 011-1h20a1 1 0 110 2H2a1 1 0 01-1-1z"/>
|
||||
</svg>
|
After Width: | Height: | Size: 282 B |
3
ghost/admin/public/assets/icons/align-left.svg
Normal file
3
ghost/admin/public/assets/icons/align-left.svg
Normal file
@ -0,0 +1,3 @@
|
||||
<svg width="24" height="24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M1 6a1 1 0 011-1h20a1 1 0 110 2H2a1 1 0 01-1-1zM1 12.5a1 1 0 011-1h12a1 1 0 110 2H2a1 1 0 01-1-1zM1 19a1 1 0 011-1h20a1 1 0 110 2H2a1 1 0 01-1-1z"/>
|
||||
</svg>
|
After Width: | Height: | Size: 283 B |
Loading…
Reference in New Issue
Block a user