Skip to content

Commit

Permalink
Merge pull request #347 from tgstation/WhatsNext
Browse files Browse the repository at this point in the history
Setup network specific handling and use preloaded queries
  • Loading branch information
Cyberboss authored Oct 21, 2024
2 parents ed9acc6 + 991e9e4 commit ed5ab0a
Show file tree
Hide file tree
Showing 26 changed files with 659 additions and 106 deletions.
4 changes: 2 additions & 2 deletions .storybook/MockRelayEnvironment.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import { makeDecorator } from "@storybook/preview-api";
import { RelayEnvironmentProvider } from "react-relay";
import { GraphQLTaggedNode, OperationType } from "relay-runtime";
import { GraphQLTaggedNode, OperationType, VariablesOf } from "relay-runtime";
import { createMockEnvironment, MockPayloadGenerator } from "relay-test-utils";
import { OperationMockResolver } from "relay-test-utils/lib/RelayModernMockEnvironment";
import { PartialDeep } from "type-fest";
Expand Down Expand Up @@ -45,7 +45,7 @@ export type WithRelayParameters<TQuery extends OperationType, TResolvers = objec
/**
* Optional. Variables to pass to the query.
*/
variables?: TQuery["variables"];
variables?: VariablesOf<TQuery>;

/**
* Optional. Mock resolver object pass to the relay-test-utils MockPayloadGenerator.generate function.
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "tgstation-server-webpanel",
"private": true,
"version": "7.0.0",
"tgs_graphql_api_version": "0.2.0",
"tgs_graphql_api_version": "0.3.0",
"tgs_rest_api_version": "10.10.0",
"homepage": "https://tgstation.github.io/tgstation-server-webpanel",
"repository": {
Expand Down
44 changes: 21 additions & 23 deletions src/components/App.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { lazy, StrictMode, Suspense, useEffect, useState } from "react";
import { lazy, Suspense, useEffect, useState } from "react";
import { IntlProvider } from "react-intl";

import ConfigProvider from "../context/config/ConfigProvider";
Expand Down Expand Up @@ -71,29 +71,27 @@ const App = (props: IProps) => {
});

return (
<StrictMode>
<ConfigProvider>
{translations ? (
<IntlProvider
locale={translations.locale}
messages={translations.messages}
defaultLocale="en">
<Suspense
fallback={
<div className="grid lg:grid-cols-11 md:grid-cols-8">
<div className="lg:col-start-3 lg:col-end-9 md:col-start-2 md:col-end-8">
<Loading message="loading.loading" />
</div>
<ConfigProvider>
{translations ? (
<IntlProvider
locale={translations.locale}
messages={translations.messages}
defaultLocale="en">
<Suspense
fallback={
<div className="grid lg:grid-cols-11 md:grid-cols-8">
<div className="lg:col-start-3 lg:col-end-9 md:col-start-2 md:col-end-8">
<Loading message="loading.loading" />
</div>
}>
<Environment />
</Suspense>
</IntlProvider>
) : (
<Loading />
)}
</ConfigProvider>
</StrictMode>
</div>
}>
<Environment />
</Suspense>
</IntlProvider>
) : (
<Loading />
)}
</ConfigProvider>
);
};

Expand Down
19 changes: 10 additions & 9 deletions src/components/core/Environment/Environment.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@ import Router from "../Router/Router";

import Pkg from "@/../package.json";
import useConfig from "@/context/config/useConfig";
import SetCredentialsContext from "@/context/credentials/SetCredentialsContext";
import ErrorsProvider from "@/context/errors/ErrorsProvider";
import SessionProvider from "@/context/session/SessionProvider";
import CreateRelayEnvironment from "@/lib/CreateRelayEnvironment";
import CreateTgsRelayEnvironment from "@/lib/CreateTgsRelayEnvironment";

const Environment = () => {
const version = Pkg.version;
Expand All @@ -22,19 +23,19 @@ const Environment = () => {
const config = useConfig();

const { relayEnviroment, setCredentials } = useMemo(
() => CreateRelayEnvironment(config.ApiPath.value),
() => CreateTgsRelayEnvironment(config.ApiPath.value),
[config.ApiPath.value]
);

return (
<RelayEnvironmentProvider environment={relayEnviroment}>
<SessionProvider setCredentials={credentials => setCredentials(credentials, false)}>
<ErrorsProvider>
<Router
setTemporaryCredentials={credentials => setCredentials(credentials, true)}
/>
</ErrorsProvider>
</SessionProvider>
<SetCredentialsContext.Provider value={{ setCredentials }}>
<SessionProvider>
<ErrorsProvider>
<Router />
</ErrorsProvider>
</SessionProvider>
</SetCredentialsContext.Provider>
</RelayEnvironmentProvider>
);
};
Expand Down
29 changes: 11 additions & 18 deletions src/components/core/Router/Router.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,16 @@
import { lazy, Suspense } from "react";
import { useRelayEnvironment } from "react-relay";
import { createBrowserRouter, RouterProvider } from "react-router-dom";

import HomeRoutes from "../../routed/Home/HomeRoutes";

import ProtectedRoute from "./ProtectedRoute/ProtectedRoute";
import RethrowRouteError from "./RethrowRouteError/RethrowRouteError";

import HomeRouteLoader from "@/components/routed/Home/HomeRouteLoader";
import Loading from "@/components/utils/Loading/Loading";
import { ICredentials } from "@/lib/Credentials";
import devDelay from "@/lib/devDelay";

const Home = lazy(
async () =>
await devDelay(() => import("@/components/routed/Home/Home"), "Component Load: Home")
);

const Layout = lazy(
async () =>
await devDelay(() => import("@/components/core/Layout/Layout"), "Component Load: Layout")
Expand All @@ -33,11 +29,9 @@ const NotFound = lazy(
)
);

interface IProps {
setTemporaryCredentials: (credentials: ICredentials) => void;
}

const Router = (props: IProps) => {
const Router = () => {
const relayEnviroment = useRelayEnvironment();
const homeRoutes = HomeRoutes(relayEnviroment);
const router = createBrowserRouter([
{
path: "/",
Expand All @@ -46,17 +40,16 @@ const Router = (props: IProps) => {
children: [
{
path: "login",
element: <Login setTemporaryCredentials={props.setTemporaryCredentials} />
element: <Login />
},
...HomeRoutes.filter(route => route.unprotected),
...homeRoutes.filter(route => route.unprotected),
{
element: <ProtectedRoute />,
children: [
{
path: "",
element: <Home />
},
...HomeRoutes.filter(route => !route.unprotected),
HomeRouteLoader(relayEnviroment, {
path: ""
}),
...homeRoutes.filter(route => !route.unprotected),
{
path: "*",
element: <NotFound />
Expand Down
44 changes: 30 additions & 14 deletions src/components/routed/Home/Home.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,32 +1,47 @@
import { Meta, StoryObj } from "@storybook/react";
import { Suspense } from "react";
import { loadQuery, useRelayEnvironment } from "react-relay";

import { HomeCardPermissionsQuery } from "./graphql/__generated__/HomeCardPermissionsQuery.graphql";
import HomeCardPermissions from "./graphql/HomeCardPermissions";
import Home from "./Home";

import { WithRelayParameters } from "@/../.storybook/MockRelayEnvironment";
import SessionContext from "@/context/session/SessionContext";
import { DefaultUserPasswordCredentials, UserPasswordCredentials } from "@/lib/Credentials";
import { UserPasswordCredentials } from "@/lib/Credentials";

interface IArgs {
defaultCredentials: boolean;
}

const variables = {
userID: "fdsa"
};

const TestComponent = (props: IArgs) => {
const session = {
currentSession: {
bearer: "asdf",
userId: "fdsa",
originalCredentials: props.defaultCredentials
? new DefaultUserPasswordCredentials()
: new UserPasswordCredentials("asdf", "asdf")
},
setSession: () => {}
};
const queryRef = loadQuery<HomeCardPermissionsQuery>(
useRelayEnvironment(),
HomeCardPermissions,
variables
);

return (
<SessionContext.Provider value={session}>
<Home />
<SessionContext.Provider
value={{
currentSession: {
bearer: "asdf",
userID: "fdsa",
originalCredentials: new UserPasswordCredentials(
"asdf",
"asdf",
props.defaultCredentials
)
},
setSession: () => {}
}}>
<Suspense>
<Home queryRef={queryRef} />
</Suspense>
</SessionContext.Provider>
);
};
Expand All @@ -48,7 +63,8 @@ const CreateRelay = (fieldsEnabled: boolean): WithRelayParameters<HomeCardPermis
canRead: fieldsEnabled
}
})
}
},
variables
});

const config: Meta<typeof TestComponent> = {
Expand Down
25 changes: 17 additions & 8 deletions src/components/routed/Home/Home.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { FormattedMessage } from "react-intl";
import { useLazyLoadQuery } from "react-relay";
import { PreloadedQuery, usePreloadedQuery, useRelayEnvironment } from "react-relay";

import { HomeCardPermissionsQuery } from "./graphql/__generated__/HomeCardPermissionsQuery.graphql";
import HomeCardPermissions from "./graphql/HomeCardPermissions";
Expand All @@ -9,14 +9,21 @@ import HomeRoutes from "./HomeRoutes";
import { Alert, AlertDescription } from "@/components/ui/alert";
import useSession from "@/context/session/useSession";

const Home = () => {
interface IProps {
queryRef?: PreloadedQuery<HomeCardPermissionsQuery> | null;
}

const Home = (props: IProps) => {
const session = useSession();
const relayEnvironment = useRelayEnvironment();
const usingDefaultCredentials =
!!session.currentSession?.originalCredentials.defaultCredentials;

const data = useLazyLoadQuery<HomeCardPermissionsQuery>(HomeCardPermissions, {
userID: session.currentSession!.userId
});
if (!props.queryRef) {
throw new Error("HomeCardPermissionsQuery ref was null");
}

const data = usePreloadedQuery<HomeCardPermissionsQuery>(HomeCardPermissions, props.queryRef);

return (
<>
Expand All @@ -28,9 +35,11 @@ const Home = () => {
</Alert>
) : null}
<div className="flex flex-row flex-wrap justify-center">
{HomeRoutes.map(route => (
<div className="basis-full sm:basis-1/2 md:basis-1/3 lg:basis-1/4">
<HomeCard key={route.localeNameId} {...route} queryData={data} />
{HomeRoutes(relayEnvironment).map(route => (
<div
key={route.localeNameId}
className="basis-full sm:basis-1/2 md:basis-1/3 lg:basis-1/4">
<HomeCard {...route} queryData={data} />
</div>
))}
</div>
Expand Down
33 changes: 33 additions & 0 deletions src/components/routed/Home/HomeRouteLoader.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { lazy } from "react";
import { Environment } from "react-relay";
import { RouteObject } from "react-router-dom";

import { HomeCardPermissionsQuery } from "./graphql/__generated__/HomeCardPermissionsQuery.graphql";
import HomeCardPermissions from "./graphql/HomeCardPermissions";

import useSession from "@/context/session/useSession";
import devDelay from "@/lib/devDelay";
import RouteQueryLoader from "@/lib/RouteQueryLoader";

const Home = lazy(async () => await devDelay(() => import("./Home"), "Component Load: Home"));

const HomeRouteLoader = (relayEnvironment: Environment, partialRoute: RouteObject): RouteObject => {
const session = useSession();
return RouteQueryLoader<HomeCardPermissionsQuery>(
relayEnvironment,
HomeCardPermissions,
() => {
if (!session.currentSession) {
return null;
}

return {
userID: session.currentSession.userID
};
},
partialRoute,
queryRef => <Home queryRef={queryRef} />
);
};

export default HomeRouteLoader;
12 changes: 7 additions & 5 deletions src/components/routed/Home/HomeRoutes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,11 @@ import {
faUser
} from "@fortawesome/free-solid-svg-icons";
import { lazy } from "react";
import { Environment } from "react-relay";
import { RouteObject } from "react-router-dom";

import ServerInfoRouteLoader from "../ServerInfo/ServerInfoRouteLoader";

import HomeCardProps from "./HomeCard/HomeCardProps";

import NotFound from "@/components/core/NotFound/NotFound";
Expand All @@ -28,7 +31,7 @@ interface IHomeRouteProtected {

type HomeRoute = RouteObject & IHomeRouteProtected & Omit<HomeCardProps, "queryData">;

const HomeRoutes: HomeRoute[] = [
const HomeRoutes = (relayEnviroment: Environment): HomeRoute[] => [
{
path: "instances",
icon: faHdd,
Expand Down Expand Up @@ -72,12 +75,11 @@ const HomeRoutes: HomeRoute[] = [
element: <Configuration />,
unprotected: true
},
{
ServerInfoRouteLoader(relayEnviroment, {
path: "/info",
icon: faInfoCircle,
localeNameId: "routes.info",
element: <NotFound />
}
localeNameId: "routes.info"
})
];

export default HomeRoutes;
Loading

0 comments on commit ed5ab0a

Please sign in to comment.