summaryrefslogtreecommitdiffstats
path: root/webapp/components/backstage/installed_integrations.jsx
diff options
context:
space:
mode:
Diffstat (limited to 'webapp/components/backstage/installed_integrations.jsx')
-rw-r--r--webapp/components/backstage/installed_integrations.jsx289
1 files changed, 289 insertions, 0 deletions
diff --git a/webapp/components/backstage/installed_integrations.jsx b/webapp/components/backstage/installed_integrations.jsx
new file mode 100644
index 000000000..ff0b6e4ec
--- /dev/null
+++ b/webapp/components/backstage/installed_integrations.jsx
@@ -0,0 +1,289 @@
+// Copyright (c) 2016 Mattermost, Inc. All Rights Reserved.
+// See License.txt for license information.
+
+import React from 'react';
+
+import * as AsyncClient from 'utils/async_client.jsx';
+import ChannelStore from 'stores/channel_store.jsx';
+import IntegrationStore from 'stores/integration_store.jsx';
+import * as Utils from 'utils/utils.jsx';
+
+import {FormattedMessage} from 'react-intl';
+import InstalledIncomingWebhook from './installed_incoming_webhook.jsx';
+import InstalledOutgoingWebhook from './installed_outgoing_webhook.jsx';
+import {Link} from 'react-router';
+
+export default class InstalledIntegrations extends React.Component {
+ constructor(props) {
+ super(props);
+
+ this.handleIntegrationChange = this.handleIntegrationChange.bind(this);
+ this.updateFilter = this.updateFilter.bind(this);
+ this.updateTypeFilter = this.updateTypeFilter.bind(this);
+
+ this.deleteIncomingWebhook = this.deleteIncomingWebhook.bind(this);
+ this.regenOutgoingWebhookToken = this.regenOutgoingWebhookToken.bind(this);
+ this.deleteOutgoingWebhook = this.deleteOutgoingWebhook.bind(this);
+
+ this.state = {
+ incomingWebhooks: [],
+ outgoingWebhooks: [],
+ typeFilter: '',
+ filter: ''
+ };
+ }
+
+ componentWillMount() {
+ IntegrationStore.addChangeListener(this.handleIntegrationChange);
+
+ if (window.mm_config.EnableIncomingWebhooks === 'true') {
+ if (IntegrationStore.hasReceivedIncomingWebhooks()) {
+ this.setState({
+ incomingWebhooks: IntegrationStore.getIncomingWebhooks()
+ });
+ } else {
+ AsyncClient.listIncomingHooks();
+ }
+ }
+
+ if (window.mm_config.EnableOutgoingWebhooks === 'true') {
+ if (IntegrationStore.hasReceivedOutgoingWebhooks()) {
+ this.setState({
+ outgoingWebhooks: IntegrationStore.getOutgoingWebhooks()
+ });
+ } else {
+ AsyncClient.listOutgoingHooks();
+ }
+ }
+ }
+
+ componentWillUnmount() {
+ IntegrationStore.removeChangeListener(this.handleIntegrationChange);
+ }
+
+ handleIntegrationChange() {
+ this.setState({
+ incomingWebhooks: IntegrationStore.getIncomingWebhooks(),
+ outgoingWebhooks: IntegrationStore.getOutgoingWebhooks()
+ });
+ }
+
+ updateTypeFilter(e, typeFilter) {
+ e.preventDefault();
+
+ this.setState({
+ typeFilter
+ });
+ }
+
+ updateFilter(e) {
+ this.setState({
+ filter: e.target.value
+ });
+ }
+
+ deleteIncomingWebhook(incomingWebhook) {
+ AsyncClient.deleteIncomingHook(incomingWebhook.id);
+ }
+
+ regenOutgoingWebhookToken(outgoingWebhook) {
+ AsyncClient.regenOutgoingHookToken(outgoingWebhook.id);
+ }
+
+ deleteOutgoingWebhook(outgoingWebhook) {
+ AsyncClient.deleteOutgoingHook(outgoingWebhook.id);
+ }
+
+ renderTypeFilters(incomingWebhooks, outgoingWebhooks) {
+ const fields = [];
+
+ if (incomingWebhooks.length > 0 || outgoingWebhooks.length > 0) {
+ let filterClassName = 'type-filter';
+ if (this.state.typeFilter === '') {
+ filterClassName += ' type-filter--selected';
+ }
+
+ fields.push(
+ <a
+ key='allFilter'
+ className={filterClassName}
+ href='#'
+ onClick={(e) => this.updateTypeFilter(e, '')}
+ >
+ <FormattedMessage
+ id='installed_integrations.allFilter'
+ defaultMessage='All ({count})'
+ values={{
+ count: incomingWebhooks.length + outgoingWebhooks.length
+ }}
+ />
+ </a>
+ );
+ }
+
+ if (incomingWebhooks.length > 0) {
+ fields.push(
+ <span
+ key='incomingWebhooksDivider'
+ className='divider'
+ >
+ {'|'}
+ </span>
+ );
+
+ let filterClassName = 'type-filter';
+ if (this.state.typeFilter === 'incomingWebhooks') {
+ filterClassName += ' type-filter--selected';
+ }
+
+ fields.push(
+ <a
+ key='incomingWebhooksFilter'
+ className={filterClassName}
+ href='#'
+ onClick={(e) => this.updateTypeFilter(e, 'incomingWebhooks')}
+ >
+ <FormattedMessage
+ id='installed_integrations.incomingWebhooksFilter'
+ defaultMessage='Incoming Webhooks ({count})'
+ values={{
+ count: incomingWebhooks.length
+ }}
+ />
+ </a>
+ );
+ }
+
+ if (outgoingWebhooks.length > 0) {
+ fields.push(
+ <span
+ key='outgoingWebhooksDivider'
+ className='divider'
+ >
+ {'|'}
+ </span>
+ );
+
+ let filterClassName = 'type-filter';
+ if (this.state.typeFilter === 'outgoingWebhooks') {
+ filterClassName += ' type-filter--selected';
+ }
+
+ fields.push(
+ <a
+ key='outgoingWebhooksFilter'
+ className={filterClassName}
+ href='#'
+ onClick={(e) => this.updateTypeFilter(e, 'outgoingWebhooks')}
+ >
+ <FormattedMessage
+ id='installed_integrations.outgoingWebhooksFilter'
+ defaultMessage='Outgoing Webhooks ({count})'
+ values={{
+ count: outgoingWebhooks.length
+ }}
+ />
+ </a>
+ );
+ }
+
+ return (
+ <div className='type-filters'>
+ {fields}
+ </div>
+ );
+ }
+
+ render() {
+ const incomingWebhooks = this.state.incomingWebhooks;
+ const outgoingWebhooks = this.state.outgoingWebhooks;
+
+ const filter = this.state.filter.toLowerCase();
+
+ const integrations = [];
+ if (!this.state.typeFilter || this.state.typeFilter === 'incomingWebhooks') {
+ for (const incomingWebhook of incomingWebhooks) {
+ if (filter) {
+ const channel = ChannelStore.get(incomingWebhook.channel_id);
+
+ if (!channel || channel.name.toLowerCase().indexOf(filter) === -1) {
+ continue;
+ }
+ }
+
+ integrations.push(
+ <InstalledIncomingWebhook
+ key={incomingWebhook.id}
+ incomingWebhook={incomingWebhook}
+ onDeleteClick={this.deleteIncomingWebhook}
+ />
+ );
+ }
+ }
+
+ if (!this.state.typeFilter || this.state.typeFilter === 'outgoingWebhooks') {
+ for (const outgoingWebhook of outgoingWebhooks) {
+ if (filter) {
+ const channel = ChannelStore.get(outgoingWebhook.channel_id);
+
+ if (!channel || channel.name.toLowerCase().indexOf(filter) === -1) {
+ continue;
+ }
+ }
+
+ integrations.push(
+ <InstalledOutgoingWebhook
+ key={outgoingWebhook.id}
+ outgoingWebhook={outgoingWebhook}
+ onRegenToken={this.regenOutgoingWebhookToken}
+ onDelete={this.deleteOutgoingWebhook}
+ />
+ );
+ }
+ }
+
+ return (
+ <div className='backstage row'>
+ <div className='installed-integrations'>
+ <div className='backstage__header'>
+ <h1 className='text'>
+ <FormattedMessage
+ id='installed_integrations.header'
+ defaultMessage='Installed Integrations'
+ />
+ </h1>
+ <Link
+ className='add-integrations-link'
+ to={'/settings/integrations/add'}
+ >
+ <button
+ type='button'
+ className='btn btn-primary'
+ >
+ <span>
+ <FormattedMessage
+ id='installed_integrations.add'
+ defaultMessage='Add Integration'
+ />
+ </span>
+ </button>
+ </Link>
+ </div>
+ <div className='installed-integrations__filters'>
+ {this.renderTypeFilters(this.state.incomingWebhooks, this.state.outgoingWebhooks)}
+ <input
+ type='search'
+ placeholder={Utils.localizeMessage('installed_integrations.search', 'Search Integrations')}
+ value={this.state.filter}
+ onChange={this.updateFilter}
+ style={{flexGrow: 0, flexShrink: 0}}
+ />
+ </div>
+ <div className='installed-integrations__list'>
+ {integrations}
+ </div>
+ </div>
+ </div>
+ );
+ }
+}