From e204bdb5634013b91a5003cd7e3b1552defc50b4 Mon Sep 17 00:00:00 2001 From: philon- Date: Sun, 15 Jun 2025 21:27:38 +0200 Subject: [PATCH] Add Suspense --- src/components/Dialog/ManagedModeDialog.tsx | 4 +- .../PageComponents/Config/ConfigSuspender.tsx | 37 +++++++++++++++++++ src/pages/Config/DeviceConfig.tsx | 10 ++++- src/pages/Config/ModuleConfig.tsx | 10 ++++- 4 files changed, 56 insertions(+), 5 deletions(-) create mode 100644 src/components/PageComponents/Config/ConfigSuspender.tsx diff --git a/src/components/Dialog/ManagedModeDialog.tsx b/src/components/Dialog/ManagedModeDialog.tsx index e9831567..996139d4 100644 --- a/src/components/Dialog/ManagedModeDialog.tsx +++ b/src/components/Dialog/ManagedModeDialog.tsx @@ -48,7 +48,9 @@ export const ManagedModeDialog = ({ onChange={() => setConfirmState(!confirmState)} name="confirmUnderstanding" > - {t("managedMode.confirmUnderstanding")} +

+ {t("managedMode.confirmUnderstanding")} +

diff --git a/src/components/PageComponents/Config/ConfigSuspender.tsx b/src/components/PageComponents/Config/ConfigSuspender.tsx new file mode 100644 index 00000000..83eaa89d --- /dev/null +++ b/src/components/PageComponents/Config/ConfigSuspender.tsx @@ -0,0 +1,37 @@ +import { + useDevice, + ValidConfigType, + ValidModuleConfigType, +} from "@core/stores/deviceStore.ts"; +import { useEffect, useState } from "react"; + +export function ConfigSuspender({ + configCase, + moduleConfigCase, + children, +}: { + configCase?: ValidConfigType; + moduleConfigCase?: ValidModuleConfigType; + children: React.ReactNode; +}) { + const { config, moduleConfig } = useDevice(); + + let cfg = undefined; + if (configCase) { + cfg = config[configCase]; + } else if (moduleConfigCase) { + cfg = moduleConfig[moduleConfigCase]; + } else { + return children; + } + + const [ready, setReady] = useState(() => cfg !== undefined); + + useEffect(() => { + if (cfg !== undefined) setReady(true); + }, [cfg]); + + if (!ready) throw new Promise(() => {}); // triggers suspense fallback + + return children; +} diff --git a/src/pages/Config/DeviceConfig.tsx b/src/pages/Config/DeviceConfig.tsx index 34d48d4d..314d5f26 100644 --- a/src/pages/Config/DeviceConfig.tsx +++ b/src/pages/Config/DeviceConfig.tsx @@ -12,11 +12,13 @@ import { TabsList, TabsTrigger, } from "@components/UI/Tabs.tsx"; +import { Spinner } from "@components/UI/Spinner.tsx"; import { useTranslation } from "react-i18next"; import { useDevice, type ValidConfigType } from "@core/stores/deviceStore.ts"; import { useMemo } from "react"; -import type { ComponentType } from "react"; +import { type ComponentType, Suspense } from "react"; import type { UseFormReturn } from "react-hook-form"; +import { ConfigSuspender } from "@components/PageComponents/Config/ConfigSuspender.tsx"; interface ConfigProps { // We can get rid of this exception if we import every config schema and pass the union type @@ -105,7 +107,11 @@ export const DeviceConfig = ({ onFormInit }: ConfigProps) => { {tabs.map((tab) => ( - + }> + + + + ))} diff --git a/src/pages/Config/ModuleConfig.tsx b/src/pages/Config/ModuleConfig.tsx index 4803a6f1..db0cb106 100644 --- a/src/pages/Config/ModuleConfig.tsx +++ b/src/pages/Config/ModuleConfig.tsx @@ -16,14 +16,16 @@ import { TabsList, TabsTrigger, } from "@components/UI/Tabs.tsx"; +import { Spinner } from "@components/UI/Spinner.tsx"; import { useTranslation } from "react-i18next"; import { useDevice, type ValidModuleConfigType, } from "@core/stores/deviceStore.ts"; import { useMemo } from "react"; -import type { ComponentType } from "react"; +import { type ComponentType, Suspense } from "react"; import type { UseFormReturn } from "react-hook-form"; +import { ConfigSuspender } from "@components/PageComponents/Config/ConfigSuspender.tsx"; interface ConfigProps { // We can get rid of this exception if we import every config schema and pass the union type @@ -128,7 +130,11 @@ export const ModuleConfig = ({ onFormInit }: ConfigProps) => { {tabs.map((tab) => ( - + }> + + + + ))}