summaryrefslogtreecommitdiffstats
path: root/webapp/components
diff options
context:
space:
mode:
authorHarrison Healey <harrisonmhealey@gmail.com>2016-05-05 09:32:12 -0400
committerChristopher Speller <crspeller@gmail.com>2016-05-05 09:32:12 -0400
commit2c92540471004c79e317e8a0daf3e612560beda7 (patch)
tree2abed81a2b4340cfaeaed47e70a6b14d0129bc47 /webapp/components
parentfcb5b70eb348368421464553066ef9c715c66ff0 (diff)
downloadchat-2c92540471004c79e317e8a0daf3e612560beda7.tar.gz
chat-2c92540471004c79e317e8a0daf3e612560beda7.tar.bz2
chat-2c92540471004c79e317e8a0daf3e612560beda7.zip
PLT-2698 Integrations improvements (#2883)
* Fixed Integrations link to show up for non-admins (when enabled) and when only slash commands are enabled * Updated BackstageSidebar to only show enabled integrations * Added placeholder to integrations list when none exist * Added loading spinner to integrations pages when they're loading
Diffstat (limited to 'webapp/components')
-rw-r--r--webapp/components/backstage/backstage_category.jsx4
-rw-r--r--webapp/components/backstage/backstage_sidebar.jsx75
-rw-r--r--webapp/components/backstage/installed_commands.jsx27
-rw-r--r--webapp/components/backstage/installed_incoming_webhooks.jsx25
-rw-r--r--webapp/components/backstage/installed_integrations.jsx25
-rw-r--r--webapp/components/backstage/installed_outgoing_webhooks.jsx25
-rw-r--r--webapp/components/navbar_dropdown.jsx28
7 files changed, 130 insertions, 79 deletions
diff --git a/webapp/components/backstage/backstage_category.jsx b/webapp/components/backstage/backstage_category.jsx
index 913c7562c..8e6c8541b 100644
--- a/webapp/components/backstage/backstage_category.jsx
+++ b/webapp/components/backstage/backstage_category.jsx
@@ -40,6 +40,10 @@ export default class BackstageCategory extends React.Component {
<ul className='sections'>
{
React.Children.map(children, (child) => {
+ if (!child) {
+ return child;
+ }
+
return React.cloneElement(child, {
parentLink: link
});
diff --git a/webapp/components/backstage/backstage_sidebar.jsx b/webapp/components/backstage/backstage_sidebar.jsx
index 6f8e0b86a..4d8d8337d 100644
--- a/webapp/components/backstage/backstage_sidebar.jsx
+++ b/webapp/components/backstage/backstage_sidebar.jsx
@@ -10,6 +10,51 @@ import {FormattedMessage} from 'react-intl';
export default class BackstageSidebar extends React.Component {
render() {
+ let incomingWebhooks = null;
+ if (window.mm_config.EnableIncomingWebhooks === 'true') {
+ incomingWebhooks = (
+ <BackstageSection
+ name='incoming_webhooks'
+ title={(
+ <FormattedMessage
+ id='backstage_sidebar.integrations.incoming_webhooks'
+ defaultMessage='Incoming Webhooks'
+ />
+ )}
+ />
+ );
+ }
+
+ let outgoingWebhooks = null;
+ if (window.mm_config.EnableOutgoingWebhooks === 'true') {
+ outgoingWebhooks = (
+ <BackstageSection
+ name='outgoing_webhooks'
+ title={(
+ <FormattedMessage
+ id='backstage_sidebar.integrations.outgoing_webhooks'
+ defaultMessage='Outgoing Webhooks'
+ />
+ )}
+ />
+ );
+ }
+
+ let commands = null;
+ if (window.mm_config.EnableCommands === 'true') {
+ commands = (
+ <BackstageSection
+ name='commands'
+ title={(
+ <FormattedMessage
+ id='backstage_sidebar.integrations.commands'
+ defaultMessage='Slash Commands'
+ />
+ )}
+ />
+ );
+ }
+
return (
<div className='backstage-sidebar'>
<ul>
@@ -24,33 +69,9 @@ export default class BackstageSidebar extends React.Component {
/>
}
>
- <BackstageSection
- name='incoming_webhooks'
- title={(
- <FormattedMessage
- id='backstage_sidebar.integrations.incoming_webhooks'
- defaultMessage='Incoming Webhooks'
- />
- )}
- />
- <BackstageSection
- name='outgoing_webhooks'
- title={(
- <FormattedMessage
- id='backstage_sidebar.integrations.outgoing_webhooks'
- defaultMessage='Outgoing Webhooks'
- />
- )}
- />
- <BackstageSection
- name='commands'
- title={(
- <FormattedMessage
- id='backstage_sidebar.integrations.commands'
- defaultMessage='Slash Commands'
- />
- )}
- />
+ {incomingWebhooks}
+ {outgoingWebhooks}
+ {commands}
</BackstageCategory>
</ul>
</div>
diff --git a/webapp/components/backstage/installed_commands.jsx b/webapp/components/backstage/installed_commands.jsx
index 8b0cd59c8..71373e077 100644
--- a/webapp/components/backstage/installed_commands.jsx
+++ b/webapp/components/backstage/installed_commands.jsx
@@ -21,21 +21,16 @@ export default class InstalledCommands extends React.Component {
this.deleteCommand = this.deleteCommand.bind(this);
this.state = {
- commands: []
+ commands: IntegrationStore.getCommands(),
+ loading: !IntegrationStore.hasReceivedCommands()
};
}
- componentWillMount() {
+ componentDidMount() {
IntegrationStore.addChangeListener(this.handleIntegrationChange);
- if (window.mm_config.EnableCommands === 'true') {
- if (IntegrationStore.hasReceivedCommands()) {
- this.setState({
- commands: IntegrationStore.getCommands()
- });
- } else {
- AsyncClient.listTeamCommands();
- }
+ if (window.mm_config.EnableCommands === 'true' && this.state.loading) {
+ AsyncClient.listTeamCommands();
}
}
@@ -44,10 +39,9 @@ export default class InstalledCommands extends React.Component {
}
handleIntegrationChange() {
- const commands = IntegrationStore.getCommands();
-
this.setState({
- commands
+ commands: IntegrationStore.getCommands(),
+ loading: !IntegrationStore.hasReceivedCommands()
});
}
@@ -86,6 +80,13 @@ export default class InstalledCommands extends React.Component {
/>
}
addLink={'/' + Utils.getTeamNameFromUrl() + '/settings/integrations/commands/add'}
+ emptyText={
+ <FormattedMessage
+ id='installed_commands.empty'
+ defaultMessage='No slash commands found'
+ />
+ }
+ loading={this.state.loading}
>
{commands}
</InstalledIntegrations>
diff --git a/webapp/components/backstage/installed_incoming_webhooks.jsx b/webapp/components/backstage/installed_incoming_webhooks.jsx
index 0d6f900d1..389f65919 100644
--- a/webapp/components/backstage/installed_incoming_webhooks.jsx
+++ b/webapp/components/backstage/installed_incoming_webhooks.jsx
@@ -20,21 +20,16 @@ export default class InstalledIncomingWebhooks extends React.Component {
this.deleteIncomingWebhook = this.deleteIncomingWebhook.bind(this);
this.state = {
- incomingWebhooks: []
+ incomingWebhooks: IntegrationStore.getIncomingWebhooks(),
+ loading: !IntegrationStore.hasReceivedIncomingWebhooks()
};
}
- componentWillMount() {
+ componentDidMount() {
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.EnableIncomingWebhooks === 'true' && this.state.loading) {
+ AsyncClient.listIncomingHooks();
}
}
@@ -44,7 +39,8 @@ export default class InstalledIncomingWebhooks extends React.Component {
handleIntegrationChange() {
this.setState({
- incomingWebhooks: IntegrationStore.getIncomingWebhooks()
+ incomingWebhooks: IntegrationStore.getIncomingWebhooks(),
+ loading: !IntegrationStore.hasReceivedIncomingWebhooks()
});
}
@@ -78,6 +74,13 @@ export default class InstalledIncomingWebhooks extends React.Component {
/>
}
addLink={'/' + Utils.getTeamNameFromUrl() + '/settings/integrations/incoming_webhooks/add'}
+ emptyText={
+ <FormattedMessage
+ id='installed_incoming_webhooks.empty'
+ defaultMessage='No incoming webhooks found'
+ />
+ }
+ loading={this.state.loading}
>
{incomingWebhooks}
</InstalledIntegrations>
diff --git a/webapp/components/backstage/installed_integrations.jsx b/webapp/components/backstage/installed_integrations.jsx
index baf74447f..cff0611d7 100644
--- a/webapp/components/backstage/installed_integrations.jsx
+++ b/webapp/components/backstage/installed_integrations.jsx
@@ -6,6 +6,7 @@ import React from 'react';
import * as Utils from 'utils/utils.jsx';
import {Link} from 'react-router';
+import LoadingScreen from 'components/loading_screen.jsx';
export default class InstalledIntegrations extends React.Component {
static get propTypes() {
@@ -13,7 +14,9 @@ export default class InstalledIntegrations extends React.Component {
children: React.PropTypes.node,
header: React.PropTypes.node.isRequired,
addLink: React.PropTypes.string.isRequired,
- addText: React.PropTypes.node.isRequired
+ addText: React.PropTypes.node.isRequired,
+ emptyText: React.PropTypes.node.isRequired,
+ loading: React.PropTypes.bool.isRequired
};
}
@@ -36,9 +39,23 @@ export default class InstalledIntegrations extends React.Component {
render() {
const filter = this.state.filter.toLowerCase();
- const children = React.Children.map(this.props.children, (child) => {
- return React.cloneElement(child, {filter});
- });
+ let children;
+
+ if (this.props.loading) {
+ children = <LoadingScreen/>;
+ } else {
+ children = React.Children.map(this.props.children, (child) => {
+ return React.cloneElement(child, {filter});
+ });
+
+ if (children.length === 0) {
+ children = (
+ <span className='backstage-list__item backstage-list_empty'>
+ {this.props.emptyText}
+ </span>
+ );
+ }
+ }
return (
<div className='backstage-content'>
diff --git a/webapp/components/backstage/installed_outgoing_webhooks.jsx b/webapp/components/backstage/installed_outgoing_webhooks.jsx
index 98992b081..e0817fda8 100644
--- a/webapp/components/backstage/installed_outgoing_webhooks.jsx
+++ b/webapp/components/backstage/installed_outgoing_webhooks.jsx
@@ -21,21 +21,16 @@ export default class InstalledOutgoingWebhooks extends React.Component {
this.deleteOutgoingWebhook = this.deleteOutgoingWebhook.bind(this);
this.state = {
- outgoingWebhooks: []
+ outgoingWebhooks: IntegrationStore.getOutgoingWebhooks(),
+ loading: !IntegrationStore.hasReceivedOutgoingWebhooks()
};
}
- componentWillMount() {
+ componentDidMount() {
IntegrationStore.addChangeListener(this.handleIntegrationChange);
- if (window.mm_config.EnableOutgoingWebhooks === 'true') {
- if (IntegrationStore.hasReceivedOutgoingWebhooks()) {
- this.setState({
- outgoingWebhooks: IntegrationStore.getOutgoingWebhooks()
- });
- } else {
- AsyncClient.listOutgoingHooks();
- }
+ if (window.mm_config.EnableOutgoingWebhooks === 'true' && this.state.loading) {
+ AsyncClient.listOutgoingHooks();
}
}
@@ -45,7 +40,8 @@ export default class InstalledOutgoingWebhooks extends React.Component {
handleIntegrationChange() {
this.setState({
- outgoingWebhooks: IntegrationStore.getOutgoingWebhooks()
+ outgoingWebhooks: IntegrationStore.getOutgoingWebhooks(),
+ loading: !IntegrationStore.hasReceivedOutgoingWebhooks()
});
}
@@ -84,6 +80,13 @@ export default class InstalledOutgoingWebhooks extends React.Component {
/>
}
addLink={'/' + Utils.getTeamNameFromUrl() + '/settings/integrations/outgoing_webhooks/add'}
+ emptyText={
+ <FormattedMessage
+ id='installed_outgoing_webhooks.empty'
+ defaultMessage='No outgoing webhooks found'
+ />
+ }
+ loading={this.state.loading}
>
{outgoingWebhooks}
</InstalledIntegrations>
diff --git a/webapp/components/navbar_dropdown.jsx b/webapp/components/navbar_dropdown.jsx
index 71c1f0d5b..967c5a95c 100644
--- a/webapp/components/navbar_dropdown.jsx
+++ b/webapp/components/navbar_dropdown.jsx
@@ -143,19 +143,21 @@ export default class NavbarDropdown extends React.Component {
);
}
- if (window.mm_config.EnableIncomingWebhooks === 'true' || window.mm_config.EnableOutgoingWebhooks === 'true') {
- if (isAdmin || window.EnableAdminOnlyIntegrations !== 'true') {
- integrationsLink = (
- <li>
- <Link to={'/' + Utils.getTeamNameFromUrl() + '/settings/integrations'}>
- <FormattedMessage
- id='navbar_dropdown.integrations'
- defaultMessage='Integrations'
- />
- </Link>
- </li>
- );
- }
+ const integrationsEnabled =
+ window.mm_config.EnableIncomingWebhooks === 'true' ||
+ window.mm_config.EnableOutgoingWebhooks === 'true' ||
+ window.mm_config.EnableCommands === 'true';
+ if (integrationsEnabled && (isAdmin || window.EnableOnlyAdminIntegrations !== 'true')) {
+ integrationsLink = (
+ <li>
+ <Link to={'/' + Utils.getTeamNameFromUrl() + '/settings/integrations'}>
+ <FormattedMessage
+ id='navbar_dropdown.integrations'
+ defaultMessage='Integrations'
+ />
+ </Link>
+ </li>
+ );
}
if (isSystemAdmin) {