Skip to content
This repository has been archived by the owner on Nov 28, 2022. It is now read-only.

Commit

Permalink
Added integration details to Zapier integration screen behind dev flag
Browse files Browse the repository at this point in the history
no issue
- the new version of our Zapier App uses API Key auth so we need to expose the details on the Zapier integration screen
- extracted `copyTextToClipboard` into a util function
- added `integrationModelHook` method to `settings.integrations` controller to remove duplication in the `settings.integration` and `settings.integration.zapier` routes
- fixed missing "Zapier" title token
  • Loading branch information
kevinansfield committed Apr 4, 2019
1 parent a5bfd36 commit c1c49fd
Show file tree
Hide file tree
Showing 7 changed files with 134 additions and 40 deletions.
21 changes: 5 additions & 16 deletions app/controllers/settings/integration.js
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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);
}
})
});
22 changes: 21 additions & 1 deletion app/controllers/settings/integrations.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
});
}
});
30 changes: 29 additions & 1 deletion app/controllers/settings/integrations/zapier.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,42 @@
/* 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() {
this._super(...arguments);
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);
})
});
28 changes: 6 additions & 22 deletions app/routes/settings/integration.js
Original file line number Diff line number Diff line change
Expand Up @@ -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: {
Expand Down
11 changes: 11 additions & 0 deletions app/routes/settings/integrations/zapier.js
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
});
51 changes: 51 additions & 0 deletions app/templates/settings/integrations/zapier.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,57 @@
</div>
</section>

{{#if config.enableDeveloperExperiments}}
<div class="m15 ba br3 b--lightgrey mt4">
<table class="ma0" style="table-layout: fixed">
<tbody>
<tr class="bb b--lightgrey">
<td class="pa3 w50 fw7">Admin API Key</td>
<td class="pa0">
<div class="pa3 relative truncate {{unless copyAdminKey.isRunning "hide-child-instant"}}">
<span class="midgrey" data-test-text="admin-key">
{{this.integration.adminKey.secret}}
</span>
<div class="absolute top-1 right-2">
<div class="pt1 pr3 pb1 pl3 bg-black-70 child br3 f8 nudge-top--4 nudge-right--1">
<button type="button" {{action (perform copyAdminKey)}} class="white fw4 flex items-center">
{{#if copyAdminKey.isRunning}}
{{svg-jar "check-circle" class="w3 v-mid mr2"}} Copied
{{else}}
Copy
{{/if}}
</button>
</div>
</div>
</div>
</td>
</tr>
<tr>
<td class="pa3 w50 fw7">API URL</td>
<td class="pa0 truncate">
<div class="pa3 relative truncate {{unless copyApiUrl.isRunning "hide-child-instant"}}">
<span class="midgrey" data-test-text="api-url">
{{this.apiUrl}}
</span>
<div class="absolute top-1 right-2">
<div class="pt1 pr3 pb1 pl3 bg-black-70 child br3 f8 nudge-top--4 nudge-right--1">
<button type="button" {{action (perform copyApiUrl)}} class="white fw4 flex items-center">
{{#if copyApiUrl.isRunning}}
{{svg-jar "check-circle" class="w3 v-mid mr2"}} Copied
{{else}}
Copy
{{/if}}
</button>
</div>
</div>
</div>
</td>
</tr>
</tbody>
</table>
</div>
{{/if}}

<div class="gh-setting-header">Zapier configuration</div>
<div class="gh-setting" id="zapier-toggle">
<div class="gh-setting-content gh-setting-content--no-action">
Expand Down
11 changes: 11 additions & 0 deletions app/utils/copy-text-to-clipboard.js
Original file line number Diff line number Diff line change
@@ -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);
}

0 comments on commit c1c49fd

Please sign in to comment.