Plan/Plan/react/dashboard/src/components/cards/server/graphs/PerformanceGraphsCard.js

148 lines
7.6 KiB
JavaScript

import {useParams} from "react-router-dom";
import {useDataRequest} from "../../../../hooks/dataFetchHook";
import {fetchOptimizedPerformance, fetchPingGraph, fetchPluginHistory} from "../../../../service/serverService";
import {ErrorViewBody} from "../../../../views/ErrorView";
import {useTranslation} from "react-i18next";
import {Card} from "react-bootstrap";
import CardTabs from "../../../CardTabs";
import {faGears, faHdd, faMap, faMicrochip, faSignal, faTachometerAlt} from "@fortawesome/free-solid-svg-icons";
import React, {useEffect, useState} from "react";
import {ChartLoader} from "../../../navigation/Loader";
import AllPerformanceGraph from "../../../graphs/performance/AllPerformanceGraph";
import TpsPerformanceGraph from "../../../graphs/performance/TpsPerformanceGraph";
import CpuRamPerformanceGraph from "../../../graphs/performance/CpuRamPerformanceGraph";
import WorldPerformanceGraph from "../../../graphs/performance/WorldPerformanceGraph";
import DiskPerformanceGraph from "../../../graphs/performance/DiskPerformanceGraph";
import PingGraph from "../../../graphs/performance/PingGraph";
import {mapPerformanceDataToSeries} from "../../../../util/graphs";
import {useAuth} from "../../../../hooks/authenticationHook";
const AllGraphTab = ({data, dataSeries, pluginHistorySeries, loadingError}) => {
if (loadingError) return <ErrorViewBody error={loadingError}/>
if (!dataSeries) return <ChartLoader style={{height: "450px"}}/>;
return <AllPerformanceGraph id="server-performance-all-chart" data={data} dataSeries={dataSeries}
pluginHistorySeries={pluginHistorySeries}/>
}
const TpsGraphTab = ({data, dataSeries, pluginHistorySeries, loadingError}) => {
if (loadingError) return <ErrorViewBody error={loadingError}/>
if (!dataSeries) return <ChartLoader style={{height: "450px"}}/>;
return <TpsPerformanceGraph id="server-performance-tps-chart" data={data} dataSeries={dataSeries}
pluginHistorySeries={pluginHistorySeries}/>
}
const CpuRamGraphTab = ({data, dataSeries, pluginHistorySeries, loadingError}) => {
if (loadingError) return <ErrorViewBody error={loadingError}/>
if (!dataSeries) return <ChartLoader style={{height: "450px"}}/>;
return <CpuRamPerformanceGraph id="server-performance-cpuram-chart" data={data} dataSeries={dataSeries}
pluginHistorySeries={pluginHistorySeries}/>
}
const WorldGraphTab = ({data, dataSeries, pluginHistorySeries, loadingError}) => {
if (loadingError) return <ErrorViewBody error={loadingError}/>
if (!dataSeries) return <ChartLoader style={{height: "450px"}}/>;
return <WorldPerformanceGraph id="server-performance-world-chart" data={data} dataSeries={dataSeries}
pluginHistorySeries={pluginHistorySeries}/>
}
const DiskGraphTab = ({data, dataSeries, pluginHistorySeries, loadingError}) => {
if (loadingError) return <ErrorViewBody error={loadingError}/>
if (!dataSeries) return <ChartLoader style={{height: "450px"}}/>;
return <DiskPerformanceGraph id="server-performance-disk-chart" data={data} dataSeries={dataSeries}
pluginHistorySeries={pluginHistorySeries}/>
}
const PingGraphTab = ({identifier}) => {
const {data, loadingError} = useDataRequest(fetchPingGraph, [identifier]);
if (loadingError) return <ErrorViewBody error={loadingError}/>
if (!data) return <ChartLoader style={{height: "450px"}}/>;
return <PingGraph id="server-performance-ping-chart" data={data}/>;
}
const PerformanceGraphsCard = () => {
const {t} = useTranslation();
const {authRequired, hasPermission} = useAuth();
const {identifier} = useParams();
const {data, loadingError} = useDataRequest(fetchOptimizedPerformance, [identifier]);
const [parsedData, setParsedData] = useState(undefined);
const {
data: pluginHistory,
loadingError: pluginHistoryLoadingError
} = useDataRequest(fetchPluginHistory, [identifier], authRequired && hasPermission('page.server.plugin.history'));
const [pluginHistorySeries, setPluginHistorySeries] = useState({});
useEffect(() => {
if (data) {
mapPerformanceDataToSeries(data.values).then(parsed => setParsedData(parsed))
}
}, [data, setParsedData]);
useEffect(() => {
// https://stackoverflow.com/a/34890276/20825073
const groupBy = function (xs, key) {
return xs.reduce(function (rv, x) {
(rv[x[key]] = rv[x[key]] || []).push(x);
return rv;
}, {});
};
if (pluginHistory) {
const grouped = groupBy(pluginHistory.history.reverse(), 'modified');
setPluginHistorySeries({
type: 'flags',
accessibility: {
exposeAsGroupOnly: true,
description: t('html.label.pluginVersionHistory')
},
tooltip: {headerFormat: ''},
data: Object.entries(grouped).map(entry => {
const installedLines = entry[1].filter(p => p.version).map(plugin => plugin.name + ': ' + plugin.version).join(', <br>');
const uninstalledLines = entry[1].filter(p => !p.version).map(plugin => plugin.name).join(', <br>');
return {
x: entry[0],
title: entry[1].length,
text: (installedLines.length ? '<b>' + t('html.label.installed') + '</b><br>' + installedLines : '') +
(uninstalledLines.length ? '<b>' + t('html.label.uninstalled') + '</b><br>' + uninstalledLines : '')
}
})
})
}
}, [pluginHistory, setPluginHistorySeries, t]);
return <Card id={"performance-graphs"}>
<CardTabs tabs={[
{
name: t('html.label.all'), icon: faGears, color: 'blue-grey', href: 'all',
element: <AllGraphTab data={data} dataSeries={parsedData} pluginHistorySeries={pluginHistorySeries}
loadingError={loadingError || pluginHistoryLoadingError}/>
}, {
name: t('html.label.tps'), icon: faTachometerAlt, color: 'red', href: 'tps',
element: <TpsGraphTab data={data} dataSeries={parsedData} pluginHistorySeries={pluginHistorySeries}
loadingError={loadingError || pluginHistoryLoadingError}/>
}, {
name: t('html.label.cpuRam'), icon: faMicrochip, color: 'light-green', href: 'cpu-ram',
element: <CpuRamGraphTab data={data} dataSeries={parsedData} pluginHistorySeries={pluginHistorySeries}
loadingError={loadingError || pluginHistoryLoadingError}/>
}, {
name: t('html.label.world'), icon: faMap, color: 'purple', href: 'world-load',
element: <WorldGraphTab data={data} dataSeries={parsedData} pluginHistorySeries={pluginHistorySeries}
loadingError={loadingError || pluginHistoryLoadingError}/>
}, {
name: t('html.label.ping'), icon: faSignal, color: 'amber', href: 'ping',
element: <PingGraphTab identifier={identifier}/>
}, {
name: t('html.label.diskSpace'), icon: faHdd, color: 'green', href: 'disk',
element: <DiskGraphTab data={data} dataSeries={parsedData} pluginHistorySeries={pluginHistorySeries}
loadingError={loadingError || pluginHistoryLoadingError}/>
},
]}/>
</Card>
}
export default PerformanceGraphsCard;