mirror of
https://github.com/TryGhost/Ghost.git
synced 2025-02-24 23:48:13 -05:00
Added edit webhook modal (#1056)
requires https://github.com/TryGhost/Ghost/pull/10033 - added `settings.integration.webhooks.edit` route - `/integrations/:integration_id/webhooks/:webhook_id` - added error handling to the webhook form modal that copes with the actual errors we get back from the server - added `event-name` helper to display humanised event names in the webhooks list - added delete button to the webhooks list and associated confirmation modal
This commit is contained in:
parent
832968d4a5
commit
296e35493d
11 changed files with 139 additions and 9 deletions
26
ghost/admin/app/components/modal-delete-webhook.js
Normal file
26
ghost/admin/app/components/modal-delete-webhook.js
Normal file
|
@ -0,0 +1,26 @@
|
|||
import ModalComponent from 'ghost-admin/components/modal-base';
|
||||
import {alias} from '@ember/object/computed';
|
||||
import {inject as service} from '@ember/service';
|
||||
import {task} from 'ember-concurrency';
|
||||
|
||||
export default ModalComponent.extend({
|
||||
notifications: service(),
|
||||
|
||||
webhook: alias('model'),
|
||||
|
||||
actions: {
|
||||
confirm() {
|
||||
this.deleteWebhook.perform();
|
||||
}
|
||||
},
|
||||
|
||||
deleteWebhook: task(function* () {
|
||||
try {
|
||||
yield this.confirm();
|
||||
} catch (error) {
|
||||
this.notifications.showAPIError(error, {key: 'webhook.delete.failed'});
|
||||
} finally {
|
||||
this.send('closeModal');
|
||||
}
|
||||
}).drop()
|
||||
});
|
|
@ -1,5 +1,6 @@
|
|||
import ModalComponent from 'ghost-admin/components/modal-base';
|
||||
import Webhook from 'ghost-admin/models/webhook';
|
||||
import {AVAILABLE_EVENTS} from 'ghost-admin/helpers/event-name';
|
||||
import {alias} from '@ember/object/computed';
|
||||
import {camelize} from '@ember/string';
|
||||
import {isInvalidError} from 'ember-ajax/errors';
|
||||
|
@ -10,6 +11,7 @@ export default ModalComponent.extend({
|
|||
router: service(),
|
||||
|
||||
availableEvents: null,
|
||||
error: null,
|
||||
buttonText: 'Save',
|
||||
successText: 'Saved',
|
||||
|
||||
|
@ -19,11 +21,7 @@ export default ModalComponent.extend({
|
|||
|
||||
init() {
|
||||
this._super(...arguments);
|
||||
this.availableEvents = [
|
||||
{event: 'site.changed', name: 'Site Changed (rebuild)'},
|
||||
{event: 'subscriber.added', name: 'Subscriber Added'},
|
||||
{event: 'subscriber.deleted', name: 'Subscriber Deleted'}
|
||||
];
|
||||
this.availableEvents = AVAILABLE_EVENTS;
|
||||
},
|
||||
|
||||
didReceiveAttrs() {
|
||||
|
@ -45,6 +43,8 @@ export default ModalComponent.extend({
|
|||
},
|
||||
|
||||
saveWebhook: task(function* () {
|
||||
this.set('error', null);
|
||||
|
||||
try {
|
||||
let webhook = yield this.confirm();
|
||||
let integration = yield webhook.get('integration');
|
||||
|
@ -62,6 +62,8 @@ export default ModalComponent.extend({
|
|||
if (property && attrs.includes(property)) {
|
||||
this.webhook.errors.add(property, message);
|
||||
this.webhook.hasValidated.pushObject(property);
|
||||
} else {
|
||||
this.set('error', message);
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -61,6 +61,18 @@ export default Controller.extend({
|
|||
this.integration.rollbackAttributes();
|
||||
|
||||
return transition.retry();
|
||||
},
|
||||
|
||||
confirmWebhookDeletion(webhook) {
|
||||
this.set('webhookToDelete', webhook);
|
||||
},
|
||||
|
||||
cancelWebhookDeletion() {
|
||||
this.set('webhookToDelete', null);
|
||||
},
|
||||
|
||||
deleteWebhook() {
|
||||
return this.webhookToDelete.destroyRecord();
|
||||
}
|
||||
},
|
||||
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
import Controller from '@ember/controller';
|
||||
import {alias} from '@ember/object/computed';
|
||||
|
||||
export default Controller.extend({
|
||||
webhook: alias('model'),
|
||||
|
||||
actions: {
|
||||
save() {
|
||||
return this.webhook.save();
|
||||
},
|
||||
|
||||
cancel() {
|
||||
// 'new' route's dectivate hook takes care of rollback
|
||||
return this.webhook.get('integration').then((integration) => {
|
||||
this.transitionToRoute('settings.integration', integration);
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
15
ghost/admin/app/helpers/event-name.js
Normal file
15
ghost/admin/app/helpers/event-name.js
Normal file
|
@ -0,0 +1,15 @@
|
|||
import {helper} from '@ember/component/helper';
|
||||
|
||||
export const AVAILABLE_EVENTS = [
|
||||
{event: 'site.changed', name: 'Site Changed (rebuild)'},
|
||||
{event: 'subscriber.added', name: 'Subscriber Added'},
|
||||
{event: 'subscriber.deleted', name: 'Subscriber Deleted'}
|
||||
];
|
||||
|
||||
export function eventName([event]/*, hash*/) {
|
||||
let match = AVAILABLE_EVENTS.findBy('event', event);
|
||||
|
||||
return match ? match.name : event;
|
||||
}
|
||||
|
||||
export default helper(eventName);
|
|
@ -57,6 +57,7 @@ Router.map(function () {
|
|||
});
|
||||
this.route('settings.integration', {path: '/settings/integrations/:integration_id'}, function () {
|
||||
this.route('webhooks.new', {path: 'webhooks/new'});
|
||||
this.route('webhooks.edit', {path: 'webhooks/:webhook_id'});
|
||||
});
|
||||
this.route('settings.integrations.slack', {path: '/settings/integrations/slack'});
|
||||
this.route('settings.integrations.amp', {path: '/settings/integrations/amp'});
|
||||
|
|
14
ghost/admin/app/routes/settings/integration/webhooks/edit.js
Normal file
14
ghost/admin/app/routes/settings/integration/webhooks/edit.js
Normal file
|
@ -0,0 +1,14 @@
|
|||
import Route from '@ember/routing/route';
|
||||
|
||||
export default Route.extend({
|
||||
model(params) {
|
||||
let integration = this.modelFor('settings.integration');
|
||||
let webhook = integration.webhooks.findBy('id', params.webhook_id);
|
||||
return webhook;
|
||||
},
|
||||
|
||||
deactivate() {
|
||||
this._super(...arguments);
|
||||
this.controller.webhook.rollbackAttributes();
|
||||
}
|
||||
});
|
|
@ -0,0 +1,15 @@
|
|||
<header class="modal-header">
|
||||
<h1>Are you sure?</h1>
|
||||
</header>
|
||||
<a class="close" href="" title="Close" {{action "closeModal"}}>{{svg-jar "close"}}<span class="hidden">Close</span></a>
|
||||
|
||||
<div class="modal-body">
|
||||
<p>
|
||||
Deleting this webhook may prevent the integration from functioning.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="modal-footer">
|
||||
<button {{action "closeModal"}} class="gh-btn"><span>Cancel</span></button>
|
||||
{{gh-task-button "Delete Webhook" successText="Deleted" task=deleteWebhook class="gh-btn gh-btn-red gh-btn-icon"}}
|
||||
</div>
|
|
@ -78,6 +78,9 @@
|
|||
{{gh-error-message errors=webhook.errors property="secret" data-test-error="new-webhook-secret"}}
|
||||
{{/gh-form-group}}
|
||||
</fieldset>
|
||||
{{#if error}}
|
||||
<p class="red">{{error}}</p>
|
||||
{{/if}}
|
||||
</div>
|
||||
|
||||
<div class="modal-footer">
|
||||
|
|
|
@ -127,16 +127,27 @@
|
|||
<th class="pa3 br3 br--bottom br--right bg-lightgrey-l1">Name</th>
|
||||
<th class="pa3 bg-lightgrey-l1">Event</th>
|
||||
<th class="pa3 bg-lightgrey-l1">URL</th>
|
||||
<th class="pa3 br3 br--top br--left bg-lightgrey-l1">Last triggered</th>
|
||||
<th class="pa3 bg-lightgrey-l1">Last triggered</th>
|
||||
<th class="pa3 br3 br--top br--left bg-lightgrey-l1"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{#each filteredWebhooks as |webhook|}}
|
||||
<tr>
|
||||
<tr class="hide-child">
|
||||
<td class="pa3">{{webhook.name}}</td>
|
||||
<td class="pa3">{{webhook.event}}</td>
|
||||
<td class="pa3">{{event-name webhook.event}}</td>
|
||||
<td class="pa3">{{webhook.targetUrl}}</td>
|
||||
<td class="pa3">{{webhook.lastTriggeredAtUTC}}</td>
|
||||
<td class="pa3">{{or webhook.lastTriggeredAtUTC "Not triggered"}}</td>
|
||||
<td class="w1 pa3 nowrap">
|
||||
<div class="child">
|
||||
{{#link-to "settings.integration.webhooks.edit" integration webhook}}
|
||||
{{svg-jar "koenig/kg-thin-edit" class="w4 fill-black-80"}}
|
||||
{{/link-to}}
|
||||
<button {{action "confirmWebhookDeletion" webhook}}>
|
||||
{{svg-jar "trash" class="w4 fill-red"}}
|
||||
</button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
{{else}}
|
||||
<tr>
|
||||
|
@ -164,4 +175,11 @@
|
|||
modifier="action wide"}}
|
||||
{{/if}}
|
||||
|
||||
{{#if webhookToDelete}}
|
||||
{{gh-fullscreen-modal "delete-webhook"
|
||||
confirm=(action "deleteWebhook")
|
||||
close=(action "cancelWebhookDeletion")
|
||||
modifier="action wide"}}
|
||||
{{/if}}
|
||||
|
||||
{{outlet}}
|
|
@ -0,0 +1,5 @@
|
|||
{{gh-fullscreen-modal "webhook-form"
|
||||
model=webhook
|
||||
confirm=(action "save")
|
||||
close=(action "cancel")
|
||||
modifier="action wide"}}
|
Loading…
Add table
Reference in a new issue