Skip to content

Commit

Permalink
Fix Plugin Nav; Other fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
gigincg committed Sep 30, 2024
1 parent 03da7d4 commit c890524
Show file tree
Hide file tree
Showing 13 changed files with 109 additions and 112 deletions.
23 changes: 14 additions & 9 deletions src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,24 +1,29 @@
import { Suspense } from "react";
import { useState, Suspense } from "react";
import Routers from "./Routers";
import ThemedFavicon from "./CAREUI/misc/ThemedFavicon";
import Intergrations from "./Integrations";
import Loading from "./Components/Common/Loading";
import HistoryAPIProvider from "./Providers/HistoryAPIProvider";
import AuthUserProvider from "./Providers/AuthUserProvider";
import PluginEngine from "./PluginEngine";
import { PluginConfigType } from "./Common/hooks/useConfig";

const App = () => {
const [plugins, setPlugins] = useState<PluginConfigType[]>(["care-livekit"]);
return (
<Suspense fallback={<Loading />}>
<ThemedFavicon />
<HistoryAPIProvider>
<AuthUserProvider unauthorized={<Routers.SessionRouter />}>
<Routers.AppRouter />
</AuthUserProvider>
<PluginEngine plugins={plugins} setPlugins={setPlugins}>
<HistoryAPIProvider>
<AuthUserProvider unauthorized={<Routers.SessionRouter />}>
<Routers.AppRouter />
</AuthUserProvider>

{/* Integrations */}
<Intergrations.Sentry disabled={!import.meta.env.PROD} />
<Intergrations.Plausible />
</HistoryAPIProvider>
{/* Integrations */}
<Intergrations.Sentry disabled={!import.meta.env.PROD} />
<Intergrations.Plausible />
</HistoryAPIProvider>
</PluginEngine>
</Suspense>
);
};
Expand Down
27 changes: 0 additions & 27 deletions src/Common/hooks/useAppConfig_legacy.ts

This file was deleted.

43 changes: 43 additions & 0 deletions src/Common/hooks/useCareApps.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { createContext, useContext } from "react";
import { PluginConfigType } from "./useConfig";
import { INavItem } from "@core/Components/Common/Sidebar/Sidebar";

type CareAppsContextType = PluginConfigType[];

export const CareAppsContext = createContext<CareAppsContextType | null>(null);

export const useCareApps = () => {
const ctx = useContext(CareAppsContext);
if (!ctx) {
throw new Error(
"'useCareApps' must be used within 'CareAppsProvider' only",
);
}
return ctx;
};

export const useCareAppNavItems = () => {
const careApps = useCareApps();
const navItems = careApps.reduce<INavItem[]>((acc, plugin) => {
if (typeof plugin === "string") {
return acc;
}
return [...acc, ...(plugin.navItems || [])];
}, []);
return navItems;
};

// If required; Reduce plugin.routes to a single pluginRoutes object of type Record<string, () => JSX.Element>
export function usePluginRoutes() {
const careApps = useCareApps();
const routes = careApps.reduce((acc, plugin) => {
if (typeof plugin === "string") {
return acc;
}
return { ...acc, ...plugin.routes };
}, {});
if (!routes) {
throw new Error("'usePluginRoutes' must be used within 'AppRouter' only");
}
return routes;
}
5 changes: 4 additions & 1 deletion src/Common/hooks/useConfig.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { INavItem } from "@core/Components/Common/Sidebar/Sidebar";
import { AppRoutes } from "@core/Routers/AppRouter";
import { createContext, useContext } from "react";

