Make Ping Table use DataTablesTable

Also fixed issue where server ping table never loaded
This commit is contained in:
Aurora Lahtela 2024-01-27 21:02:04 +02:00
parent 67c487b820
commit a8decff8e8
6 changed files with 59 additions and 47 deletions

View File

@ -320,9 +320,9 @@ public class JSONFactory {
tableEntries.add(Maps.builder(String.class, Object.class)
.put("country", geolocation)
.put("avg_ping", formatters.decimals().apply(ping.getAverage()) + " ms")
.put("min_ping", ping.getMin() + " ms")
.put("max_ping", ping.getMax() + " ms")
.put("avg_ping", ping.getAverage())
.put("min_ping", ping.getMin())
.put("max_ping", ping.getMax())
.build());
}
return tableEntries;

View File

@ -104,7 +104,7 @@ const ExportMenu = ({matchingData}) => {
filename: "data-" + new Date().toISOString().replaceAll(":", '').substring(0, 17)
});
const csvOutput = generateCsv(csvConfig)(rows);
await download(csvConfig)(csvOutput);
download(csvConfig)(csvOutput);
setGenerating(false)
}, [matchingData, setGenerating])
@ -125,7 +125,7 @@ const ExportMenu = ({matchingData}) => {
)
}
const DataTablesTable = ({id, rowKeyFunction, options, colorClass}) => {
const DataTablesTable = ({id, rowKeyFunction, options, colorClass, expandComponent}) => {
const {t} = useTranslation();
const {nightModeEnabled} = useTheme();
@ -158,7 +158,7 @@ const DataTablesTable = ({id, rowKeyFunction, options, colorClass}) => {
const visibleColumns = visibleColumnIndexes.map(i => columns[i]);
const invisibleColumns = columns.filter((c, i) => !visibleColumnIndexes.includes(i));
const [selectedPaginationCount, setSelectedPaginationCount] = useState(0)
const [selectedPaginationCount, setSelectedPaginationCount] = useState(options.paginationCount || 0)
const paginationCountOptions = ["10", "25", "100"];
const paginationCount = Number(paginationCountOptions[selectedPaginationCount]);
@ -233,7 +233,7 @@ const DataTablesTable = ({id, rowKeyFunction, options, colorClass}) => {
return () => window.removeEventListener('resize', onResize);
}, [onResize]);
const someColumnsHidden = columns.length !== visibleColumns.length;
const someColumnsHidden = expandComponent || columns.length !== visibleColumns.length;
return (
<div id={id + "-container"}>
@ -306,6 +306,7 @@ const DataTablesTable = ({id, rowKeyFunction, options, colorClass}) => {
{expandedRows.includes(rowKeyFunction(row, null)) &&
<tr key={"hidden-row" + rowKeyFunction(row, null)}>
<td colSpan={visibleColumns.length}>
{expandComponent && expandComponent({row})}
{invisibleColumns.map(column => {
if (column.data._ !== undefined) {
return <p key={"p-" + rowKeyFunction(row, column)}>

View File

@ -1,44 +1,53 @@
import React from "react";
import {useTheme} from "../../hooks/themeHook";
import {useTranslation} from "react-i18next";
import Scrollable from "../Scrollable";
const PingRow = ({country}) => {
return (
<tr>
<td>{country.country}</td>
<td>{country.avg_ping}</td>
<td>{country.min_ping}</td>
<td>{country.max_ping}</td>
</tr>
);
}
import {FontAwesomeIcon as Fa} from "@fortawesome/react-fontawesome";
import {faGlobe, faSignal} from "@fortawesome/free-solid-svg-icons";
import {formatDecimals} from "../../util/formatters.js";
import {usePreferences} from "../../hooks/preferencesHook.jsx";
import DataTablesTable from "./DataTablesTable.jsx";
const PingTable = ({countries}) => {
const {t} = useTranslation();
const {nightModeEnabled} = useTheme();
const {preferencesLoaded, decimalFormat} = usePreferences();
const columns = [{
title: <><Fa icon={faGlobe}/> {t('html.label.country')}</>,
data: "country"
}, {
title: <><Fa icon={faSignal}/> {t('html.label.averagePing')}</>,
data: {_: "pingAverage", display: "pingAverageFormatted"}
}, {
title: <><Fa icon={faSignal}/> {t('html.label.bestPing')}</>,
data: {_: "pingMin", display: "pingMinFormatted"}
}, {
title: <><Fa icon={faSignal}/> {t('html.label.worstPing')}</>,
data: {_: "pingMax", display: "pingMaxFormatted"}
}];
const rows = countries.map(country => {
return {
country: country.country,
pingAverage: country.avg_ping,
pingAverageFormatted: formatDecimals(country.avg_ping, decimalFormat) + " ms",
pingMax: country.max_ping,
pingMaxFormatted: country.max_ping + " ms",
pingMin: country.min_ping,
pingMinFormatted: country.min_ping + " ms"
};
});
const options = {
responsive: true,
deferRender: true,
columns: columns,
data: rows,
paginationCount: 2,
order: [[0, "desc"]]
}
if (!preferencesLoaded) return <></>;
return (
<Scrollable>
<table className={"table mb-0" + (nightModeEnabled ? " table-dark" : '')}>
<thead className="bg-amber" style={{position: "sticky", top: 0}}>
<tr>
<th>{t('html.label.country')}</th>
<th>{t('html.label.averagePing')}</th>
<th>{t('html.label.bestPing')}</th>
<th>{t('html.label.worstPing')}</th>
</tr>
</thead>
<tbody>
{countries.length ? countries.map(country => <PingRow key={country?.country} country={country}/>) : <tr>
<td>{t('generic.noData')}</td>
<td>-</td>
<td>-</td>
<td>-</td>
</tr>}
</tbody>
</table>
</Scrollable>
<DataTablesTable id={"ping-table"} options={options} colorClass={"bg-amber"}/>
)
};

View File

@ -106,9 +106,9 @@ const PlayerTable = ({data, orderBy}) => {
pingAverage: player.pingAverage,
pingAverageFormatted: formatDecimals(player.pingAverage, decimalFormat) + "ms",
pingMax: player.pingMax,
pingMaxFormatted: formatDecimals(player.pingMax, decimalFormat) + "ms",
pingMaxFormatted: player.pingMax + "ms",
pingMin: player.pingMin,
pingMinFormatted: formatDecimals(player.pingMin, decimalFormat) + "ms"
pingMinFormatted: player.pingMin + "ms"
};
data.extensionDescriptors.forEach(descriptor => {
row[descriptor.name] = <ExtensionValueTableCell data={player.extensionValues[descriptor.name]}/>;

View File

@ -1,4 +1,4 @@
import {useEffect, useState} from "react";
import {useEffect, useMemo, useState} from "react";
import {useNavigation} from "./navigationHook";
import {useDataStore} from "./datastoreHook";
import {useMetadata} from "./metadataHook";
@ -23,7 +23,7 @@ export const useDataRequest = (fetchMethod, parameters, shouldRequest) => {
const timestamp = json.timestamp;
if (!staticSite && timestamp) {
// Data has timestamp, the data may come from cache
const acceptedTimestamp = timestamp + (refreshBarrierMs ? refreshBarrierMs : 15000);
const acceptedTimestamp = timestamp + (refreshBarrierMs || 15000);
if (acceptedTimestamp < updateRequested) {
// Request again, received data was too old
setTimeout(() => {
@ -66,5 +66,7 @@ export const useDataRequest = (fetchMethod, parameters, shouldRequest) => {
}, [fetchMethod, parameters.length, ...parameters, updateRequested, refreshBarrierMs, shouldRequest])
/* eslint-enable react-hooks/exhaustive-deps */
return {data, loadingError};
return useMemo(() => {
return {data, loadingError}
}, [data, loadingError]);
}

View File

@ -12,7 +12,7 @@ const ServerGeolocations = () => {
const seeGeolocations = hasPermission('page.server.geolocations.map');
const seePing = hasPermission('page.server.geolocations.ping.per.country');
const {data, loadingError} = useDataRequest(fetchGeolocations, [identifier], seeGeolocations);
const {pingData, pingLoadingError} = useDataRequest(fetchPingTable, [identifier], seePing);
const {data: pingData, loadingError: pingLoadingError} = useDataRequest(fetchPingTable, [identifier], seePing);
return (
<Geolocations className={"server-geolocations"}