Load server extension data in separate context to speed up loading time

This commit is contained in:
Aurora Lahtela 2022-08-31 18:06:08 +03:00
parent e772713ac0
commit 019a3353ca
4 changed files with 89 additions and 50 deletions

View File

@ -0,0 +1,30 @@
import {createContext, useContext, useEffect, useState} from "react";
import {useDataRequest} from "./dataFetchHook";
import {fetchExtensionData} from "../service/serverService";
import {useParams} from "react-router-dom";
const ServerExtensionContext = createContext({});
export const ServerExtensionContextProvider = ({children}) => {
const {identifier} = useParams();
const [extensionData, setExtensionData] = useState(undefined);
const [extensionDataLoadingError, setExtensionDataLoadingError] = useState(undefined);
const {data, loadingError} = useDataRequest(fetchExtensionData, [identifier]);
useEffect(() => {
setExtensionData(data);
setExtensionDataLoadingError(loadingError);
}, [data, loadingError, setExtensionData, setExtensionDataLoadingError])
const sharedState = {extensionData, extensionDataLoadingError}
return (<ServerExtensionContext.Provider value={sharedState}>
{children}
</ServerExtensionContext.Provider>
)
}
export const useServerExtensionContext = () => {
return useContext(ServerExtensionContext);
}

View File

