diff --git a/web/react/components/admin_console/admin_controller.jsx b/web/react/components/admin_console/admin_controller.jsx index 7593e50a48..e82fe1b767 100644 --- a/web/react/components/admin_console/admin_controller.jsx +++ b/web/react/components/admin_console/admin_controller.jsx @@ -1,14 +1,12 @@ // Copyright (c) 2015 Spinpunch, Inc. All Rights Reserved. // See License.txt for license information. -var Navbar = require('../../components/navbar.jsx'); var AdminSidebar = require('./admin_sidebar.jsx'); var AdminStore = require('../../stores/admin_store.jsx'); var AsyncClient = require('../../utils/async_client.jsx'); var LoadingScreen = require('../loading_screen.jsx'); var EmailSettingsTab = require('./email_settings.jsx'); -var JobsSettingsTab = require('./jobs_settings.jsx'); var LogSettingsTab = require('./log_settings.jsx'); var LogsTab = require('./logs.jsx'); @@ -51,12 +49,10 @@ export default class AdminController extends React.Component { if (this.state.config != null) { if (this.state.selected === 'email_settings') { tab = ; - } else if (this.state.selected === 'job_settings') { - tab = ; - } else if (this.state.selected === 'logs') { - tab = ; } else if (this.state.selected === 'log_settings') { tab = ; + } else if (this.state.selected === 'logs') { + tab = ; } } @@ -72,7 +68,6 @@ export default class AdminController extends React.Component { />
-
{ + this.blockToggle = true; + setTimeout(() => { + this.blockToggle = false; + }, 100); + }); + } + + componentWillUnmount() { + $(React.findDOMNode(this.refs.dropdown)).off('hide.bs.dropdown'); + } + + render() { + return ( + + ); + } +} \ No newline at end of file diff --git a/web/react/components/admin_console/admin_sidebar.jsx b/web/react/components/admin_console/admin_sidebar.jsx index 855da398b5..a6e689490e 100644 --- a/web/react/components/admin_console/admin_sidebar.jsx +++ b/web/react/components/admin_console/admin_sidebar.jsx @@ -1,7 +1,7 @@ // Copyright (c) 2015 Spinpunch, Inc. All Rights Reserved. // See License.txt for license information. -var SidebarHeader = require('../sidebar_header.jsx'); +var AdminSidebarHeader = require('./admin_sidebar_header.jsx'); export default class AdminSidebar extends React.Component { constructor(props) { @@ -14,7 +14,8 @@ export default class AdminSidebar extends React.Component { }; } - handleClick(name) { + handleClick(name, e) { + e.preventDefault(); this.props.selectTab(name); } @@ -27,46 +28,13 @@ export default class AdminSidebar extends React.Component { } componentDidMount() { - // $('.nav__menu-item').on('click', function clickme(e) { - // e.preventDefault(); - // $(this).closest('.sidebar--collapsable').find('.nav__menu-item').removeClass('active'); - // $(this).addClass('active'); - // $(this).closest('.sidebar--collapsable').find('.nav__sub-menu').addClass('hide'); - // $(this).next('.nav__sub-menu').removeClass('hide'); - // }); - - // $('.nav__sub-menu a').on('click', function clickme(e) { - // e.preventDefault(); - // $(this).closest('.nav__sub-menu').find('a').removeClass('active'); - // $(this).addClass('active'); - // }); - - // $('.nav__sub-menu-item').on('click', function clickme(e) { - // e.preventDefault(); - // $(this).closest('.sidebar--collapsable').find('.nav__inner-menu').addClass('hide'); - // $(this).closest('li').next('li').find('.nav__inner-menu').removeClass('hide'); - // $(this).closest('li').next('li').find('.nav__inner-menu li:first a').addClass('active'); - // }); - - // $('.nav__inner-menu a').on('click', function clickme() { - // $(this).closest('.nav__inner-menu').closest('li').prev('li').find('a').addClass('active'); - // }); - - // $('.nav__sub-menu .menu__close').on('click', function close() { - // var menuItem = $(this).closest('li'); - // menuItem.next('li').remove(); - // menuItem.remove(); - // }); } render() { return (
- + diff --git a/web/react/components/admin_console/admin_sidebar_header.jsx b/web/react/components/admin_console/admin_sidebar_header.jsx index 959411f1ea..81798da455 100644 --- a/web/react/components/admin_console/admin_sidebar_header.jsx +++ b/web/react/components/admin_console/admin_sidebar_header.jsx @@ -1,8 +1,8 @@ // Copyright (c) 2015 Spinpunch, Inc. All Rights Reserved. // See License.txt for license information. -var NavbarDropdown = require('./navbar_dropdown.jsx'); -var UserStore = require('../stores/user_store.jsx'); +var AdminNavbarDropdown = require('./admin_navbar_dropdown.jsx'); +var UserStore = require('../../stores/user_store.jsx'); export default class SidebarHeader extends React.Component { constructor(props) { @@ -12,13 +12,18 @@ export default class SidebarHeader extends React.Component { this.state = {}; } - toggleDropdown() { + + toggleDropdown(e) { + e.preventDefault(); + if (this.refs.dropdown.blockToggle) { this.refs.dropdown.blockToggle = false; return; } + $('.team__header').find('.dropdown-toggle').dropdown('toggle'); } + render() { var me = UserStore.getCurrentUser(); var profilePicture = null; @@ -45,23 +50,11 @@ export default class SidebarHeader extends React.Component { {profilePicture}
{'@' + me.username}
-
{this.props.teamDisplayName}
+
{'System Console'}
- +
); } -} - -SidebarHeader.defaultProps = { - teamDisplayName: global.window.config.SiteName, - teamType: '' -}; -SidebarHeader.propTypes = { - teamDisplayName: React.PropTypes.string, - teamType: React.PropTypes.string -}; +} \ No newline at end of file diff --git a/web/react/components/admin_console/jobs_settings.jsx b/web/react/components/admin_console/jobs_settings.jsx deleted file mode 100644 index 0b4fc41855..0000000000 --- a/web/react/components/admin_console/jobs_settings.jsx +++ /dev/null @@ -1,183 +0,0 @@ -// Copyright (c) 2015 Spinpunch, Inc. All Rights Reserved. -// See License.txt for license information. - -export default class Jobs extends React.Component { - constructor(props) { - super(props); - - this.state = { - }; - } - - render() { - return ( -
-

