mirror of
https://github.com/TryGhost/Ghost.git
synced 2024-12-25 20:03:12 +03:00
Completed Octane migration of integration controller
refs https://github.com/TryGhost/Ghost/issues/14101 Applied scout rule to fix linter errors when touching a file. - added local `updateProperty` and `validateProperty` methods to remove use of `target=` - our validation implementation does not properly bind `this` so direct usage of `this.integration.validate` fails - added `on-input` argument support to our `TextInput` mixin so we we're not overwriting the native event handlers on classic input components
This commit is contained in:
parent
d1e7ccbe00
commit
f44c54862b
@ -1839,3 +1839,26 @@ add|ember-template-lint|no-nested-landmark|131|24|131|24|9eb7d301f1f50334e793aaf
|
||||
remove|ember-template-lint|table-groups|5|8|5|8|9b53737f259340d2970119c70be1af3a83081cab|1643760000000|1646352000000|1648940400000|app/components/gh-portal-links.hbs
|
||||
remove|ember-template-lint|no-action|11|72|11|72|a8b13fedc345ad6ca2c1514b209e84a19d82915d|1643760000000|1646352000000|1648940400000|app/components/gh-portal-links.hbs
|
||||
remove|ember-template-lint|no-invalid-interactive|11|64|11|64|5b5bb32075e5f0470fbe12d099229964f1dc7dfe|1643760000000|1646352000000|1648940400000|app/components/gh-portal-links.hbs
|
||||
remove|ember-template-lint|no-action|32|48|32|48|993079a3ad8b556330d2aa5a0cb01dcb63a4bdb0|1643760000000|1646352000000|1648940400000|app/templates/settings/integration.hbs
|
||||
remove|ember-template-lint|no-action|43|44|43|44|166ab6daac6556b497c8693a94715fca7c8158f9|1643760000000|1646352000000|1648940400000|app/templates/settings/integration.hbs
|
||||
remove|ember-template-lint|no-action|71|43|71|43|8234e3f75b9c72cbd8e726b3d26f03d0a2a26dfb|1643760000000|1646352000000|1648940400000|app/templates/settings/integration.hbs
|
||||
remove|ember-template-lint|no-action|72|47|72|47|829a527ba5a2ff30234ea240400d9935421c5556|1643760000000|1646352000000|1648940400000|app/templates/settings/integration.hbs
|
||||
remove|ember-template-lint|no-action|90|43|90|43|ffe817ddea62969f8b2d45127828416d6adfc773|1643760000000|1646352000000|1648940400000|app/templates/settings/integration.hbs
|
||||
remove|ember-template-lint|no-action|91|47|91|47|bb670279bd6dc2dfca1b714200cc42b1b4b38d69|1643760000000|1646352000000|1648940400000|app/templates/settings/integration.hbs
|
||||
remove|ember-template-lint|no-action|107|74|107|74|159455060ac247ee60be18b8ebb8f7907f652132|1643760000000|1646352000000|1648940400000|app/templates/settings/integration.hbs
|
||||
remove|ember-template-lint|no-action|110|74|110|74|38bfdf3e4ec8c79d195e80a48c2f343757845cab|1643760000000|1646352000000|1648940400000|app/templates/settings/integration.hbs
|
||||
remove|ember-template-lint|no-action|132|74|132|74|2e441eb8956fdd6684b75ae1139f097237ebc1fa|1643760000000|1646352000000|1648940400000|app/templates/settings/integration.hbs
|
||||
remove|ember-template-lint|no-action|135|74|135|74|2d51bed033fe50baea3002bf5acc234ac3738b58|1643760000000|1646352000000|1648940400000|app/templates/settings/integration.hbs
|
||||
remove|ember-template-lint|no-action|157|74|157|74|bfcab210b651dbe74a1b9e5eb565756ab863f3bb|1643760000000|1646352000000|1648940400000|app/templates/settings/integration.hbs
|
||||
remove|ember-template-lint|no-passed-in-event-handlers|71|36|71|36|094eea0b41531dd31234f4a47d22faa0ad3cbaa7|1643760000000|1646352000000|1648940400000|app/templates/settings/integration.hbs
|
||||
remove|ember-template-lint|no-passed-in-event-handlers|90|36|90|36|ecfb8bbcc595aaaf0c1a929efa948e75787a5e18|1643760000000|1646352000000|1648940400000|app/templates/settings/integration.hbs
|
||||
remove|ember-template-lint|no-action|202|92|202|92|bb9a5097405a3fcaad689d0d592294e1741edd7b|1643760000000|1646352000000|1648940400000|app/templates/settings/integration.hbs
|
||||
remove|ember-template-lint|no-action|246|72|246|72|541a413eb944fa0091ea28f7256a20e2a724a3a9|1643760000000|1646352000000|1648940400000|app/templates/settings/integration.hbs
|
||||
remove|ember-template-lint|no-action|255|17|255|17|9fa650a0ca3325ef8182634ad5d34c5db548287a|1643760000000|1646352000000|1648940400000|app/templates/settings/integration.hbs
|
||||
remove|ember-template-lint|no-action|256|15|256|15|2fe6989da74d54cbdbaef0ae0a7cc68f22825a1d|1643760000000|1646352000000|1648940400000|app/templates/settings/integration.hbs
|
||||
remove|ember-template-lint|no-action|266|17|266|17|1907c9b1ae81cfb450b7a2ae7e0f874c26595144|1643760000000|1646352000000|1648940400000|app/templates/settings/integration.hbs
|
||||
remove|ember-template-lint|no-action|267|15|267|15|20eb710122c95e74c9293fe14e11f105a86f172a|1643760000000|1646352000000|1648940400000|app/templates/settings/integration.hbs
|
||||
remove|ember-template-lint|no-action|273|17|273|17|17ede810216f1750e8f5a0447f0d8ca9dd51eefd|1643760000000|1646352000000|1648940400000|app/templates/settings/integration.hbs
|
||||
remove|ember-template-lint|no-action|274|15|274|15|97a8488c705fd167d8803635395470e929e57425|1643760000000|1646352000000|1648940400000|app/templates/settings/integration.hbs
|
||||
remove|ember-template-lint|no-action|280|17|280|17|989fbbea271b49165ed76435745c43151cfc7ef7|1643760000000|1646352000000|1648940400000|app/templates/settings/integration.hbs
|
||||
remove|ember-template-lint|no-action|281|15|281|15|6466c92ea49ac23d994c08c504e6d4ffefcadbff|1643760000000|1646352000000|1648940400000|app/templates/settings/integration.hbs
|
||||
|
@ -1,39 +1,41 @@
|
||||
import Controller from '@ember/controller';
|
||||
import classic from 'ember-classic-decorator';
|
||||
import config from 'ghost-admin/config/environment';
|
||||
import copyTextToClipboard from 'ghost-admin/utils/copy-text-to-clipboard';
|
||||
import {
|
||||
IMAGE_EXTENSIONS,
|
||||
IMAGE_MIME_TYPES
|
||||
} from 'ghost-admin/components/gh-image-uploader';
|
||||
import {action, computed} from '@ember/object';
|
||||
import {alias} from '@ember/object/computed';
|
||||
import {action} from '@ember/object';
|
||||
import {htmlSafe} from '@ember/template';
|
||||
import {inject as service} from '@ember/service';
|
||||
import {task, timeout} from 'ember-concurrency';
|
||||
import {tracked} from '@glimmer/tracking';
|
||||
|
||||
@classic
|
||||
export default class IntegrationController extends Controller {
|
||||
@service config;
|
||||
@service ghostPaths;
|
||||
|
||||
imageExtensions = IMAGE_EXTENSIONS;
|
||||
imageMimeTypes = IMAGE_MIME_TYPES;
|
||||
showRegenerateKeyModal = false;
|
||||
selectedApiKey = null;
|
||||
isApiKeyRegenerated = false;
|
||||
|
||||
init() {
|
||||
super.init(...arguments);
|
||||
@tracked showDeleteIntegrationModal = false;
|
||||
@tracked showRegenerateKeyModal = false;
|
||||
@tracked showUnsavedChangesModal = false;
|
||||
@tracked selectedApiKey = null;
|
||||
@tracked isApiKeyRegenerated = false;
|
||||
@tracked webhookToDelete;
|
||||
|
||||
constructor() {
|
||||
super(...arguments);
|
||||
if (this.isTesting === undefined) {
|
||||
this.isTesting = config.environment === 'test';
|
||||
}
|
||||
}
|
||||
|
||||
@alias('model')
|
||||
integration;
|
||||
get integration() {
|
||||
return this.model;
|
||||
}
|
||||
|
||||
@computed
|
||||
get apiUrl() {
|
||||
let origin = window.location.origin;
|
||||
let subdir = this.ghostPaths.subdir;
|
||||
@ -42,20 +44,17 @@ export default class IntegrationController extends Controller {
|
||||
return url.replace(/\/$/, '');
|
||||
}
|
||||
|
||||
@computed('isApiKeyRegenerated', 'selectedApiKey')
|
||||
get regeneratedKeyType() {
|
||||
if (this.isApiKeyRegenerated) {
|
||||
return this.get('selectedApiKey.type');
|
||||
return this.selectedApiKey.type;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@computed
|
||||
get allWebhooks() {
|
||||
return this.store.peekAll('webhook');
|
||||
}
|
||||
|
||||
@computed('integration.id', 'allWebhooks.@each.{isNew,isDeleted}')
|
||||
get filteredWebhooks() {
|
||||
return this.allWebhooks.filter((webhook) => {
|
||||
let matchesIntegration = webhook.belongsTo('integration').id() === this.integration.id;
|
||||
@ -66,7 +65,6 @@ export default class IntegrationController extends Controller {
|
||||
});
|
||||
}
|
||||
|
||||
@computed('integration.iconImage')
|
||||
get iconImageStyle() {
|
||||
let url = this.integration.iconImage;
|
||||
if (url) {
|
||||
@ -83,11 +81,22 @@ export default class IntegrationController extends Controller {
|
||||
}
|
||||
|
||||
@action
|
||||
triggerIconFileDialog() {
|
||||
triggerIconFileDialog(event) {
|
||||
event.preventDefault();
|
||||
let input = document.querySelector('input[type="file"][name="iconImage"]');
|
||||
input.click();
|
||||
}
|
||||
|
||||
@action
|
||||
updateProperty(property, event) {
|
||||
this.integration.set(property, event.target.value);
|
||||
}
|
||||
|
||||
@action
|
||||
validateProperty(property) {
|
||||
this.integration.validate({property});
|
||||
}
|
||||
|
||||
@action
|
||||
setIconImage([image]) {
|
||||
this.integration.set('iconImage', image.url);
|
||||
@ -103,13 +112,13 @@ export default class IntegrationController extends Controller {
|
||||
let leaveTransition = this.leaveScreenTransition;
|
||||
|
||||
if (!transition && this.showUnsavedChangesModal) {
|
||||
this.set('leaveScreenTransition', null);
|
||||
this.set('showUnsavedChangesModal', false);
|
||||
this.leaveScreenTransition = null;
|
||||
this.showUnsavedChangesModal = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!leaveTransition || transition.targetName === leaveTransition.targetName) {
|
||||
this.set('leaveScreenTransition', transition);
|
||||
this.leaveScreenTransition = transition;
|
||||
|
||||
// if a save is running, wait for it to finish then transition
|
||||
if (this.saveTask.isRunning) {
|
||||
@ -119,12 +128,13 @@ export default class IntegrationController extends Controller {
|
||||
}
|
||||
|
||||
// we genuinely have unsaved data, show the modal
|
||||
this.set('showUnsavedChangesModal', true);
|
||||
this.showUnsavedChangesModal = true;
|
||||
}
|
||||
}
|
||||
|
||||
@action
|
||||
leaveScreen() {
|
||||
leaveScreen(event) {
|
||||
event?.preventDefault();
|
||||
let transition = this.leaveScreenTransition;
|
||||
|
||||
if (!transition) {
|
||||
@ -139,53 +149,63 @@ export default class IntegrationController extends Controller {
|
||||
}
|
||||
|
||||
@action
|
||||
deleteIntegration() {
|
||||
deleteIntegration(event) {
|
||||
event?.preventDefault();
|
||||
this.integration.destroyRecord();
|
||||
}
|
||||
|
||||
@action
|
||||
confirmIntegrationDeletion() {
|
||||
this.set('showDeleteIntegrationModal', true);
|
||||
confirmIntegrationDeletion(event) {
|
||||
event?.preventDefault();
|
||||
this.showDeleteIntegrationModal = true;
|
||||
}
|
||||
|
||||
@action
|
||||
cancelIntegrationDeletion() {
|
||||
this.set('showDeleteIntegrationModal', false);
|
||||
cancelIntegrationDeletion(event) {
|
||||
event?.preventDefault();
|
||||
this.showDeleteIntegrationModal = false;
|
||||
}
|
||||
|
||||
@action
|
||||
confirmRegenerateKeyModal(apiKey) {
|
||||
this.set('showRegenerateKeyModal', true);
|
||||
this.set('isApiKeyRegenerated', false);
|
||||
this.set('selectedApiKey', apiKey);
|
||||
confirmRegenerateKeyModal(apiKey, event) {
|
||||
event?.preventDefault();
|
||||
this.showRegenerateKeyModal = true;
|
||||
this.isApiKeyRegenerated = false;
|
||||
this.selectedApiKey = apiKey;
|
||||
}
|
||||
|
||||
@action
|
||||
cancelRegenerateKeyModal() {
|
||||
this.set('showRegenerateKeyModal', false);
|
||||
cancelRegenerateKeyModal(event) {
|
||||
event?.preventDefault();
|
||||
this.showRegenerateKeyModal = false;
|
||||
}
|
||||
|
||||
@action
|
||||
regenerateKey() {
|
||||
this.set('isApiKeyRegenerated', true);
|
||||
regenerateKey(event) {
|
||||
event?.preventDefault();
|
||||
this.isApiKeyRegenerated = true;
|
||||
}
|
||||
|
||||
@action
|
||||
confirmWebhookDeletion(webhook) {
|
||||
this.set('webhookToDelete', webhook);
|
||||
confirmWebhookDeletion(webhook, event) {
|
||||
event?.preventDefault();
|
||||
this.webhookToDelete = webhook;
|
||||
}
|
||||
|
||||
@action
|
||||
cancelWebhookDeletion() {
|
||||
this.set('webhookToDelete', null);
|
||||
cancelWebhookDeletion(event) {
|
||||
event?.preventDefault();
|
||||
this.webhookToDelete = null;
|
||||
}
|
||||
|
||||
@action
|
||||
deleteWebhook() {
|
||||
deleteWebhook(event) {
|
||||
event?.preventDefault();
|
||||
return this.webhookToDelete.destroyRecord();
|
||||
}
|
||||
|
||||
@task(function* () {
|
||||
@task
|
||||
*saveTask() {
|
||||
try {
|
||||
return yield this.integration.save();
|
||||
} catch (e) {
|
||||
@ -196,24 +216,23 @@ export default class IntegrationController extends Controller {
|
||||
|
||||
throw e;
|
||||
}
|
||||
})
|
||||
saveTask;
|
||||
}
|
||||
|
||||
@task(function* () {
|
||||
@task
|
||||
*copyContentKey() {
|
||||
copyTextToClipboard(this.integration.contentKey.secret);
|
||||
yield timeout(this.isTesting ? 50 : 3000);
|
||||
})
|
||||
copyContentKey;
|
||||
}
|
||||
|
||||
@task(function* () {
|
||||
@task
|
||||
*copyAdminKey() {
|
||||
copyTextToClipboard(this.integration.adminKey.secret);
|
||||
yield timeout(this.isTesting ? 50 : 3000);
|
||||
})
|
||||
copyAdminKey;
|
||||
}
|
||||
|
||||
@task(function* () {
|
||||
@task
|
||||
*copyApiUrl() {
|
||||
copyTextToClipboard(this.apiUrl);
|
||||
yield timeout(this.isTesting ? 50 : 3000);
|
||||
})
|
||||
copyApiUrl;
|
||||
}
|
||||
}
|
||||
|
@ -35,6 +35,10 @@ export default Mixin.create({
|
||||
}
|
||||
},
|
||||
|
||||
input(event) {
|
||||
this['on-input']?.(event);
|
||||
},
|
||||
|
||||
keyDown(event) {
|
||||
// stop event propagation when pressing "enter"
|
||||
// most useful in the case when undesired (global) keyboard shortcuts
|
||||
|
@ -29,7 +29,7 @@
|
||||
|
||||
<GhUploader
|
||||
@extensions={{this.imageExtensions}}
|
||||
@onComplete={{action "setIconImage"}}
|
||||
@onComplete={{this.setIconImage}}
|
||||
as |uploader|
|
||||
>
|
||||
{{#if uploader.isUploading}}
|
||||
@ -40,7 +40,7 @@
|
||||
<button
|
||||
type="button"
|
||||
class="child app-custom-icon-uploadlabel"
|
||||
{{action "triggerIconFileDialog"}}
|
||||
{{on "click" this.triggerIconFileDialog}}
|
||||
>
|
||||
Upload
|
||||
</button>
|
||||
@ -68,8 +68,8 @@
|
||||
@class="gh-input mt1 mb1"
|
||||
@type="text"
|
||||
@value={{readonly this.integration.name}}
|
||||
@input={{action (mut this.integration.name) value="target.value"}}
|
||||
@focus-out={{action "validate" "name" target=this.integration}}
|
||||
@on-input={{fn this.updateProperty "name"}}
|
||||
@focus-out={{fn this.validateProperty "name"}}
|
||||
data-test-input="name"
|
||||
/>
|
||||
<GhErrorMessage @errors={{this.integration.errors}} @property="name" data-test-error="name" class="ma0" />
|
||||
@ -87,8 +87,8 @@
|
||||
@class="gh-input mt1"
|
||||
@type="text"
|
||||
@value={{readonly this.integration.description}}
|
||||
@input={{action (mut this.integration.description) value="target.value"}}
|
||||
@focus-out={{action "validate" "description" target=this.integration}}
|
||||
@on-input={{fn this.updateProperty "description"}}
|
||||
@focus-out={{fn this.validateProperty "description"}}
|
||||
data-test-input="description"
|
||||
/>
|
||||
<GhErrorMessage @errors={{this.integration.errors}} @property="description" data-test-error="description" class="ma0" />
|
||||
@ -104,10 +104,10 @@
|
||||
{{this.integration.contentKey.secret}}
|
||||
</span>
|
||||
<div class="app-api-buttons child">
|
||||
<button type="button" {{action "confirmRegenerateKeyModal" this.integration.contentKey}} class="app-button-regenerate" data-tooltip="Regenerate">
|
||||
<button type="button" {{on "click" (fn this.confirmRegenerateKeyModal this.integration.contentKey)}} class="app-button-regenerate" data-tooltip="Regenerate">
|
||||
{{svg-jar "reload" class="w4 h4 stroke-midgrey"}}
|
||||
</button>
|
||||
<button type="button" {{action (perform this.copyContentKey)}} class="app-button-copy">
|
||||
<button type="button" {{on "click" (perform this.copyContentKey)}} class="app-button-copy">
|
||||
{{#if this.copyContentKey.isRunning}}
|
||||
{{svg-jar "check-circle" class="w3 v-mid mr2 stroke-white"}} Copied
|
||||
{{else}}
|
||||
@ -129,10 +129,10 @@
|
||||
{{this.integration.adminKey.secret}}
|
||||
</span>
|
||||
<div class="app-api-buttons child">
|
||||
<button type="button" {{action "confirmRegenerateKeyModal" this.integration.adminKey}} class="app-button-regenerate" data-tooltip="Regenerate">
|
||||
<button type="button" {{on "click" (fn this.confirmRegenerateKeyModal this.integration.adminKey)}} class="app-button-regenerate" data-tooltip="Regenerate">
|
||||
{{svg-jar "reload" class="w4 h4 stroke-midgrey"}}
|
||||
</button>
|
||||
<button type="button" {{action (perform this.copyAdminKey)}} class="app-button-copy">
|
||||
<button type="button" {{on "click" (perform this.copyAdminKey)}} class="app-button-copy">
|
||||
{{#if this.copyAdminKey.isRunning}}
|
||||
{{svg-jar "check-circle" class="w3 v-mid mr2 stroke-white"}} Copied
|
||||
{{else}}
|
||||
@ -154,7 +154,7 @@
|
||||
{{this.apiUrl}}
|
||||
</span>
|
||||
<div class="app-api-buttons child">
|
||||
<button type="button" {{action (perform this.copyApiUrl)}} class="app-button-copy">
|
||||
<button type="button" {{on "click" (perform this.copyApiUrl)}} class="app-button-copy">
|
||||
{{#if this.copyApiUrl.isRunning}}
|
||||
{{svg-jar "check-circle" class="w3 v-mid mr2 stroke-white"}} Copied
|
||||
{{else}}
|
||||
@ -199,7 +199,7 @@
|
||||
<LinkTo @route="settings.integration.webhooks.edit" @models={{array this.integration webhook}} data-test-link="edit-webhook">
|
||||
{{svg-jar "pen" class="w6 h6 fill-midgrey pa1 mr1"}}
|
||||
</LinkTo>
|
||||
<button data-test-button="delete-webhook" type="button" {{action "confirmWebhookDeletion" webhook}}>
|
||||
<button data-test-button="delete-webhook" type="button" {{on "click" (fn this.confirmWebhookDeletion webhook)}}>
|
||||
{{svg-jar "trash" class="w6 fill-red pa1"}}
|
||||
</button>
|
||||
</div>
|
||||
@ -243,7 +243,7 @@
|
||||
|
||||
<section class="gh-main-section">
|
||||
<div class="gh-main-section-block">
|
||||
<button class="gh-btn gh-btn-red gh-btn-icon" type="button" {{action "confirmIntegrationDeletion"}}>
|
||||
<button class="gh-btn gh-btn-red gh-btn-icon" type="button" {{on "click" this.confirmIntegrationDeletion}}>
|
||||
<span> Delete integration </span>
|
||||
</button>
|
||||
</div>
|
||||
@ -252,8 +252,8 @@
|
||||
|
||||
{{#if this.showUnsavedChangesModal}}
|
||||
<GhFullscreenModal @modal="leave-settings"
|
||||
@confirm={{action "leaveScreen"}}
|
||||
@close={{action "toggleUnsavedChangesModal"}}
|
||||
@confirm={{this.leaveScreen}}
|
||||
@close={{this.toggleUnsavedChangesModal}}
|
||||
@modifier="action wide" />
|
||||
{{/if}}
|
||||
|
||||
@ -263,22 +263,22 @@
|
||||
apiKey=this.selectedApiKey
|
||||
integration=this.integration
|
||||
}}
|
||||
@confirm={{action "regenerateKey"}}
|
||||
@close={{action "cancelRegenerateKeyModal"}}
|
||||
@confirm={{this.regenerateKey}}
|
||||
@close={{this.cancelRegenerateKeyModal}}
|
||||
@modifier="action wide" />
|
||||
{{/if}}
|
||||
|
||||
{{#if this.showDeleteIntegrationModal}}
|
||||
<GhFullscreenModal @modal="delete-integration"
|
||||
@confirm={{action "deleteIntegration"}}
|
||||
@close={{action "cancelIntegrationDeletion"}}
|
||||
@confirm={{this.deleteIntegration}}
|
||||
@close={{this.cancelIntegrationDeletion}}
|
||||
@modifier="action wide" />
|
||||
{{/if}}
|
||||
|
||||
{{#if this.webhookToDelete}}
|
||||
<GhFullscreenModal @modal="delete-webhook"
|
||||
@confirm={{action "deleteWebhook"}}
|
||||
@close={{action "cancelWebhookDeletion"}}
|
||||
@confirm={{this.deleteWebhook}}
|
||||
@close={{this.cancelWebhookDeletion}}
|
||||
@modifier="action wide" />
|
||||
{{/if}}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user