summaryrefslogtreecommitdiffstats
path: root/webapp/components/admin_console/admin_sidebar.jsx
diff options
context:
space:
mode:
Diffstat (limited to 'webapp/components/admin_console/admin_sidebar.jsx')
-rw-r--r--webapp/components/admin_console/admin_sidebar.jsx830
1 files changed, 449 insertions, 381 deletions
diff --git a/webapp/components/admin_console/admin_sidebar.jsx b/webapp/components/admin_console/admin_sidebar.jsx
index 4ffc31815..cdb7e29d5 100644
--- a/webapp/components/admin_console/admin_sidebar.jsx
+++ b/webapp/components/admin_console/admin_sidebar.jsx
@@ -2,69 +2,80 @@
// See License.txt for license information.
import $ from 'jquery';
+import React from 'react';
-import AdminSidebarHeader from './admin_sidebar_header.jsx';
-import SelectTeamModal from './select_team_modal.jsx';
+import AdminStore from 'stores/admin_store.jsx';
+import * as AsyncClient from 'utils/async_client.jsx';
import * as Utils from 'utils/utils.jsx';
+import AdminSidebarHeader from './admin_sidebar_header.jsx';
+import AdminSidebarTeam from './admin_sidebar_team.jsx';
import {FormattedMessage} from 'react-intl';
-
-import {Tooltip, OverlayTrigger} from 'react-bootstrap';
-
-import React from 'react';
+import {browserHistory} from 'react-router';
+import {OverlayTrigger, Tooltip} from 'react-bootstrap';
+import SelectTeamModal from './select_team_modal.jsx';
+import AdminSidebarCategory from './admin_sidebar_category.jsx';
+import AdminSidebarSection from './admin_sidebar_section.jsx';
export default class AdminSidebar extends React.Component {
+ static get contextTypes() {
+ return {
+ router: React.PropTypes.object.isRequired
+ };
+ }
+
constructor(props) {
super(props);
- this.isSelected = this.isSelected.bind(this);
- this.handleClick = this.handleClick.bind(this);
+ this.handleAllTeamsChange = this.handleAllTeamsChange.bind(this);
+
this.removeTeam = this.removeTeam.bind(this);
this.showTeamSelect = this.showTeamSelect.bind(this);
this.teamSelectedModal = this.teamSelectedModal.bind(this);
this.teamSelectedModalDismissed = this.teamSelectedModalDismissed.bind(this);
+ this.renderAddTeamButton = this.renderAddTeamButton.bind(this);
+ this.renderTeams = this.renderTeams.bind(this);
+
this.state = {
+ teams: AdminStore.getAllTeams(),
+ selectedTeams: AdminStore.getSelectedTeams(),
showSelectModal: false
};
}
+ componentDidMount() {
+ AdminStore.addAllTeamsChangeListener(this.handleAllTeamsChange);
+ AsyncClient.getAllTeams();
+ }
+
componentDidUpdate() {
if (!Utils.isMobile()) {
- $('.sidebar--left .nav-pills__container').perfectScrollbar();
+ $('.admin-sidebar .nav-pills__container').perfectScrollbar();
}
}
- handleClick(name, teamId, e) {
- e.preventDefault();
- this.props.selectTab(name, teamId);
+ componentWillUnmount() {
+ AdminStore.removeAllTeamsChangeListener(this.handleAllTeamsChange);
}
- isSelected(name, teamId) {
- if (this.props.selected === name) {
- if (name === 'team_users' || name === 'team_analytics') {
- if (this.props.selectedTeam != null && this.props.selectedTeam === teamId) {
- return 'active';
- }
- } else {
- return 'active';
- }
- }
-
- return '';
+ handleAllTeamsChange() {
+ this.setState({
+ teams: AdminStore.getAllTeams(),
+ selectedTeams: AdminStore.getSelectedTeams()
+ });
}
- removeTeam(teamId, e) {
- e.preventDefault();
- e.stopPropagation();
- Reflect.deleteProperty(this.props.selectedTeams, teamId);
- this.props.removeSelectedTeam(teamId);
+ removeTeam(team) {
+ const selectedTeams = Object.assign({}, this.state.selectedTeams);
+ Reflect.deleteProperty(selectedTeams, team.id);
+ AdminStore.saveSelectedTeams(selectedTeams);
- if (this.props.selected === 'team_users') {
- if (this.props.selectedTeam != null && this.props.selectedTeam === teamId) {
- this.props.selectTab('service_settings', null);
- }
+ this.handleAllTeamsChange();
+
+ if (this.context.router.isActive('/admin_console/team/' + team.id)) {
+ browserHistory.push('/admin_console');
}
}
@@ -74,31 +85,23 @@ export default class AdminSidebar extends React.Component {
}
teamSelectedModal(teamId) {
- this.setState({showSelectModal: false});
- this.props.addSelectedTeam(teamId);
- this.forceUpdate();
+ this.setState({
+ showSelectModal: false
+ });
+
+ const selectedTeams = Object.assign({}, this.state.selectedTeams);
+ selectedTeams[teamId] = true;
+
+ AdminStore.saveSelectedTeams(selectedTeams);
+
+ this.handleAllTeamsChange();
}
teamSelectedModalDismissed() {
this.setState({showSelectModal: false});
}
- render() {
- var count = '*';
- var teams = (
- <FormattedMessage
- id='admin.sidebar.loading'
- defaultMessage='Loading'
- />
- );
- const removeTooltip = (
- <Tooltip id='remove-team-tooltip'>
- <FormattedMessage
- id='admin.sidebar.rmTeamSidebar'
- defaultMessage='Remove team from sidebar menu'
- />
- </Tooltip>
- );
+ renderAddTeamButton() {
const addTeamTooltip = (
<Tooltip id='add-team-tooltip'>
<FormattedMessage
@@ -108,393 +111,468 @@ export default class AdminSidebar extends React.Component {
</Tooltip>
);
- if (this.props.teams != null) {
- count = '' + Object.keys(this.props.teams).length;
+ return (
+ <span className='menu-icon--right'>
+ <OverlayTrigger
+ delayShow={1000}
+ placement='top'
+ overlay={addTeamTooltip}
+ >
+ <a
+ href='#'
+ onClick={this.showTeamSelect}
+ >
+ <i
+ className='fa fa-plus'
+ ></i>
+ </a>
+ </OverlayTrigger>
+ </span>
+ );
+ }
+
+ renderTeams() {
+ const teams = [];
- teams = [];
- for (var key in this.props.selectedTeams) {
- if (this.props.selectedTeams.hasOwnProperty(key)) {
- var team = this.props.teams[key];
+ for (const key in this.state.selectedTeams) {
+ if (!this.state.selectedTeams.hasOwnProperty(key)) {
+ continue;
+ }
- if (team != null) {
- teams.push(
- <ul
- key={'team_' + team.id}
- className='nav nav__sub-menu'
- >
- <li>
- <a
- href='#'
- onClick={this.handleClick.bind(this, 'team_users', team.id)}
- className={'nav__sub-menu-item ' + this.isSelected('team_users', team.id) + ' ' + this.isSelected('team_analytics', team.id)}
- >
- {team.name}
- <OverlayTrigger
- delayShow={1000}
- placement='top'
- overlay={removeTooltip}
- >
- <span
- className='menu-icon--right menu__close'
- onClick={this.removeTeam.bind(this, team.id)}
- style={{cursor: 'pointer'}}
- >
- {'×'}
- </span>
- </OverlayTrigger>
- </a>
- </li>
- <li>
- <ul className='nav nav__inner-menu'>
- <li>
- <a
- href='#'
- className={this.isSelected('team_users', team.id)}
- onClick={this.handleClick.bind(this, 'team_users', team.id)}
- >
- <FormattedMessage
- id='admin.sidebar.users'
- defaultMessage='- Users'
- />
- </a>
- </li>
- <li>
- <a
- href='#'
- className={this.isSelected('team_analytics', team.id)}
- onClick={this.handleClick.bind(this, 'team_analytics', team.id)}
- >
- <FormattedMessage
- id='admin.sidebar.statistics'
- defaultMessage='- Statistics'
- />
- </a>
- </li>
- </ul>
- </li>
- </ul>
- );
- }
- }
+ const team = this.state.teams[key];
+
+ if (!team) {
+ continue;
}
+
+ teams.push(
+ <AdminSidebarTeam
+ key={team.id}
+ team={team}
+ onRemoveTeam={this.removeTeam}
+ />
+ );
}
- let ldapSettings;
- let complianceSettings;
- let licenseSettings;
- if (global.window.mm_config.BuildEnterpriseReady === 'true') {
- if (global.window.mm_license.IsLicensed === 'true') {
+ return (
+ <AdminSidebarCategory
+ parentLink='/admin_console'
+ icon='fa-gear'
+ title={
+ <FormattedMessage
+ id='admin.sidebar.teams'
+ defaultMessage='TEAMS ({count, number})'
+ values={{
+ count: Object.keys(this.state.teams).length
+ }}
+ />
+ }
+ action={this.renderAddTeamButton()}
+ >
+ {teams}
+ </AdminSidebarCategory>
+ );
+ }
+
+ render() {
+ let ldapSettings = null;
+ let complianceSettings = null;
+
+ let license = null;
+ let audits = null;
+
+ if (window.mm_config.BuildEnterpriseReady === 'true') {
+ if (window.mm_license.IsLicensed === 'true') {
if (global.window.mm_license.LDAP === 'true') {
ldapSettings = (
- <li>
- <a
- href='#'
- className={this.isSelected('ldap_settings')}
- onClick={this.handleClick.bind(this, 'ldap_settings', null)}
- >
+ <AdminSidebarSection
+ name='ldap'
+ title={
<FormattedMessage
id='admin.sidebar.ldap'
- defaultMessage='LDAP Settings'
+ defaultMessage='LDAP'
/>
- </a>
- </li>
+ }
+ />
);
}
if (global.window.mm_license.Compliance === 'true') {
complianceSettings = (
- <li>
- <a
- href='#'
- className={this.isSelected('compliance_settings')}
- onClick={this.handleClick.bind(this, 'compliance_settings', null)}
- >
+ <AdminSidebarSection
+ name='compliance'
+ title={
<FormattedMessage
id='admin.sidebar.compliance'
- defaultMessage='Compliance Settings'
+ defaultMessage='Compliance'
/>
- </a>
- </li>
+ }
+ />
);
}
}
- licenseSettings = (
- <li>
- <a
- href='#'
- className={this.isSelected('license')}
- onClick={this.handleClick.bind(this, 'license', null)}
- >
+ license = (
+ <AdminSidebarSection
+ name='license'
+ title={
<FormattedMessage
id='admin.sidebar.license'
defaultMessage='Edition and License'
/>
- </a>
- </li>
+ }
+ />
);
}
- let audits;
- if (global.window.mm_license.IsLicensed === 'true') {
+ if (window.mm_license.IsLicensed === 'true') {
audits = (
- <li>
- <a
- href='#'
- className={this.isSelected('audits')}
- onClick={this.handleClick.bind(this, 'audits', null)}
- >
+ <AdminSidebarSection
+ name='audits'
+ title={
<FormattedMessage
id='admin.sidebar.audits'
- defaultMessage='Compliance and Auditing'
+ defaultMessage='Complaince and Auditing'
/>
- </a>
- </li>
+ }
+ />
);
}
return (
- <div className='sidebar--left sidebar--collapsable'>
+ <div className='admin-sidebar'>
<AdminSidebarHeader/>
<div className='nav-pills__container'>
<ul className='nav nav-pills nav-stacked'>
- <li>
- <ul className='nav nav__sub-menu'>
- <li>
- <h4>
- <span className='icon fa fa-gear'></span>
- <span>
- <FormattedMessage
- id='admin.sidebar.reports'
- defaultMessage='SITE REPORTS'
- />
- </span>
- </h4>
- </li>
- </ul>
- <ul className='nav nav__sub-menu padded'>
- <li>
- <a
- href='#'
- className={this.isSelected('system_analytics')}
- onClick={this.handleClick.bind(this, 'system_analytics', null)}
- >
+ <AdminSidebarCategory
+ parentLink='/admin_console'
+ icon='fa-gear'
+ title={
+ <FormattedMessage
+ id='admin.sidebar.reports'
+ defaultMessage='SITE REPORTS'
+ />
+ }
+ >
+ <AdminSidebarSection
+ name='system_analytics'
+ title={
+ <FormattedMessage
+ id='admin.sidebar.view_statistics'
+ defaultMessage='View Statistics'
+ />
+ }
+ />
+ </AdminSidebarCategory>
+ <AdminSidebarCategory
+ parentLink='/admin_console'
+ icon='fa-gear'
+ title={
+ <FormattedMessage
+ id='admin.sidebar.settings'
+ defaultMessage='SETTINGS'
+ />
+ }
+ >
+ <AdminSidebarSection
+ name='general'
+ title={
+ <FormattedMessage
+ id='admin.sidebar.general'
+ defaultMessage='General'
+ />
+ }
+ >
+ <AdminSidebarSection
+ name='configuration'
+ title={
<FormattedMessage
- id='admin.sidebar.view_statistics'
- defaultMessage='View Statistics'
+ id='admin.sidebar.configuration'
+ defaultMessage='Configuration'
/>
- </a>
- </li>
- </ul>
- <ul className='nav nav__sub-menu'>
- <li>
- <h4>
- <span className='icon fa fa-gear'></span>
- <span>
- <FormattedMessage
- id='admin.sidebar.settings'
- defaultMessage='SETTINGS'
- />
- </span>
- </h4>
- </li>
- </ul>
- <ul className='nav nav__sub-menu padded'>
- <li>
- <a
- href='#'
- className={this.isSelected('service_settings')}
- onClick={this.handleClick.bind(this, 'service_settings', null)}
- >
+ }
+ />
+ <AdminSidebarSection
+ name='users_and_teams'
+ title={
<FormattedMessage
- id='admin.sidebar.service'
- defaultMessage='Service Settings'
+ id='admin.sidebar.usersAndTeams'
+ defaultMessage='Users and Teams'
/>
- </a>
- </li>
- <li>
- <a
- href='#'
- className={this.isSelected('team_settings')}
- onClick={this.handleClick.bind(this, 'team_settings', null)}
- >
+ }
+ />
+ <AdminSidebarSection
+ name='privacy'
+ title={
<FormattedMessage
- id='admin.sidebar.team'
- defaultMessage='Team Settings'
+ id='admin.sidebar.privacy'
+ defaultMessage='Privacy'
/>
- </a>
- </li>
- <li>
- <a
- href='#'
- className={this.isSelected('sql_settings')}
- onClick={this.handleClick.bind(this, 'sql_settings', null)}
- >
+ }
+ />
+ <AdminSidebarSection
+ name='logging'
+ title={
<FormattedMessage
- id='admin.sidebar.sql'
- defaultMessage='SQL Settings'
+ id='admin.sidebar.logging'
+ defaultMessage='Logging'
/>
- </a>
- </li>
- <li>
- <a
- href='#'
- className={this.isSelected('email_settings')}
- onClick={this.handleClick.bind(this, 'email_settings', null)}
- >
+ }
+ />
+ </AdminSidebarSection>
+ <AdminSidebarSection
+ name='authentication'
+ title={
+ <FormattedMessage
+ id='admin.sidebar.authentication'
+ defaultMessage='Authentication'
+ />
+ }
+ >
+ <AdminSidebarSection
+ name='email'
+ title={
<FormattedMessage
id='admin.sidebar.email'
- defaultMessage='Email Settings'
+ defaultMessage='Email'
/>
- </a>
- </li>
- <li>
- <a
- href='#'
- className={this.isSelected('image_settings')}
- onClick={this.handleClick.bind(this, 'image_settings', null)}
- >
+ }
+ />
+ <AdminSidebarSection
+ name='gitlab'
+ title={
<FormattedMessage
- id='admin.sidebar.file'
- defaultMessage='File Settings'
+ id='admin.sidebar.gitlab'
+ defaultMessage='GitLab'
/>
- </a>
- </li>
- <li>
- <a
- href='#'
- className={this.isSelected('log_settings')}
- onClick={this.handleClick.bind(this, 'log_settings', null)}
- >
+ }
+ />
+ {ldapSettings}
+ </AdminSidebarSection>
+ <AdminSidebarSection
+ name='security'
+ title={
+ <FormattedMessage
+ id='admin.sidebar.security'
+ defaultMessage='Security'
+ />
+ }
+ >
+ <AdminSidebarSection
+ name='sign_up'
+ title={
<FormattedMessage
- id='admin.sidebar.log'
- defaultMessage='Log Settings'
+ id='admin.sidebar.signUp'
+ defaultMessage='Sign Up'
/>
- </a>
- </li>
- <li>
- <a
- href='#'
- className={this.isSelected('rate_settings')}
- onClick={this.handleClick.bind(this, 'rate_settings', null)}
- >
+ }
+ />
+ <AdminSidebarSection
+ name='login'
+ title={
<FormattedMessage
- id='admin.sidebar.rate_limit'
- defaultMessage='Rate Limit Settings'
+ id='admin.sidebar.login'
+ defaultMessage='Login'
/>
- </a>
- </li>
- <li>
- <a
- href='#'
- className={this.isSelected('privacy_settings')}
- onClick={this.handleClick.bind(this, 'privacy_settings', null)}
- >
+ }
+ />
+ <AdminSidebarSection
+ name='public_links'
+ title={
<FormattedMessage
- id='admin.sidebar.privacy'
- defaultMessage='Privacy Settings'
+ id='admin.sidebar.publicLinks'
+ defaultMessage='Public Links'
/>
- </a>
- </li>
- <li>
- <a
- href='#'
- className={this.isSelected('gitlab_settings')}
- onClick={this.handleClick.bind(this, 'gitlab_settings', null)}
- >
+ }
+ />
+ <AdminSidebarSection
+ name='sessions'
+ title={
<FormattedMessage
- id='admin.sidebar.gitlab'
- defaultMessage='GitLab Settings'
+ id='admin.sidebar.sessions'
+ defaultMessage='Sessions'
/>
- </a>
- </li>
- {ldapSettings}
- {complianceSettings}
- <li>
- <a
- href='#'
- className={this.isSelected('legal_and_support_settings')}
- onClick={this.handleClick.bind(this, 'legal_and_support_settings', null)}
- >
+ }
+ />
+ <AdminSidebarSection
+ name='connections'
+ title={
<FormattedMessage
- id='admin.sidebar.support'
- defaultMessage='Legal and Support Settings'
+ id='admin.sidebar.connections'
+ defaultMessage='Connections'
/>
- </a>
- </li>
- </ul>
- <ul className='nav nav__sub-menu'>
- <li>
- <h4>
- <span className='icon fa fa-gear'></span>
- <span>
- <FormattedMessage
- id='admin.sidebar.teams'
- defaultMessage='TEAMS ({count})'
- values={{
- count: count
- }}
- />
- </span>
- <span className='menu-icon--right'>
- <OverlayTrigger
- delayShow={1000}
- placement='top'
- overlay={addTeamTooltip}
- >
- <a
- href='#'
- onClick={this.showTeamSelect}
- >
- <i
- className='fa fa-plus'
- ></i>
- </a>
- </OverlayTrigger>
- </span>
- </h4>
- </li>
- </ul>
- <ul className='nav nav__sub-menu padded'>
- <li>
- {teams}
- </li>
- </ul>
- <ul className='nav nav__sub-menu'>
- <li>
- <h4>
- <span className='icon fa fa-gear'></span>
- <span>
- <FormattedMessage
- id='admin.sidebar.other'
- defaultMessage='OTHER'
- />
- </span>
- </h4>
- </li>
- </ul>
- <ul className='nav nav__sub-menu padded'>
- {licenseSettings}
- {audits}
- <li>
- <a
- href='#'
- className={this.isSelected('logs')}
- onClick={this.handleClick.bind(this, 'logs', null)}
- >
+ }
+ />
+ </AdminSidebarSection>
+ <AdminSidebarSection
+ name='notifications'
+ title={
+ <FormattedMessage
+ id='admin.sidebar.notifications'
+ defaultMessage='Notifications'
+ />
+ }
+ >
+ <AdminSidebarSection
+ name='email'
+ title={
+ <FormattedMessage
+ id='admin.sidebar.email'
+ defaultMessage='Email'
+ />
+ }
+ />
+ <AdminSidebarSection
+ name='push'
+ title={
+ <FormattedMessage
+ id='admin.sidebar.push'
+ defaultMessage='Mobile Push'
+ />
+ }
+ />
+ </AdminSidebarSection>
+ <AdminSidebarSection
+ name='integrations'
+ title={
+ <FormattedMessage
+ id='admin.sidebar.integrations'
+ defaultMessage='Integrations'
+ />
+ }
+ >
+ <AdminSidebarSection
+ name='webhooks'
+ title={
+ <FormattedMessage
+ id='admin.sidebar.webhooks'
+ defaultMessage='Webhooks and Commands'
+ />
+ }
+ />
+ <AdminSidebarSection
+ name='external'
+ title={
+ <FormattedMessage
+ id='admin.sidebar.external'
+ defaultMessage='External Services'
+ />
+ }
+ />
+ </AdminSidebarSection>
+ <AdminSidebarSection
+ name='database'
+ title={
+ <FormattedMessage
+ id='admin.sidebar.database'
+ defaultMessage='Database'
+ />
+ }
+ />
+ <AdminSidebarSection
+ name='files'
+ title={
+ <FormattedMessage
+ id='admin.sidebar.files'
+ defaultMessage='Files'
+ />
+ }
+ >
+ <AdminSidebarSection
+ name='storage'
+ title={
<FormattedMessage
- id='admin.sidebar.logs'
- defaultMessage='Logs'
+ id='admin.sidebar.storage'
+ defaultMessage='Storage'
/>
- </a>
- </li>
- </ul>
- </li>
+ }
+ />
+ <AdminSidebarSection
+ name='images'
+ title={
+ <FormattedMessage
+ id='admin.sidebar.images'
+ defaultMessage='Images'
+ />
+ }
+ />
+ </AdminSidebarSection>
+ <AdminSidebarSection
+ name='customization'
+ title={
+ <FormattedMessage
+ id='admin.sidebar.customization'
+ defaultMessage='Customization'
+ />
+ }
+ >
+ <AdminSidebarSection
+ name='custom_brand'
+ title={
+ <FormattedMessage
+ id='admin.sidebar.customBrand'
+ defaultMessage='Custom Branding'
+ />
+
+ }
+ />
+ <AdminSidebarSection
+ name='legal_and_support'
+ title={
+ <FormattedMessage
+ id='admin.sidebar.legalAndSupport'
+ defaultMessage='Legal and Support'
+ />
+ }
+ />
+ </AdminSidebarSection>
+ {complianceSettings}
+ <AdminSidebarSection
+ name='rate'
+ title={
+ <FormattedMessage
+ id='admin.sidebar.rate'
+ defaultMessage='Rate Limiting'
+ />
+ }
+ />
+ <AdminSidebarSection
+ name='developer'
+ title={
+ <FormattedMessage
+ id='admin.sidebar.developer'
+ defaultMessage='Developer'
+ />
+ }
+ />
+ </AdminSidebarCategory>
+ {this.renderTeams()}
+ <AdminSidebarCategory
+ parentLink='/admin_console'
+ icon='fa-gear'
+ title={
+ <FormattedMessage
+ id='admin.sidebar.other'
+ defaultMessage='OTHER'
+ />
+ }
+ >
+ {license}
+ {audits}
+ <AdminSidebarSection
+ name='logs'
+ title={
+ <FormattedMessage
+ id='admin.sidebar.logs'
+ defaultMessage='Logs'
+ />
+ }
+ />
+ </AdminSidebarCategory>
</ul>
</div>
-
<SelectTeamModal
- teams={this.props.teams}
+ teams={this.state.teams}
show={this.state.showSelectModal}
onModalSubmit={this.teamSelectedModal}
onModalDismissed={this.teamSelectedModalDismissed}
@@ -503,13 +581,3 @@ export default class AdminSidebar extends React.Component {
);
}
}
-
-AdminSidebar.propTypes = {
- teams: React.PropTypes.object,
- selectedTeams: React.PropTypes.object,
- removeSelectedTeam: React.PropTypes.func,
- addSelectedTeam: React.PropTypes.func,
- selected: React.PropTypes.string,
- selectedTeam: React.PropTypes.string,
- selectTab: React.PropTypes.func
-};