1
0
mirror of https://github.com/ascribe/onion.git synced 2025-01-03 18:35:09 +01:00

Refactor webhooks: add source, clear state on create hide create on no items left

This commit is contained in:
Tim Daubenschütz 2015-11-27 13:36:42 +01:00
parent 1c25f8e776
commit 7146f00c05
6 changed files with 153 additions and 94 deletions

View File

@ -1,47 +1,19 @@
'use strict'; 'use strict';
import { alt } from '../alt'; import { alt } from '../alt';
import WebhookFetcher from '../fetchers/webhook_fetcher';
class WebhookActions { class WebhookActions {
constructor() { constructor() {
this.generateActions( this.generateActions(
'updateWebhooks', 'fetchWebhooks',
'updateEvents', 'successFetchWebhooks',
'removeWebhook' 'fetchWebhookEvents',
'successFetchWebhookEvents',
'removeWebhook',
'successRemoveWebhook'
); );
} }
fetchWebhooks() {
WebhookFetcher.fetch()
.then((res) => {
this.actions.updateWebhooks(res.webhooks);
})
.catch((err) => {
console.logGlobal(err);
});
}
fetchWebhookEvents() {
WebhookFetcher.fetchEvents()
.then((res) => {
this.actions.updateEvents(res.events);
})
.catch((err) => {
console.logGlobal(err);
});
}
deleteWebhook(id){
WebhookFetcher.deleteWebhook(id)
.then((res) => {
this.actions.removeWebhook(id);
})
.catch((err) => {
console.logGlobal(err);
});
}
} }
export default alt.createActions(WebhookActions); export default alt.createActions(WebhookActions);

View File