{' ************** JOB Settings'}

-
-
- -
- - -

{'This is some sample help text for the Bypass Email field'}

-
-
-
- -
- -
-
{' This is some error text for the Bypass Email field'}
-
-

{'This is some sample help text for the SMTP username field'}

-
-
-
-
- -
-
-
- -
- -

{'This is some sample help text for the Apple push server field'}

-
-
-
- -
- -
-
-
- -
- -
-
-
-
-
-
- -
-
- -
-
-
-
- ); - } -} \ No newline at end of file diff --git a/web/react/components/channel_header.jsx b/web/react/components/channel_header.jsx index 0dbbc20d4c..8d23ec6463 100644 --- a/web/react/components/channel_header.jsx +++ b/web/react/components/channel_header.jsx @@ -111,7 +111,7 @@ export default class ChannelHeader extends React.Component { const popoverContent = React.renderToString(); let channelTitle = channel.display_name; const currentId = UserStore.getCurrentId(); - const isAdmin = this.state.memberChannel.roles.indexOf('admin') > -1 || this.state.memberTeam.roles.indexOf('admin') > -1; + const isAdmin = Utils.isAdmin(this.state.memberChannel.roles) || Utils.isAdmin(this.state.memberTeam.roles); const isDirect = (this.state.channel.type === 'D'); if (isDirect) { diff --git a/web/react/components/channel_invite_modal.jsx b/web/react/components/channel_invite_modal.jsx index 5feeb4e889..82fc511843 100644 --- a/web/react/components/channel_invite_modal.jsx +++ b/web/react/components/channel_invite_modal.jsx @@ -121,7 +121,7 @@ export default class ChannelInviteModal extends React.Component { var currentMember = ChannelStore.getCurrentMember(); var isAdmin = false; if (currentMember) { - isAdmin = currentMember.roles.indexOf('admin') > -1 || UserStore.getCurrentUser().roles.indexOf('admin') > -1; + isAdmin = utils.isAdmin(currentMember.roles) || utils.isAdmin(UserStore.getCurrentUser().roles); } var content; diff --git a/web/react/components/channel_members.jsx b/web/react/components/channel_members.jsx index 04fa2c7a21..1eda6a1042 100644 --- a/web/react/components/channel_members.jsx +++ b/web/react/components/channel_members.jsx @@ -130,7 +130,7 @@ export default class ChannelMembers extends React.Component { const currentMember = ChannelStore.getCurrentMember(); let isAdmin = false; if (currentMember) { - isAdmin = currentMember.roles.indexOf('admin') > -1 || UserStore.getCurrentUser().roles.indexOf('admin') > -1; + isAdmin = Utils.isAdmin(currentMember.roles) || Utils.isAdmin(UserStore.getCurrentUser().roles); } var memberList = null; diff --git a/web/react/components/member_list_item.jsx b/web/react/components/member_list_item.jsx index 9a31a2e30d..158ff65beb 100644 --- a/web/react/components/member_list_item.jsx +++ b/web/react/components/member_list_item.jsx @@ -2,6 +2,7 @@ // See License.txt for license information. var UserStore = require('../stores/user_store.jsx'); +const Utils = require('../utils/utils.jsx'); export default class MemberListItem extends React.Component { constructor(props) { @@ -26,7 +27,7 @@ export default class MemberListItem extends React.Component { render() { var member = this.props.member; var isAdmin = this.props.isAdmin; - var isMemberAdmin = member.roles.indexOf('admin') > -1; + var isMemberAdmin = Utils.isAdmin(member.roles); var timestamp = UserStore.getCurrentUser().update_at; var invite; diff --git a/web/react/components/navbar.jsx b/web/react/components/navbar.jsx index cae9f12e40..da9874b0b1 100644 --- a/web/react/components/navbar.jsx +++ b/web/react/components/navbar.jsx @@ -8,6 +8,7 @@ var ChannelStore = require('../stores/channel_store.jsx'); var TeamStore = require('../stores/team_store.jsx'); var MessageWrapper = require('./message_wrapper.jsx'); var NotifyCounts = require('./notify_counts.jsx'); +const Utils = require('../utils/utils.jsx'); var Constants = require('../utils/constants.jsx'); var ActionTypes = Constants.ActionTypes; @@ -335,7 +336,7 @@ export default class Navbar extends React.Component { options={{singleline: true, mentionHighlight: false}} /> ); - isAdmin = this.state.member.roles.indexOf('admin') > -1; + isAdmin = Utils.isAdmin(this.state.member.roles); if (channel.type === 'O') { channelTitle = channel.display_name; diff --git a/web/react/components/navbar_dropdown.jsx b/web/react/components/navbar_dropdown.jsx index b7566cfb9d..65f741e4b2 100644 --- a/web/react/components/navbar_dropdown.jsx +++ b/web/react/components/navbar_dropdown.jsx @@ -30,12 +30,12 @@ export default class NavbarDropdown extends React.Component { UserStore.addTeamsChangeListener(this.onListenerChange); TeamStore.addChangeListener(this.onListenerChange); - $(React.findDOMNode(this.refs.dropdown)).on('hide.bs.dropdown', function resetDropdown() { + $(React.findDOMNode(this.refs.dropdown)).on('hide.bs.dropdown', () => { this.blockToggle = true; - setTimeout(function blockTimeout() { + setTimeout(() => { this.blockToggle = false; - }.bind(this), 100); - }.bind(this)); + }, 100); + }); } componentWillUnmount() { UserStore.removeTeamsChangeListener(this.onListenerChange); @@ -53,12 +53,16 @@ export default class NavbarDropdown extends React.Component { var teamLink = ''; var inviteLink = ''; var manageLink = ''; + var sysAdminLink = ''; + var adminDivider = ''; var currentUser = UserStore.getCurrentUser(); var isAdmin = false; + var isSystemAdmin = false; var teamSettings = null; if (currentUser != null) { - isAdmin = currentUser.roles.indexOf('admin') > -1; + isAdmin = Utils.isAdmin(currentUser.roles); + isSystemAdmin = Utils.isInRole(currentUser.roles, 'system_admin'); inviteLink = (
  • @@ -67,7 +71,7 @@ export default class NavbarDropdown extends React.Component { data-toggle='modal' data-target='#invite_member' > - Invite New Member + {'Invite New Member'}
  • ); @@ -82,7 +86,7 @@ export default class NavbarDropdown extends React.Component { data-title='Team Invite' data-value={Utils.getWindowLocationOrigin() + '/signup_user_complete/?id=' + currentUser.team_id} > - Get Team Invite Link + {'Get Team Invite Link'} ); @@ -97,19 +101,36 @@ export default class NavbarDropdown extends React.Component { data-toggle='modal' data-target='#team_members' > - Manage Team + {'Manage Team'} + + + ); + + adminDivider = (
  • ); + + teamSettings = ( +
  • + + {'Team Settings'} + +
  • + ); + } + + if (isSystemAdmin) { + sysAdminLink = ( +
  • + + {'System Console'}
  • ); - teamSettings = (
  • - - Team Settings - -
  • ); } var teams = []; @@ -123,9 +144,9 @@ export default class NavbarDropdown extends React.Component { ); if (this.state.teams.length > 1 && this.state.currentTeam) { var curTeamName = this.state.currentTeam.name; - this.state.teams.forEach(function listTeams(teamName) { + this.state.teams.forEach((teamName) => { if (teamName !== curTeamName) { - teams.push(
  • Switch to {teamName}
  • ); + teams.push(
  • {'Switch to ' + teamName}
  • ); } }); } @@ -135,7 +156,7 @@ export default class NavbarDropdown extends React.Component { target='_blank' href={Utils.getWindowLocationOrigin() + '/signup_team'} > - Create a New Team + {'Create a New Team'} ); @@ -167,29 +188,31 @@ export default class NavbarDropdown extends React.Component { data-toggle='modal' data-target='#user_settings' > - Account Settings + {'Account Settings'} - {teamSettings} {inviteLink} {teamLink} + {adminDivider} + {teamSettings} {manageLink} + {sysAdminLink} + {teams} +
  • - Logout + {'Logout'}
  • - {teams} -
  • - Help + {'Help'}
  • @@ -197,7 +220,7 @@ export default class NavbarDropdown extends React.Component { target='_blank' href='/static/help/report_problem.html' > - Report a Problem + {'Report a Problem'}
  • diff --git a/web/react/components/post_info.jsx b/web/react/components/post_info.jsx index c80b287a38..34ac9e7599 100644 --- a/web/react/components/post_info.jsx +++ b/web/react/components/post_info.jsx @@ -20,7 +20,7 @@ export default class PostInfo extends React.Component { createDropdown() { var post = this.props.post; var isOwner = UserStore.getCurrentId() === post.user_id; - var isAdmin = UserStore.getCurrentUser().roles.indexOf('admin') > -1; + var isAdmin = utils.isAdmin(UserStore.getCurrentUser().roles); if (post.state === Constants.POST_FAILED || post.state === Constants.POST_LOADING || post.state === Constants.POST_DELETED) { return ''; diff --git a/web/react/components/post_list.jsx b/web/react/components/post_list.jsx index faa5e5f0b3..94cccaac31 100644 --- a/web/react/components/post_list.jsx +++ b/web/react/components/post_list.jsx @@ -419,7 +419,7 @@ export default class PostList extends React.Component { var members = ChannelStore.getExtraInfo(channel.id).members; for (var i = 0; i < members.length; i++) { - if (members[i].roles.indexOf('admin') > -1) { + if (utils.isAdmin(members[i].roles)) { return members[i].username; } } diff --git a/web/react/components/sidebar_header.jsx b/web/react/components/sidebar_header.jsx index 959411f1ea..072c14e0a1 100644 --- a/web/react/components/sidebar_header.jsx +++ b/web/react/components/sidebar_header.jsx @@ -12,7 +12,8 @@ export default class SidebarHeader extends React.Component { this.state = {}; } - toggleDropdown() { + toggleDropdown(e) { + e.preventDefault(); if (this.refs.dropdown.blockToggle) { this.refs.dropdown.blockToggle = false; return; diff --git a/web/react/components/sidebar_right_menu.jsx b/web/react/components/sidebar_right_menu.jsx index 5ecd502ba8..2671d560b9 100644 --- a/web/react/components/sidebar_right_menu.jsx +++ b/web/react/components/sidebar_right_menu.jsx @@ -26,7 +26,7 @@ export default class SidebarRightMenu extends React.Component { var isAdmin = false; if (currentUser != null) { - isAdmin = currentUser.roles.indexOf('admin') > -1; + isAdmin = utils.isAdmin(currentUser.roles); inviteLink = (
  • diff --git a/web/react/utils/utils.jsx b/web/react/utils/utils.jsx index 032cf4ff4e..0745914891 100644 --- a/web/react/utils/utils.jsx +++ b/web/react/utils/utils.jsx @@ -54,6 +54,29 @@ export function isTestDomain() { return false; } +export function isInRole(roles, inRole) { + var parts = roles.split(' '); + for (var i = 0; i < parts.length; i++) { + if (parts[i] === inRole) { + return true; + } + } + + return false; +} + +export function isAdmin(roles) { + if (isInRole(roles, 'admin')) { + return true; + } + + if (isInRole(roles, 'system_admin')) { + return true; + } + + return false; +} + export function getDomainWithOutSub() { var parts = window.location.host.split('.'); diff --git a/web/sass-files/sass/partials/_sidebar--left.scss b/web/sass-files/sass/partials/_sidebar--left.scss index f714a23f80..94583b153a 100644 --- a/web/sass-files/sass/partials/_sidebar--left.scss +++ b/web/sass-files/sass/partials/_sidebar--left.scss @@ -11,7 +11,7 @@ padding-top: 44px; } .dropdown-menu { - max-height: 300px; + max-height: 400px; overflow-x: hidden; overflow-y: auto; max-width: 200px;