export const AppConfigContext = createContext<IConfig | null>(null);
Expand Down Expand Up @@ -93,7 +95,8 @@ export interface IBaseConfig {

export interface PluginConfig {
plugin: string;
routes: Record<string, () => JSX.Element>;
routes: AppRoutes;
navItems: INavItem[];
}

export type PluginConfigType = string | PluginConfig;
Expand Down
19 changes: 13 additions & 6 deletions src/Components/Common/Sidebar/Sidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,18 @@ import { classNames } from "../../../Utils/utils";
import { Link } from "raviger";
import useAuthUser from "../../../Common/hooks/useAuthUser";
import careConfig from "@careConfig";
import { useCareAppNavItems } from "@core/Common/hooks/useCareApps";

export const SIDEBAR_SHRINK_PREFERENCE_KEY = "sidebarShrinkPreference";

const LOGO_COLLAPSE = "/images/logo_collapsed.svg";

export interface INavItem {
text: string;
to?: string;
icon: IconName;
}

type StatelessSidebarProps =
| {
shrinkable: true;
Expand All @@ -36,11 +43,7 @@ const StatelessSidebar = ({
}: StatelessSidebarProps) => {
const authUser = useAuthUser();

const NavItems: {
text: string;
to: string;
icon: IconName;
}[] = [
const BaseNavItems: INavItem[] = [
{ text: "Facilities", to: "/facility", icon: "l-hospital" },
{ text: "Patients", to: "/patients", icon: "l-user-injured" },
{ text: "Assets", to: "/assets", icon: "l-shopping-cart-alt" },
Expand All @@ -62,6 +65,10 @@ const StatelessSidebar = ({
{ text: "Notice Board", to: "/notice_board", icon: "l-meeting-board" },
];

const PluginNavItems = useCareAppNavItems();

const NavItems = [...BaseNavItems, ...PluginNavItems];

const activeLink = useActiveLink();
const Item = shrinked ? ShrinkedSidebarItem : SidebarItem;

Expand Down Expand Up @@ -147,7 +154,7 @@ const StatelessSidebar = ({
{...i}
icon={<CareIcon icon={i.icon} className="h-5" />}
selected={i.to === activeLink}
do={() => onItemClick && onItemClick(false)}
onItemClick={() => onItemClick && onItemClick(false)}
handleOverflow={handleOverflow}
/>
);
Expand Down
15 changes: 11 additions & 4 deletions src/Components/Common/Sidebar/SidebarItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,12 @@ type SidebarItemProps = {
ref?: React.Ref<HTMLAnchorElement>;
text: string;
icon: SidebarIcon;
onItemClick?: () => void;
external?: true | undefined;
badgeCount?: number | undefined;
selected?: boolean | undefined;
handleOverflow?: any;
} & ({ to: string; do?: undefined } | { to?: string; do: () => void });
} & ({ to?: string; do?: undefined } | { to?: string; do: () => void });

type SidebarItemBaseProps = SidebarItemProps & {
shrinked?: boolean;
Expand All @@ -32,15 +33,21 @@ const SidebarItemBase = forwardRef(
return (
<Link
ref={ref}
className={`tooltip relative ml-1 mr-3 h-full min-h-[40px] flex-1 cursor-pointer rounded-lg text-white transition-all duration-200 ease-in-out md:h-11 md:flex-none ${
className={`${props.to ? "to" : ""} ${props.do ? "do" : ""} tooltip relative ml-1 mr-3 h-full min-h-[40px] flex-1 cursor-pointer rounded-lg text-white transition-all duration-200 ease-in-out md:h-11 md:flex-none ${
props.selected
? "bg-primary-900 font-bold"
: "bg-primary-800 font-normal hover:bg-primary-700"
: "bg-primary-800 font-normal" +
(props.to || props.do ? " hover:bg-primary-700" : "")
}`}
target={external && "_blank"}
rel={external && "noreferrer"}
href={props.to ?? ""}
onClick={props.do ?? resetHistory}
onClick={() => {
// On Review: Check if resetHistory is working as intended.
props.do?.();
props.onItemClick?.();
resetHistory();
}}
onMouseEnter={() => {
props.handleOverflow(true);
}}
Expand Down
3 changes: 1 addition & 2 deletions src/Components/Notifications/ShowPushNotification.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import { DetailRoute } from "../../Routers/types";
import useQuery from "../../Utils/request/useQuery";
import routes from "../../Redux/api";
import { NotificationData } from "./models";

export default function ShowPushNotification({ id }: DetailRoute) {
export default function ShowPushNotification({ id }: { id: string }) {
useQuery(routes.getNotificationData, {
pathParams: { id },
onResponse(res) {
Expand Down
33 changes: 17 additions & 16 deletions src/PluginEngine.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
/* eslint-disable i18next/no-literal-string */
import React, { useEffect, useState } from "react";
import React, { useEffect } from "react";
import { PluginConfigType } from "./Common/hooks/useConfig";
import { CareAppsContext } from "./Common/hooks/useCareApps";

type PluginComponentType = React.ComponentType<any>;
// type PluginComponentType = React.ComponentType<any>;

export default function PluginEngine({
// eslint-disable-next-line @typescript-eslint/no-unused-vars
Expand All @@ -15,18 +16,17 @@ export default function PluginEngine({
setPlugins: React.Dispatch<React.SetStateAction<PluginConfigType[]>>;
children: React.ReactNode;
}) {
const [pluginComponents, setPluginComponents] = useState<
PluginComponentType[]
>([]);

useEffect(() => {
const loadPlugins = async () => {
try {
const module = await import("@apps/care-scribe-alpha-plug");
setPluginComponents([module.Scribe]);
setPlugins((plugins) => [
...plugins,
{ plugin: "care-scribe-alpha-plug", routes: module.routes },
const module = await import("@apps/care-livekit");
setPlugins((prevPlugins) => [
...prevPlugins,
{
plugin: "care-livekit",
routes: module.routes,
navItems: module.manifest.navItems,
},
]);

console.log("Loaded plugins", module);
Expand All @@ -40,11 +40,12 @@ export default function PluginEngine({

return (
<>
<>Dynamic Plugins here:</>
{pluginComponents.map((PluginComponent, index) => (
<PluginComponent key={index} />
))}
{children}
<CareAppsContext.Provider value={plugins}>
{children}
<span className="absolute left-0 top-0 z-50 w-screen bg-green-800 text-center text-sm text-white">
CareApps Enabled
</span>
</CareAppsContext.Provider>
</>
);
}
37 changes: 0 additions & 37 deletions src/Providers/AppConfigProvider.tsx

This file was deleted.

2 changes: 1 addition & 1 deletion src/Redux/api.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1163,7 +1163,7 @@ const routes = {
path: "/api/v1/notification/notify/",
method: "POST",
TRes: Type<IFacilityNotificationResponse>(),
Tbody: Type<IFacilityNotificationRequest>(),
TBody: Type<IFacilityNotificationRequest>(),
},

// FileUpload Create
Expand Down
9 changes: 3 additions & 6 deletions src/Routers/AppRouter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import ResourceRoutes from "./routes/ResourceRoutes";
import ExternalResultRoutes from "./routes/ExternalResultRoutes";
import useAuthUser from "../Common/hooks/useAuthUser";
import careConfig from "@careConfig";
import { usePluginRoutes } from "@core/Common/hooks/useCareApps";

export type RouteParams<T extends string> =
T extends `${string}:${infer Param}/${infer Rest}`
Expand Down Expand Up @@ -72,6 +73,8 @@ const Routes: AppRoutes = {
export default function AppRouter() {
const authUser = useAuthUser();

const pluginRoutes = usePluginRoutes();

let routes = Routes;

if (careConfig.hcx.enabled) {
Expand All @@ -87,12 +90,6 @@ export default function AppRouter() {
}

useRedirect("/user", "/users");
// Reduce plugin.routes to a single pluginRoutes object of type Record<string, () => JSX.Element>
const pluginRoutes = {};
// plugins.reduce((acc, plugin) => {
// if (typeof plugin === "string") return acc;
// return { ...acc, ...plugin.routes };
// }, {});

const allRoutes = {
...routes,
Expand Down
2 changes: 1 addition & 1 deletion src/Utils/useTimer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export const useTimer = (autoStart = false) => {
const [time, setTime] = useState(0);

useEffect(() => {
let interval: number;
let interval: ReturnType<typeof setInterval>;
if (running) {
interval = setInterval(() => {
setTime((prevTime) => prevTime + 1);
Expand Down
3 changes: 1 addition & 2 deletions vite.config.mts
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import path from "node:path";
import path from "path";
import { createRequire } from "node:module";
import { VitePWA } from "vite-plugin-pwa";
import react from "@vitejs/plugin-react-swc";
import checker from "vite-plugin-checker";
import { viteStaticCopy } from "vite-plugin-static-copy";
import { treeShakeCareIcons } from "./plugins/treeShakeCareIcons";
import path from "path";
import fs from "fs";

const pdfWorkerPath = path.join(
Expand Down

0 comments on commit c890524

Please sign in to comment.