// Copyright (c) 2016-present 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 {FormattedMessage, FormattedHTMLMessage} from 'react-intl'; import React from 'react'; export default 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; const isLicensed = global.window.mm_license.IsLicensed === 'true'; const skippedIntensiveQueries = stats[StatTypes.TOTAL_POSTS] === -1; const postCountsDay = formatPostsPerDayData(stats[StatTypes.POST_PER_DAY]); const userCountsWithPostsDay = formatUsersWithPostsPerDayData(stats[StatTypes.USERS_WITH_POSTS_PER_DAY]); let banner; let postCount; let postTotalGraph; let activeUserGraph; if (skippedIntensiveQueries) { banner = (
); } else { postCount = ( } icon='fa-comment' count={stats[StatTypes.TOTAL_POSTS]} /> ); postTotalGraph = (
} data={postCountsDay} options={{ legend: { display: false } }} width='740' height='225' />
); activeUserGraph = (
} data={userCountsWithPostsDay} options={{ legend: { display: false } }} width='740' height='225' />
); } let advancedStats; let advancedGraphs; let sessionCount; let commandCount; let incomingCount; let outgoingCount; if (global.window.mm_license.IsLicensed === 'true') { sessionCount = ( } icon='fa-signal' count={stats[StatTypes.TOTAL_SESSIONS]} /> ); commandCount = ( } icon='fa-terminal' count={stats[StatTypes.TOTAL_COMMANDS]} /> ); incomingCount = ( } icon='fa-arrow-down' count={stats[StatTypes.TOTAL_IHOOKS]} /> ); outgoingCount = ( } icon='fa-arrow-up' count={stats[StatTypes.TOTAL_OHOOKS]} /> ); advancedStats = (
} icon='fa-user' count={stats[StatTypes.TOTAL_WEBSOCKET_CONNECTIONS]} /> } icon='fa-terminal' count={stats[StatTypes.TOTAL_MASTER_DB_CONNECTIONS]} /> } icon='fa-terminal' count={stats[StatTypes.TOTAL_READ_DB_CONNECTIONS]} />
); const channelTypeData = formatChannelDoughtnutData(stats[StatTypes.TOTAL_PUBLIC_CHANNELS], stats[StatTypes.TOTAL_PRIVATE_GROUPS]); const postTypeData = formatPostDoughtnutData(stats[StatTypes.TOTAL_FILE_POSTS], stats[StatTypes.TOTAL_HASHTAG_POSTS], stats[StatTypes.TOTAL_POSTS]); let postTypeGraph; if (stats[StatTypes.TOTAL_POSTS] !== -1) { postTypeGraph = ( } data={postTypeData} width='300' height='225' /> ); } advancedGraphs = (
} data={channelTypeData} width='300' height='225' /> {postTypeGraph}
); } const userCount = ( } icon='fa-user' count={stats[StatTypes.TOTAL_USERS]} /> ); const teamCount = ( } icon='fa-users' count={stats[StatTypes.TOTAL_TEAMS]} /> ); const channelCount = ( } icon='fa-globe' count={stats[StatTypes.TOTAL_PUBLIC_CHANNELS] + stats[StatTypes.TOTAL_PRIVATE_GROUPS]} /> ); const dailyActiveUsers = ( } icon='fa-users' count={stats[StatTypes.DAILY_ACTIVE_USERS]} /> ); const monthlyActiveUsers = ( } icon='fa-users' count={stats[StatTypes.MONTHLY_ACTIVE_USERS]} /> ); let firstRow; let secondRow; if (isLicensed && skippedIntensiveQueries) { firstRow = (
{userCount} {teamCount} {channelCount} {sessionCount}
); secondRow = (
{commandCount} {incomingCount} {outgoingCount}
); } else if (isLicensed && !skippedIntensiveQueries) { firstRow = (
{userCount} {teamCount} {channelCount} {postCount}
); secondRow = (
{sessionCount} {commandCount} {incomingCount} {outgoingCount}
); } else if (!isLicensed) { firstRow = (
{userCount} {teamCount} {channelCount} {postCount}
); } const thirdRow = (
{dailyActiveUsers} {monthlyActiveUsers}
); return (

{banner}
{firstRow} {secondRow} {thirdRow} {advancedStats}
{advancedGraphs} {postTotalGraph} {activeUserGraph}
); } } export function formatChannelDoughtnutData(totalPublic, totalPrivate) { const channelTypeData = { labels: [ Utils.localizeMessage('analytics.system.publicChannels', 'Public Channels'), Utils.localizeMessage('analytics.system.privateGroups', 'Private Channels') ], datasets: [{ data: [totalPublic, totalPrivate], backgroundColor: ['#46BFBD', '#FDB45C'], hoverBackgroundColor: ['#5AD3D1', '#FFC870'] }] }; return channelTypeData; } export function formatPostDoughtnutData(filePosts, hashtagPosts, totalPosts) { const postTypeData = { labels: [ Utils.localizeMessage('analytics.system.totalFilePosts', 'Posts with Files'), Utils.localizeMessage('analytics.system.totalHashtagPosts', 'Posts with Hashtags'), Utils.localizeMessage('analytics.system.textPosts', 'Posts with Text-only') ], datasets: [{ data: [filePosts, hashtagPosts, (totalPosts - filePosts - hashtagPosts)], backgroundColor: ['#46BFBD', '#F7464A', '#FDB45C'], hoverBackgroundColor: ['#5AD3D1', '#FF5A5E', '#FFC870'] }] }; return postTypeData; } export function formatPostsPerDayData(data) { var chartData = { labels: [], datasets: [{ fillColor: 'rgba(151,187,205,0.2)', borderColor: 'rgba(151,187,205,1)', pointBackgroundColor: 'rgba(151,187,205,1)', pointBorderColor: '#fff', pointHoverBackgroundColor: '#fff', pointHoverBorderColor: '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: [{ label: '', fillColor: 'rgba(151,187,205,0.2)', borderColor: 'rgba(151,187,205,1)', pointBackgroundColor: 'rgba(151,187,205,1)', pointBorderColor: '#fff', pointHoverBackgroundColor: '#fff', pointHoverBorderColor: '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; }