// Copyright (c) 2016 Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
import LineChart from './line_chart.jsx';
import DoughnutChart from './doughnut_chart.jsx';
import StatisticCount from './statistic_count.jsx';
import AnalyticsStore from 'stores/analytics_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 {injectIntl, intlShape, defineMessages, FormattedMessage} from 'react-intl';
const holders = defineMessages({
analyticsPublicChannels: {
id: 'analytics.system.publicChannels',
defaultMessage: 'Public Channels'
},
analyticsPrivateGroups: {
id: 'analytics.system.privateGroups',
defaultMessage: 'Private Groups'
},
analyticsFilePosts: {
id: 'analytics.system.totalFilePosts',
defaultMessage: 'Posts with Files'
},
analyticsHashtagPosts: {
id: 'analytics.system.totalHashtagPosts',
defaultMessage: 'Posts with Hashtags'
},
analyticsTextPosts: {
id: 'analytics.system.textPosts',
defaultMessage: 'Posts with Text-only'
}
});
import React from 'react';
class SystemAnalytics extends React.Component {
constructor(props) {
super(props);
this.onChange = this.onChange.bind(this);
this.state = {stats: AnalyticsStore.getAllSystem()};
}
componentDidMount() {
AnalyticsStore.addChangeListener(this.onChange);
AsyncClient.getStandardAnalytics();
AsyncClient.getPostsPerDayAnalytics();
AsyncClient.getUsersPerDayAnalytics();
if (global.window.mm_license.IsLicensed === 'true') {
AsyncClient.getAdvancedAnalytics();
}
}
componentWillUnmount() {
AnalyticsStore.removeChangeListener(this.onChange);
}
shouldComponentUpdate(nextProps, nextState) {
if (!Utils.areObjectsEqual(nextState.stats, this.state.stats)) {
return true;
}
return false;
}
onChange() {
this.setState({stats: AnalyticsStore.getAllSystem()});
}
render() {
const stats = this.state.stats;
let advancedCounts;
let advancedGraphs;
if (global.window.mm_license.IsLicensed === 'true') {
advancedCounts = (
}
icon='fa-signal'
count={stats[StatTypes.TOTAL_SESSIONS]}
/>
}
icon='fa-terminal'
count={stats[StatTypes.TOTAL_COMMANDS]}
/>
}
icon='fa-arrow-down'
count={stats[StatTypes.TOTAL_IHOOKS]}
/>
}
icon='fa-arrow-up'
count={stats[StatTypes.TOTAL_OHOOKS]}
/>
);
const channelTypeData = formatChannelDoughtnutData(stats[StatTypes.TOTAL_PUBLIC_CHANNELS], stats[StatTypes.TOTAL_PRIVATE_GROUPS], this.props.intl);
const postTypeData = formatPostDoughtnutData(stats[StatTypes.TOTAL_FILE_POSTS], stats[StatTypes.TOTAL_HASHTAG_POSTS], stats[StatTypes.TOTAL_POSTS], this.props.intl);
advancedGraphs = (
}
data={channelTypeData}
width='300'
height='225'
/>
}
data={postTypeData}
width='300'
height='225'
/>
);
}
const postCountsDay = formatPostsPerDayData(stats[StatTypes.POST_PER_DAY]);
const userCountsWithPostsDay = formatUsersWithPostsPerDayData(stats[StatTypes.USERS_WITH_POSTS_PER_DAY]);
return (
}
icon='fa-user'
count={stats[StatTypes.TOTAL_USERS]}
/>
}
icon='fa-users'
count={stats[StatTypes.TOTAL_TEAMS]}
/>
}
icon='fa-comment'
count={stats[StatTypes.TOTAL_POSTS]}
/>
}
icon='fa-globe'
count={stats[StatTypes.TOTAL_PUBLIC_CHANNELS] + stats[StatTypes.TOTAL_PRIVATE_GROUPS]}
/>
{advancedCounts}
{advancedGraphs}
}
data={postCountsDay}
width='740'
height='225'
/>
}
data={userCountsWithPostsDay}
width='740'
height='225'
/>
);
}
}
SystemAnalytics.propTypes = {
intl: intlShape.isRequired,
team: React.PropTypes.object
};
export default injectIntl(SystemAnalytics);
export function formatChannelDoughtnutData(totalPublic, totalPrivate, intl) {
const {formatMessage} = intl;
const channelTypeData = [
{
value: totalPublic,
color: '#46BFBD',
highlight: '#5AD3D1',
label: formatMessage(holders.analyticsPublicChannels)
},
{
value: totalPrivate,
color: '#FDB45C',
highlight: '#FFC870',
label: formatMessage(holders.analyticsPrivateGroups)
}
];
return channelTypeData;
}
export function formatPostDoughtnutData(filePosts, hashtagPosts, totalPosts, intl) {
const {formatMessage} = intl;
const postTypeData = [
{
value: filePosts,
color: '#46BFBD',
highlight: '#5AD3D1',
label: formatMessage(holders.analyticsFilePosts)
},
{
value: hashtagPosts,
color: '#F7464A',
highlight: '#FF5A5E',
label: formatMessage(holders.analyticsHashtagPosts)
},
{
value: totalPosts - filePosts - hashtagPosts,
color: '#FDB45C',
highlight: '#FFC870',
label: formatMessage(holders.analyticsTextPosts)
}
];
return postTypeData;
}
export function formatPostsPerDayData(data) {
var chartData = {
labels: [],
datasets: [{
fillColor: 'rgba(151,187,205,0.2)',
strokeColor: 'rgba(151,187,205,1)',
pointColor: 'rgba(151,187,205,1)',
pointStrokeColor: '#fff',
pointHighlightFill: '#fff',
pointHighlightStroke: 'rgba(151,187,205,1)',
data: []
}]
};
for (var index in data) {
if (data[index]) {
var row = data[index];
chartData.labels.push(row.name);
chartData.datasets[0].data.push(row.value);
}
}
return chartData;
}
export function formatUsersWithPostsPerDayData(data) {
var chartData = {
labels: [],
datasets: [{
fillColor: 'rgba(151,187,205,0.2)',
strokeColor: 'rgba(151,187,205,1)',
pointColor: 'rgba(151,187,205,1)',
pointStrokeColor: '#fff',
pointHighlightFill: '#fff',
pointHighlightStroke: 'rgba(151,187,205,1)',
data: []
}]
};
for (var index in data) {
if (data[index]) {
var row = data[index];
chartData.labels.push(row.name);
chartData.datasets[0].data.push(row.value);
}
}
return chartData;
}