@ -1,6 +1,6 @@
import React, {useEffect, useState} from "react";
import {useTranslation} from "react-i18next";
import {Outlet, useOutletContext, useParams} from "react-router-dom";
import {Outlet, useParams} from "react-router-dom";
import {useNavigation} from "../../hooks/navigationHook";
import {
faCampground,
@ -25,27 +25,19 @@ import ErrorPage from "./ErrorPage";
import {SwitchTransition} from "react-transition-group";
import MainPageRedirect from "../../components/navigation/MainPageRedirect";
import {useDataRequest} from "../../hooks/dataFetchHook";
import {fetchExtensionData, fetchServerIdentity} from "../../service/serverService";
import {fetchServerIdentity} from "../../service/serverService";
import ExtensionIcon from "../../components/extensions/ExtensionIcon";
import {ServerExtensionContextProvider, useServerExtensionContext} from "../../hooks/serverExtensionDataContext";
const ServerPage = () => {
const ServerSidebar = () => {
const {t, i18n} = useTranslation();
const {identifier} = useParams();
const {isProxy, serverName} = useMetadata();
const {
data: serverIdentity,
loadingError: identityLoadingError
} = useDataRequest(fetchServerIdentity, [identifier]);
const {
data: extensionData,
loadingError: extensionDataLoadingError
} = useDataRequest(fetchExtensionData, [identifier]);
const [error] = useState(undefined);
const [sidebarItems, setSidebarItems] = useState([]);
const {extensionData} = useServerExtensionContext();
const {authRequired, loggedIn, user} = useAuth();
const {currentTab} = useNavigation();
const {isProxy} = useMetadata();
const showBackButton = isProxy
&& (!authRequired || (loggedIn && user.permissions.filter(perm => perm !== 'page.network').length));
useEffect(() => {
const items = [
@ -84,10 +76,10 @@ const ServerPage = () => {
{name: 'html.label.performance', icon: faCogs, href: "performance"},
{},
{name: 'html.label.plugins'},
{name: 'html.label.pluginsOverview', icon: faCubes, href: "plugins-overview"}
]
if (extensionData) {
items.push({name: 'html.label.pluginsOverview', icon: faCubes, href: "plugins-overview"})
extensionData.extensions.filter(extension => extension.wide)
.map(extension => extension.extensionInformation)
.map(info => {
@ -109,12 +101,27 @@ const ServerPage = () => {
window.document.title = `Plan | Server Analysis`;
}, [t, i18n, extensionData])
const {authRequired, loggedIn, user} = useAuth();
return (
<Sidebar items={sidebarItems} showBackButton={showBackButton}/>
)
}
const ServerPage = () => {
const {t} = useTranslation();
const {identifier} = useParams();
const {isProxy, serverName} = useMetadata();
const {
data: serverIdentity,
loadingError: identityLoadingError
} = useDataRequest(fetchServerIdentity, [identifier]);
const [error] = useState(undefined);
const {currentTab} = useNavigation();
const {authRequired, loggedIn} = useAuth();
if (authRequired && !loggedIn) return <MainPageRedirect/>
const showBackButton = isProxy && (!authRequired || user.permissions.filter(perm => perm !== 'page.network').length);
const getDisplayedServerName = () => {
if (serverIdentity) {
return serverIdentity.serverName;
@ -134,34 +141,28 @@ const ServerPage = () => {
error={{title: t('html.error.404NotFound'), message: t('html.error.serverNotSeen')}}/>
return <ErrorPage error={identityLoadingError}/>
}
if (extensionDataLoadingError) {
return <ErrorPage error={extensionDataLoadingError}/>
}
if (!extensionData) return <></>
return (
<>
<NightModeCss/>
<Sidebar items={sidebarItems} showBackButton={showBackButton}/>
<div className="d-flex flex-column" id="content-wrapper">
<Header page={displayedServerName} tab={currentTab}/>
<div id="content" style={{display: 'flex'}}>
<main className="container-fluid mt-4">
<SwitchTransition>
<Outlet context={extensionData}/>
</SwitchTransition>
</main>
<aside>
<ColorSelectorModal/>
</aside>
<ServerExtensionContextProvider>
<ServerSidebar/>
<div className="d-flex flex-column" id="content-wrapper">
<Header page={displayedServerName} tab={currentTab}/>
<div id="content" style={{display: 'flex'}}>
<main className="container-fluid mt-4">
<SwitchTransition>
<Outlet/>
</SwitchTransition>
</main>
<aside>
<ColorSelectorModal/>
</aside>
</div>
</div>
</div>
</ServerExtensionContextProvider>
</>
)
}
export const useServer = () => {
return useOutletContext();
}
export default ServerPage;

View File

@ -1,13 +1,16 @@
import React, {useEffect} from 'react';
import {useServer} from "../layout/ServerPage";
import Masonry from "masonry-layout";
import LoadIn from "../../components/animation/LoadIn";
import {Card, Col, Row} from "react-bootstrap-v5";
import ExtensionCard, {ExtensionCardWrapper} from "../../components/extensions/ExtensionCard";
import Loader from "../../components/navigation/Loader";
import {useTranslation} from "react-i18next";
import {useServerExtensionContext} from "../../hooks/serverExtensionDataContext";
import ErrorView from "../ErrorView";
const ServerPluginData = () => {
const extensionData = useServer();
console.log(extensionData);
const {t} = useTranslation();
const {extensionData, extensionDataLoadingError} = useServerExtensionContext();
const extensions = extensionData ? extensionData.extensions.filter(extension => !extension.wide) : [];
useEffect(() => {
@ -23,6 +26,8 @@ const ServerPluginData = () => {
}
}, [])
if (extensionDataLoadingError) return <ErrorView error={extensionDataLoadingError}/>;
if (!extensions || !extensions.length) {
return (
<LoadIn>
@ -31,7 +36,7 @@ const ServerPluginData = () => {
<Col md={12}>
<Card>
<Card.Body>
<p>No Extension data</p>
<p>{extensionData ? t('html.text.noExtensionData') : <Loader/>}</p>
</Card.Body>
</Card>
</Col>

View File

@ -1,14 +1,17 @@
import React from 'react';
import {useServer} from "../layout/ServerPage";
import ErrorView from "../ErrorView";
import LoadIn from "../../components/animation/LoadIn";
import {Card, Col, Row} from "react-bootstrap-v5";
import ExtensionCard from "../../components/extensions/ExtensionCard";
import {useParams} from "react-router-dom";
import {useTranslation} from "react-i18next";
import Loader from "../../components/navigation/Loader";
import {useServerExtensionContext} from "../../hooks/serverExtensionDataContext";
const ServerWidePluginData = () => {
const {t} = useTranslation();
const {plugin} = useParams();
const {extensionData, extensionDataLoadingError} = useServer();
const {extensionData, extensionDataLoadingError} = useServerExtensionContext();
if (extensionDataLoadingError) return <ErrorView error={extensionDataLoadingError}/>;
@ -22,7 +25,7 @@ const ServerWidePluginData = () => {
<Col md={12}>
<Card>
<Card.Body>
<p>No Extension data</p>
<p>{extensionData ? t('html.text.noExtensionData') : <Loader/>}</p>
</Card.Body>
</Card>
</Col>