diff --git a/app/controllers/settings/integration.js b/app/controllers/settings/integration.js index acb930fcec..72a4b0d362 100644 --- a/app/controllers/settings/integration.js +++ b/app/controllers/settings/integration.js @@ -1,4 +1,5 @@ import Controller from '@ember/controller'; +import copyTextToClipboard from 'ghost-admin/utils/copy-text-to-clipboard'; import { IMAGE_EXTENSIONS, IMAGE_MIME_TYPES @@ -136,29 +137,17 @@ export default Controller.extend({ }), copyContentKey: task(function* () { - this._copyTextToClipboard(this.integration.contentKey.secret); + copyTextToClipboard(this.integration.contentKey.secret); yield timeout(3000); }), copyAdminKey: task(function* () { - this._copyTextToClipboard(this.integration.adminKey.secret); + copyTextToClipboard(this.integration.adminKey.secret); yield timeout(3000); }), copyApiUrl: task(function* () { - this._copyTextToClipboard(this.apiUrl); + copyTextToClipboard(this.apiUrl); yield timeout(3000); - }), - - _copyTextToClipboard(text) { - let textarea = document.createElement('textarea'); - textarea.value = text; - textarea.setAttribute('readonly', ''); - textarea.style.position = 'absolute'; - textarea.style.left = '-9999px'; - document.body.appendChild(textarea); - textarea.select(); - document.execCommand('copy'); - document.body.removeChild(textarea); - } + }) }); diff --git a/app/controllers/settings/integrations.js b/app/controllers/settings/integrations.js index dd10985501..9425ec3df9 100644 --- a/app/controllers/settings/integrations.js +++ b/app/controllers/settings/integrations.js @@ -28,5 +28,25 @@ export default Controller.extend({ // screen display fetchIntegrations: task(function* () { return yield this.store.findAll('integration'); - }) + }), + + // used by individual integration routes' `model` hooks + integrationModelHook(prop, value, route, transition) { + let integration = this.store.peekAll('integration').findBy(prop, value); + + if (integration) { + return integration; + } + + return this.fetchIntegrations.perform().then((integrations) => { + let integration = integrations.findBy(prop, value); + + if (!integration) { + let path = transition.intent.url.replace(/^\//, ''); + return route.replaceWith('error404', {path, status: 404}); + } + + return integration; + }); + } }); diff --git a/app/controllers/settings/integrations/zapier.js b/app/controllers/settings/integrations/zapier.js index e48d2e3c08..8eb77c068b 100644 --- a/app/controllers/settings/integrations/zapier.js +++ b/app/controllers/settings/integrations/zapier.js @@ -1,8 +1,16 @@ /* eslint-disable ghost/ember/alias-model-in-controller */ import Controller from '@ember/controller'; import config from 'ghost-admin/config/environment'; +import copyTextToClipboard from 'ghost-admin/utils/copy-text-to-clipboard'; +import {alias} from '@ember/object/computed'; +import {computed} from '@ember/object'; +import {inject as service} from '@ember/service'; +import {task, timeout} from 'ember-concurrency'; export default Controller.extend({ + config: service(), + ghostPaths: service(), + isTesting: undefined, init() { @@ -10,5 +18,25 @@ export default Controller.extend({ if (this.isTesting === undefined) { this.isTesting = config.environment === 'test'; } - } + }, + + integration: alias('model'), + + apiUrl: computed(function () { + let origin = window.location.origin; + let subdir = this.ghostPaths.subdir; + let url = this.ghostPaths.url.join(origin, subdir); + + return url.replace(/\/$/, ''); + }), + + copyAdminKey: task(function* () { + copyTextToClipboard(this.integration.adminKey.secret); + yield timeout(3000); + }), + + copyApiUrl: task(function* () { + copyTextToClipboard(this.apiUrl); + yield timeout(3000); + }) }); diff --git a/app/routes/settings/integration.js b/app/routes/settings/integration.js index 3b61f157e0..e77dcdf2e7 100644 --- a/app/routes/settings/integration.js +++ b/app/routes/settings/integration.js @@ -14,28 +14,12 @@ export default AuthenticatedRoute.extend(styleBody, CurrentUserSettings, { }, model(params, transition) { - let integration = this.store.peekRecord('integration', params.integration_id); - - if (integration) { - return integration; - } - - // integration is not already in the store so use the integrations controller - // to fetch all of them and pull out the one we're interested in. Using the - // integrations controller means it's possible to navigate back to the integrations - // screen without triggering a loading state - return this.controllerFor('settings.integrations') - .fetchIntegrations.perform() - .then((integrations) => { - let integration = integrations.findBy('id', params.integration_id); - - if (!integration) { - let path = transition.intent.url.replace(/^\//, ''); - return this.replaceWith('error404', {path, status: 404}); - } - - return integration; - }); + // use the integrations controller to fetch all integrations and pick + // out the one we want. Allows navigation back to integrations screen + // without a loading state + return this + .controllerFor('settings.integrations') + .integrationModelHook('id', params.integration_id, this, transition); }, actions: { diff --git a/app/routes/settings/integrations/zapier.js b/app/routes/settings/integrations/zapier.js index cb7790eaa2..7e5e428cd9 100644 --- a/app/routes/settings/integrations/zapier.js +++ b/app/routes/settings/integrations/zapier.js @@ -2,10 +2,21 @@ import AuthenticatedRoute from 'ghost-admin/routes/authenticated'; import CurrentUserSettings from '../../../mixins/current-user-settings'; export default AuthenticatedRoute.extend(CurrentUserSettings, { + titleToken: 'Zapier', + beforeModel() { this._super(...arguments); return this.get('session.user') .then(this.transitionAuthor()) .then(this.transitionEditor()); + }, + + model(params, transition) { + // use the integrations controller to fetch all integrations and pick + // out the one we want. Allows navigation back to integrations screen + // without a loading state + return this + .controllerFor('settings.integrations') + .integrationModelHook('slug', 'zapier', this, transition); } }); diff --git a/app/templates/settings/integrations/zapier.hbs b/app/templates/settings/integrations/zapier.hbs index d3b7786044..561d785781 100644 --- a/app/templates/settings/integrations/zapier.hbs +++ b/app/templates/settings/integrations/zapier.hbs @@ -19,6 +19,57 @@ + {{#if config.enableDeveloperExperiments}} +
+ + + + + + + + + + + +
Admin API Key +
+ + {{this.integration.adminKey.secret}} + +
+
+ +
+
+
+
API URL +
+ + {{this.apiUrl}} + +
+
+ +
+
+
+
+
+ {{/if}} +
Zapier configuration
diff --git a/app/utils/copy-text-to-clipboard.js b/app/utils/copy-text-to-clipboard.js new file mode 100644 index 0000000000..386ab42d3c --- /dev/null +++ b/app/utils/copy-text-to-clipboard.js @@ -0,0 +1,11 @@ +export default function copyTextToClipboard(text) { + let textarea = document.createElement('textarea'); + textarea.value = text; + textarea.setAttribute('readonly', ''); + textarea.style.position = 'absolute'; + textarea.style.left = '-9999px'; + document.body.appendChild(textarea); + textarea.select(); + document.execCommand('copy'); + document.body.removeChild(textarea); +}