diff --git a/src/PluginEngine.tsx b/src/PluginEngine.tsx index 92f3ab9b6ef..58b3b142bf4 100644 --- a/src/PluginEngine.tsx +++ b/src/PluginEngine.tsx @@ -73,13 +73,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 +122,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)[]>([]); @@ -159,7 +166,9 @@ export default function PluginEngine({ } > - + }>{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..00c35698f62 100644 --- a/src/hooks/useCareApps.tsx +++ b/src/hooks/useCareApps.tsx @@ -13,7 +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 CareAppsContext = createContext(null); export const useCareApps = () => { const ctx = useContext(CareAppsContext); @@ -22,9 +27,12 @@ export const useCareApps = () => { "'useCareApps' must be used within 'CareAppsProvider' only", ); } - return ctx; + return ctx.apps; }; +export const useCareAppsLoading = () => + useContext(CareAppsContext)?.isLoading ?? false; + // export const useCareAppNavItems = () => { // const careApps = useCareApps(); // const navItems = careApps.reduce((acc, plugin) => {