diff options
author | Harrison Healey <harrisonmhealey@gmail.com> | 2017-03-30 12:46:47 -0400 |
---|---|---|
committer | Corey Hulen <corey@hulen.com> | 2017-03-30 09:46:47 -0700 |
commit | 689cac535e45c47a4f603b236dc129dd456efcc9 (patch) | |
tree | 767ef80b310d6d073840bd5216da38c439f6e193 /webapp/components/analytics/team_analytics.jsx | |
parent | 9a9729f22fea7275637eafb4046900c9f372ec56 (diff) | |
download | chat-689cac535e45c47a4f603b236dc129dd456efcc9.tar.gz chat-689cac535e45c47a4f603b236dc129dd456efcc9.tar.bz2 chat-689cac535e45c47a4f603b236dc129dd456efcc9.zip |
PLT-2713/PLT-6028 Added System Users list to System Console (#5882)
* PLT-2713 Added ability for admins to list users not in any team
* Updated style of unit test
* Split SearchableUserList to give better control over its properties
* Added users without any teams to the user store
* Added ManageUsers page
* Renamed ManageUsers to SystemUsers
* Added ability to search by user id in SystemUsers page
* Added SystemUsersDropdown
* Removed unnecessary injectIntl
* Created TeamUtils
* Reduced scope of system console heading CSS
* Added team filter to TeamAnalytics page
* Updated admin console sidebar
* Removed unnecessary TODO
* Removed unused reference to deleted modal
* Fixed system console sidebar not scrolling on first load
* Fixed TeamAnalytics page not rendering on first load
* Fixed chart.js throwing an error when switching between teams
* Changed TeamAnalytics header to show the team's display name
* Fixed appearance of TeamAnalytics and SystemUsers on small screen widths
* Fixed placement of 'No users found' message
* Fixed teams not appearing in SystemUsers on first load
* Updated user count text for SystemUsers
* Changed search by id fallback to trigger less often
* Fixed SystemUsers list items not updating when searching
* Fixed localization strings for SystemUsers page
Diffstat (limited to 'webapp/components/analytics/team_analytics.jsx')
-rw-r--r-- | webapp/components/analytics/team_analytics.jsx | 151 |
1 files changed, 106 insertions, 45 deletions
diff --git a/webapp/components/analytics/team_analytics.jsx b/webapp/components/analytics/team_analytics.jsx index 66eb7e2db..135bab4b4 100644 --- a/webapp/components/analytics/team_analytics.jsx +++ b/webapp/components/analytics/team_analytics.jsx @@ -1,40 +1,43 @@ // Copyright (c) 2016 Mattermost, Inc. All Rights Reserved. // See License.txt for license information. +import React from 'react'; +import {FormattedDate, FormattedMessage, FormattedHTMLMessage} from 'react-intl'; + import Banner from 'components/admin_console/banner.jsx'; -import LineChart from './line_chart.jsx'; -import StatisticCount from './statistic_count.jsx'; -import TableChart from './table_chart.jsx'; +import LoadingScreen from 'components/loading_screen.jsx'; import AdminStore from 'stores/admin_store.jsx'; import AnalyticsStore from 'stores/analytics_store.jsx'; +import BrowserStore from 'stores/browser_store.jsx'; -import * as Utils from 'utils/utils.jsx'; import * as AsyncClient from 'utils/async_client.jsx'; -import Constants from 'utils/constants.jsx'; -const StatTypes = Constants.StatTypes; +import {StatTypes} from 'utils/constants.jsx'; +import {convertTeamMapToList} from 'utils/team_utils.jsx'; +import LineChart from './line_chart.jsx'; +import StatisticCount from './statistic_count.jsx'; +import TableChart from './table_chart.jsx'; import {formatPostsPerDayData, formatUsersWithPostsPerDayData} from './system_analytics.jsx'; -import {FormattedMessage, FormattedDate, FormattedHTMLMessage} from 'react-intl'; -import React from 'react'; +const LAST_ANALYTICS_TEAM = 'last_analytics_team'; export default class TeamAnalytics extends React.Component { - static get propTypes() { - return { - params: React.PropTypes.object.isRequired - }; - } - constructor(props) { super(props); this.onChange = this.onChange.bind(this); this.onAllTeamsChange = this.onAllTeamsChange.bind(this); + this.handleTeamChange = this.handleTeamChange.bind(this); + + const teams = convertTeamMapToList(AdminStore.getAllTeams()); + const teamId = BrowserStore.getGlobalItem(LAST_ANALYTICS_TEAM, teams.length > 0 ? teams[0].id : ''); this.state = { - team: AdminStore.getTeam(this.props.params.team), - stats: AnalyticsStore.getAllTeam(this.props.params.team) + teams, + teamId, + team: AdminStore.getTeam(teamId), + stats: AnalyticsStore.getAllTeam(teamId) }; } @@ -42,7 +45,19 @@ export default class TeamAnalytics extends React.Component { AnalyticsStore.addChangeListener(this.onChange); AdminStore.addAllTeamsChangeListener(this.onAllTeamsChange); - this.getData(this.props.params.team); + if (this.state.teamId !== '') { + this.getData(this.state.teamId); + } + + if (this.state.teams.length === 0) { + AsyncClient.getAllTeams(); + } + } + + componentWillUpdate(nextProps, nextState) { + if (nextState.teamId !== this.state.teamId) { + this.getData(nextState.teamId); + } } getData(id) { @@ -57,40 +72,60 @@ export default class TeamAnalytics extends React.Component { AdminStore.removeAllTeamsChangeListener(this.onAllTeamsChange); } - componentWillReceiveProps(nextProps) { - this.getData(nextProps.params.team); + onChange() { this.setState({ - stats: AnalyticsStore.getAllTeam(nextProps.params.team) + stats: AnalyticsStore.getAllTeam(this.state.teamId) }); } - shouldComponentUpdate(nextProps, nextState) { - if (!Utils.areObjectsEqual(nextState.stats, this.state.stats)) { - return true; - } - - if (!Utils.areObjectsEqual(nextProps.params.team, this.props.params.team)) { - return true; + onAllTeamsChange() { + const teams = convertTeamMapToList(AdminStore.getAllTeams()); + + if (teams.length > 0) { + if (this.state.teamId) { + this.setState({ + team: AdminStore.getTeam(this.state.teamId) + }); + } else { + this.setState({ + teamId: teams[0].id, + team: teams[0] + }); + } } - return false; - } - - onChange() { this.setState({ - stats: AnalyticsStore.getAllTeam(this.props.params.team) + teams }); } - onAllTeamsChange() { + handleTeamChange(e) { + const teamId = e.target.value; + this.setState({ - team: AdminStore.getTeam(this.props.params.team) + teamId, + team: AdminStore.getTeam(teamId) }); + + BrowserStore.setGlobalItem(LAST_ANALYTICS_TEAM, teamId); } render() { - if (!this.state.team || !this.state.stats) { - return null; + if (this.state.teams.length === 0 || !this.state.team || !this.state.stats) { + return <LoadingScreen/>; + } + + if (this.state.teamId === '') { + return ( + <Banner + description={ + <FormattedMessage + id='analytics.team.noTeams' + defaultMessage='There are no teams on this server for which to view statistics.' + /> + } + /> + ); } const stats = this.state.stats; @@ -129,6 +164,7 @@ export default class TeamAnalytics extends React.Component { postTotalGraph = ( <div className='row'> <LineChart + key={this.state.team.id} title={ <FormattedMessage id='analytics.team.totalPosts' @@ -150,6 +186,7 @@ export default class TeamAnalytics extends React.Component { userActiveGraph = ( <div className='row'> <LineChart + key={this.state.team.id} title={ <FormattedMessage id='analytics.team.activeUsers' @@ -172,17 +209,41 @@ export default class TeamAnalytics extends React.Component { const recentActiveUsers = formatRecentUsersData(stats[StatTypes.RECENTLY_ACTIVE_USERS]); const newlyCreatedUsers = formatNewUsersData(stats[StatTypes.NEWLY_CREATED_USERS]); + const teams = this.state.teams.map((team) => { + return ( + <option + key={team.id} + value={team.id} + > + {team.display_name} + </option> + ); + }); + return ( <div className='wrapper--fixed team_statistics'> - <h3> - <FormattedMessage - id='analytics.team.title' - defaultMessage='Team Statistics for {team}' - values={{ - team: this.state.team.name - }} - /> - </h3> + <div className='admin-console-header team-statistics__header-row'> + <div className='team-statistics__header'> + <h3> + <FormattedMessage + id='analytics.team.title' + defaultMessage='Team Statistics for {team}' + values={{ + team: this.state.team.display_name + }} + /> + </h3> + </div> + <div className='team-statistics__team-filter'> + <select + className='form-control team-statistics__team-filter__dropdown' + onChange={this.handleTeamChange} + value={this.state.teamId} + > + {teams} + </select> + </div> + </div> {banner} <div className='row'> <StatisticCount |