From 22e0b8ed8243f68f3138aada56273a962b3b02f2 Mon Sep 17 00:00:00 2001 From: Aurora Lahtela <24460436+AuroraLS3@users.noreply.github.com> Date: Sat, 30 Nov 2024 13:26:07 +0200 Subject: [PATCH] Allow defining specific view criteria for server performance graphs Adds permissions for specific data series on the performance page Affects issues: - Close #3738 --- .../delivery/domain/auth/WebPermission.java | 8 +++ .../resolver/json/GraphsJSONResolver.java | 23 ++++++- .../server/graphs/PerformanceGraphsCard.jsx | 61 +++++++++++-------- .../performance/AllPerformanceGraph.jsx | 35 ++++++----- .../performance/CpuRamPerformanceGraph.jsx | 12 ++-- .../performance/TpsPerformanceGraph.jsx | 9 ++- .../performance/WorldPerformanceGraph.jsx | 12 ++-- .../src/views/server/ServerPerformance.jsx | 4 +- 8 files changed, 108 insertions(+), 56 deletions(-) diff --git a/Plan/common/src/main/java/com/djrapitops/plan/delivery/domain/auth/WebPermission.java b/Plan/common/src/main/java/com/djrapitops/plan/delivery/domain/auth/WebPermission.java index 5aa3502fa4..a67e1a7533 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/delivery/domain/auth/WebPermission.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/delivery/domain/auth/WebPermission.java @@ -95,6 +95,14 @@ public enum WebPermission implements Supplier, Lang { PAGE_SERVER_GEOLOCATIONS_PING_PER_COUNTRY("See Ping Per Country table"), PAGE_SERVER_PERFORMANCE("See Performance tab"), PAGE_SERVER_PERFORMANCE_GRAPHS("See Performance graphs"), + PAGE_SERVER_PERFORMANCE_GRAPHS_PLAYERS_ONLINE("See Players Online data in Performance graphs"), + PAGE_SERVER_PERFORMANCE_GRAPHS_TPS("See TPS data in Performance graphs"), + PAGE_SERVER_PERFORMANCE_GRAPHS_CPU("See CPU usage in Performance graphs"), + PAGE_SERVER_PERFORMANCE_GRAPHS_RAM("See Memory usage in Performance graphs"), + PAGE_SERVER_PERFORMANCE_GRAPHS_ENTITIES("See Entity count data in Performance graphs"), + PAGE_SERVER_PERFORMANCE_GRAPHS_CHUNKS("See Chunk count data in Performance graphs"), + PAGE_SERVER_PERFORMANCE_GRAPHS_DISK("See Disk Space usage Performance graphs"), + PAGE_SERVER_PERFORMANCE_GRAPHS_PING("See Ping data in Performance graphs"), PAGE_SERVER_PERFORMANCE_OVERVIEW("See Performance numbers"), PAGE_SERVER_PLUGIN_HISTORY("See Plugin History"), PAGE_SERVER_PLUGINS("See Plugins -tabs of servers"), diff --git a/Plan/common/src/main/java/com/djrapitops/plan/delivery/webserver/resolver/json/GraphsJSONResolver.java b/Plan/common/src/main/java/com/djrapitops/plan/delivery/webserver/resolver/json/GraphsJSONResolver.java index e1236bc7bb..2c5506ea00 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/delivery/webserver/resolver/json/GraphsJSONResolver.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/delivery/webserver/resolver/json/GraphsJSONResolver.java @@ -218,10 +218,29 @@ private DataID getDataID(@Untrusted String type) { private List getRequiredPermission(DataID dataID) { switch (dataID) { case GRAPH_PERFORMANCE: - return List.of(WebPermission.PAGE_SERVER_PERFORMANCE_GRAPHS); + return List.of(WebPermission.PAGE_SERVER_PERFORMANCE_GRAPHS, + WebPermission.PAGE_SERVER_PERFORMANCE_GRAPHS_PLAYERS_ONLINE, + WebPermission.PAGE_SERVER_PERFORMANCE_GRAPHS_TPS, + WebPermission.PAGE_SERVER_PERFORMANCE_GRAPHS_CPU, + WebPermission.PAGE_SERVER_PERFORMANCE_GRAPHS_RAM, + WebPermission.PAGE_SERVER_PERFORMANCE_GRAPHS_CHUNKS, + WebPermission.PAGE_SERVER_PERFORMANCE_GRAPHS_DISK + ); case GRAPH_PING: + return List.of(WebPermission.PAGE_SERVER_PERFORMANCE_GRAPHS, + WebPermission.PAGE_SERVER_PERFORMANCE_GRAPHS_PING, + WebPermission.PAGE_NETWORK_PERFORMANCE + ); case GRAPH_OPTIMIZED_PERFORMANCE: - return List.of(WebPermission.PAGE_SERVER_PERFORMANCE_GRAPHS, WebPermission.PAGE_NETWORK_PERFORMANCE); + return List.of(WebPermission.PAGE_SERVER_PERFORMANCE_GRAPHS, + WebPermission.PAGE_SERVER_PERFORMANCE_GRAPHS_PLAYERS_ONLINE, + WebPermission.PAGE_SERVER_PERFORMANCE_GRAPHS_TPS, + WebPermission.PAGE_SERVER_PERFORMANCE_GRAPHS_CPU, + WebPermission.PAGE_SERVER_PERFORMANCE_GRAPHS_RAM, + WebPermission.PAGE_SERVER_PERFORMANCE_GRAPHS_CHUNKS, + WebPermission.PAGE_SERVER_PERFORMANCE_GRAPHS_DISK, + WebPermission.PAGE_NETWORK_PERFORMANCE + ); case GRAPH_ONLINE: return List.of(WebPermission.PAGE_SERVER_OVERVIEW_PLAYERS_ONLINE_GRAPH, WebPermission.PAGE_NETWORK_OVERVIEW_GRAPHS_ONLINE); case GRAPH_UNIQUE_NEW: diff --git a/Plan/react/dashboard/src/components/cards/server/graphs/PerformanceGraphsCard.jsx b/Plan/react/dashboard/src/components/cards/server/graphs/PerformanceGraphsCard.jsx index 75ef173d87..15ab689014 100644 --- a/Plan/react/dashboard/src/components/cards/server/graphs/PerformanceGraphsCard.jsx +++ b/Plan/react/dashboard/src/components/cards/server/graphs/PerformanceGraphsCard.jsx @@ -67,7 +67,7 @@ const PingGraphTab = ({identifier}) => { const PerformanceGraphsCard = () => { const {t} = useTranslation(); - const {authRequired, hasPermission} = useAuth(); + const {authRequired, hasPermission, hasChildPermission} = useAuth(); const {identifier} = useParams(); const {data, loadingError} = useDataRequest(fetchOptimizedPerformance, [identifier]); @@ -115,33 +115,40 @@ const PerformanceGraphsCard = () => { } }, [pluginHistory, setPluginHistorySeries, t]); + const tabs = [ + { + name: t('html.label.all'), icon: faGears, color: 'blue-grey', href: 'all', + element: , + permission: 'page.server.performance.graphs' + }, { + name: t('html.label.tps'), icon: faTachometerAlt, color: 'red', href: 'tps', + element: , + permission: 'page.server.performance.graphs.tps' + }, { + name: t('html.label.cpuRam'), icon: faMicrochip, color: 'light-green', href: 'cpu-ram', + element: , + permission: ['page.server.performance.graphs.cpu', 'page.server.performance.graphs.ram'] + }, { + name: t('html.label.world'), icon: faMap, color: 'purple', href: 'world-load', + element: , + permission: ['page.server.performance.graphs.entities', 'page.server.performance.graphs.chunks'] + }, { + name: t('html.label.ping'), icon: faSignal, color: 'amber', href: 'ping', + element: , + permission: 'page.server.performance.graphs.ping' + }, { + name: t('html.label.diskSpace'), icon: faHdd, color: 'green', href: 'disk', + element: , + permission: 'page.server.performance.graphs.disk' + }, + ].filter(tab => hasChildPermission(tab.permission)); return - - }, { - name: t('html.label.tps'), icon: faTachometerAlt, color: 'red', href: 'tps', - element: - }, { - name: t('html.label.cpuRam'), icon: faMicrochip, color: 'light-green', href: 'cpu-ram', - element: - }, { - name: t('html.label.world'), icon: faMap, color: 'purple', href: 'world-load', - element: - }, { - name: t('html.label.ping'), icon: faSignal, color: 'amber', href: 'ping', - element: - }, { - name: t('html.label.diskSpace'), icon: faHdd, color: 'green', href: 'disk', - element: - }, - ]}/> + } diff --git a/Plan/react/dashboard/src/components/graphs/performance/AllPerformanceGraph.jsx b/Plan/react/dashboard/src/components/graphs/performance/AllPerformanceGraph.jsx index 5fe38ff209..812804477d 100644 --- a/Plan/react/dashboard/src/components/graphs/performance/AllPerformanceGraph.jsx +++ b/Plan/react/dashboard/src/components/graphs/performance/AllPerformanceGraph.jsx @@ -8,6 +8,7 @@ import {useTheme} from "../../../hooks/themeHook"; import {withReducedSaturation} from "../../../util/colors"; import Accessibility from "highcharts/modules/accessibility"; import {useMetadata} from "../../../hooks/metadataHook"; +import {useAuth} from "../../../hooks/authenticationHook.jsx"; const yAxis = [ { @@ -66,6 +67,7 @@ const AllPerformanceGraph = ({id, data, dataSeries, pluginHistorySeries}) => { const {t} = useTranslation(); const {graphTheming, nightModeEnabled} = useTheme(); const {timeZoneOffsetMinutes} = useMetadata(); + const {hasPermission} = useAuth(); const onResize = useCallback(() => { let chartElement = document.getElementById(id); @@ -74,14 +76,14 @@ const AllPerformanceGraph = ({id, data, dataSeries, pluginHistorySeries}) => { if (chart?.yAxis?.length) { const newWidth = window.innerWidth - chart.yAxis[0].update({labels: {enabled: newWidth >= 900}}); - chart.yAxis[1].update({labels: {enabled: newWidth >= 900}}); - chart.yAxis[2].update({labels: {enabled: newWidth >= 1000}}); - chart.yAxis[3].update({labels: {enabled: newWidth >= 1000}}); - chart.yAxis[4].update({labels: {enabled: newWidth >= 1400}}); - chart.yAxis[5].update({labels: {enabled: newWidth >= 1400}}); + chart.yAxis[0].update({labels: {enabled: newWidth >= 900 && hasPermission('page.server.performance.graphs.players.online')}}); + chart.yAxis[1].update({labels: {enabled: newWidth >= 900 && hasPermission('page.server.performance.graphs.tps')}}); + chart.yAxis[2].update({labels: {enabled: newWidth >= 1000 && hasPermission('page.server.performance.graphs.cpu')}}); + chart.yAxis[3].update({labels: {enabled: newWidth >= 1000 && hasPermission('page.server.performance.graphs.ram')}}); + chart.yAxis[4].update({labels: {enabled: newWidth >= 1400 && hasPermission('page.server.performance.graphs.entities')}}); + chart.yAxis[5].update({labels: {enabled: newWidth >= 1400 && hasPermission('page.server.performance.graphs.chunks')}}); } - }, [id]) + }, [id, hasPermission]) useEffect(() => { window.addEventListener("resize", onResize); @@ -107,14 +109,15 @@ const AllPerformanceGraph = ({id, data, dataSeries, pluginHistorySeries}) => { const spline = 'spline' const series = { - playersOnline: { + playersOnline: hasPermission('page.server.performance.graphs.players.online') ? { name: t('html.label.playersOnline'), type: 'areaspline', tooltip: tooltip.zeroDecimals, data: dataSeries.playersOnline, color: data.colors.playersOnline, yAxis: 0 - }, tps: { + } : {}, + tps: hasPermission('page.server.performance.graphs.tps') ? { name: t('html.label.tps'), type: spline, color: nightModeEnabled ? withReducedSaturation(data.colors.high) : data.colors.high, @@ -122,35 +125,39 @@ const AllPerformanceGraph = ({id, data, dataSeries, pluginHistorySeries}) => { tooltip: tooltip.twoDecimals, data: dataSeries.tps, yAxis: 1 - }, cpu: { + } : {}, + cpu: hasPermission('page.server.performance.graphs.cpu') ? { name: t('html.label.cpu'), type: spline, tooltip: tooltip.twoDecimals, data: dataSeries.cpu, color: nightModeEnabled ? withReducedSaturation(data.colors.cpu) : data.colors.cpu, yAxis: 2 - }, ram: { + } : {}, + ram: hasPermission('page.server.performance.graphs.ram') ? { name: t('html.label.ram'), type: spline, tooltip: tooltip.zeroDecimals, data: dataSeries.ram, color: nightModeEnabled ? withReducedSaturation(data.colors.ram) : data.colors.ram, yAxis: 3 - }, entities: { + } : {}, + entities: hasPermission('page.server.performance.graphs.entities') ? { name: t('html.label.loadedEntities'), type: spline, tooltip: tooltip.zeroDecimals, data: dataSeries.entities, color: nightModeEnabled ? withReducedSaturation(data.colors.entities) : data.colors.entities, yAxis: 4 - }, chunks: { + } : {}, + chunks: hasPermission('page.server.performance.graphs.chunks') ? { name: t('html.label.loadedChunks'), type: spline, tooltip: tooltip.zeroDecimals, data: dataSeries.chunks, color: nightModeEnabled ? withReducedSaturation(data.colors.chunks) : data.colors.chunks, yAxis: 5 - } + } : {} }; NoDataDisplay(Highcharts); diff --git a/Plan/react/dashboard/src/components/graphs/performance/CpuRamPerformanceGraph.jsx b/Plan/react/dashboard/src/components/graphs/performance/CpuRamPerformanceGraph.jsx index ed491b5443..f37e1bc453 100644 --- a/Plan/react/dashboard/src/components/graphs/performance/CpuRamPerformanceGraph.jsx +++ b/Plan/react/dashboard/src/components/graphs/performance/CpuRamPerformanceGraph.jsx @@ -8,38 +8,42 @@ import {useTheme} from "../../../hooks/themeHook"; import {withReducedSaturation} from "../../../util/colors"; import Accessibility from "highcharts/modules/accessibility"; import {useMetadata} from "../../../hooks/metadataHook"; +import {useAuth} from "../../../hooks/authenticationHook.jsx"; const CpuRamPerformanceGraph = ({id, data, dataSeries, pluginHistorySeries}) => { const {t} = useTranslation(); const {graphTheming, nightModeEnabled} = useTheme(); const {timeZoneOffsetMinutes} = useMetadata(); + const {hasPermission} = useAuth(); useEffect(() => { const spline = 'spline' const series = { - playersOnline: { + playersOnline: hasPermission('page.server.performance.graphs.players.online') ? { name: t('html.label.playersOnline'), type: 'areaspline', tooltip: tooltip.zeroDecimals, data: dataSeries.playersOnline, color: data.colors.playersOnline, yAxis: 0 - }, cpu: { + } : {}, + cpu: hasPermission('page.server.performance.graphs.cpu') ? { name: t('html.label.cpu'), type: spline, tooltip: tooltip.twoDecimals, data: dataSeries.cpu, color: nightModeEnabled ? withReducedSaturation(data.colors.cpu) : data.colors.cpu, yAxis: 1 - }, ram: { + } : {}, + ram: hasPermission('page.server.performance.graphs.ram') ? { name: t('html.label.ram'), type: spline, tooltip: tooltip.zeroDecimals, data: dataSeries.ram, color: nightModeEnabled ? withReducedSaturation(data.colors.ram) : data.colors.ram, yAxis: 2 - } + } : {} }; NoDataDisplay(Highcharts); diff --git a/Plan/react/dashboard/src/components/graphs/performance/TpsPerformanceGraph.jsx b/Plan/react/dashboard/src/components/graphs/performance/TpsPerformanceGraph.jsx index a34d574a0a..c37388c0e2 100644 --- a/Plan/react/dashboard/src/components/graphs/performance/TpsPerformanceGraph.jsx +++ b/Plan/react/dashboard/src/components/graphs/performance/TpsPerformanceGraph.jsx @@ -8,11 +8,13 @@ import {useTheme} from "../../../hooks/themeHook"; import {withReducedSaturation} from "../../../util/colors"; import Accessibility from "highcharts/modules/accessibility"; import {useMetadata} from "../../../hooks/metadataHook"; +import {useAuth} from "../../../hooks/authenticationHook.jsx"; const TpsPerformanceGraph = ({id, data, dataSeries, pluginHistorySeries}) => { const {t} = useTranslation(); const {graphTheming, nightModeEnabled} = useTheme(); const {timeZoneOffsetMinutes} = useMetadata(); + const {hasPermission} = useAuth(); useEffect(() => { const zones = { @@ -30,14 +32,15 @@ const TpsPerformanceGraph = ({id, data, dataSeries, pluginHistorySeries}) => { const spline = 'spline' const series = { - playersOnline: { + playersOnline: hasPermission('page.server.performance.graphs.players.online') ? { name: t('html.label.playersOnline'), type: 'areaspline', tooltip: tooltip.zeroDecimals, data: dataSeries.playersOnline, color: data.colors.playersOnline, yAxis: 0 - }, tps: { + } : {}, + tps: hasPermission('page.server.performance.graphs.tps') ? { name: t('html.label.tps'), type: spline, color: nightModeEnabled ? withReducedSaturation(data.colors.high) : data.colors.high, @@ -45,7 +48,7 @@ const TpsPerformanceGraph = ({id, data, dataSeries, pluginHistorySeries}) => { tooltip: tooltip.twoDecimals, data: dataSeries.tps, yAxis: 1 - } + } : {} }; NoDataDisplay(Highcharts); diff --git a/Plan/react/dashboard/src/components/graphs/performance/WorldPerformanceGraph.jsx b/Plan/react/dashboard/src/components/graphs/performance/WorldPerformanceGraph.jsx index 75ff7640a8..fa23cf97cb 100644 --- a/Plan/react/dashboard/src/components/graphs/performance/WorldPerformanceGraph.jsx +++ b/Plan/react/dashboard/src/components/graphs/performance/WorldPerformanceGraph.jsx @@ -8,38 +8,42 @@ import {useTheme} from "../../../hooks/themeHook"; import {withReducedSaturation} from "../../../util/colors"; import Accessibility from "highcharts/modules/accessibility"; import {useMetadata} from "../../../hooks/metadataHook"; +import {useAuth} from "../../../hooks/authenticationHook.jsx"; const WorldPerformanceGraph = ({id, data, dataSeries, pluginHistorySeries}) => { const {t} = useTranslation(); const {graphTheming, nightModeEnabled} = useTheme(); const {timeZoneOffsetMinutes} = useMetadata(); + const {hasPermission} = useAuth(); useEffect(() => { const spline = 'spline' const series = { - playersOnline: { + playersOnline: hasPermission('page.server.performance.graphs.players.online') ? { name: t('html.label.playersOnline'), type: 'areaspline', tooltip: tooltip.zeroDecimals, data: dataSeries.playersOnline, color: data.colors.playersOnline, yAxis: 0 - }, entities: { + } : {}, + entities: hasPermission('page.server.performance.graphs.entities') ? { name: t('html.label.loadedEntities'), type: spline, tooltip: tooltip.zeroDecimals, data: dataSeries.entities, color: nightModeEnabled ? withReducedSaturation(data.colors.entities) : data.colors.entities, yAxis: 1 - }, chunks: { + } : {}, + chunks: hasPermission('page.server.performance.graphs.chunks') ? { name: t('html.label.loadedChunks'), type: spline, tooltip: tooltip.zeroDecimals, data: dataSeries.chunks, color: nightModeEnabled ? withReducedSaturation(data.colors.chunks) : data.colors.chunks, yAxis: 2 - } + } : {} }; NoDataDisplay(Highcharts); diff --git a/Plan/react/dashboard/src/views/server/ServerPerformance.jsx b/Plan/react/dashboard/src/views/server/ServerPerformance.jsx index b378bcdeb5..e33377d0f5 100644 --- a/Plan/react/dashboard/src/views/server/ServerPerformance.jsx +++ b/Plan/react/dashboard/src/views/server/ServerPerformance.jsx @@ -12,10 +12,10 @@ import ExtendableRow from "../../components/layout/extension/ExtendableRow"; import {useAuth} from "../../hooks/authenticationHook"; const ServerPerformance = () => { - const {hasPermission} = useAuth(); + const {hasPermission, hasChildPermission} = useAuth(); const {identifier} = useParams(); - const seeGraphs = hasPermission('page.server.performance.graphs'); + const seeGraphs = hasChildPermission('page.server.performance.graphs'); const seeOverview = hasPermission('page.server.performance.overview'); const {data, loadingError} = useDataRequest(fetchPerformanceOverview, [identifier], seeOverview);