From b02062a836df8559e19870f7c7268de4a2346032 Mon Sep 17 00:00:00 2001 From: Rithvik Nishad Date: Wed, 16 Oct 2024 15:53:11 +0530 Subject: [PATCH 1/2] Fixes multiple tiny issues (#8784) --- public/favicon-light.ico | Bin 217598 -> 0 bytes public/favicon.ico | Bin 217598 -> 6439 bytes src/App.tsx | 2 -- src/CAREUI/misc/PaginatedList.tsx | 10 ++++++- src/CAREUI/misc/ThemedFavicon.tsx | 14 ---------- src/Components/ABDM/LinkABHANumberModal.tsx | 1 - src/Components/Assets/AssetsList.tsx | 1 - src/Components/Common/Breadcrumbs.tsx | 9 +++--- src/Components/Common/Sidebar/Sidebar.tsx | 10 +++---- .../Common/Sidebar/SidebarUserCard.tsx | 8 +----- .../Facility/DischargedPatientsList.tsx | 26 +++++++++--------- src/Components/Facility/FacilityBlock.tsx | 6 ++-- src/Components/Facility/FacilityCard.tsx | 7 +---- src/Components/Facility/FacilityHome.tsx | 22 ++++++--------- .../Facility/LocationManagement.tsx | 22 +++++++-------- src/Components/Patient/ManagePatients.tsx | 9 +++--- .../Patient/PatientConsentRecordBlock.tsx | 5 +--- src/Components/Patient/PatientHome.tsx | 2 +- src/Components/Patient/PatientRegister.tsx | 6 ++-- src/Components/Users/ManageUsers.tsx | 6 ++-- src/Components/Users/SkillsSlideOver.tsx | 1 + src/Locale/en.json | 9 ++++-- src/Routers/AppRouter.tsx | 2 +- 23 files changed, 75 insertions(+), 103 deletions(-) delete mode 100644 public/favicon-light.ico delete mode 100644 src/CAREUI/misc/ThemedFavicon.tsx diff --git a/public/favicon-light.ico b/public/favicon-light.ico deleted file mode 100644 index 244b9d6c1d30aab5b36ffafc41845202059a07d8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 217598 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 W+mE&7plRj;>^scKcsnF+4*vt$Z=fLn diff --git a/public/favicon.ico b/public/favicon.ico index 244b9d6c1d30aab5b36ffafc41845202059a07d8..67a5686e32ffe2212a032deb9ee098827e52f887 100644 GIT binary patch literal 6439 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 Apa1{> literal 217598 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 W+mE&7plRj;>^scKcsnF+4*vt$Z=fLn diff --git a/src/App.tsx b/src/App.tsx index 98cf307f18a..c02982fd6df 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,6 +1,5 @@ import { Suspense } from "react"; import Routers from "./Routers"; -import ThemedFavicon from "./CAREUI/misc/ThemedFavicon"; import Integrations from "./Integrations"; import Loading from "./Components/Common/Loading"; import HistoryAPIProvider from "./Providers/HistoryAPIProvider"; @@ -11,7 +10,6 @@ import { Toaster } from "./Components/ui/toaster"; const App = () => { return ( }> - }> diff --git a/src/CAREUI/misc/PaginatedList.tsx b/src/CAREUI/misc/PaginatedList.tsx index ec270bf8134..3b68b23bd30 100644 --- a/src/CAREUI/misc/PaginatedList.tsx +++ b/src/CAREUI/misc/PaginatedList.tsx @@ -33,6 +33,8 @@ function useContextualized() { interface Props extends QueryOptions> { route: QueryRoute>; perPage?: number; + initialPage?: number; + onPageChange?: (page: number) => void; queryCB?: ( query: ReturnType>>, ) => void; @@ -49,7 +51,13 @@ export default function PaginatedList({ queryCB, ...queryOptions }: Props) { - const [currentPage, setPage] = useState(1); + const [currentPage, _setPage] = useState(queryOptions.initialPage ?? 1); + + const setPage = (page: number) => { + _setPage(page); + queryOptions.onPageChange?.(page); + }; + const query = useQuery(route, { ...queryOptions, query: { diff --git a/src/CAREUI/misc/ThemedFavicon.tsx b/src/CAREUI/misc/ThemedFavicon.tsx deleted file mode 100644 index b908f566b89..00000000000 --- a/src/CAREUI/misc/ThemedFavicon.tsx +++ /dev/null @@ -1,14 +0,0 @@ -import { useEffect } from "react"; - -export default function ThemedFavicon() { - useEffect(() => { - const darkThemeMq = window.matchMedia("(prefers-color-scheme: dark)"); - const favicon = document.querySelector( - "link[rel~='icon']", - ) as HTMLLinkElement; - - favicon.href = darkThemeMq.matches ? "/favicon-light.ico" : "/favicon.ico"; - }, []); - - return null; -} diff --git a/src/Components/ABDM/LinkABHANumberModal.tsx b/src/Components/ABDM/LinkABHANumberModal.tsx index 8d6365387cd..c2855ae7569 100644 --- a/src/Components/ABDM/LinkABHANumberModal.tsx +++ b/src/Components/ABDM/LinkABHANumberModal.tsx @@ -225,7 +225,6 @@ const ScanABHAQRSection = ({ Notify.Error({ msg: "Linking Failed" }); } } catch (e) { - console.log(e); Notify.Error({ msg: "Invalid ABHA QR" }); } finally { setIsLoading(false); diff --git a/src/Components/Assets/AssetsList.tsx b/src/Components/Assets/AssetsList.tsx index ee27c2a484f..77961d15b0d 100644 --- a/src/Components/Assets/AssetsList.tsx +++ b/src/Components/Assets/AssetsList.tsx @@ -159,7 +159,6 @@ const AssetsList = () => { }); } } catch (err) { - console.log(err); Notification.Error({ msg: t("invalid_asset_id_msg"), }); diff --git a/src/Components/Common/Breadcrumbs.tsx b/src/Components/Common/Breadcrumbs.tsx index c092ecbbc93..aaee7ac0b64 100644 --- a/src/Components/Common/Breadcrumbs.tsx +++ b/src/Components/Common/Breadcrumbs.tsx @@ -58,8 +58,8 @@ export default function Breadcrumbs({ style: replacements[field]?.style || "", })); - const renderCrumb = (crumb: any, index: number, array: any[]) => { - const isLastItem = index === array.length - 1; + const renderCrumb = (crumb: any, index: number) => { + const isLastItem = index === crumbs!.length - 1; return (
  • )} - {crumbs && - crumbs.length > 0 && - renderCrumb(crumbs[crumbs.length - 1], crumbs.length - 1, crumbs)} + {crumbs?.length && + renderCrumb(crumbs[crumbs.length - 1], crumbs.length - 1)} ); diff --git a/src/Components/Common/Sidebar/Sidebar.tsx b/src/Components/Common/Sidebar/Sidebar.tsx index 0e9ee34b715..31efe00f1b1 100644 --- a/src/Components/Common/Sidebar/Sidebar.tsx +++ b/src/Components/Common/Sidebar/Sidebar.tsx @@ -104,11 +104,11 @@ const StatelessSidebar = ({ : "overflow-y-auto overflow-x-hidden" }`} > - {shrinked && ( + {setShrinked && shrinked && (
    setShrinked && setShrinked(!shrinked)} + toggle={() => setShrinked(!shrinked)} />
    )} @@ -123,11 +123,11 @@ const StatelessSidebar = ({ src={shrinked ? LOGO_COLLAPSE : careConfig.mainLogo?.light} /> - {!shrinked && ( + {setShrinked && !shrinked && (
    setShrinked && setShrinked(!shrinked)} + toggle={() => setShrinked(!shrinked)} />
    )} @@ -220,7 +220,7 @@ interface ToggleShrinkProps { const ToggleShrink = ({ shrinked, toggle }: ToggleShrinkProps) => (
    = ({ shrinked }) => { id="sign-out-button" className={`flex h-full items-center justify-start transition-all duration-200 ease-in-out ${shrinked ? "pl-2" : "pl-5 pr-4"}`} > -
    - -
    - + {!shrinked && (
    {t("sign_out")} diff --git a/src/Components/Facility/DischargedPatientsList.tsx b/src/Components/Facility/DischargedPatientsList.tsx index 6603f3964af..47e5cd5a68d 100644 --- a/src/Components/Facility/DischargedPatientsList.tsx +++ b/src/Components/Facility/DischargedPatientsList.tsx @@ -47,15 +47,16 @@ const DischargedPatientsList = ({ pathParams: { id: facility_external_id }, }); - const { qParams, updateQuery, advancedFilter, FilterBadges } = useFilters({ - limit: 12, - cacheBlacklist: [ - "name", - "patient_no", - "phone_number", - "emergency_phone_number", - ], - }); + const { qParams, updateQuery, advancedFilter, FilterBadges, updatePage } = + useFilters({ + limit: 12, + cacheBlacklist: [ + "name", + "patient_no", + "phone_number", + "emergency_phone_number", + ], + }); useEffect(() => { if (!qParams.phone_number && phone_number.length >= 13) { @@ -434,10 +435,9 @@ const DischargedPatientsList = ({ route={routes.listFacilityDischargedPatients} pathParams={{ facility_external_id }} query={{ ordering: "-modified_date", ...qParams }} - queryCB={(query) => { - setCount(query.data?.count || 0); - console.log(query.data?.count); - }} + queryCB={(query) => setCount(query.data?.count || 0)} + initialPage={qParams.page} + onPageChange={updatePage} > {() => (
    diff --git a/src/Components/Facility/FacilityBlock.tsx b/src/Components/Facility/FacilityBlock.tsx index 64c0a24d78d..891bb4d4e59 100644 --- a/src/Components/Facility/FacilityBlock.tsx +++ b/src/Components/Facility/FacilityBlock.tsx @@ -1,6 +1,6 @@ import { Link } from "raviger"; -import CareIcon from "../../CAREUI/icons/CareIcon"; import { FacilityModel } from "./models"; +import { Avatar } from "@/Components/Common/Avatar"; export default function FacilityBlock(props: { facility: FacilityModel }) { const { facility } = props; @@ -18,9 +18,7 @@ export default function FacilityBlock(props: { facility: FacilityModel }) { src={facility.read_cover_image_url} /> ) : ( - <> - - + )}
    diff --git a/src/Components/Facility/FacilityCard.tsx b/src/Components/Facility/FacilityCard.tsx index 0febe36e4b7..f3614d2685a 100644 --- a/src/Components/Facility/FacilityCard.tsx +++ b/src/Components/Facility/FacilityCard.tsx @@ -61,12 +61,7 @@ export const FacilityCard = (props: { facility: any; userType: any }) => { alt={facility.name} className="h-full max-h-32 w-full object-cover" /> - )) || ( - - )} + )) || }
    diff --git a/src/Components/Facility/FacilityHome.tsx b/src/Components/Facility/FacilityHome.tsx index 7edbb939b8a..6f73fee4a54 100644 --- a/src/Components/Facility/FacilityHome.tsx +++ b/src/Components/Facility/FacilityHome.tsx @@ -43,6 +43,7 @@ type Props = { }; import Loading from "@/Components/Common/Loading"; +import { Avatar } from "@/Components/Common/Avatar.js"; export const getFacilityFeatureIcon = (featureId: number) => { const feature = FACILITY_FEATURE_TYPES.find((f) => f.id === featureId); if (!feature?.icon) return null; @@ -124,7 +125,7 @@ export const FacilityHome = ({ facilityId }: Props) => { onClick={() => setEditCoverImage(true)} > - {`${hasCoverImage ? "Edit" : "Upload"}`} + {t(hasCoverImage ? "edit" : "upload")}
    ); @@ -181,11 +182,7 @@ export const FacilityHome = ({ facilityId }: Props) => { hasPermissionToEditCoverImage && setEditCoverImage(true) } > -
    )} @@ -210,13 +207,7 @@ export const FacilityHome = ({ facilityId }: Props) => { ) : (
    - - - +
    )} {editCoverImageTooltip} @@ -291,7 +282,10 @@ export const FacilityHome = ({ facilityId }: Props) => {
    {spokesQuery.data?.results.map((spoke) => ( - + ))}
    diff --git a/src/Components/Facility/LocationManagement.tsx b/src/Components/Facility/LocationManagement.tsx index 1aaf57b7233..2223aa2e8fd 100644 --- a/src/Components/Facility/LocationManagement.tsx +++ b/src/Components/Facility/LocationManagement.tsx @@ -16,6 +16,7 @@ import useAuthUser from "../../Common/hooks/useAuthUser"; import useQuery from "../../Utils/request/useQuery"; import Loading from "@/Components/Common/Loading"; +import { cn } from "@/lib/utils"; interface Props { facilityId: string; } @@ -87,14 +88,14 @@ export default function LocationManagement({ facilityId }: Props) { id="add-new-location" href={`/facility/${facilityId}/location/add`} authorizeFor={NonReadOnlyUsers} - className="mr-4 hidden lg:block" + className="hidden lg:block" > Add New Location } > -
    +
    - className="my-8 grid gap-3 @4xl:grid-cols-2 @6xl:grid-cols-3 @[100rem]:grid-cols-4 lg:mx-8"> + className="my-8 grid gap-3 @4xl:grid-cols-2 @6xl:grid-cols-3 @[100rem]:grid-cols-4"> {(item) => ( { - const { loading, data } = useQuery(routes.listFacilityBeds, { + const bedsQuery = useQuery(routes.listFacilityBeds, { query: { facility: facilityId, location: id, }, }); - const totalBeds = data?.count ?? 0; - - if (loading) { - return ; - } + const totalBeds = bedsQuery.data?.count; return (
    @@ -290,13 +287,16 @@ const Location = ({ id="manage-bed-button" variant="secondary" border - className="mt-3 flex w-full items-center justify-between" + className={cn( + "mt-3 flex w-full items-center justify-between", + totalBeds != null && "opacity-50", + )} href={`location/${id}/beds`} > Manage Beds - {totalBeds} + {totalBeds ?? "--"}
    diff --git a/src/Components/Patient/ManagePatients.tsx b/src/Components/Patient/ManagePatients.tsx index 0be6fe6b819..46dad347dd5 100644 --- a/src/Components/Patient/ManagePatients.tsx +++ b/src/Components/Patient/ManagePatients.tsx @@ -471,7 +471,7 @@ export const PatientManager = () => { let patientList: ReactNode[] = []; if (data?.count) { - patientList = data.results.map((patient: any) => { + patientList = data.results.map((patient) => { let patientUrl = ""; if ( patient.last_consultation && @@ -506,7 +506,7 @@ export const PatientManager = () => {
    -
    +
    {patient?.last_consultation?.current_bed && patient?.last_consultation?.discharge_date === null ? (
    @@ -541,9 +541,10 @@ export const PatientManager = () => {
    ) : ( -
    +
    diff --git a/src/Components/Patient/PatientConsentRecordBlock.tsx b/src/Components/Patient/PatientConsentRecordBlock.tsx index 07931380cb6..b66a6cbd8aa 100644 --- a/src/Components/Patient/PatientConsentRecordBlock.tsx +++ b/src/Components/Patient/PatientConsentRecordBlock.tsx @@ -70,10 +70,7 @@ export default function PatientConsentRecordBlockGroup(props: { { - console.log(e.value); - setPatientCodeStatus(e.value); - }} + onChange={(e) => setPatientCodeStatus(e.value)} value={ CONSENT_PATIENT_CODE_STATUS_CHOICES.find( (c) => c.id === patientCodeStatus, diff --git a/src/Components/Patient/PatientHome.tsx b/src/Components/Patient/PatientHome.tsx index f6fe4f28a72..4b88df5bd20 100644 --- a/src/Components/Patient/PatientHome.tsx +++ b/src/Components/Patient/PatientHome.tsx @@ -253,7 +253,7 @@ export const PatientHome = (props: any) => { return ( {
    {field("nationality").value === "India" && ( -
    +
    {
    )} -
    +
    {
    -
    +

    Insurance Details diff --git a/src/Components/Users/ManageUsers.tsx b/src/Components/Users/ManageUsers.tsx index 2a00a2a8305..801ffae03af 100644 --- a/src/Components/Users/ManageUsers.tsx +++ b/src/Components/Users/ManageUsers.tsx @@ -415,7 +415,7 @@ export default function ManageUsers() { }} > -

    Linked Facilities

    +

    {t("linked_facilities")}

    -

    Linked Skills

    +

    {t("linked_skills")}

    {["DistrictAdmin", "StateAdmin"].includes( @@ -781,7 +781,7 @@ export function UserFacilities(props: { user: any }) { selected={facility} setSelected={setFacility} errors="" - className="z-40" + className="z-40 w-full" /> { selected={selectedSkill} setSelected={setSelectedSkill} errors="" + className="w-full" userSkills={skills?.results || []} /> -
    +
    {pages}
    From 45a39301cc938d042f1c568940a9a697abf52140 Mon Sep 17 00:00:00 2001 From: Gigin George Date: Wed, 16 Oct 2024 16:00:22 +0530 Subject: [PATCH 2/2] WIP: Care Plugin Support (#8660) Co-authored-by: Shivank Kacker --- .cursorrules | 23 + .env.docker | 2 + .example.env | 2 + .gitignore | 4 + .nvmrc | 1 + .prettierrc.json | 7 +- README.md | 19 +- care.config.ts | 7 + cypress/e2e/users_spec/UsersHomepage.cy.ts | 2 +- .../pageobject/Facility/FacilityCreation.ts | 2 +- package-lock.json | 1090 ++++++++--------- package.json | 21 +- scripts/setup-care-apps.js | 113 ++ src/App.tsx | 26 +- src/CAREUI/display/Timeline.tsx | 4 +- src/CAREUI/icons/CareIcon.tsx | 39 +- src/CAREUI/icons/icon.js | 49 - src/CAREUI/interactive/LegendInput.tsx | 13 +- src/Common/hooks/useCareApps.ts | 35 + .../CentralLiveMonitoring/index.tsx | 2 +- src/Components/Common/ErrorBoundary.tsx | 36 + src/Components/Common/Sidebar/Sidebar.tsx | 19 +- src/Components/Common/Sidebar/SidebarItem.tsx | 22 +- src/Components/Common/SortDropdown.tsx | 1 + .../Facility/DoctorVideoSlideover.tsx | 2 + .../{HospitalList.tsx => FacilityList.tsx} | 2 +- .../Notifications/ShowPushNotification.tsx | 3 +- src/Components/Users/UserProfile.tsx | 100 +- src/Locale/en.json | 27 +- src/PluginEngine.tsx | 51 + src/Redux/api.tsx | 2 +- src/Routers/AppRouter.tsx | 37 +- src/Routers/routes/AssetRoutes.tsx | 25 +- src/Routers/routes/ConsultationRoutes.tsx | 68 +- .../routes/FacilityInventoryRoutes.tsx | 19 +- src/Routers/routes/FacilityLocationRoutes.tsx | 25 +- src/Routers/routes/FacilityRoutes.tsx | 31 +- src/Routers/routes/HCXRoutes.tsx | 17 +- src/Routers/routes/PatientRoutes.tsx | 26 +- src/Routers/routes/ResourceRoutes.tsx | 12 +- src/Routers/routes/SampleRoutes.tsx | 20 +- src/Routers/routes/ShiftingRoutes.tsx | 11 +- src/Routers/routes/UserRoutes.tsx | 5 +- src/Utils/useTimer.tsx | 2 +- src/pluginTypes.ts | 54 + src/vite-env.d.ts | 1 + tsconfig.json | 5 +- vite.config.mts | 61 +- 48 files changed, 1275 insertions(+), 870 deletions(-) create mode 100644 .cursorrules create mode 100644 .env.docker create mode 100644 .nvmrc create mode 100644 scripts/setup-care-apps.js delete mode 100644 src/CAREUI/icons/icon.js create mode 100644 src/Common/hooks/useCareApps.ts create mode 100644 src/Components/Common/ErrorBoundary.tsx rename src/Components/Facility/{HospitalList.tsx => FacilityList.tsx} (99%) create mode 100644 src/PluginEngine.tsx create mode 100644 src/pluginTypes.ts diff --git a/.cursorrules b/.cursorrules new file mode 100644 index 00000000000..a561180ab91 --- /dev/null +++ b/.cursorrules @@ -0,0 +1,23 @@ +Care is a React Typescript Project, built with Vite and styled with TailwindCSS. + +Care uses a Plugin Architecture. Apps are installed in /apps. + +Care uses a custom useQuery hook to fetch data from the API. APIs are defined in the api.tsx file + +Here's an example of how to use the useQuery hook to fetch data from the API: + +``` +useQuery from "@/Common/hooks/useQuery"; +const { data, loading, error } = useQuery(routes.getFacilityUsers, { + facility_id: "1", +}); + +request from "@/Common/utils/request"; +const { res } = await request(routes.partialUpdateAsset, { + pathParams: { external_id: assetId }, + body: data, +}); +``` + + + diff --git a/.env.docker b/.env.docker new file mode 100644 index 00000000000..fb5179c6c50 --- /dev/null +++ b/.env.docker @@ -0,0 +1,2 @@ +# Care API URL without the /api prefix +REACT_CARE_API_URL=http://localhost:9000 \ No newline at end of file diff --git a/.example.env b/.example.env index f3f303bc1e3..0ce9043b9a3 100644 --- a/.example.env +++ b/.example.env @@ -16,6 +16,8 @@ REACT_PLAUSIBLE_SITE_DOMAIN= # Plausible server URL (default: https://plausible.10bedicu.in) REACT_PLAUSIBLE_SERVER_URL= +# Care Apps. repo@branch seperated by commas +REACT_ENABLED_APPS="ohcnetwork/care_livekit_fe@main,ohcnetwork/care_scribe" # Main logo (JSON string with light and dark properties) REACT_HEADER_LOGO= diff --git a/.gitignore b/.gitignore index d8e2615c727..000a965c44a 100644 --- a/.gitignore +++ b/.gitignore @@ -58,3 +58,7 @@ bun.lockb # Cypress cypress/downloads cypress/fixtures/token.json + +# Care Apps +/apps/* +src/pluginMap.ts diff --git a/.nvmrc b/.nvmrc new file mode 100644 index 00000000000..2edeafb09db --- /dev/null +++ b/.nvmrc @@ -0,0 +1 @@ +20 \ No newline at end of file diff --git a/.prettierrc.json b/.prettierrc.json index e3a9c2acae9..ba722afdd73 100644 --- a/.prettierrc.json +++ b/.prettierrc.json @@ -5,7 +5,6 @@ "semi": true, "jsxSingleQuote": false, "arrowParens": "always", - "tailwindFunctions": [ - "classNames" - ] -} \ No newline at end of file + "tailwindFunctions": ["classNames"], + "plugins": ["prettier-plugin-tailwindcss"] +} diff --git a/README.md b/README.md index 73ce06815d1..7ea8fe1a221 100644 --- a/README.md +++ b/README.md @@ -8,20 +8,22 @@

    Our goal is to continuously improve the quality and accessibility of public healthcare services using digital tools.

    -

    🚀 Staging Deploy

    -

    +

    🚀 Staging Deployment

    +
    + +[![Netlify Status](https://api.netlify.com/api/v1/badges/de76351f-b1f0-4bf8-8445-d9faf6391b13/deploy-status)](https://app.netlify.com/sites/care-ohc/deploys) + +

    Auto deployed to care.ohc.network for develop branch. All pull requests have preview builds powered by Netlify.

    [![](https://sourcerer.io/fame/tomahawk-pilot/ohcnetwork/care_fe/images/0)](https://sourcerer.io/fame/tomahawk-pilot/ohcnetwork/care_fe/links/0)[![](https://sourcerer.io/fame/tomahawk-pilot/ohcnetwork/care_fe/images/1)](https://sourcerer.io/fame/tomahawk-pilot/ohcnetwork/care_fe/links/1)[![](https://sourcerer.io/fame/tomahawk-pilot/ohcnetwork/care_fe/images/2)](https://sourcerer.io/fame/tomahawk-pilot/ohcnetwork/care_fe/links/2)[![](https://sourcerer.io/fame/tomahawk-pilot/ohcnetwork/care_fe/images/3)](https://sourcerer.io/fame/tomahawk-pilot/ohcnetwork/care_fe/links/3)[![](https://sourcerer.io/fame/tomahawk-pilot/ohcnetwork/care_fe/images/4)](https://sourcerer.io/fame/tomahawk-pilot/ohcnetwork/care_fe/links/4)[![](https://sourcerer.io/fame/tomahawk-pilot/ohcnetwork/care_fe/images/5)](https://sourcerer.io/fame/tomahawk-pilot/ohcnetwork/care_fe/links/5)[![](https://sourcerer.io/fame/tomahawk-pilot/ohcnetwork/care_fe/images/6)](https://sourcerer.io/fame/tomahawk-pilot/ohcnetwork/care_fe/links/6)[![](https://sourcerer.io/fame/tomahawk-pilot/ohcnetwork/care_fe/images/7)](https://sourcerer.io/fame/tomahawk-pilot/ohcnetwork/care_fe/links/7) -[![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=coronasafe_care_fe&metric=alert_status)](https://sonarcloud.io/summary/new_code?id=coronasafe_care_fe) ![Code scanning - action](https://github.com/ohcnetwork/care_fe/workflows/Code%20scanning%20-%20action/badge.svg) ![OSSAR](https://github.com/ohcnetwork/care_fe/workflows/OSSAR/badge.svg) [![Cypress Tests](https://img.shields.io/endpoint?url=https://cloud.cypress.io/badge/simple/wf7d2m/develop&style=flat&logo=cypress)](https://cloud.cypress.io/projects/wf7d2m/runs) ![Staging Release](https://github.com/ohcnetwork/care_fe/workflows/CARE%20Develop%20Registry/badge.svg) ![Production Release](https://github.com/ohcnetwork/care_fe/workflows/Production%20Release/badge.svg) [![Codacy Badge](https://api.codacy.com/project/badge/Grade/200482ab117e4b5397ff3f5ae5719aa2)](https://www.codacy.com/gh/ohcnetwork/care_fe?utm_source=github.com&utm_medium=referral&utm_content=ohcnetwork/care_fe&utm_campaign=Badge_Grade) -[![CircleCI](https://circleci.com/gh/ohcnetwork/care_fe.svg?style=svg)](https://circleci.com/gh/ohcnetwork/care_fe) [![Maintainability](https://api.codeclimate.com/v1/badges/f1438f693aa459805301/maintainability)](https://codeclimate.com/github/ohcnetwork/care_fe/maintainability) ## Getting started @@ -33,7 +35,14 @@ #### Install the required dependencies ```sh -npm install +npm run install-all +``` +#### First-time setup + +For first-time setup, run the following command to generate the pluginMap and install plugin configurations: + +```sh +npm run setup ``` #### 🏃 Run the app in development mode diff --git a/care.config.ts b/care.config.ts index c032ba613f3..ed82d69554a 100644 --- a/care.config.ts +++ b/care.config.ts @@ -103,6 +103,13 @@ const careConfig = { abdm: { enabled: (env.REACT_ENABLE_ABDM ?? "true") === "true", }, + + careApps: env.REACT_ENABLED_APPS + ? env.REACT_ENABLED_APPS.split(",").map((app) => ({ + branch: app.split("@")[1], + package: app.split("@")[0], + })) + : [], } as const; export default careConfig; diff --git a/cypress/e2e/users_spec/UsersHomepage.cy.ts b/cypress/e2e/users_spec/UsersHomepage.cy.ts index 0cf25cacfc8..634336a4ef9 100644 --- a/cypress/e2e/users_spec/UsersHomepage.cy.ts +++ b/cypress/e2e/users_spec/UsersHomepage.cy.ts @@ -14,7 +14,7 @@ describe("User Homepage", () => { const altPhoneNumber = "8878825662"; const homeFacility = "Dummy Facility 40"; const nurseUserName = "dummynurse1"; - const doctorUserName = "devdoctor"; + const doctorUserName = "devdoctor1"; before(() => { loginPage.loginAsDisctrictAdmin(); diff --git a/cypress/pageobject/Facility/FacilityCreation.ts b/cypress/pageobject/Facility/FacilityCreation.ts index 26f387935ac..fe838a88f41 100644 --- a/cypress/pageobject/Facility/FacilityCreation.ts +++ b/cypress/pageobject/Facility/FacilityCreation.ts @@ -297,7 +297,7 @@ class FacilityPage { selectLocation(location: string) { cy.intercept("https://maps.googleapis.com/**").as("mapApi"); - cy.get("span > svg.care-svg-icon__baseline.care-l-map-marker").click(); + cy.get("#facility-location-button").click(); cy.wait("@mapApi").its("response.statusCode").should("eq", 200); cy.get("input#pac-input").type(location).type("{enter}"); cy.wait(2000); diff --git a/package-lock.json b/package-lock.json index e66a3ea4ead..e5bae3c6d02 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,6 +8,9 @@ "name": "care_fe", "version": "2.5.4", "license": "MIT", + "workspaces": [ + "apps/*" + ], "dependencies": { "@fontsource/figtree": "^5.1.0", "@googlemaps/react-wrapper": "^1.1.35", @@ -20,7 +23,7 @@ "@radix-ui/react-slot": "^1.1.0", "@radix-ui/react-toast": "^1.2.2", "@sentry/browser": "^8.33.0", - "@yudiel/react-qr-scanner": "^2.0.0-beta.3", + "@yudiel/react-qr-scanner": "^2.0.8", "axios": "^1.7.7", "bowser": "^2.11.0", "browser-image-compression": "^2.0.2", @@ -68,7 +71,7 @@ "@types/lodash-es": "^4.17.12", "@types/node": "^22.7.4", "@types/qrcode.react": "^1.0.5", - "@types/react": "18.3.2", + "@types/react": "^18.3.11", "@types/react-copy-to-clipboard": "^5.0.7", "@types/react-csv": "^1.1.10", "@types/react-dom": "^18.3.0", @@ -79,6 +82,7 @@ "autoprefixer": "^10.4.19", "cypress-localstorage-commands": "^2.2.5", "cypress-split": "^1.23.2", + "dotenv": "^16.4.5", "eslint-config-prettier": "^9.1.0", "eslint-plugin-i18next": "^6.0.9", "eslint-plugin-mdx": "^3.1.5", @@ -106,6 +110,24 @@ "node": ">=20.12.0" } }, + "apps/care_livekit_fe": { + "name": "care-livekit", + "version": "0.0.1", + "license": "ISC", + "dependencies": { + "@livekit/components-react": "^2.6.2", + "@livekit/components-styles": "^1.1.3", + "livekit-client": "^2.5.5" + }, + "devDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" + }, + "peerDependencies": { + "react": "18.3.1", + "react-dom": "18.3.1" + } + }, "node_modules/@actions/core": { "version": "1.11.1", "resolved": "https://registry.npmjs.org/@actions/core/-/core-1.11.1.tgz", @@ -178,18 +200,18 @@ } }, "node_modules/@babel/compat-data": { - "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.25.7.tgz", - "integrity": "sha512-9ickoLz+hcXCeh7jrcin+/SLWm+GkxE2kTvoYyp38p4WkdFXfQJxDFGWp/YHjiKLPx06z2A7W8XKuqbReXDzsw==", + "version": "7.25.8", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.25.8.tgz", + "integrity": "sha512-ZsysZyXY4Tlx+Q53XdnOFmqwfB9QDTHYxaZYajWRoBLuLEAwI2UIbtxOjWh/cFaa9IKUlcB+DDuoskLuKu56JA==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/core": { - "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.25.7.tgz", - "integrity": "sha512-yJ474Zv3cwiSOO9nXJuqzvwEeM+chDuQ8GJirw+pZ91sCGCyOZ3dJkVE09fTV0VEVzXyLWhh3G/AolYTPX7Mow==", + "version": "7.25.8", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.25.8.tgz", + "integrity": "sha512-Oixnb+DzmRT30qu9d3tJSQkxuygWm32DFykT4bRoORPa9hZ/L4KhVB/XiRm6KG+roIEM7DBQlmg27kw2HZkdZg==", "dev": true, "dependencies": { "@ampproject/remapping": "^2.2.0", @@ -198,10 +220,10 @@ "@babel/helper-compilation-targets": "^7.25.7", "@babel/helper-module-transforms": "^7.25.7", "@babel/helpers": "^7.25.7", - "@babel/parser": "^7.25.7", + "@babel/parser": "^7.25.8", "@babel/template": "^7.25.7", "@babel/traverse": "^7.25.7", - "@babel/types": "^7.25.7", + "@babel/types": "^7.25.8", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -636,12 +658,12 @@ } }, "node_modules/@babel/parser": { - "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.25.7.tgz", - "integrity": "sha512-aZn7ETtQsjjGG5HruveUK06cU3Hljuhd9Iojm4M8WWv3wLE6OkE5PWbDUkItmMgegmccaITudyuW5RPYrYlgWw==", + "version": "7.25.8", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.25.8.tgz", + "integrity": "sha512-HcttkxzdPucv3nNFmfOOMfFf64KgdJVqm1KaCm25dPGMLElo9nsLvXeJECQg8UzPuBGLyTSA0ZzqCtDSzKTEoQ==", "dev": true, "dependencies": { - "@babel/types": "^7.25.7" + "@babel/types": "^7.25.8" }, "bin": { "parser": "bin/babel-parser.js" @@ -741,69 +763,6 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-syntax-async-generators": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", - "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-class-properties": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", - "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.12.13" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-class-static-block": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", - "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-dynamic-import": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", - "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-export-namespace-from": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz", - "integrity": "sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.3" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, "node_modules/@babel/plugin-syntax-import-assertions": { "version": "7.25.7", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.25.7.tgz", @@ -834,30 +793,6 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-syntax-import-meta": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", - "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-json-strings": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", - "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, "node_modules/@babel/plugin-syntax-jsx": { "version": "7.25.7", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.25.7.tgz", @@ -873,108 +808,6 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-syntax-logical-assignment-operators": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", - "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", - "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-numeric-separator": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", - "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-object-rest-spread": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", - "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-optional-catch-binding": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", - "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-optional-chaining": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", - "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-private-property-in-object": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", - "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-top-level-await": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", - "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, "node_modules/@babel/plugin-syntax-unicode-sets-regex": { "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz", @@ -1007,14 +840,13 @@ } }, "node_modules/@babel/plugin-transform-async-generator-functions": { - "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.25.7.tgz", - "integrity": "sha512-4B6OhTrwYKHYYgcwErvZjbmH9X5TxQBsaBHdzEIB4l71gR5jh/tuHGlb9in47udL2+wVUcOz5XXhhfhVJwEpEg==", + "version": "7.25.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.25.8.tgz", + "integrity": "sha512-9ypqkozyzpG+HxlH4o4gdctalFGIjjdufzo7I2XPda0iBnZ6a+FO0rIEQcdSPXp02CkvGsII1exJhmROPQd5oA==", "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.25.7", "@babel/helper-remap-async-to-generator": "^7.25.7", - "@babel/plugin-syntax-async-generators": "^7.8.4", "@babel/traverse": "^7.25.7" }, "engines": { @@ -1088,14 +920,13 @@ } }, "node_modules/@babel/plugin-transform-class-static-block": { - "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.25.7.tgz", - "integrity": "sha512-rvUUtoVlkDWtDWxGAiiQj0aNktTPn3eFynBcMC2IhsXweehwgdI9ODe+XjWw515kEmv22sSOTp/rxIRuTiB7zg==", + "version": "7.25.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.25.8.tgz", + "integrity": "sha512-e82gl3TCorath6YLf9xUwFehVvjvfqFhdOo4+0iVIVju+6XOi5XHkqB3P2AXnSwoeTX0HBoXq5gJFtvotJzFnQ==", "dev": true, "dependencies": { "@babel/helper-create-class-features-plugin": "^7.25.7", - "@babel/helper-plugin-utils": "^7.25.7", - "@babel/plugin-syntax-class-static-block": "^7.14.5" + "@babel/helper-plugin-utils": "^7.25.7" }, "engines": { "node": ">=6.9.0" @@ -1212,13 +1043,12 @@ } }, "node_modules/@babel/plugin-transform-dynamic-import": { - "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.25.7.tgz", - "integrity": "sha512-UvcLuual4h7/GfylKm2IAA3aph9rwvAM2XBA0uPKU3lca+Maai4jBjjEVUS568ld6kJcgbouuumCBhMd/Yz17w==", + "version": "7.25.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.25.8.tgz", + "integrity": "sha512-gznWY+mr4ZQL/EWPcbBQUP3BXS5FwZp8RUOw06BaRn8tQLzN4XLIxXejpHN9Qo8x8jjBmAAKp6FoS51AgkSA/A==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.25.7", - "@babel/plugin-syntax-dynamic-import": "^7.8.3" + "@babel/helper-plugin-utils": "^7.25.7" }, "engines": { "node": ">=6.9.0" @@ -1244,13 +1074,12 @@ } }, "node_modules/@babel/plugin-transform-export-namespace-from": { - "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.25.7.tgz", - "integrity": "sha512-h3MDAP5l34NQkkNulsTNyjdaR+OiB0Im67VU//sFupouP8Q6m9Spy7l66DcaAQxtmCqGdanPByLsnwFttxKISQ==", + "version": "7.25.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.25.8.tgz", + "integrity": "sha512-sPtYrduWINTQTW7FtOy99VCTWp4H23UX7vYcut7S4CIMEXU+54zKX9uCoGkLsWXteyaMXzVHgzWbLfQ1w4GZgw==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.25.7", - "@babel/plugin-syntax-export-namespace-from": "^7.8.3" + "@babel/helper-plugin-utils": "^7.25.7" }, "engines": { "node": ">=6.9.0" @@ -1293,13 +1122,12 @@ } }, "node_modules/@babel/plugin-transform-json-strings": { - "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.25.7.tgz", - "integrity": "sha512-Ot43PrL9TEAiCe8C/2erAjXMeVSnE/BLEx6eyrKLNFCCw5jvhTHKyHxdI1pA0kz5njZRYAnMO2KObGqOCRDYSA==", + "version": "7.25.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.25.8.tgz", + "integrity": "sha512-4OMNv7eHTmJ2YXs3tvxAfa/I43di+VcF+M4Wt66c88EAED1RoGaf1D64cL5FkRpNL+Vx9Hds84lksWvd/wMIdA==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.25.7", - "@babel/plugin-syntax-json-strings": "^7.8.3" + "@babel/helper-plugin-utils": "^7.25.7" }, "engines": { "node": ">=6.9.0" @@ -1324,13 +1152,12 @@ } }, "node_modules/@babel/plugin-transform-logical-assignment-operators": { - "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.25.7.tgz", - "integrity": "sha512-iImzbA55BjiovLyG2bggWS+V+OLkaBorNvc/yJoeeDQGztknRnDdYfp2d/UPmunZYEnZi6Lg8QcTmNMHOB0lGA==", + "version": "7.25.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.25.8.tgz", + "integrity": "sha512-f5W0AhSbbI+yY6VakT04jmxdxz+WsID0neG7+kQZbCOjuyJNdL5Nn4WIBm4hRpKnUcO9lP0eipUhFN12JpoH8g==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.25.7", - "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" + "@babel/helper-plugin-utils": "^7.25.7" }, "engines": { "node": ">=6.9.0" @@ -1453,13 +1280,12 @@ } }, "node_modules/@babel/plugin-transform-nullish-coalescing-operator": { - "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.25.7.tgz", - "integrity": "sha512-FbuJ63/4LEL32mIxrxwYaqjJxpbzxPVQj5a+Ebrc8JICV6YX8nE53jY+K0RZT3um56GoNWgkS2BQ/uLGTjtwfw==", + "version": "7.25.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.25.8.tgz", + "integrity": "sha512-Z7WJJWdQc8yCWgAmjI3hyC+5PXIubH9yRKzkl9ZEG647O9szl9zvmKLzpbItlijBnVhTUf1cpyWBsZ3+2wjWPQ==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.25.7", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" + "@babel/helper-plugin-utils": "^7.25.7" }, "engines": { "node": ">=6.9.0" @@ -1469,13 +1295,12 @@ } }, "node_modules/@babel/plugin-transform-numeric-separator": { - "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.25.7.tgz", - "integrity": "sha512-8CbutzSSh4hmD+jJHIA8vdTNk15kAzOnFLVVgBSMGr28rt85ouT01/rezMecks9pkU939wDInImwCKv4ahU4IA==", + "version": "7.25.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.25.8.tgz", + "integrity": "sha512-rm9a5iEFPS4iMIy+/A/PiS0QN0UyjPIeVvbU5EMZFKJZHt8vQnasbpo3T3EFcxzCeYO0BHfc4RqooCZc51J86Q==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.25.7", - "@babel/plugin-syntax-numeric-separator": "^7.10.4" + "@babel/helper-plugin-utils": "^7.25.7" }, "engines": { "node": ">=6.9.0" @@ -1485,14 +1310,13 @@ } }, "node_modules/@babel/plugin-transform-object-rest-spread": { - "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.25.7.tgz", - "integrity": "sha512-1JdVKPhD7Y5PvgfFy0Mv2brdrolzpzSoUq2pr6xsR+m+3viGGeHEokFKsCgOkbeFOQxfB1Vt2F0cPJLRpFI4Zg==", + "version": "7.25.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.25.8.tgz", + "integrity": "sha512-LkUu0O2hnUKHKE7/zYOIjByMa4VRaV2CD/cdGz0AxU9we+VA3kDDggKEzI0Oz1IroG+6gUP6UmWEHBMWZU316g==", "dev": true, "dependencies": { "@babel/helper-compilation-targets": "^7.25.7", "@babel/helper-plugin-utils": "^7.25.7", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", "@babel/plugin-transform-parameters": "^7.25.7" }, "engines": { @@ -1519,13 +1343,12 @@ } }, "node_modules/@babel/plugin-transform-optional-catch-binding": { - "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.25.7.tgz", - "integrity": "sha512-m9obYBA39mDPN7lJzD5WkGGb0GO54PPLXsbcnj1Hyeu8mSRz7Gb4b1A6zxNX32ZuUySDK4G6it8SDFWD1nCnqg==", + "version": "7.25.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.25.8.tgz", + "integrity": "sha512-EbQYweoMAHOn7iJ9GgZo14ghhb9tTjgOc88xFgYngifx7Z9u580cENCV159M4xDh3q/irbhSjZVpuhpC2gKBbg==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.25.7", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" + "@babel/helper-plugin-utils": "^7.25.7" }, "engines": { "node": ">=6.9.0" @@ -1535,14 +1358,13 @@ } }, "node_modules/@babel/plugin-transform-optional-chaining": { - "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.25.7.tgz", - "integrity": "sha512-h39agClImgPWg4H8mYVAbD1qP9vClFbEjqoJmt87Zen8pjqK8FTPUwrOXAvqu5soytwxrLMd2fx2KSCp2CHcNg==", + "version": "7.25.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.25.8.tgz", + "integrity": "sha512-q05Bk7gXOxpTHoQ8RSzGSh/LHVB9JEIkKnk3myAWwZHnYiTGYtbdrYkIsS8Xyh4ltKf7GNUSgzs/6P2bJtBAQg==", "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.25.7", - "@babel/helper-skip-transparent-expression-wrappers": "^7.25.7", - "@babel/plugin-syntax-optional-chaining": "^7.8.3" + "@babel/helper-skip-transparent-expression-wrappers": "^7.25.7" }, "engines": { "node": ">=6.9.0" @@ -1583,15 +1405,14 @@ } }, "node_modules/@babel/plugin-transform-private-property-in-object": { - "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.25.7.tgz", - "integrity": "sha512-LzA5ESzBy7tqj00Yjey9yWfs3FKy4EmJyKOSWld144OxkTji81WWnUT8nkLUn+imN/zHL8ZQlOu/MTUAhHaX3g==", + "version": "7.25.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.25.8.tgz", + "integrity": "sha512-8Uh966svuB4V8RHHg0QJOB32QK287NBksJOByoKmHMp1TAobNniNalIkI2i5IPj5+S9NYCG4VIjbEuiSN8r+ow==", "dev": true, "dependencies": { "@babel/helper-annotate-as-pure": "^7.25.7", "@babel/helper-create-class-features-plugin": "^7.25.7", - "@babel/helper-plugin-utils": "^7.25.7", - "@babel/plugin-syntax-private-property-in-object": "^7.14.5" + "@babel/helper-plugin-utils": "^7.25.7" }, "engines": { "node": ">=6.9.0" @@ -1786,12 +1607,12 @@ } }, "node_modules/@babel/preset-env": { - "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.25.7.tgz", - "integrity": "sha512-Gibz4OUdyNqqLj+7OAvBZxOD7CklCtMA5/j0JgUEwOnaRULsPDXmic2iKxL2DX2vQduPR5wH2hjZas/Vr/Oc0g==", + "version": "7.25.8", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.25.8.tgz", + "integrity": "sha512-58T2yulDHMN8YMUxiLq5YmWUnlDCyY1FsHM+v12VMx+1/FlrUj5tY50iDCpofFQEM8fMYOaY9YRvym2jcjn1Dg==", "dev": true, "dependencies": { - "@babel/compat-data": "^7.25.7", + "@babel/compat-data": "^7.25.8", "@babel/helper-compilation-targets": "^7.25.7", "@babel/helper-plugin-utils": "^7.25.7", "@babel/helper-validator-option": "^7.25.7", @@ -1801,45 +1622,30 @@ "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.25.7", "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.25.7", "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", - "@babel/plugin-syntax-async-generators": "^7.8.4", - "@babel/plugin-syntax-class-properties": "^7.12.13", - "@babel/plugin-syntax-class-static-block": "^7.14.5", - "@babel/plugin-syntax-dynamic-import": "^7.8.3", - "@babel/plugin-syntax-export-namespace-from": "^7.8.3", "@babel/plugin-syntax-import-assertions": "^7.25.7", "@babel/plugin-syntax-import-attributes": "^7.25.7", - "@babel/plugin-syntax-import-meta": "^7.10.4", - "@babel/plugin-syntax-json-strings": "^7.8.3", - "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", - "@babel/plugin-syntax-numeric-separator": "^7.10.4", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", - "@babel/plugin-syntax-optional-chaining": "^7.8.3", - "@babel/plugin-syntax-private-property-in-object": "^7.14.5", - "@babel/plugin-syntax-top-level-await": "^7.14.5", "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", "@babel/plugin-transform-arrow-functions": "^7.25.7", - "@babel/plugin-transform-async-generator-functions": "^7.25.7", + "@babel/plugin-transform-async-generator-functions": "^7.25.8", "@babel/plugin-transform-async-to-generator": "^7.25.7", "@babel/plugin-transform-block-scoped-functions": "^7.25.7", "@babel/plugin-transform-block-scoping": "^7.25.7", "@babel/plugin-transform-class-properties": "^7.25.7", - "@babel/plugin-transform-class-static-block": "^7.25.7", + "@babel/plugin-transform-class-static-block": "^7.25.8", "@babel/plugin-transform-classes": "^7.25.7", "@babel/plugin-transform-computed-properties": "^7.25.7", "@babel/plugin-transform-destructuring": "^7.25.7", "@babel/plugin-transform-dotall-regex": "^7.25.7", "@babel/plugin-transform-duplicate-keys": "^7.25.7", "@babel/plugin-transform-duplicate-named-capturing-groups-regex": "^7.25.7", - "@babel/plugin-transform-dynamic-import": "^7.25.7", + "@babel/plugin-transform-dynamic-import": "^7.25.8", "@babel/plugin-transform-exponentiation-operator": "^7.25.7", - "@babel/plugin-transform-export-namespace-from": "^7.25.7", + "@babel/plugin-transform-export-namespace-from": "^7.25.8", "@babel/plugin-transform-for-of": "^7.25.7", "@babel/plugin-transform-function-name": "^7.25.7", - "@babel/plugin-transform-json-strings": "^7.25.7", + "@babel/plugin-transform-json-strings": "^7.25.8", "@babel/plugin-transform-literals": "^7.25.7", - "@babel/plugin-transform-logical-assignment-operators": "^7.25.7", + "@babel/plugin-transform-logical-assignment-operators": "^7.25.8", "@babel/plugin-transform-member-expression-literals": "^7.25.7", "@babel/plugin-transform-modules-amd": "^7.25.7", "@babel/plugin-transform-modules-commonjs": "^7.25.7", @@ -1847,15 +1653,15 @@ "@babel/plugin-transform-modules-umd": "^7.25.7", "@babel/plugin-transform-named-capturing-groups-regex": "^7.25.7", "@babel/plugin-transform-new-target": "^7.25.7", - "@babel/plugin-transform-nullish-coalescing-operator": "^7.25.7", - "@babel/plugin-transform-numeric-separator": "^7.25.7", - "@babel/plugin-transform-object-rest-spread": "^7.25.7", + "@babel/plugin-transform-nullish-coalescing-operator": "^7.25.8", + "@babel/plugin-transform-numeric-separator": "^7.25.8", + "@babel/plugin-transform-object-rest-spread": "^7.25.8", "@babel/plugin-transform-object-super": "^7.25.7", - "@babel/plugin-transform-optional-catch-binding": "^7.25.7", - "@babel/plugin-transform-optional-chaining": "^7.25.7", + "@babel/plugin-transform-optional-catch-binding": "^7.25.8", + "@babel/plugin-transform-optional-chaining": "^7.25.8", "@babel/plugin-transform-parameters": "^7.25.7", "@babel/plugin-transform-private-methods": "^7.25.7", - "@babel/plugin-transform-private-property-in-object": "^7.25.7", + "@babel/plugin-transform-private-property-in-object": "^7.25.8", "@babel/plugin-transform-property-literals": "^7.25.7", "@babel/plugin-transform-regenerator": "^7.25.7", "@babel/plugin-transform-reserved-words": "^7.25.7", @@ -1958,9 +1764,9 @@ } }, "node_modules/@babel/types": { - "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.7.tgz", - "integrity": "sha512-vwIVdXG+j+FOpkwqHRcBgHLYNL7XMkufrlaFvL9o6Ai9sJn9+PdyIL5qa0XzTZw084c+u9LOls53eoZWP/W5WQ==", + "version": "7.25.8", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.8.tgz", + "integrity": "sha512-JWtuCu8VQsMladxVz/P4HzHUGCAwpuqacmowgXFs5XjxIgKuNjnLokQzuVjlTvIzODaDmpjT3oxcC48vyk9EWg==", "dev": true, "dependencies": { "@babel/helper-string-parser": "^7.25.7", @@ -1971,6 +1777,11 @@ "node": ">=6.9.0" } }, + "node_modules/@bufbuild/protobuf": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@bufbuild/protobuf/-/protobuf-1.10.0.tgz", + "integrity": "sha512-QDdVFLoN93Zjg36NoQPZfsVH9tZew7wKDKyV5qRdj8ntT4wQCOradQjRaTdwMhWUYsgKsvCINKKm87FdEk96Ag==" + }, "node_modules/@colors/colors": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", @@ -2539,9 +2350,9 @@ } }, "node_modules/@floating-ui/react": { - "version": "0.26.24", - "resolved": "https://registry.npmjs.org/@floating-ui/react/-/react-0.26.24.tgz", - "integrity": "sha512-2ly0pCkZIGEQUq5H8bBK0XJmc1xIK/RM3tvVzY3GBER7IOD1UgmC2Y2tjj4AuS+TC+vTE1KJv2053290jua0Sw==", + "version": "0.26.25", + "resolved": "https://registry.npmjs.org/@floating-ui/react/-/react-0.26.25.tgz", + "integrity": "sha512-hZOmgN0NTOzOuZxI1oIrDu3Gcl8WViIkvPMpB4xdd4QD6xAMtwgwr3VPoiyH/bLtRcS1cDnhxLSD1NsMJmwh/A==", "dependencies": { "@floating-ui/react-dom": "^2.1.2", "@floating-ui/utils": "^0.2.8", @@ -2596,9 +2407,9 @@ "integrity": "sha512-3iHuO8H0jPehftsMK0kgyJzPYU/g/oiTRw+wu/yltqSZ7wJPt3vfsJHkPiuRpQjbnnWygX+T3mkRGyK/eyZ/lw==" }, "node_modules/@headlessui/react": { - "version": "2.1.9", - "resolved": "https://registry.npmjs.org/@headlessui/react/-/react-2.1.9.tgz", - "integrity": "sha512-ckWw7vlKtnoa1fL2X0fx1a3t/Li9MIKDVXn3SgG65YlxvDAsNrY39PPCxVM7sQRA7go2fJsuHSSauKFNaJHH7A==", + "version": "2.1.10", + "resolved": "https://registry.npmjs.org/@headlessui/react/-/react-2.1.10.tgz", + "integrity": "sha512-6mLa2fjMDAFQi+/R10B+zU3edsUk/MDtENB2zHho0lqKU1uzhAfJLUduWds4nCo8wbl3vULtC5rJfZAQ1yqIng==", "dependencies": { "@floating-ui/react": "^0.26.16", "@react-aria/focus": "^3.17.1", @@ -2834,6 +2645,64 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, + "node_modules/@livekit/components-core": { + "version": "0.11.9", + "resolved": "https://registry.npmjs.org/@livekit/components-core/-/components-core-0.11.9.tgz", + "integrity": "sha512-LPE1BZ+YTaqsVqGy/GAlpiO5rEI8XpEaf1TQcGdZN1BCBas9hTHt7/aHMbHQJ0K5xuAFQx8is6dFe451T4qXIQ==", + "dependencies": { + "@floating-ui/dom": "1.6.11", + "loglevel": "1.9.1", + "rxjs": "7.8.1" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "livekit-client": "^2.5.7", + "tslib": "^2.6.2" + } + }, + "node_modules/@livekit/components-react": { + "version": "2.6.5", + "resolved": "https://registry.npmjs.org/@livekit/components-react/-/components-react-2.6.5.tgz", + "integrity": "sha512-G3BpBlKy+lWTV9MH3/oBTBC17Z8CWqZ9GnjcG/xmYI0IvqmY89tVWph7cj2Bq0taniA+mD3U9EMPr68fOb1m1g==", + "dependencies": { + "@livekit/components-core": "0.11.9", + "clsx": "2.1.1", + "usehooks-ts": "3.1.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@livekit/krisp-noise-filter": "^0.2.12", + "livekit-client": "^2.5.7", + "react": ">=18", + "react-dom": ">=18", + "tslib": "^2.6.2" + }, + "peerDependenciesMeta": { + "@livekit/krisp-noise-filter": { + "optional": true + } + } + }, + "node_modules/@livekit/components-styles": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@livekit/components-styles/-/components-styles-1.1.4.tgz", + "integrity": "sha512-QCupn7tQ/dy/WZclrfsgtDe8peiGYS6Ied1IGkKOysaXo04l90t62SIUTKyxgd0dNDhUDC0p34qCggGZs/44lQ==", + "engines": { + "node": ">=18" + } + }, + "node_modules/@livekit/protocol": { + "version": "1.24.0", + "resolved": "https://registry.npmjs.org/@livekit/protocol/-/protocol-1.24.0.tgz", + "integrity": "sha512-9dCsqnkMn7lvbI4NGh18zhLDsrXyUcpS++TEFgEk5Xv1WM3R2kT3EzqgL1P/mr3jaabM6rJ8wZA/KJLuQNpF5w==", + "dependencies": { + "@bufbuild/protobuf": "^1.10.0" + } + }, "node_modules/@mapbox/node-pre-gyp": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.11.tgz", @@ -3556,11 +3425,11 @@ } }, "node_modules/@react-aria/focus": { - "version": "3.18.3", - "resolved": "https://registry.npmjs.org/@react-aria/focus/-/focus-3.18.3.tgz", - "integrity": "sha512-WKUElg+5zS0D3xlVn8MntNnkzJql2J6MuzAMP8Sv5WTgFDse/XGR842dsxPTIyKKdrWVCRegCuwa4m3n/GzgJw==", + "version": "3.18.4", + "resolved": "https://registry.npmjs.org/@react-aria/focus/-/focus-3.18.4.tgz", + "integrity": "sha512-91J35077w9UNaMK1cpMUEFRkNNz0uZjnSwiyBCFuRdaVuivO53wNC9XtWSDNDdcO5cGy87vfJRVAiyoCn/mjqA==", "dependencies": { - "@react-aria/interactions": "^3.22.3", + "@react-aria/interactions": "^3.22.4", "@react-aria/utils": "^3.25.3", "@react-types/shared": "^3.25.0", "@swc/helpers": "^0.5.0", @@ -3571,9 +3440,9 @@ } }, "node_modules/@react-aria/interactions": { - "version": "3.22.3", - "resolved": "https://registry.npmjs.org/@react-aria/interactions/-/interactions-3.22.3.tgz", - "integrity": "sha512-RRUb/aG+P0IKTIWikY/SylB6bIbLZeztnZY2vbe7RAG5MgVaCgn5HQ45SI15GlTmhsFG8CnF6slJsUFJiNHpbQ==", + "version": "3.22.4", + "resolved": "https://registry.npmjs.org/@react-aria/interactions/-/interactions-3.22.4.tgz", + "integrity": "sha512-E0vsgtpItmknq/MJELqYJwib+YN18Qag8nroqwjk1qOnBa9ROIkUhWJerLi1qs5diXq9LHKehZDXRlwPvdEFww==", "dependencies": { "@react-aria/ssr": "^3.9.6", "@react-aria/utils": "^3.25.3", @@ -3926,145 +3795,145 @@ ] }, "node_modules/@sentry-internal/browser-utils": { - "version": "8.33.1", - "resolved": "https://registry.npmjs.org/@sentry-internal/browser-utils/-/browser-utils-8.33.1.tgz", - "integrity": "sha512-TW6/r+Gl5jiXv54iK1xZ3mlVgTS/jaBp4vcQ0xGMdgiQ3WchEPcFSeYovL+YHT3tSud0GZqVtDQCz+5i76puqA==", + "version": "8.34.0", + "resolved": "https://registry.npmjs.org/@sentry-internal/browser-utils/-/browser-utils-8.34.0.tgz", + "integrity": "sha512-4AcYOzPzD1tL5eSRQ/GpKv5enquZf4dMVUez99/Bh3va8qiJrNP55AcM7UzZ7WZLTqKygIYruJTU5Zu2SpEAPQ==", "dependencies": { - "@sentry/core": "8.33.1", - "@sentry/types": "8.33.1", - "@sentry/utils": "8.33.1" + "@sentry/core": "8.34.0", + "@sentry/types": "8.34.0", + "@sentry/utils": "8.34.0" }, "engines": { "node": ">=14.18" } }, "node_modules/@sentry-internal/feedback": { - "version": "8.33.1", - "resolved": "https://registry.npmjs.org/@sentry-internal/feedback/-/feedback-8.33.1.tgz", - "integrity": "sha512-qauMRTm3qDaLqZ3ibI03cj4gLF40y0ij65nj+cns6iWxGCtPrO8tjvXFWuQsE7Aye9dGMnBgmv7uN+NTUtC3RA==", + "version": "8.34.0", + "resolved": "https://registry.npmjs.org/@sentry-internal/feedback/-/feedback-8.34.0.tgz", + "integrity": "sha512-aYSM2KPUs0FLPxxbJCFSwCYG70VMzlT04xepD1Y/tTlPPOja/02tSv2tyOdZbv8Uw7xslZs3/8Lhj74oYcTBxw==", "dependencies": { - "@sentry/core": "8.33.1", - "@sentry/types": "8.33.1", - "@sentry/utils": "8.33.1" + "@sentry/core": "8.34.0", + "@sentry/types": "8.34.0", + "@sentry/utils": "8.34.0" }, "engines": { "node": ">=14.18" } }, "node_modules/@sentry-internal/replay": { - "version": "8.33.1", - "resolved": "https://registry.npmjs.org/@sentry-internal/replay/-/replay-8.33.1.tgz", - "integrity": "sha512-fm4coIOjmanU29NOVN9MyaP4fUCOYytbtFqVSKRFNZQ/xAgNeySiBIbUd6IjujMmnOk9bY0WEUMcdm3Uotjdog==", + "version": "8.34.0", + "resolved": "https://registry.npmjs.org/@sentry-internal/replay/-/replay-8.34.0.tgz", + "integrity": "sha512-EoMh9NYljNewZK1quY23YILgtNdGgrkzJ9TPsj6jXUG0LZ0Q7N7eFWd0xOEDBvFxrmI3cSXF1i4d1sBb+eyKRw==", "dependencies": { - "@sentry-internal/browser-utils": "8.33.1", - "@sentry/core": "8.33.1", - "@sentry/types": "8.33.1", - "@sentry/utils": "8.33.1" + "@sentry-internal/browser-utils": "8.34.0", + "@sentry/core": "8.34.0", + "@sentry/types": "8.34.0", + "@sentry/utils": "8.34.0" }, "engines": { "node": ">=14.18" } }, "node_modules/@sentry-internal/replay-canvas": { - "version": "8.33.1", - "resolved": "https://registry.npmjs.org/@sentry-internal/replay-canvas/-/replay-canvas-8.33.1.tgz", - "integrity": "sha512-nsxTFTPCT10Ty/v6+AiST3+yotGP1sUb8xqfKB9fPnS1hZHFryp0NnEls7xFjBsBbZPU1GpFkzrk/E6JFzixDQ==", + "version": "8.34.0", + "resolved": "https://registry.npmjs.org/@sentry-internal/replay-canvas/-/replay-canvas-8.34.0.tgz", + "integrity": "sha512-x8KhZcCDpbKHqFOykYXiamX6x0LRxv6N1OJHoH+XCrMtiDBZr4Yo30d/MaS6rjmKGMtSRij30v+Uq+YWIgxUrg==", "dependencies": { - "@sentry-internal/replay": "8.33.1", - "@sentry/core": "8.33.1", - "@sentry/types": "8.33.1", - "@sentry/utils": "8.33.1" + "@sentry-internal/replay": "8.34.0", + "@sentry/core": "8.34.0", + "@sentry/types": "8.34.0", + "@sentry/utils": "8.34.0" }, "engines": { "node": ">=14.18" } }, "node_modules/@sentry-internal/tracing": { - "version": "7.119.1", - "resolved": "https://registry.npmjs.org/@sentry-internal/tracing/-/tracing-7.119.1.tgz", - "integrity": "sha512-cI0YraPd6qBwvUA3wQdPGTy8PzAoK0NZiaTN1LM3IczdPegehWOaEG5GVTnpGnTsmBAzn1xnBXNBhgiU4dgcrQ==", + "version": "7.119.2", + "resolved": "https://registry.npmjs.org/@sentry-internal/tracing/-/tracing-7.119.2.tgz", + "integrity": "sha512-V2W+STWrafyGJhQv3ulMFXYDwWHiU6wHQAQBShsHVACiFaDrJ2kPRet38FKv4dMLlLlP2xN+ss2e5zv3tYlTiQ==", "dev": true, "dependencies": { - "@sentry/core": "7.119.1", - "@sentry/types": "7.119.1", - "@sentry/utils": "7.119.1" + "@sentry/core": "7.119.2", + "@sentry/types": "7.119.2", + "@sentry/utils": "7.119.2" }, "engines": { "node": ">=8" } }, "node_modules/@sentry-internal/tracing/node_modules/@sentry/core": { - "version": "7.119.1", - "resolved": "https://registry.npmjs.org/@sentry/core/-/core-7.119.1.tgz", - "integrity": "sha512-YUNnH7O7paVd+UmpArWCPH4Phlb5LwrkWVqzFWqL3xPyCcTSof2RL8UmvpkTjgYJjJ+NDfq5mPFkqv3aOEn5Sw==", + "version": "7.119.2", + "resolved": "https://registry.npmjs.org/@sentry/core/-/core-7.119.2.tgz", + "integrity": "sha512-hQr3d2yWq/2lMvoyBPOwXw1IHqTrCjOsU1vYKhAa6w9vGbJZFGhKGGE2KEi/92c3gqGn+gW/PC7cV6waCTDuVA==", "dev": true, "dependencies": { - "@sentry/types": "7.119.1", - "@sentry/utils": "7.119.1" + "@sentry/types": "7.119.2", + "@sentry/utils": "7.119.2" }, "engines": { "node": ">=8" } }, "node_modules/@sentry-internal/tracing/node_modules/@sentry/types": { - "version": "7.119.1", - "resolved": "https://registry.npmjs.org/@sentry/types/-/types-7.119.1.tgz", - "integrity": "sha512-4G2mcZNnYzK3pa2PuTq+M2GcwBRY/yy1rF+HfZU+LAPZr98nzq2X3+mJHNJoobeHRkvVh7YZMPi4ogXiIS5VNQ==", + "version": "7.119.2", + "resolved": "https://registry.npmjs.org/@sentry/types/-/types-7.119.2.tgz", + "integrity": "sha512-ydq1tWsdG7QW+yFaTp0gFaowMLNVikIqM70wxWNK+u98QzKnVY/3XTixxNLsUtnAB4Y+isAzFhrc6Vb5GFdFeg==", "dev": true, "engines": { "node": ">=8" } }, "node_modules/@sentry-internal/tracing/node_modules/@sentry/utils": { - "version": "7.119.1", - "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-7.119.1.tgz", - "integrity": "sha512-ju/Cvyeu/vkfC5/XBV30UNet5kLEicZmXSyuLwZu95hEbL+foPdxN+re7pCI/eNqfe3B2vz7lvz5afLVOlQ2Hg==", + "version": "7.119.2", + "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-7.119.2.tgz", + "integrity": "sha512-TLdUCvcNgzKP0r9YD7tgCL1PEUp42TObISridsPJ5rhpVGQJvpr+Six0zIkfDUxerLYWZoK8QMm9KgFlPLNQzA==", "dev": true, "dependencies": { - "@sentry/types": "7.119.1" + "@sentry/types": "7.119.2" }, "engines": { "node": ">=8" } }, "node_modules/@sentry/browser": { - "version": "8.33.1", - "resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-8.33.1.tgz", - "integrity": "sha512-c6zI/igexkLwZuGk+u8Rj26ChjxGgkhe6ZbKFsXCYaKAp5ep5X7HQRkkqgbxApiqlC0LduHdd/ymzh139JLg8w==", + "version": "8.34.0", + "resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-8.34.0.tgz", + "integrity": "sha512-3HHG2NXxzHq1lVmDy2uRjYjGNf9NsJsTPlOC70vbQdOb+S49EdH/XMPy+J3ruIoyv6Cu0LwvA6bMOM6rHZOgNQ==", "dependencies": { - "@sentry-internal/browser-utils": "8.33.1", - "@sentry-internal/feedback": "8.33.1", - "@sentry-internal/replay": "8.33.1", - "@sentry-internal/replay-canvas": "8.33.1", - "@sentry/core": "8.33.1", - "@sentry/types": "8.33.1", - "@sentry/utils": "8.33.1" + "@sentry-internal/browser-utils": "8.34.0", + "@sentry-internal/feedback": "8.34.0", + "@sentry-internal/replay": "8.34.0", + "@sentry-internal/replay-canvas": "8.34.0", + "@sentry/core": "8.34.0", + "@sentry/types": "8.34.0", + "@sentry/utils": "8.34.0" }, "engines": { "node": ">=14.18" } }, "node_modules/@sentry/core": { - "version": "8.33.1", - "resolved": "https://registry.npmjs.org/@sentry/core/-/core-8.33.1.tgz", - "integrity": "sha512-3SS41suXLFzxL3OQvTMZ6q92ZapELVq2l2SoWlZopcamWhog2Ru0dp2vkunq97kFHb2TzKRTlFH4+4gbT8SJug==", + "version": "8.34.0", + "resolved": "https://registry.npmjs.org/@sentry/core/-/core-8.34.0.tgz", + "integrity": "sha512-adrXCTK/zsg5pJ67lgtZqdqHvyx6etMjQW3P82NgWdj83c8fb+zH+K79Z47pD4zQjX0ou2Ws5nwwi4wJbz4bfA==", "dependencies": { - "@sentry/types": "8.33.1", - "@sentry/utils": "8.33.1" + "@sentry/types": "8.34.0", + "@sentry/utils": "8.34.0" }, "engines": { "node": ">=14.18" } }, "node_modules/@sentry/integrations": { - "version": "7.119.1", - "resolved": "https://registry.npmjs.org/@sentry/integrations/-/integrations-7.119.1.tgz", - "integrity": "sha512-CGmLEPnaBqbUleVqrmGYjRjf5/OwjUXo57I9t0KKWViq81mWnYhaUhRZWFNoCNQHns+3+GPCOMvl0zlawt+evw==", + "version": "7.119.2", + "resolved": "https://registry.npmjs.org/@sentry/integrations/-/integrations-7.119.2.tgz", + "integrity": "sha512-dCuXKvbUE3gXVVa696SYMjlhSP6CxpMH/gl4Jk26naEB8Xjsn98z/hqEoXLg6Nab73rjR9c/9AdKqBbwVMHyrQ==", "dev": true, "dependencies": { - "@sentry/core": "7.119.1", - "@sentry/types": "7.119.1", - "@sentry/utils": "7.119.1", + "@sentry/core": "7.119.2", + "@sentry/types": "7.119.2", + "@sentry/utils": "7.119.2", "localforage": "^1.8.1" }, "engines": { @@ -4072,103 +3941,103 @@ } }, "node_modules/@sentry/integrations/node_modules/@sentry/core": { - "version": "7.119.1", - "resolved": "https://registry.npmjs.org/@sentry/core/-/core-7.119.1.tgz", - "integrity": "sha512-YUNnH7O7paVd+UmpArWCPH4Phlb5LwrkWVqzFWqL3xPyCcTSof2RL8UmvpkTjgYJjJ+NDfq5mPFkqv3aOEn5Sw==", + "version": "7.119.2", + "resolved": "https://registry.npmjs.org/@sentry/core/-/core-7.119.2.tgz", + "integrity": "sha512-hQr3d2yWq/2lMvoyBPOwXw1IHqTrCjOsU1vYKhAa6w9vGbJZFGhKGGE2KEi/92c3gqGn+gW/PC7cV6waCTDuVA==", "dev": true, "dependencies": { - "@sentry/types": "7.119.1", - "@sentry/utils": "7.119.1" + "@sentry/types": "7.119.2", + "@sentry/utils": "7.119.2" }, "engines": { "node": ">=8" } }, "node_modules/@sentry/integrations/node_modules/@sentry/types": { - "version": "7.119.1", - "resolved": "https://registry.npmjs.org/@sentry/types/-/types-7.119.1.tgz", - "integrity": "sha512-4G2mcZNnYzK3pa2PuTq+M2GcwBRY/yy1rF+HfZU+LAPZr98nzq2X3+mJHNJoobeHRkvVh7YZMPi4ogXiIS5VNQ==", + "version": "7.119.2", + "resolved": "https://registry.npmjs.org/@sentry/types/-/types-7.119.2.tgz", + "integrity": "sha512-ydq1tWsdG7QW+yFaTp0gFaowMLNVikIqM70wxWNK+u98QzKnVY/3XTixxNLsUtnAB4Y+isAzFhrc6Vb5GFdFeg==", "dev": true, "engines": { "node": ">=8" } }, "node_modules/@sentry/integrations/node_modules/@sentry/utils": { - "version": "7.119.1", - "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-7.119.1.tgz", - "integrity": "sha512-ju/Cvyeu/vkfC5/XBV30UNet5kLEicZmXSyuLwZu95hEbL+foPdxN+re7pCI/eNqfe3B2vz7lvz5afLVOlQ2Hg==", + "version": "7.119.2", + "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-7.119.2.tgz", + "integrity": "sha512-TLdUCvcNgzKP0r9YD7tgCL1PEUp42TObISridsPJ5rhpVGQJvpr+Six0zIkfDUxerLYWZoK8QMm9KgFlPLNQzA==", "dev": true, "dependencies": { - "@sentry/types": "7.119.1" + "@sentry/types": "7.119.2" }, "engines": { "node": ">=8" } }, "node_modules/@sentry/node": { - "version": "7.119.1", - "resolved": "https://registry.npmjs.org/@sentry/node/-/node-7.119.1.tgz", - "integrity": "sha512-rpnoQCMxWh/ccjOe+qsmvXAdlTxQHXEWdaltSxnwj7QY+kOGKGP18WTQFLq/gdOBRw9aa6PEQGwhnLfhBXXaYg==", + "version": "7.119.2", + "resolved": "https://registry.npmjs.org/@sentry/node/-/node-7.119.2.tgz", + "integrity": "sha512-TPNnqxh+Myooe4jTyRiXrzrM2SH08R4+nrmBls4T7lKp2E5R/3mDSe/YTn5rRcUt1k1hPx1NgO/taG0DoS5cXA==", "dev": true, "dependencies": { - "@sentry-internal/tracing": "7.119.1", - "@sentry/core": "7.119.1", - "@sentry/integrations": "7.119.1", - "@sentry/types": "7.119.1", - "@sentry/utils": "7.119.1" + "@sentry-internal/tracing": "7.119.2", + "@sentry/core": "7.119.2", + "@sentry/integrations": "7.119.2", + "@sentry/types": "7.119.2", + "@sentry/utils": "7.119.2" }, "engines": { "node": ">=8" } }, "node_modules/@sentry/node/node_modules/@sentry/core": { - "version": "7.119.1", - "resolved": "https://registry.npmjs.org/@sentry/core/-/core-7.119.1.tgz", - "integrity": "sha512-YUNnH7O7paVd+UmpArWCPH4Phlb5LwrkWVqzFWqL3xPyCcTSof2RL8UmvpkTjgYJjJ+NDfq5mPFkqv3aOEn5Sw==", + "version": "7.119.2", + "resolved": "https://registry.npmjs.org/@sentry/core/-/core-7.119.2.tgz", + "integrity": "sha512-hQr3d2yWq/2lMvoyBPOwXw1IHqTrCjOsU1vYKhAa6w9vGbJZFGhKGGE2KEi/92c3gqGn+gW/PC7cV6waCTDuVA==", "dev": true, "dependencies": { - "@sentry/types": "7.119.1", - "@sentry/utils": "7.119.1" + "@sentry/types": "7.119.2", + "@sentry/utils": "7.119.2" }, "engines": { "node": ">=8" } }, "node_modules/@sentry/node/node_modules/@sentry/types": { - "version": "7.119.1", - "resolved": "https://registry.npmjs.org/@sentry/types/-/types-7.119.1.tgz", - "integrity": "sha512-4G2mcZNnYzK3pa2PuTq+M2GcwBRY/yy1rF+HfZU+LAPZr98nzq2X3+mJHNJoobeHRkvVh7YZMPi4ogXiIS5VNQ==", + "version": "7.119.2", + "resolved": "https://registry.npmjs.org/@sentry/types/-/types-7.119.2.tgz", + "integrity": "sha512-ydq1tWsdG7QW+yFaTp0gFaowMLNVikIqM70wxWNK+u98QzKnVY/3XTixxNLsUtnAB4Y+isAzFhrc6Vb5GFdFeg==", "dev": true, "engines": { "node": ">=8" } }, "node_modules/@sentry/node/node_modules/@sentry/utils": { - "version": "7.119.1", - "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-7.119.1.tgz", - "integrity": "sha512-ju/Cvyeu/vkfC5/XBV30UNet5kLEicZmXSyuLwZu95hEbL+foPdxN+re7pCI/eNqfe3B2vz7lvz5afLVOlQ2Hg==", + "version": "7.119.2", + "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-7.119.2.tgz", + "integrity": "sha512-TLdUCvcNgzKP0r9YD7tgCL1PEUp42TObISridsPJ5rhpVGQJvpr+Six0zIkfDUxerLYWZoK8QMm9KgFlPLNQzA==", "dev": true, "dependencies": { - "@sentry/types": "7.119.1" + "@sentry/types": "7.119.2" }, "engines": { "node": ">=8" } }, "node_modules/@sentry/types": { - "version": "8.33.1", - "resolved": "https://registry.npmjs.org/@sentry/types/-/types-8.33.1.tgz", - "integrity": "sha512-GjoAMvwtpIemoF/IiwZ7A60g4nQv3qwzR21GvJqDVUoKD0e8pv9OLX+HyXoUat4wEDGSuDUcUyUKD2G+od73QA==", + "version": "8.34.0", + "resolved": "https://registry.npmjs.org/@sentry/types/-/types-8.34.0.tgz", + "integrity": "sha512-zLRc60CzohGCo6zNsNeQ9JF3SiEeRE4aDCP9fDDdIVCOKovS+mn1rtSip0qd0Vp2fidOu0+2yY0ALCz1A3PJSQ==", "engines": { "node": ">=14.18" } }, "node_modules/@sentry/utils": { - "version": "8.33.1", - "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-8.33.1.tgz", - "integrity": "sha512-uzuYpiiJuFY3N4WNHMBWUQX5oNv2t/TbG0OHRp3Rr7yeu+HSfD542TIp9/gMZ+G0Cxd8AmVO3wkKIFbk0TL4Qg==", + "version": "8.34.0", + "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-8.34.0.tgz", + "integrity": "sha512-W1KoRlFUjprlh3t86DZPFxLfM6mzjRzshVfMY7vRlJFymBelJsnJ3A1lPeBZM9nCraOSiw6GtOWu6k5BAkiGIg==", "dependencies": { - "@sentry/types": "8.33.1" + "@sentry/types": "8.34.0" }, "engines": { "node": ">=14.18" @@ -4196,14 +4065,14 @@ } }, "node_modules/@swc/core": { - "version": "1.7.26", - "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.7.26.tgz", - "integrity": "sha512-f5uYFf+TmMQyYIoxkn/evWhNGuUzC730dFwAKGwBVHHVoPyak1/GvJUm6i1SKl+2Hrj9oN0i3WSoWWZ4pgI8lw==", + "version": "1.7.36", + "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.7.36.tgz", + "integrity": "sha512-bu7ymMX+LCJOSSrKank25Jaq66ymLVA9fOUuy4ck3/6rbXdLw+pIJPnIDKQ9uNcxww8KDxOuJk9Ui9pqR+aGFw==", "dev": true, "hasInstallScript": true, "dependencies": { "@swc/counter": "^0.1.3", - "@swc/types": "^0.1.12" + "@swc/types": "^0.1.13" }, "engines": { "node": ">=10" @@ -4213,16 +4082,16 @@ "url": "https://opencollective.com/swc" }, "optionalDependencies": { - "@swc/core-darwin-arm64": "1.7.26", - "@swc/core-darwin-x64": "1.7.26", - "@swc/core-linux-arm-gnueabihf": "1.7.26", - "@swc/core-linux-arm64-gnu": "1.7.26", - "@swc/core-linux-arm64-musl": "1.7.26", - "@swc/core-linux-x64-gnu": "1.7.26", - "@swc/core-linux-x64-musl": "1.7.26", - "@swc/core-win32-arm64-msvc": "1.7.26", - "@swc/core-win32-ia32-msvc": "1.7.26", - "@swc/core-win32-x64-msvc": "1.7.26" + "@swc/core-darwin-arm64": "1.7.36", + "@swc/core-darwin-x64": "1.7.36", + "@swc/core-linux-arm-gnueabihf": "1.7.36", + "@swc/core-linux-arm64-gnu": "1.7.36", + "@swc/core-linux-arm64-musl": "1.7.36", + "@swc/core-linux-x64-gnu": "1.7.36", + "@swc/core-linux-x64-musl": "1.7.36", + "@swc/core-win32-arm64-msvc": "1.7.36", + "@swc/core-win32-ia32-msvc": "1.7.36", + "@swc/core-win32-x64-msvc": "1.7.36" }, "peerDependencies": { "@swc/helpers": "*" @@ -4234,9 +4103,9 @@ } }, "node_modules/@swc/core-darwin-arm64": { - "version": "1.7.26", - "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.7.26.tgz", - "integrity": "sha512-FF3CRYTg6a7ZVW4yT9mesxoVVZTrcSWtmZhxKCYJX9brH4CS/7PRPjAKNk6kzWgWuRoglP7hkjQcd6EpMcZEAw==", + "version": "1.7.36", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.7.36.tgz", + "integrity": "sha512-8vDczXzCgv3ceTPhEivlpGprN44YlrCK1nbfU9g2TrhV/Aiqi09W/eM5zLesdoM1Z3mJl492gc/8nlTkpDdusw==", "cpu": [ "arm64" ], @@ -4250,9 +4119,9 @@ } }, "node_modules/@swc/core-darwin-x64": { - "version": "1.7.26", - "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.7.26.tgz", - "integrity": "sha512-az3cibZdsay2HNKmc4bjf62QVukuiMRh5sfM5kHR/JMTrLyS6vSw7Ihs3UTkZjUxkLTT8ro54LI6sV6sUQUbLQ==", + "version": "1.7.36", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.7.36.tgz", + "integrity": "sha512-Pa2Gao7+Wf5m3SsK4abKRtd48AtoUnJInvaC3d077swBfgZjbjUbQvcpdc2dOeQtWwo49rFqUZJonMsL0jnPgQ==", "cpu": [ "x64" ], @@ -4266,9 +4135,9 @@ } }, "node_modules/@swc/core-linux-arm-gnueabihf": { - "version": "1.7.26", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.7.26.tgz", - "integrity": "sha512-VYPFVJDO5zT5U3RpCdHE5v1gz4mmR8BfHecUZTmD2v1JeFY6fv9KArJUpjrHEEsjK/ucXkQFmJ0jaiWXmpOV9Q==", + "version": "1.7.36", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.7.36.tgz", + "integrity": "sha512-3YsMWd7V+WZEjbfBnLkkz/olcRBa8nyoK0iIOnNARJBMcYaJxjkJSMZpmSojCnIVwvjA1N83CPAbUL+W+fCnHg==", "cpu": [ "arm" ], @@ -4282,9 +4151,9 @@ } }, "node_modules/@swc/core-linux-arm64-gnu": { - "version": "1.7.26", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.7.26.tgz", - "integrity": "sha512-YKevOV7abpjcAzXrhsl+W48Z9mZvgoVs2eP5nY+uoMAdP2b3GxC0Df1Co0I90o2lkzO4jYBpTMcZlmUXLdXn+Q==", + "version": "1.7.36", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.7.36.tgz", + "integrity": "sha512-lqM3aBB7kJazJYOwHeA5OGNLqXoQPZ/76b3dV+XcjN1GhD0CcXz6mW5PRYVin6OSN1eKrKBKJjtDA1mqADDEvw==", "cpu": [ "arm64" ], @@ -4298,9 +4167,9 @@ } }, "node_modules/@swc/core-linux-arm64-musl": { - "version": "1.7.26", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.7.26.tgz", - "integrity": "sha512-3w8iZICMkQQON0uIcvz7+Q1MPOW6hJ4O5ETjA0LSP/tuKqx30hIniCGOgPDnv3UTMruLUnQbtBwVCZTBKR3Rkg==", + "version": "1.7.36", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.7.36.tgz", + "integrity": "sha512-bqei2YDzvUfG0pth5W2xJaj0eG4XWYk0d/NJ75vBX6bkIzK6dC8iuKQ41jOfUWonnrAs7rTDDJW0sTn/evvRdw==", "cpu": [ "arm64" ], @@ -4314,9 +4183,9 @@ } }, "node_modules/@swc/core-linux-x64-gnu": { - "version": "1.7.26", - "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.7.26.tgz", - "integrity": "sha512-c+pp9Zkk2lqb06bNGkR2Looxrs7FtGDMA4/aHjZcCqATgp348hOKH5WPvNLBl+yPrISuWjbKDVn3NgAvfvpH4w==", + "version": "1.7.36", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.7.36.tgz", + "integrity": "sha512-03maXTUyaBjeCxlDltmdzHje1ryQt1C4OWmmNgSSRXjLb+GNnAenwOJMSrcvHP/aNClD2pwsFCnYKDGy+sYE6w==", "cpu": [ "x64" ], @@ -4330,9 +4199,9 @@ } }, "node_modules/@swc/core-linux-x64-musl": { - "version": "1.7.26", - "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.7.26.tgz", - "integrity": "sha512-PgtyfHBF6xG87dUSSdTJHwZ3/8vWZfNIXQV2GlwEpslrOkGqy+WaiiyE7Of7z9AvDILfBBBcJvJ/r8u980wAfQ==", + "version": "1.7.36", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.7.36.tgz", + "integrity": "sha512-XXysqLkvjtQnXm1zHqLhy00UYPv/gk5OtwR732X+piNisnEbcJBqI8Qp9O7YvLWllRcoP8IMBGDWLGdGLSpViA==", "cpu": [ "x64" ], @@ -4346,9 +4215,9 @@ } }, "node_modules/@swc/core-win32-arm64-msvc": { - "version": "1.7.26", - "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.7.26.tgz", - "integrity": "sha512-9TNXPIJqFynlAOrRD6tUQjMq7KApSklK3R/tXgIxc7Qx+lWu8hlDQ/kVPLpU7PWvMMwC/3hKBW+p5f+Tms1hmA==", + "version": "1.7.36", + "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.7.36.tgz", + "integrity": "sha512-k7+dmb13a/zPw+E4XYfPmLZFWJgcOcBRKIjYl9nQErtYsgsg3Ji6TBbsvJVETy23lNHyewZ17V5Vq6NzaG0hzg==", "cpu": [ "arm64" ], @@ -4362,9 +4231,9 @@ } }, "node_modules/@swc/core-win32-ia32-msvc": { - "version": "1.7.26", - "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.7.26.tgz", - "integrity": "sha512-9YngxNcG3177GYdsTum4V98Re+TlCeJEP4kEwEg9EagT5s3YejYdKwVAkAsJszzkXuyRDdnHUpYbTrPG6FiXrQ==", + "version": "1.7.36", + "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.7.36.tgz", + "integrity": "sha512-ridD3ay6YM2PEYHZXXFN+edYEv0FOynaqOBP+NSnGNHA35azItIjoIe+KNi4WltGtAjpKCHSpjGCNfna12wdYQ==", "cpu": [ "ia32" ], @@ -4378,9 +4247,9 @@ } }, "node_modules/@swc/core-win32-x64-msvc": { - "version": "1.7.26", - "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.7.26.tgz", - "integrity": "sha512-VR+hzg9XqucgLjXxA13MtV5O3C0bK0ywtLIBw/+a+O+Oc6mxFWHtdUeXDbIi5AiPbn0fjgVJMqYnyjGyyX8u0w==", + "version": "1.7.36", + "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.7.36.tgz", + "integrity": "sha512-j1z2Z1Ln9d0E3dHsPkC1K9XDh0ojhRPwV+GfRTu4D61PE+aYhYLvbJC6xPvL4/204QrStRS7eDu3m+BcDp3rgQ==", "cpu": [ "x64" ], @@ -4408,9 +4277,9 @@ } }, "node_modules/@swc/types": { - "version": "0.1.12", - "resolved": "https://registry.npmjs.org/@swc/types/-/types-0.1.12.tgz", - "integrity": "sha512-wBJA+SdtkbFhHjTMYH+dEH1y4VpfGdAc2Kw/LK09i9bXd/K6j6PkDcFCEzb6iVfZMkPRrl/q0e3toqTAJdkIVA==", + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/@swc/types/-/types-0.1.13.tgz", + "integrity": "sha512-JL7eeCk6zWCbiYQg2xQSdLXQJl8Qoc9rXmG2cEKvHe3CKwMHwHGpfOb8frzNLmbycOo6I51qxnLnn9ESf4I20Q==", "dev": true, "dependencies": { "@swc/counter": "^0.1.3" @@ -4504,9 +4373,9 @@ } }, "node_modules/@types/dom-webcodecs": { - "version": "0.1.12", - "resolved": "https://registry.npmjs.org/@types/dom-webcodecs/-/dom-webcodecs-0.1.12.tgz", - "integrity": "sha512-vEkwKEr0xAO2xwNNkYhaltT7jMGjrgAbfpRR3qKRN7eW3B7R7O5fm1scx2OKBY6wMACgjCewhu+ljbCdudY+5A==" + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/@types/dom-webcodecs/-/dom-webcodecs-0.1.13.tgz", + "integrity": "sha512-O5hkiFIcjjszPIYyUSyvScyvrBoV3NOEEZx/pMlsu44TKzWNkLVBBxnxJz42in5n3QIolYOcBYFCPZZ0h8SkwQ==" }, "node_modules/@types/emscripten": { "version": "1.39.13", @@ -4634,9 +4503,9 @@ } }, "node_modules/@types/react": { - "version": "18.3.2", - "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.2.tgz", - "integrity": "sha512-Btgg89dAnqD4vV7R3hlwOxgqobUQKgx3MmrQRi0yYbs/P0ym8XozIAlkqVilPqHQwXs4e9Tf63rrCgl58BcO4w==", + "version": "18.3.11", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.11.tgz", + "integrity": "sha512-r6QZ069rFTjrEYgFdOck1gK7FLVsgJE7tTz0pQBczlBNUhBNk0MQH4UbnFSwjpQLMkLzgqvBBa+qGpLje16eTQ==", "dependencies": { "@types/prop-types": "*", "csstype": "^3.0.2" @@ -4661,9 +4530,9 @@ } }, "node_modules/@types/react-dom": { - "version": "18.3.0", - "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.0.tgz", - "integrity": "sha512-EhwApuTmMBmXuFOikhQLIBUn6uFg81SwLMOAUgodJF14SOBOCMdU04gDoYi0WOJJHD144TL32z4yDqCW3dnkQg==", + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.1.tgz", + "integrity": "sha512-qW1Mfv8taImTthu4KoXgDfLuk4bydU6Q/TkADnDWWHwi4NX4BR+LWfTp2sVmTqRrsHvyDDTelgelxJ+SsejKKQ==", "devOptional": true, "dependencies": { "@types/react": "*" @@ -4938,39 +4807,39 @@ } }, "node_modules/@vue/compiler-core": { - "version": "3.5.11", - "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.11.tgz", - "integrity": "sha512-PwAdxs7/9Hc3ieBO12tXzmTD+Ln4qhT/56S+8DvrrZ4kLDn4Z/AMUr8tXJD0axiJBS0RKIoNaR0yMuQB9v9Udg==", + "version": "3.5.12", + "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.12.tgz", + "integrity": "sha512-ISyBTRMmMYagUxhcpyEH0hpXRd/KqDU4ymofPgl2XAkY9ZhQ+h0ovEZJIiPop13UmR/54oA2cgMDjgroRelaEw==", "dev": true, "dependencies": { "@babel/parser": "^7.25.3", - "@vue/shared": "3.5.11", + "@vue/shared": "3.5.12", "entities": "^4.5.0", "estree-walker": "^2.0.2", "source-map-js": "^1.2.0" } }, "node_modules/@vue/compiler-dom": { - "version": "3.5.11", - "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.11.tgz", - "integrity": "sha512-pyGf8zdbDDRkBrEzf8p7BQlMKNNF5Fk/Cf/fQ6PiUz9at4OaUfyXW0dGJTo2Vl1f5U9jSLCNf0EZJEogLXoeew==", + "version": "3.5.12", + "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.12.tgz", + "integrity": "sha512-9G6PbJ03uwxLHKQ3P42cMTi85lDRvGLB2rSGOiQqtXELat6uI4n8cNz9yjfVHRPIu+MsK6TE418Giruvgptckg==", "dev": true, "dependencies": { - "@vue/compiler-core": "3.5.11", - "@vue/shared": "3.5.11" + "@vue/compiler-core": "3.5.12", + "@vue/shared": "3.5.12" } }, "node_modules/@vue/compiler-sfc": { - "version": "3.5.11", - "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.11.tgz", - "integrity": "sha512-gsbBtT4N9ANXXepprle+X9YLg2htQk1sqH/qGJ/EApl+dgpUBdTv3yP7YlR535uHZY3n6XaR0/bKo0BgwwDniw==", + "version": "3.5.12", + "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.12.tgz", + "integrity": "sha512-2k973OGo2JuAa5+ZlekuQJtitI5CgLMOwgl94BzMCsKZCX/xiqzJYzapl4opFogKHqwJk34vfsaKpfEhd1k5nw==", "dev": true, "dependencies": { "@babel/parser": "^7.25.3", - "@vue/compiler-core": "3.5.11", - "@vue/compiler-dom": "3.5.11", - "@vue/compiler-ssr": "3.5.11", - "@vue/shared": "3.5.11", + "@vue/compiler-core": "3.5.12", + "@vue/compiler-dom": "3.5.12", + "@vue/compiler-ssr": "3.5.12", + "@vue/shared": "3.5.12", "estree-walker": "^2.0.2", "magic-string": "^0.30.11", "postcss": "^8.4.47", @@ -4978,19 +4847,19 @@ } }, "node_modules/@vue/compiler-ssr": { - "version": "3.5.11", - "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.11.tgz", - "integrity": "sha512-P4+GPjOuC2aFTk1Z4WANvEhyOykcvEd5bIj2KVNGKGfM745LaXGr++5njpdBTzVz5pZifdlR1kpYSJJpIlSePA==", + "version": "3.5.12", + "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.12.tgz", + "integrity": "sha512-eLwc7v6bfGBSM7wZOGPmRavSWzNFF6+PdRhE+VFJhNCgHiF8AM7ccoqcv5kBXA2eWUfigD7byekvf/JsOfKvPA==", "dev": true, "dependencies": { - "@vue/compiler-dom": "3.5.11", - "@vue/shared": "3.5.11" + "@vue/compiler-dom": "3.5.12", + "@vue/shared": "3.5.12" } }, "node_modules/@vue/shared": { - "version": "3.5.11", - "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.11.tgz", - "integrity": "sha512-W8GgysJVnFo81FthhzurdRAWP/byq3q2qIw70e0JWblzVhjgOMiC2GyovXrZTFQJnFVryYaKGP3Tc9vYzYm6PQ==", + "version": "3.5.12", + "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.12.tgz", + "integrity": "sha512-L2RPSAwUFbgZH20etwrXyVyCBu9OxRSi8T/38QsvnkJyvq2LufW2lDCOzm7t/U9C1mkhJGWYfCuFBCmIuNivrg==", "dev": true }, "node_modules/@webassemblyjs/ast": { @@ -5171,9 +5040,9 @@ "optional": true }, "node_modules/acorn": { - "version": "8.12.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", - "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", + "version": "8.13.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.13.0.tgz", + "integrity": "sha512-8zSiw54Oxrdym50NlZ9sUusyO1Z1ZchgRLWRaK6c86XJFClyCgFKetdowBg5bKxyp/u+CDBJG4Mpp0m3HLZl9w==", "bin": { "acorn": "bin/acorn" }, @@ -5731,11 +5600,11 @@ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" }, "node_modules/barcode-detector": { - "version": "2.2.10", - "resolved": "https://registry.npmjs.org/barcode-detector/-/barcode-detector-2.2.10.tgz", - "integrity": "sha512-fB6285Ahd6PIbru+PRw/CL+T1+dtPQmfCwBAwHmw+IWLLHrKH0q37qlAEHXWxPNM6bEmxgTMgGO+MJu/Si1uJQ==", + "version": "2.2.11", + "resolved": "https://registry.npmjs.org/barcode-detector/-/barcode-detector-2.2.11.tgz", + "integrity": "sha512-N50XZ6Rav2sxTgHXOc38/mkpVJMan11GZ8Yqi1pPMZpTJSXuZ/FpIee6OtLehZX/Vs4ZOzGbp1DgXzFCfKggWA==", "dependencies": { - "@types/dom-webcodecs": "^0.1.12", + "@types/dom-webcodecs": "^0.1.13", "zxing-wasm": "1.2.14" } }, @@ -5961,9 +5830,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001667", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001667.tgz", - "integrity": "sha512-7LTwJjcRkzKFmtqGsibMeuXmvFDfZq/nzIjnmgCGzKKRVzjD72selLDK1oPF/Oxzmt4fNcPvTDvGqSDG4tCALw==", + "version": "1.0.30001669", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001669.tgz", + "integrity": "sha512-DlWzFDJqstqtIVx1zeSpIMLjunf5SmwOw0N2Ck/QSQdS8PLS4+9HrLaYei4w8BIAL7IB/UEDu889d8vhCTPA0w==", "funding": [ { "type": "opencollective", @@ -5994,6 +5863,10 @@ "node": ">=6" } }, + "node_modules/care-livekit": { + "resolved": "apps/care_livekit_fe", + "link": true + }, "node_modules/caseless": { "version": "0.12.0", "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", @@ -6499,12 +6372,12 @@ "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==" }, "node_modules/cypress": { - "version": "13.14.2", - "resolved": "https://registry.npmjs.org/cypress/-/cypress-13.14.2.tgz", - "integrity": "sha512-lsiQrN17vHMB2fnvxIrKLAjOr9bPwsNbPZNrWf99s4u+DVmCY6U+w7O3GGG9FvP4EUVYaDu+guWeNLiUzBrqvA==", + "version": "13.15.0", + "resolved": "https://registry.npmjs.org/cypress/-/cypress-13.15.0.tgz", + "integrity": "sha512-53aO7PwOfi604qzOkCSzNlWquCynLlKE/rmmpSPcziRH6LNfaDUAklQT6WJIsD8ywxlIy+uVZsnTMCCQVd2kTw==", "hasInstallScript": true, "dependencies": { - "@cypress/request": "^3.0.1", + "@cypress/request": "^3.0.4", "@cypress/xvfb": "^1.2.4", "@types/sinonjs__fake-timers": "8.1.1", "@types/sizzle": "^2.3.2", @@ -6567,9 +6440,9 @@ } }, "node_modules/cypress-split": { - "version": "1.24.0", - "resolved": "https://registry.npmjs.org/cypress-split/-/cypress-split-1.24.0.tgz", - "integrity": "sha512-ZEFh1m6z+HwPWpB1h9YAF1L6K/wkPBR3vD+v8Rrg8BRm50sZ7oSx6Dw+sv6zfr5Pfqv247CnobLewdFBLlPIBQ==", + "version": "1.24.4", + "resolved": "https://registry.npmjs.org/cypress-split/-/cypress-split-1.24.4.tgz", + "integrity": "sha512-sKBFQB659Ss5B08GSESeMKXBEpPD2wKNGQR1HYbKT98rnM1x5E+MugzcicqEdsK4T2Ng0feuuZQkz8XniOA18A==", "dev": true, "dependencies": { "@actions/core": "^1.10.0", @@ -6577,7 +6450,7 @@ "console.table": "^0.10.0", "debug": "^4.3.4", "fast-shuffle": "^6.1.0", - "find-cypress-specs": "1.43.4", + "find-cypress-specs": "1.45.2", "globby": "^11.1.0", "humanize-duration": "^3.28.0" }, @@ -7051,6 +6924,18 @@ "node": ">=6.0.0" } }, + "node_modules/dotenv": { + "version": "16.4.5", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.5.tgz", + "integrity": "sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, "node_modules/eastasianwidth": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", @@ -7119,9 +7004,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.5.33", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.33.tgz", - "integrity": "sha512-+cYTcFB1QqD4j4LegwLfpCNxifb6dDFUAwk6RsLusCwIaZI6or2f+q8rs5tTB2YC53HhOlIbEaqHMAAC8IOIwA==" + "version": "1.5.39", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.39.tgz", + "integrity": "sha512-4xkpSR6CjuiaNyvwiWDI85N9AxsvbPawB8xc7yzLPonYTuP19BVgYweKyUMFtHEZgIcHWMt1ks5Cqx2m+6/Grg==" }, "node_modules/emoji-regex": { "version": "8.0.0", @@ -7286,9 +7171,9 @@ } }, "node_modules/es-iterator-helpers": { - "version": "1.0.19", - "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.0.19.tgz", - "integrity": "sha512-zoMwbCcH5hwUkKJkT8kDIBZSz9I6mVG//+lDCinLCGov4+r7NIy0ld8o03M0cJxl2spVf6ESYVS6/gpIfq1FFw==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.1.0.tgz", + "integrity": "sha512-/SurEfycdyssORP/E+bj4sEu1CWw4EmLDsHynHwSXQ7utgbrMRWW195pTrCjFgFCddf/UkYm3oqKPRq5i8bJbw==", "dev": true, "dependencies": { "call-bind": "^1.0.7", @@ -7298,12 +7183,12 @@ "es-set-tostringtag": "^2.0.3", "function-bind": "^1.1.2", "get-intrinsic": "^1.2.4", - "globalthis": "^1.0.3", + "globalthis": "^1.0.4", "has-property-descriptors": "^1.0.2", "has-proto": "^1.0.3", "has-symbols": "^1.0.3", "internal-slot": "^1.0.7", - "iterator.prototype": "^1.1.2", + "iterator.prototype": "^1.1.3", "safe-array-concat": "^1.1.2" }, "engines": { @@ -8024,9 +7909,9 @@ } }, "node_modules/fast-uri": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.2.tgz", - "integrity": "sha512-GR6f0hD7XXyNJa25Tb9BuIdN0tdr+0BMi6/CJPH3wJO1JjNG3n/VsSw38AwRdKZABm8lGbPfakLRkYzx2V9row==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.3.tgz", + "integrity": "sha512-aLrHthzCjH5He4Z2H9YZ+v6Ujb9ocRuW6ZzkJQOrTxleEijANq4v1TsaPaVG1PZcuurEzrLcWRyYBYXD5cEiaw==", "dev": true }, "node_modules/fastq": { @@ -8164,16 +8049,16 @@ } }, "node_modules/find-cypress-specs": { - "version": "1.43.4", - "resolved": "https://registry.npmjs.org/find-cypress-specs/-/find-cypress-specs-1.43.4.tgz", - "integrity": "sha512-GAdz6lfBndbOq9OOJ3psThQ56hqgL8tZUCOLnl60d/l56bvHkC0TNwyqlLfBObiscirSZWSgyGL86jJkrpFMrA==", + "version": "1.45.2", + "resolved": "https://registry.npmjs.org/find-cypress-specs/-/find-cypress-specs-1.45.2.tgz", + "integrity": "sha512-D289NM0Dpqoz4+yl8oEtbioqm7zPKQo0hLcvwlg5Z9iBm7EioMIFiOYgluthDNPxUES/aJF+1xHRHAJpC3ejcA==", "dev": true, "dependencies": { "@actions/core": "^1.10.0", "arg": "^5.0.1", "console.table": "^0.10.0", "debug": "^4.3.3", - "find-test-names": "1.28.18", + "find-test-names": "1.28.30", "globby": "^11.1.0", "minimatch": "^3.0.4", "pluralize": "^8.0.0", @@ -8212,13 +8097,13 @@ } }, "node_modules/find-test-names": { - "version": "1.28.18", - "resolved": "https://registry.npmjs.org/find-test-names/-/find-test-names-1.28.18.tgz", - "integrity": "sha512-hhnGdkWK+qEA5Z02Tu0OqGQIUjFZNyOCE4WaJpbhW4hAF1+NZ7OCr0Bss9RCaj7BBtjoIjkU93utobQ8pg2iVg==", + "version": "1.28.30", + "resolved": "https://registry.npmjs.org/find-test-names/-/find-test-names-1.28.30.tgz", + "integrity": "sha512-b5PLJ5WnskdaYHBf+38FN/4TKh5lqwrltITkqxuARsN2bW6civrhqOXbVA+4727YNowYLt/jtIC9Dsn7eJSP6A==", "dev": true, "dependencies": { - "@babel/parser": "^7.23.0", - "@babel/plugin-syntax-jsx": "^7.22.5", + "@babel/parser": "^7.24.7", + "@babel/plugin-syntax-jsx": "^7.24.7", "acorn-walk": "^8.2.0", "debug": "^4.3.3", "globby": "^11.0.4", @@ -8332,9 +8217,9 @@ } }, "node_modules/form-data": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", - "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.1.tgz", + "integrity": "sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==", "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", @@ -9178,9 +9063,9 @@ } }, "node_modules/i18next": { - "version": "23.15.2", - "resolved": "https://registry.npmjs.org/i18next/-/i18next-23.15.2.tgz", - "integrity": "sha512-zcPSWzCvw6uKnuYHIqs4W7hTuB9e3AFcSdZgvCWoPXIZsBjBd4djN2/2uOHIB+1DFFkQnMBXvhNg7J3WyCuywQ==", + "version": "23.16.0", + "resolved": "https://registry.npmjs.org/i18next/-/i18next-23.16.0.tgz", + "integrity": "sha512-Ni3CG6c14teOogY19YNRl+kYaE/Rb59khy0VyHVn4uOZ97E2E/Yziyi6r3C3s9+wacjdLZiq/LLYyx+Cgd+FCw==", "funding": [ { "type": "individual", @@ -9922,9 +9807,9 @@ "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==" }, "node_modules/iterator.prototype": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.2.tgz", - "integrity": "sha512-DR33HMMr8EzwuRL8Y9D3u2BMj8+RqSE850jfGu59kS7tbmPLzGkZmVSfyCFSDxuZiEY6Rzt3T2NA/qU+NwVj1w==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.3.tgz", + "integrity": "sha512-FW5iMbeQ6rBGm/oKgzq2aW4KvAGpxPzYES8N4g4xNXUKpL1mclMvOe+76AcLDTvD+Ze+sOpVhgdAQEKF4L9iGQ==", "dev": true, "dependencies": { "define-properties": "^1.2.1", @@ -9932,6 +9817,9 @@ "has-symbols": "^1.0.3", "reflect.getprototypeof": "^1.0.4", "set-function-name": "^2.0.1" + }, + "engines": { + "node": ">= 0.4" } }, "node_modules/jackspeak": { @@ -10691,6 +10579,26 @@ "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, + "node_modules/livekit-client": { + "version": "2.5.9", + "resolved": "https://registry.npmjs.org/livekit-client/-/livekit-client-2.5.9.tgz", + "integrity": "sha512-oDpK6SKYB1F+mNO+25DA0bF0cD2XoOJeD8ji4YQpzDBQv2IxeyKrQhoqXAqrYgIKuiMNkImSf+yg2v7EHSl4Og==", + "dependencies": { + "@livekit/protocol": "1.24.0", + "events": "^3.3.0", + "loglevel": "^1.8.0", + "sdp-transform": "^2.14.1", + "ts-debounce": "^4.0.0", + "tslib": "2.7.0", + "typed-emitter": "^2.1.0", + "webrtc-adapter": "^9.0.0" + } + }, + "node_modules/livekit-client/node_modules/tslib": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.7.0.tgz", + "integrity": "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==" + }, "node_modules/load-plugin": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/load-plugin/-/load-plugin-6.0.3.tgz", @@ -10791,8 +10699,7 @@ "node_modules/lodash.debounce": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", - "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==", - "dev": true + "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==" }, "node_modules/lodash.isplainobject": { "version": "4.0.6", @@ -10878,6 +10785,18 @@ "node": ">=8" } }, + "node_modules/loglevel": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.9.1.tgz", + "integrity": "sha512-hP3I3kCrDIMuRwAwHltphhDM1r8i55H33GgqjXbrisuJhF4kRhW1dNuxsRklp4bXl8DSdLaNLuiL4A/LWRfxvg==", + "engines": { + "node": ">= 0.6.0" + }, + "funding": { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/loglevel" + } + }, "node_modules/long": { "version": "5.2.3", "resolved": "https://registry.npmjs.org/long/-/long-5.2.3.tgz", @@ -10915,9 +10834,9 @@ } }, "node_modules/magic-string": { - "version": "0.30.11", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.11.tgz", - "integrity": "sha512-+Wri9p0QHMy+545hKww7YAu5NyzF8iomPL/RQazugQ9+Ez4Ic3mERMd8ZTX5rfK944j+560ZJi8iAwgak1Ac7A==", + "version": "0.30.12", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.12.tgz", + "integrity": "sha512-Ea8I3sQMVXr8JhN4z+H/d8zwo+tYDgHE9+5G4Wnrwhs0gaK9fXTKx0Tw5Xwsd/bCPTTZNRAdpyzvoeORe9LYpw==", "dev": true, "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0" @@ -12823,9 +12742,9 @@ } }, "node_modules/nan": { - "version": "2.20.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.20.0.tgz", - "integrity": "sha512-bk3gXBZDGILuuo/6sKtr0DQmSThYHLtNCdSdXk9YkxD/jK6X2vmCyyXBBxyqZ4XcnzTyYEAThfX3DCEnLf6igw==", + "version": "2.22.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.22.0.tgz", + "integrity": "sha512-nbajikzWTMwsW+eSsNm3QwlOs7het9gGJU5dDZzRTQGk03vyBOauxgI4VakDzE0PtsGTmXPsXTbbjVhRwR5mpw==", "optional": true }, "node_modules/nanoid": { @@ -13572,9 +13491,9 @@ } }, "node_modules/postcss-load-config/node_modules/yaml": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.5.1.tgz", - "integrity": "sha512-bLQOjaX/ADgQ20isPJRvF0iRUHIxVhYvr53Of7wGcWlO2jvtUlH5m87DsmulFVxRpNLOnI4tB6p/oh8D7kpn9Q==", + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.6.0.tgz", + "integrity": "sha512-a6ae//JvKDEra2kdi1qzCyrJW/WZCgFi8ydDV+eXExl95t+5R+ijnqHJbz9tmMh8FUjx3iv2fCQ4dclAQlO2UQ==", "bin": { "yaml": "bin.mjs" }, @@ -14066,9 +13985,9 @@ } }, "node_modules/react-i18next": { - "version": "15.0.2", - "resolved": "https://registry.npmjs.org/react-i18next/-/react-i18next-15.0.2.tgz", - "integrity": "sha512-z0W3/RES9Idv3MmJUcf0mDNeeMOUXe+xoL0kPfQPbDoZHmni/XsIoq5zgT2MCFUiau283GuBUK578uD/mkAbLQ==", + "version": "15.0.3", + "resolved": "https://registry.npmjs.org/react-i18next/-/react-i18next-15.0.3.tgz", + "integrity": "sha512-BlO1P+oLKjjIxDBQ0GkAIMacgjfMbnvops+3Y5nZXF7UJ99v4KCWr0Na1azJXC8AMiNWp4kgUcFCJM7U9ZsUDg==", "dependencies": { "@babel/runtime": "^7.25.0", "html-parse-stringify": "^3.0.1" @@ -15762,6 +15681,14 @@ "resolved": "https://registry.npmjs.org/sdp/-/sdp-3.2.0.tgz", "integrity": "sha512-d7wDPgDV3DDiqulJjKiV2865wKsJ34YI+NDREbm+FySq6WuKOikwyNQcm+doLAZ1O6ltdO0SeKle2xMpN3Brgw==" }, + "node_modules/sdp-transform": { + "version": "2.14.2", + "resolved": "https://registry.npmjs.org/sdp-transform/-/sdp-transform-2.14.2.tgz", + "integrity": "sha512-icY6jVao7MfKCieyo1AyxFYm1baiM+fA00qW/KrNNVlkxHAd34riEKuEkUe4bBb3gJwLJZM+xT60Yj1QL8rHiA==", + "bin": { + "sdp-verify": "checker.js" + } + }, "node_modules/semver": { "version": "7.6.3", "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", @@ -16585,18 +16512,18 @@ "integrity": "sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==" }, "node_modules/tailwind-merge": { - "version": "2.5.3", - "resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-2.5.3.tgz", - "integrity": "sha512-d9ZolCAIzom1nf/5p4LdD5zvjmgSxY0BGgdSvmXIoMYAiPdAW/dSpP7joCDYFY7r/HkEa2qmPtkgsu0xjQeQtw==", + "version": "2.5.4", + "resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-2.5.4.tgz", + "integrity": "sha512-0q8cfZHMu9nuYP/b5Shb7Y7Sh1B7Nnl5GqNr1U+n2p6+mybvRtayrQ+0042Z5byvTA8ihjlP8Odo8/VnHbZu4Q==", "funding": { "type": "github", "url": "https://github.com/sponsors/dcastil" } }, "node_modules/tailwindcss": { - "version": "3.4.13", - "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.13.tgz", - "integrity": "sha512-KqjHOJKogOUt5Bs752ykCeiwvi0fKVkr5oqsFNt/8px/tA8scFPIlkygsf6jXrfCqGHz7VflA6+yytWuM+XhFw==", + "version": "3.4.14", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.14.tgz", + "integrity": "sha512-IcSvOcTRcUtQQ7ILQL5quRDg7Xs93PdJEk1ZLbhhvJc7uj/OAhYOnruEiwnGgBvUtaUAJ8/mhSw1o8L2jCiENA==", "dependencies": { "@alloc/quick-lru": "^5.2.0", "arg": "^5.0.2", @@ -16982,6 +16909,11 @@ "typescript": ">=4.2.0" } }, + "node_modules/ts-debounce": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/ts-debounce/-/ts-debounce-4.0.0.tgz", + "integrity": "sha512-+1iDGY6NmOGidq7i7xZGA4cm8DAa6fqdYcvO5Z6yBevH++Bdo9Qt/mN0TzHUgcCcKv1gmh9+W5dHqz8pMWbCbg==" + }, "node_modules/ts-interface-checker": { "version": "0.1.13", "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", @@ -17002,9 +16934,9 @@ } }, "node_modules/tslib": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.7.0.tgz", - "integrity": "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==" + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.0.tgz", + "integrity": "sha512-jWVzBLplnCmoaTr13V9dYbiQ99wvZRd0vNWaDRg+aVYRcjDF3nDksxFDE/+fkXnKhpnUUkmx5pK/v8mCtLVqZA==" }, "node_modules/tsx": { "version": "4.19.1", @@ -17149,6 +17081,14 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/typed-emitter": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/typed-emitter/-/typed-emitter-2.1.0.tgz", + "integrity": "sha512-g/KzbYKbH5C2vPkaXGu8DJlHrGKHLsM25Zg9WuC9pMGfuvT+X25tZQWo5fK1BjBm8+UrVE9LDCvaY0CQk+fXDA==", + "optionalDependencies": { + "rxjs": "*" + } + }, "node_modules/typedarray": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", @@ -17156,9 +17096,9 @@ "dev": true }, "node_modules/typescript": { - "version": "5.6.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.2.tgz", - "integrity": "sha512-NW8ByodCSNCwZeghjN3o+JX5OFH0Ojg6sadjEKY4huZ52TqbJTJnDo5+Tw98lSy63NZvi4n+ez5m2u5d4PkZyw==", + "version": "5.6.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.3.tgz", + "integrity": "sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==", "devOptional": true, "bin": { "tsc": "bin/tsc", @@ -17642,6 +17582,20 @@ "react": "^16.8.0 || ^17.0.0 || ^18.0.0" } }, + "node_modules/usehooks-ts": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/usehooks-ts/-/usehooks-ts-3.1.0.tgz", + "integrity": "sha512-bBIa7yUyPhE1BCc0GmR96VU/15l/9gP1Ch5mYdLcFBaFGQsdmXkvjV0TtOqW1yUd6VjIwDunm+flSciCQXujiw==", + "dependencies": { + "lodash.debounce": "^4.0.8" + }, + "engines": { + "node": ">=16.15.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17 || ^18" + } + }, "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", @@ -17937,9 +17891,9 @@ } }, "node_modules/vite": { - "version": "5.4.8", - "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.8.tgz", - "integrity": "sha512-FqrItQ4DT1NC4zCUqMB4c4AZORMKIa0m8/URVCZ77OZ/QSNeJ54bU1vrFADbDsuwfIPcgknRkmqakQcgnL4GiQ==", + "version": "5.4.9", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.9.tgz", + "integrity": "sha512-20OVpJHh0PAM0oSOELa5GaZNWeDjcAvQjGXy2Uyr+Tp+/D2/Hdz6NLgpJLsarPTA2QJ6v8mX2P1ZfbsSKvdMkg==", "dev": true, "dependencies": { "esbuild": "^0.21.3", diff --git a/package.json b/package.json index 850bba2edae..7749374be44 100644 --- a/package.json +++ b/package.json @@ -26,12 +26,19 @@ ], "author": "Open Healthcare Network Contributors", "license": "MIT", + "workspaces": [ + "apps/*" + ], "scripts": { - "build:react": "cross-env NODE_ENV=production vite build", - "build": "npm run generate-build-meta && npm run supported-browsers && npm run build:react", "dev": "npm run supported-browsers && vite", + "local": "npm run supported-browsers && vite --mode docker", "preview": "cross-env NODE_ENV=production vite preview", - "generate-build-meta": "node ./scripts/generate-build-version.js", + "build:meta": "node ./scripts/generate-build-version.js", + "build:react": "cross-env NODE_ENV=production vite build", + "supported-browsers": "node ./scripts/generate-supported-browsers.mjs", + "build": "npm run install-all && npm run build:meta && npm run supported-browsers && npm run build:react", + "setup": "node scripts/setup-care-apps.js", + "install-all": "npm install && npm run setup && npm install", "test": "snyk test", "cypress:open": "cross-env NODE_ENV=development cypress open", "cypress:run": "cross-env NODE_ENV=development cypress run", @@ -40,8 +47,7 @@ "prepare": "husky install", "lint": "eslint ./src", "lint-fix": "eslint ./src --fix", - "format": "prettier ./src --write", - "supported-browsers": "node ./scripts/generate-supported-browsers.mjs" + "format": "prettier ./src --write" }, "dependencies": { "@fontsource/figtree": "^5.1.0", @@ -55,7 +61,7 @@ "@radix-ui/react-slot": "^1.1.0", "@radix-ui/react-toast": "^1.2.2", "@sentry/browser": "^8.33.0", - "@yudiel/react-qr-scanner": "^2.0.0-beta.3", + "@yudiel/react-qr-scanner": "^2.0.8", "axios": "^1.7.7", "bowser": "^2.11.0", "browser-image-compression": "^2.0.2", @@ -103,7 +109,7 @@ "@types/lodash-es": "^4.17.12", "@types/node": "^22.7.4", "@types/qrcode.react": "^1.0.5", - "@types/react": "18.3.2", + "@types/react": "^18.3.11", "@types/react-copy-to-clipboard": "^5.0.7", "@types/react-csv": "^1.1.10", "@types/react-dom": "^18.3.0", @@ -114,6 +120,7 @@ "autoprefixer": "^10.4.19", "cypress-localstorage-commands": "^2.2.5", "cypress-split": "^1.23.2", + "dotenv": "^16.4.5", "eslint-config-prettier": "^9.1.0", "eslint-plugin-i18next": "^6.0.9", "eslint-plugin-mdx": "^3.1.5", diff --git a/scripts/setup-care-apps.js b/scripts/setup-care-apps.js new file mode 100644 index 00000000000..4106775e63e --- /dev/null +++ b/scripts/setup-care-apps.js @@ -0,0 +1,113 @@ +// eslint-disable-next-line @typescript-eslint/no-var-requires +const { execSync } = require("child_process"); +// eslint-disable-next-line @typescript-eslint/no-var-requires +const fs = require("fs"); +// eslint-disable-next-line @typescript-eslint/no-var-requires +const path = require("path"); +// eslint-disable-next-line @typescript-eslint/no-var-requires +require("dotenv").config({ path: [".env.local", ".env"] }); + +console.log("Preinstall script running"); + +// Function to read apps.json or return an empty array if it doesn't exist +function readAppsConfig() { + const appsConfig = process.env.REACT_ENABLED_APPS + ? process.env.REACT_ENABLED_APPS.split(",").map((app) => ({ + branch: app.split("@")[1], + package: app.split("@")[0], + })) + : []; + console.log("Found apps: ", appsConfig); + return appsConfig; +} + +const appsConfig = readAppsConfig(); +const appsDir = path.join(__dirname, "..", "apps"); + +// Create apps directory if it doesn't exist +if (!fs.existsSync(appsDir)) { + fs.mkdirSync(appsDir); +} + +const installApp = (app) => { + const appDir = path.join(appsDir, app.package.split("/")[1]); + + console.log(`Cloning ${app.package}...`); + execSync( + `npx -y gitget ${app.package}${app.branch ? `#${app.branch}` : ""} apps/${app.package.split("/")[1]} `, + { + stdio: "inherit", + }, + ); + // Create a care-package.lock file + fs.writeFileSync( + path.join(appDir, "care-package.lock"), + JSON.stringify( + { + package: app.package, + branch: app.branch, + }, + null, + 2, + ), + ); +}; + +// Clone or pull care apps +appsConfig.forEach((app) => { + const appDir = path.join(appsDir, app.package.split("/")[1]); + if (fs.existsSync(appDir)) { + if (fs.existsSync(path.join(appDir, "care-package.lock"))) { + // verify if the branch and package match with the care-package.lock file + const lockFile = JSON.parse( + fs.readFileSync(path.join(appDir, "care-package.lock"), "utf8"), + ); + if (lockFile.package === app.package && lockFile.branch === app.branch) { + console.log(`Package already exists. Pulling latest changes...`); + execSync(`git -C "${appDir}" pull`, { stdio: "inherit" }); + return; + } else { + console.log(`Branch/package does not match. Recreating...`); + fs.rmSync(appDir, { recursive: true, force: true }); + } + } else { + console.log( + `Package already exists but care-package.lock file does not exist. Recreating...`, + ); + fs.rmSync(appDir, { recursive: true, force: true }); + } + } + + installApp(app); +}); + +console.log("All apps have been cloned or updated in apps directory."); + +const importApps = appsConfig.map((app) => ({ + ...app, + camelCaseName: app.package + .split("/")[1] + .replace(/[-_]/g, "") + .replace(/\b\w/g, (char, index) => + index === 0 ? char.toLowerCase() : char.toUpperCase(), + ), +})); + +// Generate pluginMap.ts +const pluginMapPath = path.join(__dirname, "..", "src", "pluginMap.ts"); +const pluginMapContent = `import { PluginManifest } from "./pluginTypes"; + +${importApps + .map( + (app) => + `import ${app.camelCaseName}Manifest from "@app-manifest/${app.package.split("/")[1]}";`, + ) + .join("\n")} + +export const pluginMap: PluginManifest[] = [ +${importApps.map((app) => ` ${app.camelCaseName}Manifest`).join(",\n")} +]; +`; + +fs.writeFileSync(pluginMapPath, pluginMapContent); +console.log("Generated pluginMap.ts"); diff --git a/src/App.tsx b/src/App.tsx index c02982fd6df..180bd92839c 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -4,24 +4,28 @@ import Integrations from "./Integrations"; import Loading from "./Components/Common/Loading"; import HistoryAPIProvider from "./Providers/HistoryAPIProvider"; import AuthUserProvider from "./Providers/AuthUserProvider"; +import PluginEngine from "./PluginEngine"; import { FeatureFlagsProvider } from "./Utils/featureFlags"; import { Toaster } from "./Components/ui/toaster"; const App = () => { return ( }> - - }> - - - - + + + + }> + + + + - {/* Integrations */} - - - - + {/* Integrations */} + + + + + ); }; diff --git a/src/CAREUI/display/Timeline.tsx b/src/CAREUI/display/Timeline.tsx index ee21b337724..6701d9a7511 100644 --- a/src/CAREUI/display/Timeline.tsx +++ b/src/CAREUI/display/Timeline.tsx @@ -55,7 +55,7 @@ export const TimelineNode = (props: TimelineNodeProps) => { const { t } = useTranslation(); return ( -
  • +
    { {props.children}
    -
  • + ); }; diff --git a/src/CAREUI/icons/CareIcon.tsx b/src/CAREUI/icons/CareIcon.tsx index 3bb67629bc2..a45117cc675 100644 --- a/src/CAREUI/icons/CareIcon.tsx +++ b/src/CAREUI/icons/CareIcon.tsx @@ -1,13 +1,12 @@ import iconData from "./UniconPaths.json"; -import { transformIcons } from "./icon"; -import { useEffect } from "react"; +import "./icon.css"; export type IconName = keyof typeof iconData; export interface CareIconProps { icon: IconName; - className?: string | undefined; - onClick?: React.MouseEventHandler | undefined; + className?: string; + onClick?: React.MouseEventHandler; id?: string; } @@ -25,14 +24,32 @@ export default function CareIcon({ className, onClick, }: CareIconProps) { - const effectiveClassName = icon - ? `care-${icon} ${className ?? ""}` - : className; + // TODO: fill & strokeWidth are defined for only one icon + // Rethink Implementation + const [viewBox, path, fill, strokeWidth] = iconData[icon] as [ + number, + string, + boolean | undefined, + number | undefined, + ]; + + const svgClassName = `care-svg-icon__baseline ${className || ""}`.trim(); - useEffect(() => transformIcons(), [effectiveClassName]); return ( - - - + + + ); } diff --git a/src/CAREUI/icons/icon.js b/src/CAREUI/icons/icon.js deleted file mode 100644 index c917e664351..00000000000 --- a/src/CAREUI/icons/icon.js +++ /dev/null @@ -1,49 +0,0 @@ -import "./icon.css"; -import iconData from "./UniconPaths.json"; - -const xmlns = "http://www.w3.org/2000/svg"; - -const findIconName = (className) => { - const iconName = className.match(/care-([a-zA-Z0-9-]+)/); - return iconName ? iconName[1] : "default"; -}; - -const getIconData = (className) => { - const data = iconData[findIconName(className)]; - return typeof data === "undefined" ? iconData["default"] : data; -}; - -const createSvg = (className) => { - const icon = getIconData(className); - const el = document.createElementNS(xmlns, "svg"); - el.setAttribute( - "class", - className.replace("care", "care-svg-icon__baseline"), - ); - el.setAttribute("role", "img"); - el.setAttribute("xmlns", xmlns); - el.setAttribute("viewBox", `0 0 ${icon[0]} ${icon[0]}`); - - const path = document.createElementNS(xmlns, "path"); - if (icon[2] === false) { - path.setAttribute("stroke", "currentColor"); - path.setAttribute("stroke-width", `${icon[3]}`); - } - path.setAttribute("fill", icon[2] === false ? "none" : "currentColor"); - path.setAttribute("d", icon[1]); - el.appendChild(path); - return el; -}; - -export const transformIcons = () => { - const elements = Array.from(document.getElementsByClassName("care")); - elements.forEach((element) => { - if (element.tagName == "I") { - element.parentNode.replaceChild(createSvg(element.className), element); - } - }); -}; - -export const addListener = () => { - window.addEventListener("load", transformIcons); -}; diff --git a/src/CAREUI/interactive/LegendInput.tsx b/src/CAREUI/interactive/LegendInput.tsx index e164e4d1b4e..83486095f7a 100644 --- a/src/CAREUI/interactive/LegendInput.tsx +++ b/src/CAREUI/interactive/LegendInput.tsx @@ -2,6 +2,7 @@ import CareIcon from "../icons/CareIcon"; import { classNames } from "../../Utils/utils"; import { RefObject, useRef, useState, useEffect } from "react"; import { useTranslation } from "react-i18next"; + type InputProps = { id?: string; name: string; @@ -12,12 +13,12 @@ type InputProps = { required?: boolean; placeholder?: string; value?: string; - onChange?: (e: any) => void; - onFocus?: (e: any) => void; - onBlur?: (e: any) => void; - onKeyUp?: (e: any) => void; - onKeyDown?: (e: any) => void; - onKeyPress?: (e: any) => void; + onChange?: (e: React.ChangeEvent) => void; + onFocus?: (e: React.FocusEvent) => void; + onBlur?: (e: React.FocusEvent) => void; + onKeyUp?: (e: React.KeyboardEvent) => void; + onKeyDown?: (e: React.KeyboardEvent) => void; + onKeyPress?: (e: React.KeyboardEvent) => void; disabled?: boolean; error?: string; className?: string; diff --git a/src/Common/hooks/useCareApps.ts b/src/Common/hooks/useCareApps.ts new file mode 100644 index 00000000000..77b5489052e --- /dev/null +++ b/src/Common/hooks/useCareApps.ts @@ -0,0 +1,35 @@ +import { createContext, useContext } from "react"; +import { INavItem } from "@/Components/Common/Sidebar/Sidebar"; +import { PluginManifest } from "@/pluginTypes"; + +export const CareAppsContext = createContext([]); + +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((acc, plugin) => { + return [...acc, ...(plugin.navItems || [])]; + }, []); + return navItems; +}; + +// If required; Reduce plugin.routes to a single pluginRoutes object of type Record JSX.Element> +export function usePluginRoutes() { + const careApps = useCareApps(); + const routes = careApps.reduce((acc, plugin) => { + return { ...acc, ...plugin.routes }; + }, {}); + if (!routes) { + throw new Error("'usePluginRoutes' must be used within 'AppRouter' only"); + } + return routes; +} diff --git a/src/Components/CameraFeed/CentralLiveMonitoring/index.tsx b/src/Components/CameraFeed/CentralLiveMonitoring/index.tsx index 3cca4c00ec4..95e3b98c818 100644 --- a/src/Components/CameraFeed/CentralLiveMonitoring/index.tsx +++ b/src/Components/CameraFeed/CentralLiveMonitoring/index.tsx @@ -66,7 +66,7 @@ export default function CentralLiveMonitoring(props: { facilityId: string }) { fullscreen={isFullscreen} onExit={() => setFullscreen(false)} > -
    +
    {data.results.map((asset) => (
    diff --git a/src/Components/Common/ErrorBoundary.tsx b/src/Components/Common/ErrorBoundary.tsx new file mode 100644 index 00000000000..47172a240ef --- /dev/null +++ b/src/Components/Common/ErrorBoundary.tsx @@ -0,0 +1,36 @@ +import React, { Component, ErrorInfo, ReactNode } from "react"; + +interface Props { + children: ReactNode; + fallback?: ReactNode; +} + +interface State { + hasError: boolean; +} + +class ErrorBoundary extends Component { + public state: State = { + hasError: false, + }; + + public static getDerivedStateFromError(_: Error): State { + // Update state so the next render will show the fallback UI. + return { hasError: true }; + } + + public componentDidCatch(error: Error, errorInfo: ErrorInfo) { + console.error("Uncaught error:", error, errorInfo); + } + + public render() { + if (this.state.hasError) { + // You can render any custom fallback UI + return this.props.fallback ||

    Sorry.. there was an error

    ; + } + + return this.props.children; + } +} + +export default ErrorBoundary; diff --git a/src/Components/Common/Sidebar/Sidebar.tsx b/src/Components/Common/Sidebar/Sidebar.tsx index 31efe00f1b1..4e3929b187f 100644 --- a/src/Components/Common/Sidebar/Sidebar.tsx +++ b/src/Components/Common/Sidebar/Sidebar.tsx @@ -8,11 +8,18 @@ import SlideOver from "../../../CAREUI/interactive/SlideOver"; import { classNames } from "../../../Utils/utils"; import { Link } from "raviger"; import careConfig from "@careConfig"; +import { useCareAppNavItems } from "@/Common/hooks/useCareApps"; export const SIDEBAR_SHRINK_PREFERENCE_KEY = "sidebarShrinkPreference"; const LOGO_COLLAPSE = "/images/care_logo_mark.svg"; +export interface INavItem { + text: string; + to?: string; + icon: IconName; +} + type StatelessSidebarProps = | { shrinkable: true; @@ -32,11 +39,7 @@ const StatelessSidebar = ({ setShrinked, onItemClick, }: StatelessSidebarProps) => { - 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" }, @@ -47,6 +50,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; @@ -151,7 +158,7 @@ const StatelessSidebar = ({ {...i} icon={} selected={i.to === activeLink} - do={() => onItemClick && onItemClick(false)} + onItemClick={() => onItemClick && onItemClick(false)} handleOverflow={handleOverflow} /> ); diff --git a/src/Components/Common/Sidebar/SidebarItem.tsx b/src/Components/Common/Sidebar/SidebarItem.tsx index 265119f936e..eeee4284e2f 100644 --- a/src/Components/Common/Sidebar/SidebarItem.tsx +++ b/src/Components/Common/Sidebar/SidebarItem.tsx @@ -10,37 +10,39 @@ type SidebarItemProps = { ref?: React.Ref; 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; - ref: Ref; }; -const SidebarItemBase = forwardRef( - ( - { shrinked, external, ...props }: SidebarItemBaseProps, - ref: Ref, - ) => { +const SidebarItemBase = forwardRef( + ({ shrinked, external, ...props }, ref) => { const { t } = useTranslation(); const { resetHistory } = useAppHistory(); return ( { + // On Review: Check if resetHistory is working as intended. + props.do?.(); + props.onItemClick?.(); + resetHistory(); + }} onMouseEnter={() => { props.handleOverflow(true); }} diff --git a/src/Components/Common/SortDropdown.tsx b/src/Components/Common/SortDropdown.tsx index b54edffa595..0c4fddec58c 100644 --- a/src/Components/Common/SortDropdown.tsx +++ b/src/Components/Common/SortDropdown.tsx @@ -29,6 +29,7 @@ export default function SortDropdownMenu(props: Props) { > {props.options.map(({ isAscending, value }) => (
    +
    ); } diff --git a/src/Components/Facility/HospitalList.tsx b/src/Components/Facility/FacilityList.tsx similarity index 99% rename from src/Components/Facility/HospitalList.tsx rename to src/Components/Facility/FacilityList.tsx index e7949440307..503f0fde34d 100644 --- a/src/Components/Facility/HospitalList.tsx +++ b/src/Components/Facility/FacilityList.tsx @@ -18,7 +18,7 @@ import routes from "../../Redux/api"; import CareIcon from "../../CAREUI/icons/CareIcon"; import Loading from "@/Components/Common/Loading"; -export const HospitalList = () => { +export const FacilityList = () => { const { qParams, updateQuery, diff --git a/src/Components/Notifications/ShowPushNotification.tsx b/src/Components/Notifications/ShowPushNotification.tsx index 2d2faa5ff5f..ca465f98df7 100644 --- a/src/Components/Notifications/ShowPushNotification.tsx +++ b/src/Components/Notifications/ShowPushNotification.tsx @@ -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) { diff --git a/src/Components/Users/UserProfile.tsx b/src/Components/Users/UserProfile.tsx index b9af5b98f65..22f2a0e2607 100644 --- a/src/Components/Users/UserProfile.tsx +++ b/src/Components/Users/UserProfile.tsx @@ -469,10 +469,11 @@ export default function UserProfile() {

    - Personal Information + {t("personal_information")}

    - Local Body, District and State are Non Editable Settings. + {t("local_body")}, {t("district")}, {t("state")}{" "} + {t("are_non_editable_fields")}.

    - {showEdit ? "Cancel" : "Edit User Profile"} + {showEdit ? t("cancel") : t("edit_user_profile")} - Sign out + {t("sign_out")}
    @@ -498,7 +499,7 @@ export default function UserProfile() { id="username-profile-details" >
    - Username + {t("username")}
    {userData?.username || "-"} @@ -509,7 +510,7 @@ export default function UserProfile() { id="contactno-profile-details" >
    - Contact No + {t("phone_number")}
    {userData?.phone_number || "-"} @@ -521,7 +522,7 @@ export default function UserProfile() { id="whatsapp-profile-details" >
    - Whatsapp No + {t("whatsapp_number")}
    {userData?.alt_phone_number || "-"} @@ -532,7 +533,7 @@ export default function UserProfile() { id="emailid-profile-details" >
    - Email address + {t("email")}
    {userData?.email || "-"} @@ -543,7 +544,7 @@ export default function UserProfile() { id="firstname-profile-details" >
    - First Name + {t("first_name")}
    {userData?.first_name || "-"} @@ -554,7 +555,7 @@ export default function UserProfile() { id="lastname-profile-details" >
    - Last Name + {t("last_name")}
    {userData?.last_name || "-"} @@ -565,7 +566,7 @@ export default function UserProfile() { id="date_of_birth-profile-details" >
    - Date of Birth + {t("date_of_birth")}
    {userData?.date_of_birth @@ -575,7 +576,7 @@ export default function UserProfile() {
    - Access Level + {t("access_level")}
    {" "} @@ -587,7 +588,7 @@ export default function UserProfile() { id="gender-profile-details" >
    - Gender + {t("gender")}
    {userData?.gender || "-"} @@ -595,7 +596,7 @@ export default function UserProfile() {
    - Local Body + {t("local_body")}
    {userData?.local_body_object?.name || "-"} @@ -603,7 +604,7 @@ export default function UserProfile() {
    - District + {t("district")}
    {userData?.district_object?.name || "-"} @@ -611,7 +612,7 @@ export default function UserProfile() {
    - State + {t("state")}
    {userData?.state_object?.name || "-"} @@ -619,7 +620,7 @@ export default function UserProfile() {
    - Skills + {t("skills")}
    - Average weekly working hours + {t("average_weekly_working_hours")}
    {userData?.weekly_working_hours ?? "-"} @@ -656,7 +657,7 @@ export default function UserProfile() { id="videoconnectlink-profile-details" >
    - Video Connect Link + {t("video_conference_link")}
    {userData?.video_connect_link ? ( @@ -685,18 +686,18 @@ export default function UserProfile() { o.text} optionValue={(o) => o.text} - optionIcon={(o) => ( - {o.icon} - )} options={GENDER_TYPES} /> )}
    - +
    @@ -796,7 +798,7 @@ export default function UserProfile() {
    @@ -888,10 +890,10 @@ export default function UserProfile() {

    - Language Selection + {t("language_selection")}

    - Set your local language + {t("set_your_local_language")}

    @@ -903,10 +905,10 @@ export default function UserProfile() {

    - Software Update + {t("software_update")}

    - Check for an available update + {t("check_for_available_update")}

    @@ -915,7 +917,7 @@ export default function UserProfile() {
    - Update available + {t("update_available")}
    @@ -936,8 +938,8 @@ export default function UserProfile() { )} /> {updateStatus.isChecking - ? "Checking for update" - : "Check for update"} + ? t("checking_for_update") + : t("check_for_update")} )} diff --git a/src/Locale/en.json b/src/Locale/en.json index b4c18b685a9..0df3c961e10 100644 --- a/src/Locale/en.json +++ b/src/Locale/en.json @@ -25,6 +25,7 @@ "last_name": "Last Name", "email": "Email Address", "phone_number": "Phone Number", + "whatsapp_number": "Whatsapp Number", "district": "District", "gender": "Gender", "age": "Age", @@ -277,6 +278,29 @@ "unsupported_browser": "Unsupported Browser", "unsupported_browser_description": "Your browser ({{name}} version {{version}}) is not supported. Please update your browser to the latest version or switch to a supported browser for the best experience.", "add_remarks": "Add remarks", + "middleware_hostname": "Middleware Hostname", + "local_ipaddress": "Local IP Address", + "personal_information": "Personal Information", + "are_non_editable_fields": "are non-editable fields", + "edit_user_profile": "Edit Profile", + "skills": "Skills", + "access_level": "Access Level", + "qualification": "Qualification", + "years_of_experience": "Years of Experience", + "years_of_experience_of_the_doctor": "Years of Experience of the Doctor", + "medical_council_registration": "Medical Council Registration", + "doctor_s_medical_council_registration": "Doctor's Medical Council Registration", + "video_conference_link": "Video Conference Link", + "new_password_confirmation": "Confirm New Password", + "current_password": "Current Password", + "change_password": "Change Password", + "language_selection": "Language Selection", + "set_your_local_language": "Set your local language", + "software_update": "Software Update", + "check_for_available_update": "Check for available update", + "update_available": "Update Available", + "checking_for_update": "Checking for update", + "check_for_update": "Check for Update", "SORT_OPTIONS__-created_date": "Latest created date first", "SORT_OPTIONS__created_date": "Oldest created date first", "SORT_OPTIONS__-category_severity": "Highest Severity category first", @@ -293,9 +317,6 @@ "SORT_OPTIONS__-name": "Patient name Z-A", "SORT_OPTIONS__bed__name": "Bed No. 1-N", "SORT_OPTIONS__-bed__name": "Bed No. N-1", - "middleware_hostname": "Middleware Hostname", - "local_ipaddress": "Local IP Address", - "qualification": "Qualification", "CONSULTATION_TAB__UPDATES": "Overview", "CONSULTATION_TAB__FEED": "Feed", "CONSULTATION_TAB__SUMMARY": "Vitals", diff --git a/src/PluginEngine.tsx b/src/PluginEngine.tsx new file mode 100644 index 00000000000..3d47dba4d81 --- /dev/null +++ b/src/PluginEngine.tsx @@ -0,0 +1,51 @@ +/* eslint-disable i18next/no-literal-string */ +import React, { Suspense } from "react"; +import { CareAppsContext, useCareApps } from "./Common/hooks/useCareApps"; +import { pluginMap } from "./pluginTypes"; +import { UserAssignedModel } from "./Components/Users/models"; +import ErrorBoundary from "./Components/Common/ErrorBoundary"; + +export default function PluginEngine({ + children, +}: { + children: React.ReactNode; +}) { + return ( + Loading plugins...}> + + Error loading plugins + + } + > + + {children} + + + + ); +} + +export function PLUGIN_DoctorConnectButtons({ + user, +}: { + user: UserAssignedModel; +}) { + const plugins = useCareApps(); + return ( +
    + {plugins.map((plugin, index) => { + const DoctorConnectButtons = plugin.components.DoctorConnectButtons; + if (!DoctorConnectButtons) { + return null; + } + return ( +
    + +
    + ); + })} +
    + ); +} diff --git a/src/Redux/api.tsx b/src/Redux/api.tsx index 4775674084e..f1130345f46 100644 --- a/src/Redux/api.tsx +++ b/src/Redux/api.tsx @@ -1129,7 +1129,7 @@ const routes = { path: "/api/v1/notification/notify/", method: "POST", TRes: Type(), - Tbody: Type(), + TBody: Type(), }, // FileUpload Create diff --git a/src/Routers/AppRouter.tsx b/src/Routers/AppRouter.tsx index 9d411d11950..df154ee7a5e 100644 --- a/src/Routers/AppRouter.tsx +++ b/src/Routers/AppRouter.tsx @@ -24,11 +24,26 @@ import HCXRoutes from "./routes/HCXRoutes"; import ShiftingRoutes from "./routes/ShiftingRoutes"; import AssetRoutes from "./routes/AssetRoutes"; import ResourceRoutes from "./routes/ResourceRoutes"; -import { DetailRoute } from "./types"; +import { usePluginRoutes } from "@/Common/hooks/useCareApps"; import careConfig from "@careConfig"; import IconIndex from "../CAREUI/icons/Index"; -const Routes = { +export type RouteParams = + T extends `${string}:${infer Param}/${infer Rest}` + ? { [K in Param | keyof RouteParams]: string } + : T extends `${string}:${infer Param}` + ? { [K in Param]: string } + : Record; + +export type RouteFunction = ( + params: RouteParams, +) => JSX.Element; + +export type AppRoutes = { + [K in string]: RouteFunction; +}; + +const Routes: AppRoutes = { "/": () => , ...AssetRoutes, @@ -40,15 +55,13 @@ const Routes = { ...ShiftingRoutes, ...UserRoutes, - "/notifications/:id": ({ id }: DetailRoute) => ( - - ), + "/notifications/:id": ({ id }) => , "/notice_board": () => , - "/abdm/health-information/:id": ({ id }: { id: string }) => ( + "/abdm/health-information/:id": ({ id }) => ( ), - "/facility/:facilityId/abdm": ({ facilityId }: any) => ( + "/facility/:facilityId/abdm": ({ facilityId }) => ( ), @@ -61,6 +74,8 @@ const Routes = { }; export default function AppRouter() { + const pluginRoutes = usePluginRoutes(); + let routes = Routes; if (careConfig.hcx.enabled) { @@ -68,7 +83,15 @@ export default function AppRouter() { } useRedirect("/user", "/users"); + + // Merge in Plugin Routes + routes = { + ...routes, + ...pluginRoutes, + }; + const pages = useRoutes(routes) || ; + const path = usePath(); const [sidebarOpen, setSidebarOpen] = useState(false); diff --git a/src/Routers/routes/AssetRoutes.tsx b/src/Routers/routes/AssetRoutes.tsx index d3bd96ca437..ee0537d6c58 100644 --- a/src/Routers/routes/AssetRoutes.tsx +++ b/src/Routers/routes/AssetRoutes.tsx @@ -2,20 +2,23 @@ import AssetConfigure from "../../Components/Assets/AssetConfigure"; import AssetManage from "../../Components/Assets/AssetManage"; import AssetsList from "../../Components/Assets/AssetsList"; import AssetCreate from "../../Components/Facility/AssetCreate"; +import { AppRoutes } from "../AppRouter"; -export default { +const AssetRoutes: AppRoutes = { "/assets": () => , - - "/facility/:facilityId/assets/new": (params: any) => ( - - ), - "/facility/:facilityId/assets/:assetId/update": (params: any) => ( - + "/facility/:facilityId/assets/new": ({ facilityId }) => ( + ), - "/facility/:facilityId/assets/:assetId": (params: any) => ( - + "/facility/:facilityId/assets/:assetId/update": ({ facilityId, assetId }) => ( + ), - "/facility/:facilityId/assets/:assetId/configure": (params: any) => ( - + "/facility/:facilityId/assets/:assetId": ({ facilityId, assetId }) => ( + ), + "/facility/:facilityId/assets/:assetId/configure": ({ + facilityId, + assetId, + }) => , }; + +export default AssetRoutes; diff --git a/src/Routers/routes/ConsultationRoutes.tsx b/src/Routers/routes/ConsultationRoutes.tsx index 598fd06adc3..77efe1081bc 100644 --- a/src/Routers/routes/ConsultationRoutes.tsx +++ b/src/Routers/routes/ConsultationRoutes.tsx @@ -5,30 +5,29 @@ import ManagePrescriptions from "../../Components/Medicine/ManagePrescriptions"; import { DailyRoundListDetails } from "../../Components/Patient/DailyRoundListDetails"; import { DailyRounds } from "../../Components/Patient/DailyRounds"; import { ConsultationDetails } from "../../Components/Facility/ConsultationDetails"; -import TreatmentSummary, { - ITreatmentSummaryProps, -} from "../../Components/Facility/TreatmentSummary"; +import TreatmentSummary from "../../Components/Facility/TreatmentSummary"; import ConsultationDoctorNotes from "../../Components/Facility/ConsultationDoctorNotes"; import PatientConsentRecords from "../../Components/Patient/PatientConsentRecords"; import CriticalCareEditor from "../../Components/LogUpdate/CriticalCareEditor"; import PrescriptionsPrintPreview from "../../Components/Medicine/PrintPreview"; import CriticalCarePreview from "../../Components/LogUpdate/CriticalCarePreview"; import FileUploadPage from "../../Components/Patient/FileUploadPage"; +import { AppRoutes } from "../AppRouter"; -export default { +const consultationRoutes: AppRoutes = { "/facility/:facilityId/patient/:patientId/consultation": ({ facilityId, patientId, - }: any) => , + }) => , "/facility/:facilityId/patient/:patientId/consultation/:id/update": ({ facilityId, patientId, id, - }: any) => ( + }) => ( ), "/facility/:facilityId/patient/:patientId/consultation/:id/consent-records": - ({ facilityId, patientId, id }: any) => ( + ({ facilityId, patientId, id }) => ( ( + }) => ( ), "/facility/:facilityId/patient/:patientId/consultation/:consultationId/prescriptions": - (path: any) => , + (path) => , "/facility/:facilityId/patient/:patientId/consultation/:consultationId/prescriptions/print": () => , "/facility/:facilityId/patient/:patientId/consultation/:id/investigation": ({ facilityId, patientId, id, - }: any) => ( + }) => ( ), "/facility/:facilityId/patient/:patientId/consultation/:id/investigation/:sessionId": - ({ facilityId, patientId, id, sessionId }: any) => ( + ({ facilityId, patientId, id, sessionId }) => ( ( + }) => ( ), "/facility/:facilityId/patient/:patientId/consultation/:consultationId/daily-rounds/:id/update": - ({ facilityId, patientId, consultationId, id }: any) => ( + ({ facilityId, patientId, consultationId, id }) => ( ), "/facility/:facilityId/patient/:patientId/consultation/:consultationId/daily-rounds/:id": - ({ facilityId, patientId, consultationId, id }: any) => ( + ({ facilityId, patientId, consultationId, id }) => ( ), - "/facility/:facilityId/patient/:patientId/consultation/:consultationId/daily_rounds/:id": - (params: { - facilityId: string; - patientId: string; - consultationId: string; - id: string; - }) => , + ({ facilityId, patientId, consultationId, id }) => ( + + ), "/facility/:facilityId/patient/:patientId/consultation/:consultationId/daily_rounds/:id/update": - (params: { - facilityId: string; - patientId: string; - consultationId: string; - id: string; - }) => , + ({ facilityId, patientId, consultationId, id }) => ( + + ), "/facility/:facilityId/patient/:patientId/consultation/:consultationId": ({ facilityId, patientId, consultationId, - }: any) => ( + }) => ( ), - "/consultation/:consultationId": ({ consultationId }: any) => ( + "/consultation/:consultationId": ({ consultationId }) => ( ), "/facility/:facilityId/patient/:patientId/consultation/:consultationId/treatment-summary": - ({ facilityId, patientId, consultationId }: ITreatmentSummaryProps) => ( + ({ facilityId, patientId, consultationId }) => ( ), "/facility/:facilityId/patient/:patientId/consultation/:consultationId/notes": - ({ facilityId, patientId, consultationId }: any) => ( + ({ facilityId, patientId, consultationId }) => ( ), "/facility/:facilityId/patient/:patientId/consultation/:consultationId/:tab": - ({ facilityId, patientId, consultationId, tab }: any) => ( + ({ facilityId, patientId, consultationId, tab }) => ( ), }; + +export default consultationRoutes; diff --git a/src/Routers/routes/FacilityInventoryRoutes.tsx b/src/Routers/routes/FacilityInventoryRoutes.tsx index 17e93b2bc60..99123d8f737 100644 --- a/src/Routers/routes/FacilityInventoryRoutes.tsx +++ b/src/Routers/routes/FacilityInventoryRoutes.tsx @@ -3,22 +3,25 @@ import InventoryList from "../../Components/Facility/InventoryList"; import InventoryLog from "../../Components/Facility/InventoryLog"; import MinQuantityList from "../../Components/Facility/MinQuantityList"; import { SetInventoryForm } from "../../Components/Facility/SetInventoryForm"; +import { AppRoutes } from "../AppRouter"; -export default { - "/facility/:facilityId/inventory": ({ facilityId }: any) => ( +const FacilityInventoryRoutes: AppRoutes = { + "/facility/:facilityId/inventory": ({ facilityId }) => ( ), - "/facility/:facilityId/inventory/min_quantity/set": ({ facilityId }: any) => ( + "/facility/:facilityId/inventory/min_quantity/set": ({ facilityId }) => ( ), - "/facility/:facilityId/inventory/min_quantity/list": ({ - facilityId, - }: any) => , - "/facility/:facilityId/inventory/min_quantity": ({ facilityId }: any) => ( + "/facility/:facilityId/inventory/min_quantity/list": ({ facilityId }) => ( + + ), + "/facility/:facilityId/inventory/min_quantity": ({ facilityId }) => ( ), "/facility/:facilityId/inventory/:inventoryId": ({ facilityId, inventoryId, - }: any) => , + }) => , }; + +export default FacilityInventoryRoutes; diff --git a/src/Routers/routes/FacilityLocationRoutes.tsx b/src/Routers/routes/FacilityLocationRoutes.tsx index 5d547ebd466..c2e1add4b10 100644 --- a/src/Routers/routes/FacilityLocationRoutes.tsx +++ b/src/Routers/routes/FacilityLocationRoutes.tsx @@ -6,41 +6,42 @@ import LocationManagement from "../../Components/Facility/LocationManagement"; import CentralLiveMonitoring from "../../Components/CameraFeed/CentralLiveMonitoring"; import { AuthorizeUserRoute } from "../../Utils/AuthorizeFor"; import { CameraFeedPermittedUserTypes } from "../../Utils/permissions"; +import { AppRoutes } from "../AppRouter"; -export default { - "/facility/:facilityId/location": ({ facilityId }: any) => ( +const FacilityLocationRoutes: AppRoutes = { + "/facility/:facilityId/location": ({ facilityId }) => ( ), "/facility/:facilityId/location/:locationId/beds": ({ facilityId, locationId, - }: any) => , - "/facility/:facilityId/inventory/add": ({ facilityId }: any) => ( + }) => , + "/facility/:facilityId/inventory/add": ({ facilityId }) => ( ), - "/facility/:facilityId/location/add": ({ facilityId }: any) => ( + "/facility/:facilityId/location/add": ({ facilityId }) => ( ), "/facility/:facilityId/location/:locationId/update": ({ facilityId, locationId, - }: any) => ( - - ), + }) => , "/facility/:facilityId/location/:locationId/beds/add": ({ facilityId, locationId, - }: any) => , + }) => , "/facility/:facilityId/location/:locationId/beds/:bedId/update": ({ facilityId, locationId, bedId, - }: any) => ( + }) => ( ), - "/facility/:facilityId/live-monitoring": (props: any) => ( + "/facility/:facilityId/live-monitoring": ({ facilityId }) => ( - + ), }; + +export default FacilityLocationRoutes; diff --git a/src/Routers/routes/FacilityRoutes.tsx b/src/Routers/routes/FacilityRoutes.tsx index 2c711cf48cb..16b202ae0ce 100644 --- a/src/Routers/routes/FacilityRoutes.tsx +++ b/src/Routers/routes/FacilityRoutes.tsx @@ -2,48 +2,47 @@ import { FacilityConfigure } from "../../Components/Facility/FacilityConfigure"; import { FacilityCreate } from "../../Components/Facility/FacilityCreate"; import { FacilityHome } from "../../Components/Facility/FacilityHome"; import FacilityUsers from "../../Components/Facility/FacilityUsers"; -import { HospitalList } from "../../Components/Facility/HospitalList"; +import { FacilityList } from "../../Components/Facility/FacilityList"; import { TriageForm } from "../../Components/Facility/TriageForm"; import ResourceCreate from "../../Components/Resource/ResourceCreate"; import CentralNursingStation from "../../Components/Facility/CentralNursingStation"; import FacilityLocationRoutes from "./FacilityLocationRoutes"; import FacilityInventoryRoutes from "./FacilityInventoryRoutes"; import DischargedPatientsList from "../../Components/Facility/DischargedPatientsList"; +import { AppRoutes } from "../AppRouter"; -export default { - "/facility": () => , +const FacilityRoutes: AppRoutes = { + "/facility": () => , "/facility/create": () => , - "/facility/:facilityId/update": ({ facilityId }: any) => ( + "/facility/:facilityId/update": ({ facilityId }) => ( ), - "/facility/:facilityId/configure": ({ facilityId }: any) => ( + "/facility/:facilityId/configure": ({ facilityId }) => ( ), - "/facility/:facilityId/cns": ({ facilityId }: any) => ( + "/facility/:facilityId/cns": ({ facilityId }) => ( ), - "/facility/:facilityId": ({ facilityId }: any) => ( + "/facility/:facilityId": ({ facilityId }) => ( ), - "/facility/:id/discharged-patients": ({ id }: any) => ( + "/facility/:id/discharged-patients": ({ id }) => ( ), - - "/facility/:facilityId/users": ({ facilityId }: any) => ( + "/facility/:facilityId/users": ({ facilityId }) => ( ), - "/facility/:facilityId/resource/new": ({ facilityId }: any) => ( + "/facility/:facilityId/resource/new": ({ facilityId }) => ( ), - - // Triage related routes - "/facility/:facilityId/triage": ({ facilityId }: any) => ( + "/facility/:facilityId/triage": ({ facilityId }) => ( ), - "/facility/:facilityId/triage/:id": ({ facilityId, id }: any) => ( + "/facility/:facilityId/triage/:id": ({ facilityId, id }) => ( ), - ...FacilityLocationRoutes, ...FacilityInventoryRoutes, }; + +export default FacilityRoutes; diff --git a/src/Routers/routes/HCXRoutes.tsx b/src/Routers/routes/HCXRoutes.tsx index 80378b24621..929cc3f12bb 100644 --- a/src/Routers/routes/HCXRoutes.tsx +++ b/src/Routers/routes/HCXRoutes.tsx @@ -1,10 +1,15 @@ -import ConsultationClaims, { - IConsultationClaimsProps, -} from "../../Components/Facility/ConsultationClaims"; +import ConsultationClaims from "../../Components/Facility/ConsultationClaims"; +import { AppRoutes } from "../AppRouter"; -export default { +const HCXRoutes: AppRoutes = { "/facility/:facilityId/patient/:patientId/consultation/:consultationId/claims": - (pathParams: IConsultationClaimsProps) => ( - + ({ facilityId, patientId, consultationId }) => ( + ), }; + +export default HCXRoutes; diff --git a/src/Routers/routes/PatientRoutes.tsx b/src/Routers/routes/PatientRoutes.tsx index fcfc9b04e37..45ff044e4d2 100644 --- a/src/Routers/routes/PatientRoutes.tsx +++ b/src/Routers/routes/PatientRoutes.tsx @@ -3,44 +3,44 @@ import { PatientManager } from "../../Components/Patient/ManagePatients"; import { PatientHome } from "../../Components/Patient/PatientHome"; import PatientNotes from "../../Components/Patient/PatientNotes"; import { PatientRegister } from "../../Components/Patient/PatientRegister"; -import { DetailRoute } from "../types"; import DeathReport from "../../Components/DeathReport/DeathReport"; import { InsuranceDetails } from "../../Components/Patient/InsuranceDetails"; import FileUploadPage from "../../Components/Patient/FileUploadPage"; +import { AppRoutes } from "../AppRouter"; -export default { +const PatientRoutes: AppRoutes = { "/patients": () => , - "/patient/:id": ({ id }: DetailRoute) => , - "/patient/:id/investigation_reports": ({ id }: DetailRoute) => ( + "/patient/:id": ({ id }) => , + "/patient/:id/investigation_reports": ({ id }) => ( ), - - // Facility Scoped Routes - "/facility/:facilityId/patient": ({ facilityId }: any) => ( + "/facility/:facilityId/patient": ({ facilityId }) => ( ), - "/facility/:facilityId/patient/:id": ({ facilityId, id }: any) => ( + "/facility/:facilityId/patient/:id": ({ facilityId, id }) => ( ), - "/facility/:facilityId/patient/:id/insurance": ({ facilityId, id }: any) => ( + "/facility/:facilityId/patient/:id/insurance": ({ facilityId, id }) => ( ), - "/facility/:facilityId/patient/:id/update": ({ facilityId, id }: any) => ( + "/facility/:facilityId/patient/:id/update": ({ facilityId, id }) => ( ), "/facility/:facilityId/patient/:patientId/notes": ({ facilityId, patientId, - }: any) => , + }) => , "/facility/:facilityId/patient/:patientId/files": ({ facilityId, patientId, - }: any) => ( + }) => ( ), - "/death_report/:id": ({ id }: any) => , + "/death_report/:id": ({ id }) => , }; + +export default PatientRoutes; diff --git a/src/Routers/routes/ResourceRoutes.tsx b/src/Routers/routes/ResourceRoutes.tsx index 6636d0d83ea..d75c933f760 100644 --- a/src/Routers/routes/ResourceRoutes.tsx +++ b/src/Routers/routes/ResourceRoutes.tsx @@ -3,17 +3,17 @@ import { ResourceDetailsUpdate } from "../../Components/Resource/ResourceDetails import ListView from "../../Components/Resource/ListView"; import BoardView from "../../Components/Resource/ResourceBoardView"; import { Redirect } from "raviger"; -import { DetailRoute } from "../types"; +import { AppRoutes } from "../AppRouter"; const getDefaultView = () => localStorage.getItem("defaultResourceView") === "list" ? "list" : "board"; -export default { +const ResourceRoutes: AppRoutes = { "/resource": () => , "/resource/board": () => , "/resource/list": () => , - "/resource/:id": ({ id }: DetailRoute) => , - "/resource/:id/update": ({ id }: DetailRoute) => ( - - ), + "/resource/:id": ({ id }) => , + "/resource/:id/update": ({ id }) => , }; + +export default ResourceRoutes; diff --git a/src/Routers/routes/SampleRoutes.tsx b/src/Routers/routes/SampleRoutes.tsx index 290a34fd4eb..cf296790a81 100644 --- a/src/Routers/routes/SampleRoutes.tsx +++ b/src/Routers/routes/SampleRoutes.tsx @@ -2,24 +2,22 @@ import { SampleDetails } from "../../Components/Patient/SampleDetails"; import SampleReport from "../../Components/Patient/SamplePreview"; import { SampleTest } from "../../Components/Patient/SampleTest"; import SampleViewAdmin from "../../Components/Patient/SampleViewAdmin"; -import { DetailRoute, RouteParams } from "../types"; +import { AppRoutes } from "../AppRouter"; -export default { +const SampleRoutes: AppRoutes = { "/sample": () => , - "/sample/:id": ({ id }: DetailRoute) => , + "/sample/:id": ({ id }) => , "/patient/:patientId/test_sample/:sampleId/icmr_sample": ({ patientId, sampleId, - }: RouteParams<"patientId" | "sampleId">) => ( - - ), + }) => , "/facility/:facilityId/patient/:patientId/sample-test": ({ facilityId, patientId, - }: RouteParams<"facilityId" | "patientId">) => ( - + }) => , + "/facility/:facilityId/patient/:patientId/sample/:id": ({ id }) => ( + ), - "/facility/:facilityId/patient/:patientId/sample/:id": ({ - id, - }: DetailRoute) => , }; + +export default SampleRoutes; diff --git a/src/Routers/routes/ShiftingRoutes.tsx b/src/Routers/routes/ShiftingRoutes.tsx index f2e12de4f25..dc11ff2b8ee 100644 --- a/src/Routers/routes/ShiftingRoutes.tsx +++ b/src/Routers/routes/ShiftingRoutes.tsx @@ -4,18 +4,21 @@ import { ShiftDetailsUpdate } from "../../Components/Shifting/ShiftDetailsUpdate import ListView from "../../Components/Shifting/ListView"; import BoardView from "../../Components/Shifting/BoardView"; import { Redirect } from "raviger"; +import { AppRoutes } from "../AppRouter"; const getDefaultView = () => localStorage.getItem("defaultShiftView") === "list" ? "list" : "board"; -export default { +const ShiftingRoutes: AppRoutes = { "/shifting": () => , "/shifting/board": () => , "/shifting/list": () => , - "/shifting/:id": ({ id }: any) => , - "/shifting/:id/update": ({ id }: any) => , + "/shifting/:id": ({ id }) => , + "/shifting/:id/update": ({ id }) => , "/facility/:facilityId/patient/:patientId/shift/new": ({ facilityId, patientId, - }: any) => , + }) => , }; + +export default ShiftingRoutes; diff --git a/src/Routers/routes/UserRoutes.tsx b/src/Routers/routes/UserRoutes.tsx index 56877ca4c78..24f355b201b 100644 --- a/src/Routers/routes/UserRoutes.tsx +++ b/src/Routers/routes/UserRoutes.tsx @@ -1,9 +1,12 @@ import ManageUsers from "../../Components/Users/ManageUsers"; import { UserAdd } from "../../Components/Users/UserAdd"; import UserProfile from "../../Components/Users/UserProfile"; +import { AppRoutes } from "../AppRouter"; -export default { +const UserRoutes: AppRoutes = { "/users": () => , "/users/add": () => , "/user/profile": () => , }; + +export default UserRoutes; diff --git a/src/Utils/useTimer.tsx b/src/Utils/useTimer.tsx index 6a8d8320c5e..f7a03ffefa0 100644 --- a/src/Utils/useTimer.tsx +++ b/src/Utils/useTimer.tsx @@ -27,7 +27,7 @@ export const useTimer = (autoStart = false) => { const [time, setTime] = useState(0); useEffect(() => { - let interval: number; + let interval: ReturnType; if (running) { interval = setInterval(() => { setTime((prevTime) => prevTime + 1); diff --git a/src/pluginTypes.ts b/src/pluginTypes.ts new file mode 100644 index 00000000000..26a07e4f141 --- /dev/null +++ b/src/pluginTypes.ts @@ -0,0 +1,54 @@ +import { LazyExoticComponent } from "react"; +import { UserAssignedModel } from "./Components/Users/models"; +import { AppRoutes } from "./Routers/AppRouter"; +import { INavItem } from "./Components/Common/Sidebar/Sidebar"; +import { pluginMap } from "./pluginMap"; + +// Define the available plugins +export type AvailablePlugin = "@apps/care_livekit_fe"; + +export type AvailablePluginManifest = "@app-manifest/care_livekit_fe"; + +export type DoctorConnectButtonComponentType = React.FC<{ + user: UserAssignedModel; +}>; + +// Define supported plugin components +export type SupportedPluginComponents = { + DoctorConnectButtons: DoctorConnectButtonComponentType; +}; + +// Create a type for lazy-loaded components +// eslint-disable-next-line @typescript-eslint/no-explicit-any +type LazyComponent> = LazyExoticComponent; + +// Define PluginComponentMap with lazy-loaded components +export type PluginComponentMap = { + [K in keyof SupportedPluginComponents]?: LazyComponent< + SupportedPluginComponents[K] + >; +}; + +type SupportedPluginExtensions = + | "DoctorConnectButtons" + | "PatientExternalRegistration"; + +export type PluginManifest = { + plugin: string; + routes: AppRoutes; + extends: SupportedPluginExtensions[]; + components: PluginComponentMap; + navItems: INavItem[]; +}; + +// Create a type that ensures only available plugins can be used +export type EnabledPluginConfig = { + plugin: string; + manifestPath: AvailablePluginManifest; + path: AvailablePlugin; + manifest: Promise; + // Components are a dictionary, with the key being the component name, and the value being the component type + components: PluginComponentMap; +}; + +export { pluginMap }; diff --git a/src/vite-env.d.ts b/src/vite-env.d.ts index 7657f7da19e..f339922bfae 100644 --- a/src/vite-env.d.ts +++ b/src/vite-env.d.ts @@ -31,6 +31,7 @@ interface ImportMetaEnv { readonly REACT_JWT_TOKEN_REFRESH_INTERVAL?: string; readonly REACT_MIN_ENCOUNTER_DATE?: string; readonly REACT_ALLOWED_LOCALES?: string; + readonly REACT_ENABLED_APPS?: string; // Plugins related envs... readonly REACT_PLAUSIBLE_SERVER_URL?: string; diff --git a/tsconfig.json b/tsconfig.json index 531d6f800e1..51ffeb4a0ae 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -19,9 +19,12 @@ "baseUrl": ".", "paths": { "@/*": ["./src/*"], + "@core/*": ["src/*"], + "@apps/*": ["apps/*/src"], + "@app-manifest/*": ["apps/*/src/manifest.ts"], "@careConfig": ["./care.config.ts"] } }, - "include": ["src", "care.config.ts"], + "include": ["src/**/*", "apps/**/*", "care.config.ts"], "exclude": ["src/**/*.gen.tsx"] } diff --git a/vite.config.mts b/vite.config.mts index acb0cdf727b..905374eb923 100644 --- a/vite.config.mts +++ b/vite.config.mts @@ -1,10 +1,12 @@ -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 fs from "fs"; +import { defineConfig } from "vite"; const pdfWorkerPath = path.join( path.dirname( @@ -22,8 +24,56 @@ const cdnUrls = "http://localhost:4566", ].join(" "); +function getPluginAliases() { + const pluginsDir = path.resolve(__dirname, "apps"); + // Make sure the `apps` folder exists + if (!fs.existsSync(pluginsDir)) { + return {}; + } + const pluginFolders = fs.readdirSync(pluginsDir); + + const aliases = {}; + + pluginFolders.forEach((pluginFolder) => { + const pluginSrcPath = path.join(pluginsDir, pluginFolder, "src"); + if (fs.existsSync(pluginSrcPath)) { + aliases[`@apps/${pluginFolder}`] = pluginSrcPath; + aliases[`@app-manifest/${pluginFolder}`] = path.join( + pluginSrcPath, + "manifest.ts", + ); + } + }); + + return aliases; +} + +function getPluginDependencies() { + const pluginsDir = path.resolve(__dirname, "apps"); + // Make sure the `apps` folder exists + if (!fs.existsSync(pluginsDir)) { + return []; + } + const pluginFolders = fs.readdirSync(pluginsDir); + + const dependencies = new Set(); + + pluginFolders.forEach((pluginFolder) => { + const packageJsonPath = path.join(pluginsDir, pluginFolder, "package.json"); + if (fs.existsSync(packageJsonPath)) { + const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf8")); + const pluginDependencies = packageJson.dependencies + ? Object.keys(packageJson.dependencies) + : []; + pluginDependencies.forEach((dep) => dependencies.add(dep)); + } + }); + + return Array.from(dependencies); +} + /** @type {import('vite').UserConfig} */ -export default { +export default defineConfig({ envPrefix: "REACT_", plugins: [ viteStaticCopy({ @@ -86,10 +136,15 @@ export default { ], resolve: { alias: { + ...getPluginAliases(), "@": path.resolve(__dirname, "./src"), "@careConfig": path.resolve(__dirname, "./care.config.ts"), + "@core": path.resolve(__dirname, "src/"), }, }, + optimizeDeps: { + include: getPluginDependencies(), + }, build: { outDir: "build", assetsDir: "bundle", @@ -118,4 +173,4 @@ export default { }, port: 4000, }, -}; +});