From 01e72dc991cfe6cc1045f4b6716c7ef37758467e Mon Sep 17 00:00:00 2001 From: Rishabh Garg Date: Tue, 9 Jun 2020 01:52:58 +0530 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20Allowed=20domain=20change=20for=20m?= =?UTF-8?q?embers=20"from"=20address=20(#1597)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit refs TryGhost/Ghost#11414 - Restructures member settings in labs, from address gets its own section - Removes explicit site domain for fromAddress as we allow updating the full address - Adds new CTA to trigger magic link for updating members from address - Adds new confirmation modal for email sent to new from address - Adds notification banner for from address update redirect link --- ghost/admin/app/components/gh-alert.hbs | 2 +- .../app/components/gh-members-lab-setting.hbs | 149 +++++++++++------- .../app/components/gh-members-lab-setting.js | 27 ++++ .../modal-from-address-confirmation.hbs | 12 ++ .../modal-from-address-confirmation.js | 8 + ghost/admin/app/controllers/settings/labs.js | 3 + ghost/admin/app/routes/settings/labs.js | 15 ++ .../app/styles/components/notifications.css | 8 +- ghost/admin/app/styles/patterns/buttons.css | 9 ++ .../admin/app/styles/spirit/_line-height.css | 5 + .../public/assets/icons/close-stroke.svg | 1 + 11 files changed, 173 insertions(+), 66 deletions(-) create mode 100644 ghost/admin/app/components/modal-from-address-confirmation.hbs create mode 100644 ghost/admin/app/components/modal-from-address-confirmation.js create mode 100644 ghost/admin/public/assets/icons/close-stroke.svg diff --git a/ghost/admin/app/components/gh-alert.hbs b/ghost/admin/app/components/gh-alert.hbs index bbe2d848b4..24b6f342d9 100644 --- a/ghost/admin/app/components/gh-alert.hbs +++ b/ghost/admin/app/components/gh-alert.hbs @@ -2,5 +2,5 @@ {{message.message}} diff --git a/ghost/admin/app/components/gh-members-lab-setting.hbs b/ghost/admin/app/components/gh-members-lab-setting.hbs index 641d00859c..3dbb1b276b 100644 --- a/ghost/admin/app/components/gh-members-lab-setting.hbs +++ b/ghost/admin/app/components/gh-members-lab-setting.hbs @@ -219,74 +219,101 @@
-

Email settings

-

Customise signup, signin and subscription emails

+

From address

+

The email address your members receive newsletters from

- +
- {{#liquid-if this.membersEmailOpen}} -
- - -
- - @{{this.blogDomain}} -
-
Your members will receive system emails from this address
-
- - {{#unless this.hasBulkEmailConfig}} -
- - -
- - {{region.flag}} {{region.name}} - -
-
- - - - -
- + {{#liquid-if this.membersFromOpen}} +
- - - - Find your Mailgun API keys here » - +
+ + +
- {{/unless}} -
+ {{#if this.showFromAddressConfirmation}} +
+ {{svg-jar "check-circle" class="w4 h4 mr1 stroke-green-d1"}} Check your inbox and click the link to confirm +
+ {{/if}} +
{{/liquid-if}}
+ {{#unless this.hasBulkEmailConfig}} +
+
+
+

Mailgun settings

+

Customise signup, signin and subscription emails

+
+
+ +
+
+ + {{#liquid-if this.membersEmailOpen}} +
+
+ + +
+ + {{region.flag}} {{region.name}} + +
+
+ + + + +
+ + + + + + Find your Mailgun API keys here » + + +
+ {{/liquid-if}} +
+ {{/unless}} \ No newline at end of file diff --git a/ghost/admin/app/components/gh-members-lab-setting.js b/ghost/admin/app/components/gh-members-lab-setting.js index e6a82b788a..13b5797be1 100644 --- a/ghost/admin/app/components/gh-members-lab-setting.js +++ b/ghost/admin/app/components/gh-members-lab-setting.js @@ -3,6 +3,7 @@ import {computed} from '@ember/object'; import {reads} from '@ember/object/computed'; import {inject as service} from '@ember/service'; import {set} from '@ember/object'; +import {task} from 'ember-concurrency'; const US = {flag: '🇺🇸', name: 'US', baseUrl: 'https://api.mailgun.net/v3'}; const EU = {flag: '🇪🇺', name: 'EU', baseUrl: 'https://api.eu.mailgun.net/v3'}; @@ -30,8 +31,10 @@ export default Component.extend({ config: service(), mediaQueries: service(), ghostPaths: service(), + ajax: service(), currencies: null, + showFromAddressConfirmation: false, // passed in actions setMembersSubscriptionSettings() {}, @@ -45,6 +48,10 @@ export default Component.extend({ return CURRENCIES.findBy('value', this.get('subscriptionSettings.stripeConfig.plans.monthly.currency')); }), + disableUpdateFromAddressButton: computed('subscriptionSettings.fromAddress', function () { + return (this.originalFromAddress === this.get('subscriptionSettings.fromAddress')); + }), + mailgunRegion: computed('settings.bulkEmailSettings.baseUrl', function () { if (!this.settings.get('bulkEmailSettings.baseUrl')) { return US; @@ -103,6 +110,10 @@ export default Component.extend({ }, actions: { + toggleFromAddressConfirmation() { + this.toggleProperty('showFromAddressConfirmation'); + }, + setDefaultContentVisibility(value) { this.setDefaultContentVisibility(value); }, @@ -183,6 +194,22 @@ export default Component.extend({ } }, + updateFromAddress: task(function* () { + let url = this.get('ghostPaths.url').api('/settings/members/email'); + try { + const response = yield this.ajax.post(url, { + data: { + from_address: this.subscriptionSettings.fromAddress + } + }); + this.toggleProperty('showFromAddressConfirmation'); + return response; + } catch (e) { + // Failed to send email, retry + return false; + } + }).drop(), + get stripeConnectAuthUrl() { return this.ghostPaths.url.api('members/stripe_connect'); } diff --git a/ghost/admin/app/components/modal-from-address-confirmation.hbs b/ghost/admin/app/components/modal-from-address-confirmation.hbs new file mode 100644 index 0000000000..7649e24b5a --- /dev/null +++ b/ghost/admin/app/components/modal-from-address-confirmation.hbs @@ -0,0 +1,12 @@ + +{{svg-jar "close"}} + + + + diff --git a/ghost/admin/app/components/modal-from-address-confirmation.js b/ghost/admin/app/components/modal-from-address-confirmation.js new file mode 100644 index 0000000000..3f004e2062 --- /dev/null +++ b/ghost/admin/app/components/modal-from-address-confirmation.js @@ -0,0 +1,8 @@ +import ModalComponent from 'ghost-admin/components/modal-base'; +import {alias} from '@ember/object/computed'; + +export default ModalComponent.extend({ + + confirm() {}, + fromAddress: alias('model.fromAddress') +}); diff --git a/ghost/admin/app/controllers/settings/labs.js b/ghost/admin/app/controllers/settings/labs.js index 65122f875b..c6e0a51891 100644 --- a/ghost/admin/app/controllers/settings/labs.js +++ b/ghost/admin/app/controllers/settings/labs.js @@ -42,6 +42,8 @@ export default Controller.extend({ session: service(), settings: service(), + queryParams: ['fromAddressUpdate'], + fromAddressUpdate: null, importErrors: null, importSuccessful: false, showDeleteAllModal: false, @@ -250,5 +252,6 @@ export default Controller.extend({ reset() { this.set('importErrors', null); this.set('importSuccessful', false); + this.set('fromAddressUpdate', null); } }); diff --git a/ghost/admin/app/routes/settings/labs.js b/ghost/admin/app/routes/settings/labs.js index 8a305a2d58..81ad3fe3c0 100644 --- a/ghost/admin/app/routes/settings/labs.js +++ b/ghost/admin/app/routes/settings/labs.js @@ -4,6 +4,12 @@ import {inject as service} from '@ember/service'; export default AuthenticatedRoute.extend(CurrentUserSettings, { settings: service(), + notifications: service(), + queryParams: { + fromAddressUpdate: { + replace: true + } + }, beforeModel() { this._super(...arguments); @@ -16,6 +22,15 @@ export default AuthenticatedRoute.extend(CurrentUserSettings, { return this.settings.reload(); }, + setupController(controller) { + if (controller.fromAddressUpdate === 'success') { + this.notifications.showAlert( + `Done! Newsletter “From address” has been updated`.htmlSafe(), + {type: 'success', key: 'members.settings.from-address.updated'} + ); + } + }, + resetController(controller, isExiting) { if (isExiting) { controller.reset(); diff --git a/ghost/admin/app/styles/components/notifications.css b/ghost/admin/app/styles/components/notifications.css index e3dba4874e..6a850f152d 100644 --- a/ghost/admin/app/styles/components/notifications.css +++ b/ghost/admin/app/styles/components/notifications.css @@ -203,7 +203,7 @@ .gh-alert-content { font-size: 1.4rem; line-height: 1.3em; - font-weight: 300; + font-weight: 400; user-select: text; } @@ -216,14 +216,14 @@ .gh-alert-close { flex-shrink: 0; margin-left: 20px; - padding: 5px; + padding: 4px; font-size: 10px; line-height: 10px; } .gh-alert-close svg { - height: 10px; - width: 10px; + height: 12px; + width: 12px; } .gh-alert-close:hover { diff --git a/ghost/admin/app/styles/patterns/buttons.css b/ghost/admin/app/styles/patterns/buttons.css index a5d5386fb1..8aa524d977 100644 --- a/ghost/admin/app/styles/patterns/buttons.css +++ b/ghost/admin/app/styles/patterns/buttons.css @@ -320,6 +320,10 @@ fieldset[disabled] .gh-btn { fill: color-mod(var(--midgrey) l(+15%)); } +.gh-btn:not(.gh-btn-blue):not(.gh-btn-green) svg.gh-icon-spinner rect { + fill: color-mod(var(--midgrey) l(-7%)); +} + .gh-btn-icon-right svg, svg.gh-btn-icon-right { margin-left: 0.5em; @@ -374,6 +378,11 @@ svg.gh-btn-icon-right { box-shadow: none; } +.gh-btn-textfield-group span { + height: 36px; + line-height: 36px; +} + /* /* Button Variations diff --git a/ghost/admin/app/styles/spirit/_line-height.css b/ghost/admin/app/styles/spirit/_line-height.css index 16af74b9b7..d2bb5bffd0 100644 --- a/ghost/admin/app/styles/spirit/_line-height.css +++ b/ghost/admin/app/styles/spirit/_line-height.css @@ -8,6 +8,7 @@ */ :root { + --lh-1-0: 1.0em; --lh-1-1: 1.1em; --lh-1-3: 1.333em; --lh-1-4: 1.4em; @@ -15,6 +16,7 @@ --lh-2-0: 2.0em; } +.lh-1 { line-height: var(--lh-1-0); } .lh-solid { line-height: var(--lh-1-1); } .lh-heading { line-height: var(--lh-1-3); } .lh-title { line-height: var(--lh-1-4); } @@ -24,6 +26,7 @@ .lh-zero { line-height: 0; } @media (--breakpoint-not-small) { + .lh-1-ns { line-height: var(--lh-1-0); } .lh-solid-ns { line-height: var(--lh-1-1); } .lh-heading-ns { line-height: var(--lh-1-3); } .lh-title-ns { line-height: var(--lh-1-4); } @@ -34,6 +37,7 @@ } @media (--breakpoint-medium) { + .lh-1-m { line-height: var(--lh-1-0); } .lh-solid-m { line-height: var(--lh-1-1); } .lh-heading-m { line-height: var(--lh-1-3); } .lh-title-m { line-height: var(--lh-1-4); } @@ -44,6 +48,7 @@ } @media (--breakpoint-large) { + .lh-1-l { line-height: var(--lh-1-0); } .lh-solid-l { line-height: var(--lh-1-1); } .lh-heading-l { line-height: var(--lh-1-3); } .lh-title-l { line-height: var(--lh-1-4); } diff --git a/ghost/admin/public/assets/icons/close-stroke.svg b/ghost/admin/public/assets/icons/close-stroke.svg new file mode 100644 index 0000000000..63b8d5d6f8 --- /dev/null +++ b/ghost/admin/public/assets/icons/close-stroke.svg @@ -0,0 +1 @@ +close \ No newline at end of file