From adc4162217f51124e7e4628073194993b1d413c9 Mon Sep 17 00:00:00 2001 From: Aurora Lahtela <24460436+AuroraLS3@users.noreply.github.com> Date: Sat, 10 Sep 2022 09:38:25 +0300 Subject: [PATCH] Network sessions tab implemented in React --- .../plan/settings/locale/lang/HtmlLang.java | 2 +- Plan/react/dashboard/src/App.js | 2 ++ .../components/cards/common/ServerPieCard.js | 28 +++++++++++++++++++ .../server/insights/SessionInsightsCard.js | 23 +++++++++------ .../server/tables/ServerRecentSessionsCard.js | 6 +--- .../components/graphs/GeolocationWorldMap.js | 3 ++ .../src/components/graphs/ServerPie.js | 3 ++ .../dashboard/src/hooks/dataFetchHook.js | 2 +- .../dashboard/src/service/networkService.js | 10 +++++++ .../dashboard/src/service/serverService.js | 3 +- .../src/views/network/NetworkSessions.js | 26 +++++++++++++++++ .../src/views/server/ServerSessions.js | 6 ++-- 12 files changed, 95 insertions(+), 19 deletions(-) create mode 100644 Plan/react/dashboard/src/components/cards/common/ServerPieCard.js create mode 100644 Plan/react/dashboard/src/views/network/NetworkSessions.js diff --git a/Plan/common/src/main/java/com/djrapitops/plan/settings/locale/lang/HtmlLang.java b/Plan/common/src/main/java/com/djrapitops/plan/settings/locale/lang/HtmlLang.java index 12e652a4f..818bb4ace 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/settings/locale/lang/HtmlLang.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/settings/locale/lang/HtmlLang.java @@ -108,7 +108,7 @@ public enum HtmlLang implements Lang { LABEL_AVG_ENTITIES("html.label.averageEntities", "Average Entities"), LABEL_AVG_CHUNKS("html.label.averageChunks", "Average Chunks"), LABEL_LOW_TPS("html.label.lowTpsSpikes", "Low TPS Spikes"), - LABEL_LOW_TPS_7_DAYS("html.label.lowTpsSpikes", "Low TPS Spikes (7 days)"), + LABEL_LOW_TPS_7_DAYS("html.label.lowTpsSpikes7days", "Low TPS Spikes (7 days)"), LABEL_DOWNTIME("html.label.downtime", "Downtime"), // Sessions tab #tab-sessions-overview TITLE_RECENT_SESSIONS("html.label.recentSessions", "Recent Sessions"), diff --git a/Plan/react/dashboard/src/App.js b/Plan/react/dashboard/src/App.js index 2fbf184d4..9de041e80 100644 --- a/Plan/react/dashboard/src/App.js +++ b/Plan/react/dashboard/src/App.js @@ -37,6 +37,7 @@ const ServerJoinAddresses = React.lazy(() => import("./views/server/ServerJoinAd const NetworkPage = React.lazy(() => import("./views/layout/NetworkPage")); const NetworkOverview = React.lazy(() => import("./views/network/NetworkOverview")); const NetworkServers = React.lazy(() => import("./views/network/NetworkServers")); +const NetworkSessions = React.lazy(() => import("./views/network/NetworkSessions")); const PlayersPage = React.lazy(() => import("./views/layout/PlayersPage")); const AllPlayers = React.lazy(() => import("./views/players/AllPlayers")); @@ -119,6 +120,7 @@ function App() { }/> }/> }/> + }/> }/> }/> }/> diff --git a/Plan/react/dashboard/src/components/cards/common/ServerPieCard.js b/Plan/react/dashboard/src/components/cards/common/ServerPieCard.js new file mode 100644 index 000000000..250fcc9a8 --- /dev/null +++ b/Plan/react/dashboard/src/components/cards/common/ServerPieCard.js @@ -0,0 +1,28 @@ +import {Card} from "react-bootstrap-v5"; +import React from "react"; +import {CardLoader} from "../../navigation/Loader"; +import ServerPie from "../../graphs/ServerPie"; +import {faNetworkWired} from "@fortawesome/free-solid-svg-icons"; +import CardHeader from "../CardHeader"; +import {useDataRequest} from "../../../hooks/dataFetchHook"; +import {fetchServerPie} from "../../../service/networkService"; +import {ErrorViewCard} from "../../../views/ErrorView"; + +const ServerPieCard = () => { + const {data, loadingError} = useDataRequest(fetchServerPie, []); + + if (!data) return ; + if (loadingError) return ; + + const series = data.server_pie_series_30d; + const colors = data.server_pie_colors; + + return ( + + + + + ) +} + +export default ServerPieCard; \ No newline at end of file diff --git a/Plan/react/dashboard/src/components/cards/server/insights/SessionInsightsCard.js b/Plan/react/dashboard/src/components/cards/server/insights/SessionInsightsCard.js index a98fc452c..961ddcad8 100644 --- a/Plan/react/dashboard/src/components/cards/server/insights/SessionInsightsCard.js +++ b/Plan/react/dashboard/src/components/cards/server/insights/SessionInsightsCard.js @@ -1,6 +1,5 @@ import React from "react"; import InsightsFor30DaysCard from "../../common/InsightsFor30DaysCard"; -import {useParams} from "react-router-dom"; import {useDataRequest} from "../../../../hooks/dataFetchHook"; import {fetchSessionOverview} from "../../../../service/serverService"; import {ErrorViewCard} from "../../../../views/ErrorView"; @@ -8,29 +7,35 @@ import Datapoint from "../../../Datapoint"; import {useTranslation} from "react-i18next"; import {faGamepad, faUsers} from "@fortawesome/free-solid-svg-icons"; import {faClock} from "@fortawesome/free-regular-svg-icons"; +import {fetchNetworkSessionsOverview} from "../../../../service/networkService"; -const SessionInsightsCard = () => { +const SessionInsightsCard = ({identifier}) => { const {t} = useTranslation(); - const {identifier} = useParams(); - const {data, loadingError} = useDataRequest(fetchSessionOverview, [identifier]); + const { + data, + loadingError + } = useDataRequest(identifier ? fetchSessionOverview : fetchNetworkSessionsOverview, [identifier]); if (loadingError) return + const insights = data?.insights; + return ( ) diff --git a/Plan/react/dashboard/src/components/cards/server/tables/ServerRecentSessionsCard.js b/Plan/react/dashboard/src/components/cards/server/tables/ServerRecentSessionsCard.js index 198c21988..0740bcfec 100644 --- a/Plan/react/dashboard/src/components/cards/server/tables/ServerRecentSessionsCard.js +++ b/Plan/react/dashboard/src/components/cards/server/tables/ServerRecentSessionsCard.js @@ -1,14 +1,10 @@ import React from "react"; -import {useParams} from "react-router-dom"; import {useDataRequest} from "../../../../hooks/dataFetchHook"; import {fetchSessions} from "../../../../service/serverService"; import {ErrorViewCard} from "../../../../views/ErrorView"; import RecentSessionsCard from "../../common/RecentSessionsCard"; -const ServerRecentSessionsCard = () => { - - const {identifier} = useParams(); - +const ServerRecentSessionsCard = ({identifier}) => { const {data, loadingError} = useDataRequest(fetchSessions, [identifier]) if (loadingError) return diff --git a/Plan/react/dashboard/src/components/graphs/GeolocationWorldMap.js b/Plan/react/dashboard/src/components/graphs/GeolocationWorldMap.js index 55934ac2c..f241cab98 100644 --- a/Plan/react/dashboard/src/components/graphs/GeolocationWorldMap.js +++ b/Plan/react/dashboard/src/components/graphs/GeolocationWorldMap.js @@ -5,6 +5,7 @@ import {withReducedSaturation} from "../../util/colors"; import Highcharts from 'highcharts/highmaps.js'; import map from '@highcharts/map-collection/custom/world.geo.json'; import Accessibility from "highcharts/modules/accessibility"; +import NoDataDisplay from "highcharts/modules/no-data-to-display"; const GeolocationWorldMap = ({series, colors}) => { const {t} = useTranslation(); @@ -19,8 +20,10 @@ const GeolocationWorldMap = ({series, colors}) => { joinBy: ['iso-a3', 'code'] }; + NoDataDisplay(Highcharts); Accessibility(Highcharts); Highcharts.setOptions(graphTheming); + Highcharts.setOptions({lang: {noData: t('html.label.noDataToDisplay')}}); Highcharts.mapChart('countryWorldMap', { chart: { animation: true diff --git a/Plan/react/dashboard/src/components/graphs/ServerPie.js b/Plan/react/dashboard/src/components/graphs/ServerPie.js index 88824a2d3..c13536685 100644 --- a/Plan/react/dashboard/src/components/graphs/ServerPie.js +++ b/Plan/react/dashboard/src/components/graphs/ServerPie.js @@ -5,6 +5,7 @@ import {formatTimeAmount} from '../../util/formatters' import {useTheme} from "../../hooks/themeHook"; import {withReducedSaturation} from "../../util/colors"; import {useTranslation} from "react-i18next"; +import NoDataDisplay from "highcharts/modules/no-data-to-display"; import Accessibility from "highcharts/modules/accessibility"; const ServerPie = ({colors, series}) => { @@ -21,8 +22,10 @@ const ServerPie = ({colors, series}) => { data: series }; + NoDataDisplay(Highcharts); Accessibility(Highcharts); Highcharts.setOptions(graphTheming); + Highcharts.setOptions({lang: {noData: t('html.label.noDataToDisplay')}}); Highcharts.chart('server-pie', { chart: { backgroundColor: 'transparent', diff --git a/Plan/react/dashboard/src/hooks/dataFetchHook.js b/Plan/react/dashboard/src/hooks/dataFetchHook.js index c03cdaaef..e15ca6129 100644 --- a/Plan/react/dashboard/src/hooks/dataFetchHook.js +++ b/Plan/react/dashboard/src/hooks/dataFetchHook.js @@ -51,7 +51,7 @@ export const useDataRequest = (fetchMethod, parameters) => { console.warn(error); datastore.finishUpdate(fetchMethod) setLoadingError(error); - finishUpdate(new Date().getTime(), "Error", datastore.isSomethingUpdating()); + finishUpdate(new Date().getTime(), "Error: " + error, datastore.isSomethingUpdating()); } }; diff --git a/Plan/react/dashboard/src/service/networkService.js b/Plan/react/dashboard/src/service/networkService.js index 21b4a89e1..c4cfcc6ce 100644 --- a/Plan/react/dashboard/src/service/networkService.js +++ b/Plan/react/dashboard/src/service/networkService.js @@ -8,4 +8,14 @@ export const fetchNetworkOverview = async (updateRequested) => { export const fetchServersOverview = async (updateRequested) => { const url = `/v1/network/servers?timestamp=${updateRequested}`; return doGetRequest(url); +} + +export const fetchServerPie = async (timestamp) => { + const url = `/v1/graph?type=serverPie×tamp=${timestamp}`; + return doGetRequest(url); +} + +export const fetchNetworkSessionsOverview = async (timestamp) => { + const url = `/v1/network/sessionsOverview?timestamp=${timestamp}`; + return doGetRequest(url); } \ No newline at end of file diff --git a/Plan/react/dashboard/src/service/serverService.js b/Plan/react/dashboard/src/service/serverService.js index cd4afd6c7..07e092068 100644 --- a/Plan/react/dashboard/src/service/serverService.js +++ b/Plan/react/dashboard/src/service/serverService.js @@ -42,7 +42,8 @@ export const fetchExtensionData = async (timestamp, identifier) => { } export const fetchSessions = async (timestamp, identifier) => { - const url = `/v1/sessions?server=${identifier}×tamp=${timestamp}`; + const url = identifier ? `/v1/sessions?server=${identifier}×tamp=${timestamp}` : + `/v1/sessions?timestamp=${timestamp}`; return doGetRequest(url); } diff --git a/Plan/react/dashboard/src/views/network/NetworkSessions.js b/Plan/react/dashboard/src/views/network/NetworkSessions.js new file mode 100644 index 000000000..6405e5e69 --- /dev/null +++ b/Plan/react/dashboard/src/views/network/NetworkSessions.js @@ -0,0 +1,26 @@ +import {Col, Row} from "react-bootstrap-v5"; +import React from "react"; +import ServerRecentSessionsCard from "../../components/cards/server/tables/ServerRecentSessionsCard"; +import SessionInsightsCard from "../../components/cards/server/insights/SessionInsightsCard"; +import LoadIn from "../../components/animation/LoadIn"; +import ServerPieCard from "../../components/cards/common/ServerPieCard"; + +const NetworkSessions = () => { + return ( + +
+ + + + + + + + + +
+
+ ) +} + +export default NetworkSessions; \ No newline at end of file diff --git a/Plan/react/dashboard/src/views/server/ServerSessions.js b/Plan/react/dashboard/src/views/server/ServerSessions.js index e12d1407b..35381019e 100644 --- a/Plan/react/dashboard/src/views/server/ServerSessions.js +++ b/Plan/react/dashboard/src/views/server/ServerSessions.js @@ -4,18 +4,20 @@ import ServerWorldPieCard from "../../components/cards/server/graphs/ServerWorld import ServerRecentSessionsCard from "../../components/cards/server/tables/ServerRecentSessionsCard"; import SessionInsightsCard from "../../components/cards/server/insights/SessionInsightsCard"; import LoadIn from "../../components/animation/LoadIn"; +import {useParams} from "react-router-dom"; const ServerSessions = () => { + const {identifier} = useParams(); return (
- + - +