diff --git a/app/components/Header.tsx b/app/components/Header.tsx index e9eb2ab..aa2ec0a 100644 --- a/app/components/Header.tsx +++ b/app/components/Header.tsx @@ -11,11 +11,10 @@ import type { ReactNode } from 'react'; import { NavLink, useSubmit } from 'react-router'; import Menu from '~/components/Menu'; import cn from '~/utils/cn'; -import type { HeadplaneContext } from '~/utils/config/headplane'; import type { SessionData } from '~/utils/sessions.server'; interface Props { - config: HeadplaneContext['config']; + configAvailable: boolean; user?: SessionData['user']; } @@ -133,7 +132,7 @@ export default function Header(data: Props) { name="Access Control" icon={} /> - {data.config.read ? ( + {data.configAvailable ? ( <> } /> { - let shellRendered = false; - const userAgent = request.headers.get("user-agent"); + return new Promise((resolve, reject) => { + let shellRendered = false; + const userAgent = request.headers.get('user-agent'); - // Ensure requests from bots and SPA Mode renders wait for all content to load before responding - // https://react.dev/reference/react-dom/server/renderToPipeableStream#waiting-for-all-content-to-load-for-crawlers-and-static-generation - const readyOption: keyof RenderToPipeableStreamOptions = - (userAgent && isbot(userAgent)) || routerContext.isSpaMode - ? "onAllReady" - : "onShellReady"; + // Ensure requests from bots and SPA Mode renders wait for all content to load before responding + // https://react.dev/reference/react-dom/server/renderToPipeableStream#waiting-for-all-content-to-load-for-crawlers-and-static-generation + const readyOption: keyof RenderToPipeableStreamOptions = + (userAgent && isbot(userAgent)) || routerContext.isSpaMode + ? 'onAllReady' + : 'onShellReady'; - const { pipe, abort } = renderToPipeableStream( - , - { - [readyOption]() { - shellRendered = true; - const body = new PassThrough(); - const stream = createReadableStreamFromReadable(body); + const { pipe, abort } = renderToPipeableStream( + , + { + [readyOption]() { + shellRendered = true; + const body = new PassThrough(); + const stream = createReadableStreamFromReadable(body); - responseHeaders.set("Content-Type", "text/html"); + responseHeaders.set('Content-Type', 'text/html'); - resolve( - new Response(stream, { - headers: responseHeaders, - status: responseStatusCode, - }) - ); + resolve( + new Response(stream, { + headers: responseHeaders, + status: responseStatusCode, + }), + ); - pipe(body); - }, - onShellError(error: unknown) { - reject(error); - }, - onError(error: unknown) { - responseStatusCode = 500; - // Log streaming rendering errors from inside the shell. Don't log - // errors encountered during initial shell rendering since they'll - // reject and get logged in handleDocumentRequest. - if (shellRendered) { - console.error(error); - } - }, - } - ); + pipe(body); + }, + onShellError(error: unknown) { + reject(error); + }, + onError(error: unknown) { + // biome-ignore lint/style/noParameterAssign: Lazy + responseStatusCode = 500; + // Log streaming rendering errors from inside the shell. Don't log + // errors encountered during initial shell rendering since they'll + // reject and get logged in handleDocumentRequest. + if (shellRendered) { + console.error(error); + } + }, + }, + ); - // Abort the rendering stream after the `streamTimeout` so it has tine to - // flush down the rejected boundaries - setTimeout(abort, streamTimeout + 1000); - }); + // Abort the rendering stream after the `streamTimeout` so it has tine to + // flush down the rejected boundaries + setTimeout(abort, streamTimeout + 1000); + }); } diff --git a/app/layouts/shell.tsx b/app/layouts/shell.tsx index 6b7e2d9..b8c47f2 100644 --- a/app/layouts/shell.tsx +++ b/app/layouts/shell.tsx @@ -1,8 +1,13 @@ -import Header from '~/components/Header'; +import { + LoaderFunctionArgs, + Outlet, + redirect, + useLoaderData, +} from 'react-router'; import Footer from '~/components/Footer'; +import Header from '~/components/Header'; import { getSession } from '~/utils/sessions.server'; -import { loadContext } from '~/utils/config/headplane'; -import { useLoaderData, LoaderFunctionArgs, Outlet, redirect } from 'react-router'; +import { hp_getConfig, hs_getConfig } from '~/utils/state'; // This loads the bare minimum for the application to function // So we know that if context fails to load then well, oops? @@ -12,10 +17,13 @@ export async function loader({ request }: LoaderFunctionArgs) { return redirect('/login'); } - const context = await loadContext(); + const context = hp_getConfig(); + const { mode, config } = hs_getConfig(); + return { - config: context.config, - url: context.headscalePublicUrl ?? context.headscaleUrl, + config, + url: context.headscale.public_url ?? context.headscale.url, + configAvailable: mode !== 'no', debug: context.debug, user: session.get('user'), }; @@ -29,5 +37,5 @@ export default function Shell() {