From 8234cd5f4180ce07b29a8cfd23c22b2ddaa09403 Mon Sep 17 00:00:00 2001 From: Khavin Shankar Date: Wed, 10 Jun 2026 13:09:16 +0530 Subject: [PATCH 1/2] fix brief page not found while accessing plug page --- src/PluginEngine.tsx | 31 ++++++++++++++++++++++--------- src/Routers/AppRouter.tsx | 14 ++++++++++++-- src/hooks/useCareApps.tsx | 4 ++++ 3 files changed, 38 insertions(+), 11 deletions(-) diff --git a/src/PluginEngine.tsx b/src/PluginEngine.tsx index 92f3ab9b6ef..226a499d409 100644 --- a/src/PluginEngine.tsx +++ b/src/PluginEngine.tsx @@ -1,4 +1,8 @@ -import { CareAppsContext, useCareApps } from "@/hooks/useCareApps"; +import { + CareAppsContext, + CareAppsLoadingContext, + useCareApps, +} from "@/hooks/useCareApps"; import { PluginManifest, PluginManifestWithMeta, @@ -73,13 +77,16 @@ export default function PluginEngine({ children: React.ReactNode; }) { // Fetch enabled plugins from the backend API - const { data: enabledPlugins } = useQuery({ - queryKey: ["enabled-plugins"], - queryFn: query(plugConfigApi.list, { - silent: (response) => response.status === 401 || response.status === 403, - }), - retry: false, - }); + const { data: enabledPlugins, isLoading: isEnabledPluginsLoading } = useQuery( + { + queryKey: ["enabled-plugins"], + queryFn: query(plugConfigApi.list, { + silent: (response) => + response.status === 401 || response.status === 403, + }), + retry: false, + }, + ); const resolvedPlugins = useMemo( () => mergePlugConfigs(enabledPlugins?.configs ?? []), @@ -119,6 +126,10 @@ export default function PluginEngine({ window.__CARE_PLUGIN_RUNTIME__ = deepFreeze({ meta: pluginMeta }); }, [pluginMeta]); + // Expose plugin loading state to show loaders while a plugin page is being accessed + const arePluginsLoading = + isEnabledPluginsLoading || pluginsQuery.some((plugin) => plugin.isLoading); + // Register plugin overrides const overrideCleanupRef = useRef<(() => void)[]>([]); @@ -160,7 +171,9 @@ export default function PluginEngine({ } > - }>{children} + + }>{children} + diff --git a/src/Routers/AppRouter.tsx b/src/Routers/AppRouter.tsx index 8b88f2df255..f3d468b0a7a 100644 --- a/src/Routers/AppRouter.tsx +++ b/src/Routers/AppRouter.tsx @@ -7,12 +7,17 @@ import { SidebarProvider, SidebarTrigger } from "@/components/ui/sidebar"; import { AppSidebar, SidebarFor } from "@/components/ui/sidebar/app-sidebar"; import ErrorBoundary from "@/components/Common/ErrorBoundary"; +import Loading from "@/components/Common/Loading"; import BrowserWarning from "@/components/ErrorPages/BrowserWarning"; import ErrorPage from "@/components/ErrorPages/DefaultErrorPage"; import SessionExpired from "@/components/ErrorPages/SessionExpired"; import useAuthUser from "@/hooks/useAuthUser"; -import { useOrganizationRoutes, usePluginRoutes } from "@/hooks/useCareApps"; +import { + useCareAppsLoading, + useOrganizationRoutes, + usePluginRoutes, +} from "@/hooks/useCareApps"; import useSidebarState from "@/hooks/useSidebarState"; import { routes as publicRoutes } from "@/Routers/PublicRouter"; @@ -99,6 +104,7 @@ const publicRedirects = Object.fromEntries( export default function AppRouter() { const pluginRoutes = usePluginRoutes(); const organizationRoutes = useOrganizationRoutes(); + const arePluginsLoading = useCareAppsLoading(); let routes = Routes; useRedirect("/user", "/users"); @@ -119,7 +125,11 @@ export default function AppRouter() { const sidebarFor = isAdminPage ? SidebarFor.ADMIN : SidebarFor.FACILITY; - const pages = appPages || adminPages || publicRedirectsPages || ; + const pages = + appPages || + adminPages || + publicRedirectsPages || + (arePluginsLoading ? : ); const user = useAuthUser(); diff --git a/src/hooks/useCareApps.tsx b/src/hooks/useCareApps.tsx index a8676a37f8f..04e4dedcf16 100644 --- a/src/hooks/useCareApps.tsx +++ b/src/hooks/useCareApps.tsx @@ -15,6 +15,8 @@ export type CareAppsContextType = Array< export const CareAppsContext = createContext(null); +export const CareAppsLoadingContext = createContext(false); + export const useCareApps = () => { const ctx = useContext(CareAppsContext); if (!ctx) { @@ -25,6 +27,8 @@ export const useCareApps = () => { return ctx; }; +export const useCareAppsLoading = () => useContext(CareAppsLoadingContext); + // export const useCareAppNavItems = () => { // const careApps = useCareApps(); // const navItems = careApps.reduce((acc, plugin) => { From c5802a13be94a8788d887b090f04ba87c2cec86f Mon Sep 17 00:00:00 2001 From: Khavin Shankar Date: Mon, 15 Jun 2026 13:40:22 +0530 Subject: [PATCH 2/2] track plugs loading state in the same context as CareAppsContext --- src/PluginEngine.tsx | 14 +++++--------- src/hooks/useCareApps.tsx | 12 ++++++++---- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/PluginEngine.tsx b/src/PluginEngine.tsx index 226a499d409..58b3b142bf4 100644 --- a/src/PluginEngine.tsx +++ b/src/PluginEngine.tsx @@ -1,8 +1,4 @@ -import { - CareAppsContext, - CareAppsLoadingContext, - useCareApps, -} from "@/hooks/useCareApps"; +import { CareAppsContext, useCareApps } from "@/hooks/useCareApps"; import { PluginManifest, PluginManifestWithMeta, @@ -170,10 +166,10 @@ export default function PluginEngine({ } > - - - }>{children} - + + }>{children} diff --git a/src/hooks/useCareApps.tsx b/src/hooks/useCareApps.tsx index 04e4dedcf16..00c35698f62 100644 --- a/src/hooks/useCareApps.tsx +++ b/src/hooks/useCareApps.tsx @@ -13,9 +13,12 @@ export type CareAppsContextType = Array< (({ isLoading: false } & PluginManifestWithMeta) | { isLoading: true }) >; -export const CareAppsContext = createContext(null); +export type CareAppsContextValue = { + apps: CareAppsContextType; + isLoading: boolean; +}; -export const CareAppsLoadingContext = createContext(false); +export const CareAppsContext = createContext(null); export const useCareApps = () => { const ctx = useContext(CareAppsContext); @@ -24,10 +27,11 @@ export const useCareApps = () => { "'useCareApps' must be used within 'CareAppsProvider' only", ); } - return ctx; + return ctx.apps; }; -export const useCareAppsLoading = () => useContext(CareAppsLoadingContext); +export const useCareAppsLoading = () => + useContext(CareAppsContext)?.isLoading ?? false; // export const useCareAppNavItems = () => { // const careApps = useCareApps();