mirror of
https://github.com/plan-player-analytics/Plan.git
synced 2024-12-23 01:27:42 +01:00
Implemented react side of export for frontend BETA
This commit is contained in:
parent
973ea05283
commit
059d4553aa
@ -142,7 +142,7 @@ task determineAssetModifications {
|
||||
def modified = gitModifiedAsString.isEmpty() ? System.currentTimeMillis() : Long.parseLong(gitModifiedAsString) * 1000
|
||||
def relativePath = tree.getDir().toPath().relativize(f.toPath()) // File path relative to the tree
|
||||
versionFile.text += String.format(
|
||||
"%s: %s\n", relativePath.toString().replace('.', ','), modified
|
||||
"%s: %s\n", relativePath.toString().replace('.', ',').replace('\\', '/'), modified
|
||||
)
|
||||
}
|
||||
tree = fileTree(dir: 'src/main/resources/assets/plan/locale')
|
||||
@ -157,16 +157,17 @@ task determineAssetModifications {
|
||||
def modified = gitModifiedAsString.isEmpty() ? System.currentTimeMillis() : Long.parseLong(gitModifiedAsString) * 1000
|
||||
def relativePath = tree.getDir().toPath().relativize(f.toPath()) // File path relative to the tree
|
||||
versionFile.text += String.format(
|
||||
"%s: %s\n", relativePath.toString().replace('.', ','), modified
|
||||
"%s: %s\n", relativePath.toString().replace('.', ',').replace('\\', '/'), modified
|
||||
)
|
||||
}
|
||||
|
||||
tree = fileTree("$rootDir/react/dashboard/build")
|
||||
tree.forEach { File f ->
|
||||
if (f.getName().endsWith(".map")) return
|
||||
def modified = System.currentTimeMillis()
|
||||
def relativePath = tree.getDir().toPath().relativize(f.toPath()) // File path relative to the tree
|
||||
versionFile.text += String.format(
|
||||
"%s: %s\n", relativePath.toString().replace('.', ','), modified
|
||||
"%s: %s\n", relativePath.toString().replace('.', ',').replace('\\', '/'), modified
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -20,6 +20,7 @@ import com.djrapitops.plan.identification.Server;
|
||||
import com.djrapitops.plan.identification.ServerInfo;
|
||||
import com.djrapitops.plan.settings.config.PlanConfig;
|
||||
import com.djrapitops.plan.settings.config.paths.ExportSettings;
|
||||
import com.djrapitops.plan.settings.config.paths.PluginSettings;
|
||||
import com.djrapitops.plan.storage.database.DBSystem;
|
||||
import com.djrapitops.plan.storage.database.Database;
|
||||
import com.djrapitops.plan.storage.database.queries.objects.ServerQueries;
|
||||
@ -79,10 +80,22 @@ public class ExportScheduler extends PluginRunnable {
|
||||
return;
|
||||
}
|
||||
|
||||
scheduleReactExport();
|
||||
scheduleServerPageExport();
|
||||
schedulePlayersPageExport();
|
||||
}
|
||||
|
||||
private void scheduleReactExport() {
|
||||
if (config.isFalse(PluginSettings.FRONTEND_BETA) ||
|
||||
config.isFalse(ExportSettings.SERVER_PAGE) &&
|
||||
config.isFalse(ExportSettings.PLAYER_PAGES) &&
|
||||
config.isFalse(ExportSettings.PLAYERS_PAGE)) {return;}
|
||||
|
||||
runnableFactory.create(
|
||||
new ExportTask(exporter, Exporter::exportReact, errorLogger)
|
||||
).runTaskLaterAsynchronously(TimeAmount.toTicks(5, TimeUnit.SECONDS));
|
||||
}
|
||||
|
||||
private void schedulePlayersPageExport() {
|
||||
long period = TimeAmount.toTicks(config.get(ExportSettings.EXPORT_PERIOD), TimeUnit.MILLISECONDS)
|
||||
/ 4;
|
||||
|
@ -17,8 +17,13 @@
|
||||
package com.djrapitops.plan.delivery.export;
|
||||
|
||||
import com.djrapitops.plan.delivery.web.AssetVersions;
|
||||
import com.djrapitops.plan.delivery.web.resolver.Response;
|
||||
import com.djrapitops.plan.delivery.web.resolver.request.Request;
|
||||
import com.djrapitops.plan.delivery.webserver.resolver.json.RootJSONResolver;
|
||||
import com.djrapitops.plan.exceptions.connection.WebException;
|
||||
import com.djrapitops.plan.settings.config.PlanConfig;
|
||||
import com.djrapitops.plan.settings.config.paths.WebserverSettings;
|
||||
import com.djrapitops.plan.settings.locale.LangCode;
|
||||
import com.djrapitops.plan.storage.file.PlanFiles;
|
||||
import com.djrapitops.plan.storage.file.Resource;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
@ -27,7 +32,9 @@ import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
@ -40,16 +47,19 @@ public class ReactExporter extends FileExporter {
|
||||
|
||||
private final PlanFiles files;
|
||||
private final PlanConfig config;
|
||||
private final RootJSONResolver jsonHandler;
|
||||
private final AssetVersions assetVersions;
|
||||
|
||||
@Inject
|
||||
public ReactExporter(
|
||||
PlanFiles files,
|
||||
PlanConfig config,
|
||||
RootJSONResolver jsonHandler,
|
||||
AssetVersions assetVersions
|
||||
) {
|
||||
this.files = files;
|
||||
this.config = config;
|
||||
this.jsonHandler = jsonHandler;
|
||||
this.assetVersions = assetVersions;
|
||||
}
|
||||
|
||||
@ -62,6 +72,21 @@ public class ReactExporter extends FileExporter {
|
||||
exportAsset(toDirectory, "manifest.json");
|
||||
exportAsset(toDirectory, "robots.txt");
|
||||
exportStaticBundle(toDirectory);
|
||||
exportLocaleJson(toDirectory.resolve("locale"));
|
||||
exportMetadataJson(toDirectory.resolve("metadata"));
|
||||
}
|
||||
|
||||
private void exportMetadataJson(Path toDirectory) throws IOException {
|
||||
exportJson(toDirectory, "metadata");
|
||||
exportJson(toDirectory, "version");
|
||||
exportJson(toDirectory, "networkMetadata");
|
||||
}
|
||||
|
||||
private void exportLocaleJson(Path toDirectory) throws IOException {
|
||||
exportJson(toDirectory, "locale"); // List of languages
|
||||
for (LangCode langCode : LangCode.values()) {
|
||||
exportJson(toDirectory, "locale/" + langCode.name(), langCode.name());
|
||||
}
|
||||
}
|
||||
|
||||
private void exportStaticBundle(Path toDirectory) throws IOException {
|
||||
@ -89,4 +114,29 @@ public class ReactExporter extends FileExporter {
|
||||
export(toDirectory.resolve(asset), files.getResourceFromJar("web/" + asset));
|
||||
}
|
||||
|
||||
private void exportJson(Path toDirectory, String resource) throws IOException {
|
||||
exportJson(toDirectory, resource, toJsonResourceName(resource));
|
||||
}
|
||||
|
||||
private void exportJson(Path toDirectory, String resource, String fileName) throws IOException {
|
||||
Path to = toDirectory.resolve(fileName + ".json");
|
||||
Optional<Response> jsonResponse = getJsonResponse(resource);
|
||||
if (jsonResponse.isPresent()) {
|
||||
export(to, jsonResponse.get().getBytes());
|
||||
}
|
||||
}
|
||||
|
||||
private String toJsonResourceName(String resource) {
|
||||
return StringUtils.replaceEach(resource, new String[]{"?", "&",}, new String[]{"-", "_"});
|
||||
}
|
||||
|
||||
private Optional<Response> getJsonResponse(String resource) {
|
||||
try {
|
||||
return jsonHandler.getResolver().resolve(new Request("GET", "/v1/" + resource, null, Collections.emptyMap()));
|
||||
} catch (WebException e) {
|
||||
// The rest of the exceptions should not be thrown
|
||||
throw new IllegalStateException("Unexpected exception thrown: " + e, e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -24,15 +24,16 @@ import org.junit.jupiter.api.AfterAll;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.junit.jupiter.api.function.Executable;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertAll;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
@ExtendWith(FullSystemExtension.class)
|
||||
class ReactExporterTest {
|
||||
@ -56,11 +57,12 @@ class ReactExporterTest {
|
||||
.resolve("../react/dashboard/build");
|
||||
|
||||
List<Path> filesToExport = Files.list(reactBuildPath)
|
||||
.filter(path -> !path.endsWith(".map"))
|
||||
.map(path -> path.relativize(reactBuildPath))
|
||||
.collect(Collectors.toList());
|
||||
List<Path> filesExported = Files.list(exportPath)
|
||||
.map(path -> path.relativize(exportPath))
|
||||
.collect(Collectors.toList());
|
||||
assertEquals(filesToExport, filesExported);
|
||||
.toList();
|
||||
List<Path> filesExported = Files.list(exportPath).map(path -> path.relativize(exportPath)).toList();
|
||||
assertAll(filesToExport.stream()
|
||||
.map(path -> (Executable) () -> assertTrue(filesExported.contains(path)))
|
||||
.toList());
|
||||
}
|
||||
}
|
@ -12,6 +12,7 @@ import {MetadataContextProvider} from "./hooks/metadataHook";
|
||||
import {AuthenticationContextProvider} from "./hooks/authenticationHook";
|
||||
import {NavigationContextProvider} from "./hooks/navigationHook";
|
||||
import MainPageRedirect from "./components/navigation/MainPageRedirect";
|
||||
import {staticSite} from "./service/backendConfiguration";
|
||||
|
||||
const PlayerPage = React.lazy(() => import("./views/layout/PlayerPage"));
|
||||
const PlayerOverview = React.lazy(() => import("./views/player/PlayerOverview"));
|
||||
@ -51,6 +52,7 @@ const QueryResultView = React.lazy(() => import("./views/query/QueryResultView")
|
||||
|
||||
const LoginPage = React.lazy(() => import("./views/layout/LoginPage"));
|
||||
const RegisterPage = React.lazy(() => import("./views/layout/RegisterPage"));
|
||||
const ErrorPage = React.lazy(() => import("./views/layout/ErrorPage"));
|
||||
const ErrorsPage = React.lazy(() => import("./views/layout/ErrorsPage"));
|
||||
const SwaggerView = React.lazy(() => import("./views/SwaggerView"));
|
||||
|
||||
@ -90,8 +92,9 @@ function App() {
|
||||
<Routes>
|
||||
<Route path="" element={<MainPageRedirect/>}/>
|
||||
<Route path="/" element={<MainPageRedirect/>}/>
|
||||
<Route path="/login" element={<Lazy><LoginPage/></Lazy>}/>
|
||||
<Route path="/register" element={<Lazy><RegisterPage/></Lazy>}/>
|
||||
<Route path="index.html" element={<MainPageRedirect/>}/>
|
||||
{!staticSite && <Route path="/login" element={<Lazy><LoginPage/></Lazy>}/>}
|
||||
{!staticSite && <Route path="/register" element={<Lazy><RegisterPage/></Lazy>}/>}
|
||||
<Route path="/player/:identifier" element={<Lazy><PlayerPage/></Lazy>}>
|
||||
<Route path="" element={<Lazy><OverviewRedirect/></Lazy>}/>
|
||||
<Route path="overview" element={<Lazy><PlayerOverview/></Lazy>}/>
|
||||
@ -134,7 +137,8 @@ function App() {
|
||||
<Route path="overview" element={<Lazy><NetworkOverview/></Lazy>}/>
|
||||
<Route path="serversOverview" element={<Lazy><NetworkServers/></Lazy>}/>
|
||||
<Route path="sessions" element={<Lazy><NetworkSessions/></Lazy>}/>
|
||||
<Route path="performance" element={<Lazy><NetworkPerformance/></Lazy>}/>
|
||||
{!staticSite &&
|
||||
<Route path="performance" element={<Lazy><NetworkPerformance/></Lazy>}/>}
|
||||
<Route path="playerbase" element={<Lazy><NetworkPlayerbaseOverview/></Lazy>}/>
|
||||
<Route path="join-addresses" element={<Lazy><NetworkJoinAddresses/></Lazy>}/>
|
||||
<Route path="players" element={<Lazy><AllPlayers/></Lazy>}/>
|
||||
@ -147,13 +151,18 @@ function App() {
|
||||
icon: faMapSigns
|
||||
}}/>}/>
|
||||
</Route>
|
||||
<Route path="/query" element={<Lazy><QueryPage/></Lazy>}>
|
||||
{!staticSite && <Route path="/query" element={<Lazy><QueryPage/></Lazy>}>
|
||||
<Route path="" element={<NewRedirect/>}/>
|
||||
<Route path="new" element={<Lazy><NewQueryView/></Lazy>}/>
|
||||
<Route path="result" element={<Lazy><QueryResultView/></Lazy>}/>
|
||||
</Route>
|
||||
<Route path="/errors" element={<Lazy><ErrorsPage/></Lazy>}/>
|
||||
<Route path="/docs" element={<Lazy><SwaggerView/></Lazy>}/>
|
||||
</Route>}
|
||||
{!staticSite && <Route path="/errors" element={<Lazy><ErrorsPage/></Lazy>}/>}
|
||||
{!staticSite && <Route path="/docs" element={<Lazy><SwaggerView/></Lazy>}/>}
|
||||
<Route path="*" element={<Lazy><ErrorPage error={{
|
||||
message: 'Page not found, please correct the address',
|
||||
title: 'No such page',
|
||||
icon: faMapSigns
|
||||
}}/></Lazy>}/>
|
||||
</Routes>
|
||||
</BrowserRouter>
|
||||
</div>
|
||||
|
@ -10,7 +10,7 @@ import DropdownToggle from "react-bootstrap-v5/lib/esm/DropdownToggle";
|
||||
import {localeService} from "../../service/localeService";
|
||||
import {useTranslation} from "react-i18next";
|
||||
import {useNavigation} from "../../hooks/navigationHook";
|
||||
import {baseAddress} from "../../service/backendConfiguration";
|
||||
import {baseAddress, staticSite} from "../../service/backendConfiguration";
|
||||
|
||||
const LanguageSelector = () => {
|
||||
const languages = localeService.getLanguages();
|
||||
@ -55,9 +55,9 @@ const Header = ({page, tab, hideUpdater}) => {
|
||||
{!hideUpdater && <>
|
||||
<span className="topbar-divider"/>
|
||||
<div className="refresh-element">
|
||||
<button onClick={requestUpdate}>
|
||||
{!staticSite && <button onClick={requestUpdate}>
|
||||
<Fa icon={faSyncAlt} spin={Boolean(updating)}/>
|
||||
</button>
|
||||
</button>}
|
||||
{' '}
|
||||
<span className="refresh-time">{lastUpdate.formatted}</span>
|
||||
</div>
|
||||
|
@ -230,7 +230,7 @@ const Sidebar = ({items, showBackButton}) => {
|
||||
<Item active={false} item={{href: "/", icon: faArrowLeft, name: t('html.label.toMainPage')}}/>
|
||||
<Divider showMargin={items.length && !items[0].contents && items[0].href === undefined}/>
|
||||
</>}
|
||||
{items.length ? items.map((item, i) => renderItem(item, i, openCollapse, toggleCollapse, t)) : ''}
|
||||
{items.length ? items.filter(item => item !== undefined).map((item, i) => renderItem(item, i, openCollapse, toggleCollapse, t)) : ''}
|
||||
<Divider/>
|
||||
<FooterButtons/>
|
||||
</ul>}
|
||||
|
@ -2,6 +2,7 @@ import {useEffect, useState} from "react";
|
||||
import {useNavigation} from "./navigationHook";
|
||||
import {useDataStore} from "./datastoreHook";
|
||||
import {useMetadata} from "./metadataHook";
|
||||
import {staticSite} from "../service/backendConfiguration";
|
||||
|
||||
export const useDataRequest = (fetchMethod, parameters) => {
|
||||
const [data, setData] = useState(undefined);
|
||||
@ -16,7 +17,7 @@ export const useDataRequest = (fetchMethod, parameters) => {
|
||||
const handleResponse = (json, error, skipOldData, timeout) => {
|
||||
if (json) {
|
||||
const timestamp = json.timestamp;
|
||||
if (timestamp) {
|
||||
if (staticSite || timestamp) {
|
||||
// Data has timestamp, the data may come from cache
|
||||
const acceptedTimestamp = timestamp + (refreshBarrierMs ? refreshBarrierMs : 15000);
|
||||
if (acceptedTimestamp < updateRequested) {
|
||||
|
@ -1,6 +1,9 @@
|
||||
import {doGetRequest, doSomePostRequest, standard200option} from "./backendConfiguration";
|
||||
import {doGetRequest, doSomePostRequest, standard200option, staticSite} from "./backendConfiguration";
|
||||
|
||||
export const fetchWhoAmI = async () => {
|
||||
if (staticSite) {
|
||||
return {authRequired: false, loggedIn: false}
|
||||
}
|
||||
const url = '/v1/whoami';
|
||||
return doGetRequest(url);
|
||||
}
|
||||
|
@ -11,11 +11,8 @@ const isCurrentAddress = (address) => {
|
||||
return is;
|
||||
}
|
||||
|
||||
// Concat to prevent double string replacement.
|
||||
/*eslint-disable no-useless-concat */
|
||||
export const baseAddress = "PLAN_BASE" + "_ADDRESS" === javaReplaced.address || !isCurrentAddress(javaReplaced.address) ? "" : javaReplaced.address;
|
||||
export const staticSite = "PLAN_EXPORTED" + "_VERSION" !== javaReplaced.isStatic;
|
||||
/*eslint-enable no-useless-concat */
|
||||
export const baseAddress = javaReplaced.address.startsWith('PLAN_') || !isCurrentAddress(javaReplaced.address) ? "" : javaReplaced.address;
|
||||
export const staticSite = javaReplaced.isStatic === 'true';
|
||||
|
||||
export const doSomeGetRequest = async (url, statusOptions) => {
|
||||
return doSomeRequest(url, statusOptions, async () => axios.get(url));
|
||||
|
@ -4,6 +4,7 @@ import I18NextLocalStorageBackend from "i18next-localstorage-backend";
|
||||
import I18NextHttpBackend from 'i18next-http-backend';
|
||||
import {initReactI18next} from 'react-i18next';
|
||||
import {fetchAvailableLocales} from "./metadataService";
|
||||
import {baseAddress, staticSite} from "./backendConfiguration";
|
||||
|
||||
/**
|
||||
* A locale system for localizing the website.
|
||||
@ -53,6 +54,8 @@ export const localeService = {
|
||||
this.clientLocale = this.defaultLanguage;
|
||||
}
|
||||
|
||||
let loadPath = baseAddress + '/v1/locale/{{lng}}';
|
||||
if (staticSite) loadPath = baseAddress + '/locale/{{lng}}.json'
|
||||
await i18next
|
||||
.use(I18NextChainedBackend)
|
||||
.use(initReactI18next)
|
||||
@ -70,7 +73,7 @@ export const localeService = {
|
||||
expirationTime: 7 * 24 * 60 * 60 * 1000, // 7 days
|
||||
versions: this.languageVersions
|
||||
}, {
|
||||
loadPath: '/v1/locale/{{lng}}'
|
||||
loadPath: loadPath
|
||||
}]
|
||||
},
|
||||
}, () => {/* No need to initialize anything */
|
||||
|
@ -1,26 +1,30 @@
|
||||
import {doGetRequest} from "./backendConfiguration";
|
||||
import {doGetRequest, staticSite} from "./backendConfiguration";
|
||||
|
||||
export const fetchPlanMetadata = async () => {
|
||||
const url = '/v1/metadata';
|
||||
let url = '/v1/metadata';
|
||||
if (staticSite) url = '/metadata/metadata.json'
|
||||
return doGetRequest(url);
|
||||
}
|
||||
|
||||
export const fetchPlanVersion = async () => {
|
||||
const url = '/v1/version';
|
||||
let url = '/v1/version';
|
||||
if (staticSite) url = '/metadata/version.json'
|
||||
return doGetRequest(url);
|
||||
}
|
||||
|
||||
export const fetchAvailableLocales = async () => {
|
||||
const url = '/v1/locale';
|
||||
let url = '/v1/locale';
|
||||
if (staticSite) url = '/locale/locale.json'
|
||||
return doGetRequest(url);
|
||||
}
|
||||
|
||||
export const fetchErrorLogs = async () => {
|
||||
const url = '/v1/errors';
|
||||
let url = '/v1/errors';
|
||||
return doGetRequest(url);
|
||||
}
|
||||
|
||||
export const fetchNetworkMetadata = async () => {
|
||||
const url = '/v1/networkMetadata';
|
||||
let url = '/v1/networkMetadata';
|
||||
if (staticSite) url = '/metadata/networkMetadata.json'
|
||||
return doGetRequest(url);
|
||||
}
|
@ -1,36 +1,42 @@
|
||||
import {doGetRequest} from "./backendConfiguration";
|
||||
import {doGetRequest, staticSite} from "./backendConfiguration";
|
||||
|
||||
export const fetchNetworkOverview = async (updateRequested) => {
|
||||
const url = `/v1/network/overview?timestamp=${updateRequested}`;
|
||||
let url = `/v1/network/overview?timestamp=${updateRequested}`;
|
||||
if (staticSite) url = `/data/network-overview.json`;
|
||||
return doGetRequest(url);
|
||||
}
|
||||
|
||||
export const fetchServersOverview = async (updateRequested) => {
|
||||
const url = `/v1/network/servers?timestamp=${updateRequested}`;
|
||||
let url = `/v1/network/servers?timestamp=${updateRequested}`;
|
||||
if (staticSite) url = `/data/network-servers.json`;
|
||||
return doGetRequest(url);
|
||||
}
|
||||
|
||||
export const fetchServerPie = async (timestamp) => {
|
||||
const url = `/v1/graph?type=serverPie×tamp=${timestamp}`;
|
||||
let url = `/v1/graph?type=serverPie×tamp=${timestamp}`;
|
||||
if (staticSite) url = `/data/graph-serverPie.json`;
|
||||
return doGetRequest(url);
|
||||
}
|
||||
|
||||
export const fetchNetworkSessionsOverview = async (timestamp) => {
|
||||
const url = `/v1/network/sessionsOverview?timestamp=${timestamp}`;
|
||||
let url = `/v1/network/sessionsOverview?timestamp=${timestamp}`;
|
||||
if (staticSite) url = `/data/network-sessionsOverview.json`;
|
||||
return doGetRequest(url);
|
||||
}
|
||||
|
||||
export const fetchNetworkPlayerbaseOverview = async (timestamp) => {
|
||||
const url = `/v1/network/playerbaseOverview?timestamp=${timestamp}`;
|
||||
let url = `/v1/network/playerbaseOverview?timestamp=${timestamp}`;
|
||||
if (staticSite) url = `/data/network-playerbaseOverview.json`;
|
||||
return doGetRequest(url);
|
||||
}
|
||||
|
||||
export const fetchNetworkPingTable = async (timestamp) => {
|
||||
const url = `/v1/network/pingTable?timestamp=${timestamp}`;
|
||||
let url = `/v1/network/pingTable?timestamp=${timestamp}`;
|
||||
if (staticSite) url = `/data/network-pingTable.json`;
|
||||
return doGetRequest(url);
|
||||
}
|
||||
|
||||
export const fetchNetworkPerformanceOverview = async (timestamp, serverUUIDs) => {
|
||||
const url = `/v1/network/performanceOverview?servers=${encodeURIComponent(JSON.stringify(serverUUIDs))}×tamp=${timestamp}`;
|
||||
let url = `/v1/network/performanceOverview?servers=${encodeURIComponent(JSON.stringify(serverUUIDs))}×tamp=${timestamp}`;
|
||||
return doGetRequest(url);
|
||||
}
|
@ -1,130 +1,270 @@
|
||||
import {doGetRequest} from "./backendConfiguration";
|
||||
|
||||
import {doGetRequest, staticSite} from "./backendConfiguration";
|
||||
|
||||
export const fetchServerIdentity = async (timestamp, identifier) => {
|
||||
const url = `/v1/serverIdentity?server=${identifier}`;
|
||||
let url = `/v1/serverIdentity?server=${identifier}`;
|
||||
if (staticSite) url = `/data/serverIdentity-${identifier}.json`;
|
||||
return doGetRequest(url);
|
||||
}
|
||||
|
||||
export const fetchServerOverview = async (timestamp, identifier) => {
|
||||
const url = `/v1/serverOverview?server=${identifier}×tamp=${timestamp}`;
|
||||
let url = `/v1/serverOverview?server=${identifier}×tamp=${timestamp}`;
|
||||
if (staticSite) url = `/data/serverOverview-${identifier}.json`;
|
||||
return doGetRequest(url);
|
||||
}
|
||||
|
||||
export const fetchOnlineActivityOverview = async (timestamp, identifier) => {
|
||||
const url = `/v1/onlineOverview?server=${identifier}×tamp=${timestamp}`;
|
||||
let url = `/v1/onlineOverview?server=${identifier}×tamp=${timestamp}`;
|
||||
if (staticSite) url = `/data/onlineOverview-${identifier}.json`;
|
||||
return doGetRequest(url);
|
||||
}
|
||||
|
||||
export const fetchPlayerbaseOverview = async (timestamp, identifier) => {
|
||||
const url = `/v1/playerbaseOverview?server=${identifier}×tamp=${timestamp}`;
|
||||
let url = `/v1/playerbaseOverview?server=${identifier}×tamp=${timestamp}`;
|
||||
if (staticSite) url = `/data/playerbaseOverview-${identifier}.json`;
|
||||
return doGetRequest(url);
|
||||
}
|
||||
|
||||
export const fetchSessionOverview = async (timestamp, identifier) => {
|
||||
const url = `/v1/sessionsOverview?server=${identifier}×tamp=${timestamp}`;
|
||||
let url = `/v1/sessionsOverview?server=${identifier}×tamp=${timestamp}`;
|
||||
if (staticSite) url = `/data/sessionsOverview-${identifier}.json`;
|
||||
return doGetRequest(url);
|
||||
}
|
||||
|
||||
export const fetchPvpPve = async (timestamp, identifier) => {
|
||||
const url = `/v1/playerVersus?server=${identifier}×tamp=${timestamp}`;
|
||||
let url = `/v1/playerVersus?server=${identifier}×tamp=${timestamp}`;
|
||||
if (staticSite) url = `/data/playerVersus-${identifier}.json`;
|
||||
return doGetRequest(url);
|
||||
}
|
||||
|
||||
export const fetchPerformanceOverview = async (timestamp, identifier) => {
|
||||
const url = `/v1/performanceOverview?server=${identifier}×tamp=${timestamp}`;
|
||||
let url = `/v1/performanceOverview?server=${identifier}×tamp=${timestamp}`;
|
||||
if (staticSite) url = `/data/performanceOverview-${identifier}.json`;
|
||||
return doGetRequest(url);
|
||||
}
|
||||
|
||||
export const fetchExtensionData = async (timestamp, identifier) => {
|
||||
const url = `/v1/extensionData?server=${identifier}×tamp=${timestamp}`;
|
||||
let url = `/v1/extensionData?server=${identifier}×tamp=${timestamp}`;
|
||||
if (staticSite) url = `/data/extensionData-${identifier}.json`;
|
||||
return doGetRequest(url);
|
||||
}
|
||||
|
||||
export const fetchSessions = async (timestamp, identifier) => {
|
||||
const url = identifier ? `/v1/sessions?server=${identifier}×tamp=${timestamp}` :
|
||||
`/v1/sessions?timestamp=${timestamp}`;
|
||||
if (identifier) {
|
||||
return await fetchSessionsServer(timestamp, identifier);
|
||||
} else {
|
||||
return await fetchSessionsNetwork(timestamp);
|
||||
}
|
||||
}
|
||||
|
||||
const fetchSessionsServer = async (timestamp, identifier) => {
|
||||
let url = `/v1/sessions?server=${identifier}×tamp=${timestamp}`;
|
||||
if (staticSite) url = `/data/sessions-${identifier}.json`;
|
||||
return doGetRequest(url);
|
||||
}
|
||||
|
||||
const fetchSessionsNetwork = async (timestamp) => {
|
||||
let url = `/v1/sessions?timestamp=${timestamp}`;
|
||||
if (staticSite) url = `/data/sessions.json`;
|
||||
return doGetRequest(url);
|
||||
}
|
||||
|
||||
export const fetchKills = async (timestamp, identifier) => {
|
||||
const url = `/v1/kills?server=${identifier}×tamp=${timestamp}`;
|
||||
let url = `/v1/kills?server=${identifier}×tamp=${timestamp}`;
|
||||
if (staticSite) url = `/data/kills-${identifier}.json`;
|
||||
return doGetRequest(url);
|
||||
}
|
||||
|
||||
export const fetchPlayers = async (timestamp, identifier) => {
|
||||
const url = identifier ? `/v1/players?server=${identifier}×tamp=${timestamp}` : `/v1/players?timestamp=${timestamp}`;
|
||||
if (identifier) {
|
||||
return await fetchPlayersServer(timestamp, identifier);
|
||||
} else {
|
||||
return await fetchPlayersNetwork(timestamp);
|
||||
}
|
||||
}
|
||||
const fetchPlayersServer = async (timestamp, identifier) => {
|
||||
let url = `/v1/players?server=${identifier}×tamp=${timestamp}`;
|
||||
if (staticSite) url = `/data/players-${identifier}.json`;
|
||||
return doGetRequest(url);
|
||||
}
|
||||
|
||||
const fetchPlayersNetwork = async (timestamp) => {
|
||||
let url = `/v1/players?timestamp=${timestamp}`;
|
||||
if (staticSite) url = `/data/players.json`;
|
||||
return doGetRequest(url);
|
||||
}
|
||||
|
||||
export const fetchPingTable = async (timestamp, identifier) => {
|
||||
const url = `/v1/pingTable?server=${identifier}×tamp=${timestamp}`;
|
||||
let url = `/v1/pingTable?server=${identifier}×tamp=${timestamp}`;
|
||||
if (staticSite) url = `/data/pingTable-${identifier}.json`;
|
||||
return doGetRequest(url);
|
||||
}
|
||||
|
||||
export const fetchPlayersOnlineGraph = async (timestamp, identifier) => {
|
||||
const url = identifier ? `/v1/graph?type=playersOnline&server=${identifier}×tamp=${timestamp}` :
|
||||
`/v1/graph?type=playersOnline×tamp=${timestamp}`;
|
||||
if (identifier) {
|
||||
return await fetchPlayersOnlineGraphServer(timestamp, identifier);
|
||||
} else {
|
||||
return await fetchPlayersOnlineGraphNetwork(timestamp);
|
||||
}
|
||||
}
|
||||
|
||||
const fetchPlayersOnlineGraphServer = async (timestamp, identifier) => {
|
||||
let url = `/v1/graph?type=playersOnline&server=${identifier}×tamp=${timestamp}`;
|
||||
if (staticSite) url = `/data/graph-playersOnline_${identifier}.json`;
|
||||
return doGetRequest(url);
|
||||
}
|
||||
|
||||
const fetchPlayersOnlineGraphNetwork = async (timestamp) => {
|
||||
let url = `/v1/graph?type=playersOnline×tamp=${timestamp}`;
|
||||
if (staticSite) url = `/data/graph-playersOnline.json`;
|
||||
return doGetRequest(url);
|
||||
}
|
||||
|
||||
export const fetchPlayerbaseDevelopmentGraph = async (timestamp, identifier) => {
|
||||
const url = identifier ? `/v1/graph?type=activity&server=${identifier}×tamp=${timestamp}` :
|
||||
`/v1/graph?type=activity×tamp=${timestamp}`;
|
||||
if (identifier) {
|
||||
return await fetchPlayerbaseDevelopmentGraphServer(timestamp, identifier);
|
||||
} else {
|
||||
return await fetchPlayerbaseDevelopmentGraphNetwork(timestamp);
|
||||
}
|
||||
}
|
||||
|
||||
const fetchPlayerbaseDevelopmentGraphServer = async (timestamp, identifier) => {
|
||||
let url = `/v1/graph?type=activity&server=${identifier}×tamp=${timestamp}`;
|
||||
if (staticSite) url = `/data/graph-activity_${identifier}.json`;
|
||||
return doGetRequest(url);
|
||||
}
|
||||
|
||||
const fetchPlayerbaseDevelopmentGraphNetwork = async (timestamp) => {
|
||||
let url = `/v1/graph?type=activity×tamp=${timestamp}`;
|
||||
if (staticSite) url = `/data/graph-activity.json`;
|
||||
return doGetRequest(url);
|
||||
}
|
||||
|
||||
export const fetchDayByDayGraph = async (timestamp, identifier) => {
|
||||
const url = identifier ? `/v1/graph?type=uniqueAndNew&server=${identifier}×tamp=${timestamp}` :
|
||||
`/v1/graph?type=uniqueAndNew×tamp=${timestamp}`;
|
||||
if (identifier) {
|
||||
return await fetchDayByDayGraphServer(timestamp, identifier);
|
||||
} else {
|
||||
return await fetchDayByDayGraphNetwork(timestamp);
|
||||
}
|
||||
}
|
||||
|
||||
const fetchDayByDayGraphServer = async (timestamp, identifier) => {
|
||||
let url = `/v1/graph?type=uniqueAndNew&server=${identifier}×tamp=${timestamp}`;
|
||||
if (staticSite) url = `/data/graph-uniqueAndNew_${identifier}.json`;
|
||||
return doGetRequest(url);
|
||||
}
|
||||
|
||||
const fetchDayByDayGraphNetwork = async (timestamp) => {
|
||||
let url = `/v1/graph?type=uniqueAndNew×tamp=${timestamp}`;
|
||||
if (staticSite) url = `/data/graph-uniqueAndNew.json`;
|
||||
return doGetRequest(url);
|
||||
}
|
||||
|
||||
export const fetchHourByHourGraph = async (timestamp, identifier) => {
|
||||
const url = identifier ? `/v1/graph?type=hourlyUniqueAndNew&server=${identifier}×tamp=${timestamp}` :
|
||||
`/v1/graph?type=hourlyUniqueAndNew×tamp=${timestamp}`;
|
||||
if (identifier) {
|
||||
return await fetchHourByHourGraphServer(timestamp, identifier);
|
||||
} else {
|
||||
return await fetchHourByHourGraphNetwork(timestamp);
|
||||
}
|
||||
}
|
||||
|
||||
const fetchHourByHourGraphServer = async (timestamp, identifier) => {
|
||||
let url = `/v1/graph?type=hourlyUniqueAndNew&server=${identifier}×tamp=${timestamp}`;
|
||||
if (staticSite) url = `/data/graph-hourlyUniqueAndNew_${identifier}.json`;
|
||||
return doGetRequest(url);
|
||||
}
|
||||
|
||||
const fetchHourByHourGraphNetwork = async (timestamp) => {
|
||||
let url = `/v1/graph?type=hourlyUniqueAndNew×tamp=${timestamp}`;
|
||||
if (staticSite) url = `/data/graph-hourlyUniqueAndNew.json`;
|
||||
return doGetRequest(url);
|
||||
}
|
||||
|
||||
export const fetchServerCalendarGraph = async (timestamp, identifier) => {
|
||||
const url = `/v1/graph?type=serverCalendar&server=${identifier}×tamp=${timestamp}`;
|
||||
let url = `/v1/graph?type=serverCalendar&server=${identifier}×tamp=${timestamp}`;
|
||||
if (staticSite) url = `/data/graph-serverCalendar_${identifier}.json`;
|
||||
return doGetRequest(url);
|
||||
}
|
||||
|
||||
export const fetchPunchCardGraph = async (timestamp, identifier) => {
|
||||
const url = `/v1/graph?type=punchCard&server=${identifier}×tamp=${timestamp}`;
|
||||
let url = `/v1/graph?type=punchCard&server=${identifier}×tamp=${timestamp}`;
|
||||
if (staticSite) url = `/data/graph-punchCard_${identifier}.json`;
|
||||
return doGetRequest(url);
|
||||
}
|
||||
|
||||
export const fetchWorldPie = async (timestamp, identifier) => {
|
||||
const url = `/v1/graph?type=worldPie&server=${identifier}×tamp=${timestamp}`;
|
||||
let url = `/v1/graph?type=worldPie&server=${identifier}×tamp=${timestamp}`;
|
||||
if (staticSite) url = `/data/graph-worldPie_${identifier}.json`;
|
||||
return doGetRequest(url);
|
||||
}
|
||||
|
||||
export const fetchGeolocations = async (timestamp, identifier) => {
|
||||
const url = identifier ? `/v1/graph?type=geolocation&server=${identifier}×tamp=${timestamp}` :
|
||||
`/v1/graph?type=geolocation×tamp=${timestamp}`;
|
||||
if (identifier) {
|
||||
return await fetchGeolocationsServer(timestamp, identifier);
|
||||
} else {
|
||||
return await fetchGeolocationsNetwork(timestamp);
|
||||
}
|
||||
}
|
||||
|
||||
const fetchGeolocationsServer = async (timestamp, identifier) => {
|
||||
let url = `/v1/graph?type=geolocation&server=${identifier}×tamp=${timestamp}`;
|
||||
if (staticSite) url = `/data/graph-geolocation_${identifier}.json`;
|
||||
return doGetRequest(url);
|
||||
}
|
||||
|
||||
const fetchGeolocationsNetwork = async (timestamp) => {
|
||||
let url = `/v1/graph?type=geolocation×tamp=${timestamp}`;
|
||||
if (staticSite) url = `/data/graph-geolocation.json`;
|
||||
return doGetRequest(url);
|
||||
}
|
||||
|
||||
export const fetchOptimizedPerformance = async (timestamp, identifier, after) => {
|
||||
const url = `/v1/graph?type=optimizedPerformance&server=${identifier}×tamp=${timestamp}&after=${after}`;
|
||||
let url = `/v1/graph?type=optimizedPerformance&server=${identifier}×tamp=${timestamp}&after=${after}`;
|
||||
if (staticSite) url = `/data/graph-optimizedPerformance_${identifier}.json`;
|
||||
return doGetRequest(url);
|
||||
}
|
||||
|
||||
export const fetchPingGraph = async (timestamp, identifier) => {
|
||||
const url = `/v1/graph?type=aggregatedPing&server=${identifier}×tamp=${timestamp}`;
|
||||
let url = `/v1/graph?type=aggregatedPing&server=${identifier}×tamp=${timestamp}`;
|
||||
if (staticSite) url = `/data/graph-aggregatedPing_${identifier}.json`;
|
||||
return doGetRequest(url);
|
||||
}
|
||||
|
||||
export const fetchJoinAddressPie = async (timestamp, identifier) => {
|
||||
const url = identifier ? `/v1/graph?type=joinAddressPie&server=${identifier}×tamp=${timestamp}` :
|
||||
`/v1/graph?type=joinAddressPie×tamp=${timestamp}`;
|
||||
if (identifier) {
|
||||
return await fetchJoinAddressPieServer(timestamp, identifier);
|
||||
} else {
|
||||
return await fetchJoinAddressPieNetwork(timestamp);
|
||||
}
|
||||
}
|
||||
|
||||
const fetchJoinAddressPieServer = async (timestamp, identifier) => {
|
||||
let url = `/v1/graph?type=joinAddressPie&server=${identifier}×tamp=${timestamp}`;
|
||||
if (staticSite) url = `/data/graph-joinAddressPie_${identifier}.json`;
|
||||
return doGetRequest(url);
|
||||
}
|
||||
|
||||
const fetchJoinAddressPieNetwork = async (timestamp) => {
|
||||
let url = `/v1/graph?type=joinAddressPie×tamp=${timestamp}`;
|
||||
if (staticSite) url = `/data/graph-joinAddressPie.json`;
|
||||
return doGetRequest(url);
|
||||
}
|
||||
|
||||
export const fetchJoinAddressByDay = async (timestamp, identifier) => {
|
||||
const url = identifier ? `/v1/graph?type=joinAddressByDay&server=${identifier}×tamp=${timestamp}` :
|
||||
`/v1/graph?type=joinAddressByDay×tamp=${timestamp}`;
|
||||
if (identifier) {
|
||||
return await fetchJoinAddressByDayServer(timestamp, identifier);
|
||||
} else {
|
||||
return await fetchJoinAddressByDayNetwork(timestamp);
|
||||
}
|
||||
}
|
||||
|
||||
const fetchJoinAddressByDayServer = async (timestamp, identifier) => {
|
||||
let url = `/v1/graph?type=joinAddressByDay&server=${identifier}×tamp=${timestamp}`;
|
||||
if (staticSite) url = `/data/graph-joinAddressByDay_${identifier}.json`;
|
||||
return doGetRequest(url);
|
||||
}
|
||||
|
||||
const fetchJoinAddressByDayNetwork = async (timestamp) => {
|
||||
let url = `/v1/graph?type=joinAddressByDay×tamp=${timestamp}`;
|
||||
if (staticSite) url = `/data/graph-joinAddressByDay.json`;
|
||||
return doGetRequest(url);
|
||||
}
|
||||
|
@ -12,7 +12,7 @@ const ErrorPage = ({error}) => {
|
||||
<NightModeCss/>
|
||||
<Sidebar items={[]} showBackButton={true}/>
|
||||
<div className="d-flex flex-column" id="content-wrapper">
|
||||
<Header page={error.title ? error.title : 'Unexpected error occurred'}/>
|
||||
<Header page={error.title ? error.title : 'Unexpected error occurred'} hideUpdater/>
|
||||
<div id="content" style={{display: 'flex'}}>
|
||||
<main className="container-fluid mt-4">
|
||||
<ErrorView error={error}/>
|
||||
|
@ -26,6 +26,7 @@ import {SwitchTransition} from "react-transition-group";
|
||||
import MainPageRedirect from "../../components/navigation/MainPageRedirect";
|
||||
import {ServerExtensionContextProvider, useServerExtensionContext} from "../../hooks/serverExtensionDataContext";
|
||||
import {iconTypeToFontAwesomeClass} from "../../util/icons";
|
||||
import {staticSite} from "../../service/backendConfiguration";
|
||||
|
||||
const NetworkSidebar = () => {
|
||||
const {t, i18n} = useTranslation();
|
||||
@ -49,7 +50,7 @@ const NetworkSidebar = () => {
|
||||
href: "serversOverview"
|
||||
},
|
||||
{name: 'html.label.sessions', icon: faCalendarCheck, href: "sessions"},
|
||||
{name: 'html.label.performance', icon: faCogs, href: "performance"},
|
||||
staticSite ? undefined : {name: 'html.label.performance', icon: faCogs, href: "performance"},
|
||||
{},
|
||||
...servers.map(server => {
|
||||
return {
|
||||
|
Loading…
Reference in New Issue
Block a user