@ -11,6 +11,8 @@ import GlobalNotificationActions from '../../actions/global_notification_actions
import Form from '../ascribe_forms/form'; import Form from '../ascribe_forms/form';
import Property from '../ascribe_forms/property'; import Property from '../ascribe_forms/property';
import AclProxy from '../acl_proxy';
import ActionPanel from '../ascribe_panel/action_panel'; import ActionPanel from '../ascribe_panel/action_panel';
import CollapsibleParagraph from '../ascribe_collapsible/collapsible_paragraph'; import CollapsibleParagraph from '../ascribe_collapsible/collapsible_paragraph';
@ -43,16 +45,18 @@ let WebhookSettings = React.createClass({
this.setState(state); this.setState(state);
}, },
onDeleteWebhook(event) { onRemoveWebhook(webhookId) {
let webhookId = event.target.getAttribute('data-id'); return (event) => {
WebhookActions.deleteWebhook(webhookId); WebhookActions.removeWebhook(webhookId);
let notification = new GlobalNotificationModel(getLangText('Webhook deleted'), 'success', 2000); let notification = new GlobalNotificationModel(getLangText('Webhook deleted'), 'success', 2000);
GlobalNotificationActions.appendGlobalNotification(notification); GlobalNotificationActions.appendGlobalNotification(notification);
};
}, },
handleCreateSuccess() { handleCreateSuccess() {
WebhookActions.fetchWebhooks(); this.refs.webhookCreateForm.reset();
WebhookActions.fetchWebhooks(true);
let notification = new GlobalNotificationModel(getLangText('Webhook successfully created'), 'success', 5000); let notification = new GlobalNotificationModel(getLangText('Webhook successfully created'), 'success', 5000);
GlobalNotificationActions.appendGlobalNotification(notification); GlobalNotificationActions.appendGlobalNotification(notification);
}, },
@ -60,7 +64,7 @@ let WebhookSettings = React.createClass({
getWebhooks(){ getWebhooks(){
let content = <AscribeSpinner color='dark-blue' size='lg'/>; let content = <AscribeSpinner color='dark-blue' size='lg'/>;
if (this.state.webhooks.length > -1) { if (this.state.webhooks) {
content = this.state.webhooks.map(function(webhook, i) { content = this.state.webhooks.map(function(webhook, i) {
const event = webhook.event.split('.')[0]; const event = webhook.event.split('.')[0];
return ( return (
@ -82,8 +86,7 @@ let WebhookSettings = React.createClass({
<div className="pull-right"> <div className="pull-right">
<button <button
className="pull-right btn btn-tertiary btn-sm" className="pull-right btn btn-tertiary btn-sm"
onClick={this.onDeleteWebhook} onClick={this.onRemoveWebhook(webhook.id)}>
data-id={webhook.id}>
{getLangText('DELETE')} {getLangText('DELETE')}
</button> </button>
</div> </div>
@ -96,14 +99,13 @@ let WebhookSettings = React.createClass({
}, },
getEvents() { getEvents() {
if (this.state.events && this.state.events.length > 1) { if (this.state.webhookEvents && this.state.webhookEvents.length) {
return ( return (
<Property <Property
name='event' name='event'
label={getLangText('Select the event to trigger a webhook', '...')} label={getLangText('Select the event to trigger a webhook', '...')}>
onChange={this.onLicenseChange}> <select name="events">
<select name="license"> {this.state.webhookEvents.map((event, i) => {
{this.state.events.map((event, i) => {
return ( return (
<option <option
name={i} name={i}
@ -125,7 +127,10 @@ let WebhookSettings = React.createClass({
<CollapsibleParagraph <CollapsibleParagraph
title={getLangText('Webhooks')} title={getLangText('Webhooks')}
defaultExpanded={this.props.defaultExpanded}> defaultExpanded={this.props.defaultExpanded}>
<AclProxy
show={this.state.webhookEvents && this.state.webhookEvents.length}>
<Form <Form
ref="webhookCreateForm"
url={ApiUrls.webhooks} url={ApiUrls.webhooks}
handleSuccess={this.handleCreateSuccess}> handleSuccess={this.handleCreateSuccess}>
{ this.getEvents() } { this.getEvents() }
@ -139,9 +144,7 @@ let WebhookSettings = React.createClass({
</Property> </Property>
<hr /> <hr />
</Form> </Form>
<pre> </AclProxy>
Usage: curl &lt;url&gt; -H 'Authorization: Bearer &lt;token&gt;'
</pre>
{this.getWebhooks()} {this.getWebhooks()}
</CollapsibleParagraph> </CollapsibleParagraph>
); );

View File

@ -1,23 +0,0 @@
'use strict';
import requests from '../utils/requests';
let WebhookFetcher = {
/**
* Fetch the registered webhooks of a user from the API.
*/
fetch() {
return requests.get('webhooks');
},
deleteWebhook(id) {
return requests.delete('webhook', {'webhook_id': id });
},
fetchEvents() {
return requests.get('webhooks_events');
}
};
export default WebhookFetcher;

View File

@ -0,0 +1,46 @@
'use strict';
import requests from '../utils/requests';
import WebhookActions from '../actions/webhook_actions';
const WebhookSource = {
lookupWebhooks: {
remote() {
return requests.get('webhooks');
},
local(state) {
return state.webhooks && !Object.keys(state.webhooks).length ? state : {};
},
success: WebhookActions.successFetchWebhooks,
error: WebhookActions.errorWebhooks,
shouldFetch(state) {
return state.webhookMeta.invalidateCache || state.webhooks && !Object.keys(state.webhooks).length;
}
},
lookupWebhookEvents: {
remote() {
return requests.get('webhooks_events');
},
local(state) {
return state.webhookEvents && !Object.keys(state.webhookEvents).length ? state : {};
},
success: WebhookActions.successFetchWebhookEvents,
error: WebhookActions.errorWebhookEvents,
shouldFetch(state) {
return state.webhookEventsMeta.invalidateCache || state.webhookEvents && !Object.keys(state.webhookEvents).length;
}
},
performRemoveWebhook: {
remote(state) {
return requests.delete('webhook', {'webhook_id': state.webhookMeta.idToDelete });
},
success: WebhookActions.successRemoveWebhook,
error: WebhookActions.errorWebhooks
}
};
export default WebhookSource;

View File

@ -3,24 +3,85 @@
import { alt } from '../alt'; import { alt } from '../alt';
import WebhookActions from '../actions/webhook_actions'; import WebhookActions from '../actions/webhook_actions';
import WebhookSource from '../sources/webhook_source';
class WebhookStore { class WebhookStore {
constructor() { constructor() {
this.webhooks = {}; this.webhooks = [];
this.events = {}; this.webhookEvents = [];
this.webhookMeta = {
invalidateCache: false,
err: null,
idToDelete: null
};
this.webhookEventsMeta = {
invalidateCache: false,
err: null
};
this.bindActions(WebhookActions); this.bindActions(WebhookActions);
this.registerAsync(WebhookSource);
} }
onUpdateWebhooks(webhooks) { onFetchWebhooks(invalidateCache) {
this.webhookMeta.invalidateCache = invalidateCache;
this.getInstance().lookupWebhooks();
}
onSuccessFetchWebhooks({ webhooks }) {
this.webhookMeta.invalidateCache = false;
this.webhookMeta.err = null;
this.webhooks = webhooks; this.webhooks = webhooks;
this.webhookEventsMeta.invalidateCache = true;
this.getInstance().lookupWebhookEvents();
} }
onUpdateEvents(events) { onFetchWebhookEvents(invalidateCache) {
this.events = events; this.webhookEventsMeta.invalidateCache = invalidateCache;
this.getInstance().lookupWebhookEvents();
}
onSuccessFetchWebhookEvents({ events }) {
this.webhookEventsMeta.invalidateCache = false;
this.webhookEventsMeta.err = null;
// remove all events that have already been used.
const usedEvents = this.webhooks
.reduce((tempUsedEvents, webhook) => {
tempUsedEvents.push(webhook.event.split('.')[0]);
return tempUsedEvents;
}, []);
this.webhookEvents = events.filter((event) => {
return usedEvents.indexOf(event) === -1;
});
} }
onRemoveWebhook(id) { onRemoveWebhook(id) {
this.webhooks = this.webhooks.filter((webhook) => webhook.id !== parseInt(id)); this.webhookMeta.invalidateCache = true;
this.webhookMeta.idToDelete = id;
if(!this.getInstance().isLoading()) {
this.getInstance().performRemoveWebhook();
}
}
onSuccessRemoveWebhook() {
this.webhookMeta.idToDelete = null;
if(!this.getInstance().isLoading()) {
this.getInstance().lookupWebhooks();
}
}
onErrorWebhooks(err) {
console.logGlobal(err);
this.webhookMeta.err = err;
}
onErrorWebhookEvents(err) {
console.logGlobal(err);
this.webhookEventsMeta.err = err;
} }
} }