From aeed2c56175c40eaa7da05e344381751a2a89428 Mon Sep 17 00:00:00 2001 From: Amjith Titus Date: Thu, 30 Jan 2025 19:12:13 +0530 Subject: [PATCH 01/97] Initial Commit --- public/locale/en.json | 17 ++ .../ConsultationDetails/OverviewSideBar.tsx | 44 ++++++ .../ConsultationDetails/QuickAccess.tsx | 147 ++++++++++++++++++ .../Encounters/tabs/EncounterUpdatesTab.tsx | 6 +- 4 files changed, 211 insertions(+), 3 deletions(-) create mode 100644 src/components/Facility/ConsultationDetails/OverviewSideBar.tsx create mode 100644 src/components/Facility/ConsultationDetails/QuickAccess.tsx diff --git a/public/locale/en.json b/public/locale/en.json index 29f43a34dee..75d25fa9e03 100644 --- a/public/locale/en.json +++ b/public/locale/en.json @@ -577,7 +577,9 @@ "confirm_transfer_complete": "Confirm Transfer Complete!", "confirm_unavailability": "Confirm Unavailability", "confirmed": "Confirmed", + "consent_form": "Consent Form", "consult": "Consult", + "consultation": "Consultation", "consultation_history": "Consultation History", "consultation_missing_warning": "You have not created a consultation for the patient in", "consultation_not_filed": "You have not filed a consultation for this patient yet.", @@ -686,6 +688,7 @@ "demography": "Demography", "denied_on": "Denied On", "departments": "Departments", + "departments_and_teams": "Departments and Teams", "describe_why_the_asset_is_not_working": "Describe why the asset is not working", "description": "Description", "details_about_the_equipment": "Details about the equipment", @@ -738,6 +741,7 @@ "doctor_nurse": "Doctor/Nurse", "doctor_s_medical_council_registration": "Doctor's Medical Council Registration", "doctors_name": "Doctor's Name", + "doctors_progress_note": "Doctor's Progress Note", "domestic_healthcare_support": "Domestic healthcare support", "domestic_international_travel": "Domestic/international Travel (within last 28 days)", "done": "Done", @@ -877,6 +881,7 @@ "encounter_priority__timing_critical": "Timing critical", "encounter_priority__urgent": "Urgent", "encounter_priority__use_as_directed": "Use as directed", + "encounter_settings": "Encounter Settings", "encounter_status": "Encounter Status", "encounter_status__cancelled": "Cancelled", "encounter_status__completed": "Completed", @@ -1014,6 +1019,7 @@ "footer_body": "Open Healthcare Network is an open-source public utility designed by a multi-disciplinary team of innovators and volunteers. Open Healthcare Network CARE is a Digital Public Good recognised by the United Nations.", "forget_password": "Forgot password?", "forget_password_instruction": "Enter your username, and if it exists, we will send you a link to reset your password.", + "forms": "Forms", "frequency": "Frequency", "from": "from", "from_date_must_be_before_to_date": "From date must be before to date", @@ -1060,6 +1066,7 @@ "home_facility_updated_error": "Error while updating Home Facility", "home_facility_updated_success": "Home Facility updated successfully", "hospital_identifier": "Hospital Identifier", + "hospitalisation_details": "Hospitalization Details", "hospitalization_details": "Hospitalization Details", "hubs": "Hub Facilities", "i_declare": "I hereby declare that:", @@ -1399,9 +1406,12 @@ "number_of_chronic_diseased_dependents": "Number Of Chronic Diseased Dependents", "number_of_covid_vaccine_doses": "Number of Covid vaccine doses", "nurse": "Nurse", + "nurses_form": "Nurse's Form", "nursing_care": "Nursing Care", + "nursing_home": "Nursing Home", "nursing_information": "Nursing Information", "nutrition": "Nutrition", + "observations": "Observations", "occupancy": "Occupancy", "occupation": "Occupation", "occupied": "Occupied", @@ -1626,6 +1636,7 @@ "questionnaire_not_exist": "The questionnaire you tried to access does not exist.", "questionnaire_submission_failed": "Failed to submit questionnaire", "questionnaire_submitted_successfully": "Questionnaire submitted successfully", + "quick_access": "Quick Access", "quick_actions": "Quick Actions", "quick_actions_description": "Schedule an appointment or create a new encounter", "ration_card__APL": "APL", @@ -1642,6 +1653,7 @@ "reason_for_shift": "Reason for shift", "reason_for_visit": "Reason for visit", "reason_for_visit_placeholder": "Type the reason for booking appointment", + "recommend_discharge": "Recommend Discharge", "recommended_aspect_ratio_for": "Recommended aspect ratio for the image is {{aspectRatio}}.", "record": "Record Audio", "record_delete_confirm": "Are you sure you want to delete this record?", @@ -1724,6 +1736,7 @@ "resource_requests": "Requests", "resource_status": "Request Status", "resource_type": "Request Type", + "respiratory_status": "Respiratory Status", "result": "Result", "result_date": "Result Date", "result_details": "Result details", @@ -1976,6 +1989,7 @@ "tachycardia": "Tachycardia", "tag_name": "Tag Name", "tag_slug": "Tag Slug", + "tags": "Tags", "taper_titrate_dosage": "Taper & Titrate Dosage", "target_dosage": "Target Dosage", "template_deleted": "Template has been deleted", @@ -2080,9 +2094,12 @@ "update_asset_service_record": "Update Asset Service Record", "update_available": "Update Available", "update_bed": "Update Bed", + "update_department": "Update Department", + "update_encounter_details": "Update Hospitalization Details", "update_existing_facility": "Update the details of the existing facility.", "update_facility": "Update Facility", "update_facility_middleware_success": "Facility middleware updated successfully", + "update_hospitalisation_details": "Update Hospitalisation Details", "update_log": "Update Log", "update_password": "Update Password", "update_patient_details": "Update Patient Details", diff --git a/src/components/Facility/ConsultationDetails/OverviewSideBar.tsx b/src/components/Facility/ConsultationDetails/OverviewSideBar.tsx new file mode 100644 index 00000000000..1c645e4cbac --- /dev/null +++ b/src/components/Facility/ConsultationDetails/OverviewSideBar.tsx @@ -0,0 +1,44 @@ +import { t } from "i18next"; + +import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"; + +import { Encounter } from "@/types/emr/encounter"; + +import ObservationsList from "./ObservationsList"; +import QuickAccess from "./QuickAccess"; + +interface Props { + encounter: Encounter; +} + +export default function SideOverview(props: Props) { + return ( +
+ +
+ + + {t("quick_access")} + + + {t("observations")} + + +
+ +
+ + + + + + +
+
+
+ ); +} diff --git a/src/components/Facility/ConsultationDetails/QuickAccess.tsx b/src/components/Facility/ConsultationDetails/QuickAccess.tsx new file mode 100644 index 00000000000..7f29cb7a721 --- /dev/null +++ b/src/components/Facility/ConsultationDetails/QuickAccess.tsx @@ -0,0 +1,147 @@ +import { useQuery } from "@tanstack/react-query"; +import { Link } from "raviger"; +import { useTranslation } from "react-i18next"; + +import CareIcon from "@/CAREUI/icons/CareIcon"; + +import { Badge } from "@/components/ui/badge"; +import { Button } from "@/components/ui/button"; +import { Checkbox } from "@/components/ui/checkbox"; + +import query from "@/Utils/request/query"; +import questionnaireApi from "@/types/questionnaire/questionnaireApi"; + +interface QuickAccessProps { + facilityId: string; + patientId: string; + encounterId: string; +} + +export default function QuickAccess({ + facilityId, + patientId, + encounterId, +}: QuickAccessProps) { + const { t } = useTranslation(); + + const { data: response } = useQuery({ + queryKey: ["questionnaires"], + queryFn: query(questionnaireApi.list), + }); + + const questionnaireList = response?.results || []; + + const encounterSettings = [ + { id: "encounter_settings", label: t("encounter_settings") }, + { id: "treatment_summary", label: t("treatment_summary") }, + ]; + + return ( +
+ {/* Questionnaire Section */} +
+

{t("questionnaire")}

+
+ {questionnaireList.map((item) => ( + + + {item.title} + + ))} +
+
+ + {/* Update Encounter Details */} +
+

+ {t("update_encounter_details")} +

+
+ {encounterSettings.map((item) => ( +
+ + +
+ ))} +
+
+ + {/* Departments and Teams */} +
+
+

{t("departments_and_teams")}

+ +
+
+ {t("cardiology")} + {t("cardiology")} +
+
+ + {/* Tags */} +
+
+

{t("tags")}

+ +
+
+ {t("medico_legal_case")} + {t("medico_legal_case")} +
+
+ + {/* Hospitalisation Details */} +
+

+ {t("hospitalisation_details")} +

+
+
+ {t("admit_source")} + {t("nursing_home")} +
+
+ + {t("diet_preference")} + + {t("dairy_free")} +
+
+ {t("re_admission")} + {t("yes")} +
+
+ +
+
+ ); +} diff --git a/src/pages/Encounters/tabs/EncounterUpdatesTab.tsx b/src/pages/Encounters/tabs/EncounterUpdatesTab.tsx index b1f01ac6b16..df3e8dfc81f 100644 --- a/src/pages/Encounters/tabs/EncounterUpdatesTab.tsx +++ b/src/pages/Encounters/tabs/EncounterUpdatesTab.tsx @@ -1,4 +1,4 @@ -import ObservationsList from "@/components/Facility/ConsultationDetails/ObservationsList"; +import SideOverview from "@/components/Facility/ConsultationDetails/OverviewSideBar"; import QuestionnaireResponsesList from "@/components/Facility/ConsultationDetails/QuestionnaireResponsesList"; import { AllergyList } from "@/components/Patient/allergy/list"; import { DiagnosisList } from "@/components/Patient/diagnosis/list"; @@ -51,8 +51,8 @@ export const EncounterUpdatesTab = ({ {/* Right Column - Observations */} -
- +
+
From 333a6eebf3d21864a33139c18cc9e31444f655df Mon Sep 17 00:00:00 2001 From: Amjith Titus Date: Fri, 31 Jan 2025 09:27:15 +0530 Subject: [PATCH 02/97] Quick Access changes --- .../Facility/ConsultationDetails/QuickAccess.tsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/components/Facility/ConsultationDetails/QuickAccess.tsx b/src/components/Facility/ConsultationDetails/QuickAccess.tsx index 7f29cb7a721..00567707a1d 100644 --- a/src/components/Facility/ConsultationDetails/QuickAccess.tsx +++ b/src/components/Facility/ConsultationDetails/QuickAccess.tsx @@ -39,12 +39,12 @@ export default function QuickAccess({ return (
{/* Questionnaire Section */} -
-

{t("questionnaire")}

-
+
+

{t("questionnaire")}

+
{questionnaireList.map((item) => ( Date: Tue, 4 Feb 2025 23:30:41 +0530 Subject: [PATCH 03/97] Encounter design --- public/locale/en.json | 9 +- .../ConsultationDetails/ObservationsList.tsx | 134 +++++++++++--- .../ConsultationDetails/OverviewSideBar.tsx | 12 +- .../ConsultationDetails/QuickAccess.tsx | 168 +++++++++++------- src/components/Patient/allergy/list.tsx | 86 +++++---- .../Patient/diagnosis/DiagnosisTable.tsx | 148 +++++++-------- src/components/Patient/diagnosis/list.tsx | 38 ++-- .../Patient/symptoms/SymptomTable.tsx | 153 ++++++++-------- src/components/Patient/symptoms/list.tsx | 40 +++-- 9 files changed, 475 insertions(+), 313 deletions(-) diff --git a/public/locale/en.json b/public/locale/en.json index a37b5a52e2b..9c0d44da47e 100644 --- a/public/locale/en.json +++ b/public/locale/en.json @@ -490,6 +490,7 @@ "cannot_select_year_out_of_range": "Cannot select year out of range", "capture": "Capture", "card": "Card", + "cardiology": "Cardiology", "care": "CARE", "care_backend": "Care Backend", "care_frontend": "Care Frontend", @@ -979,6 +980,7 @@ "facility_updated_successfully": "Facility updated successfully", "failed_to_create_appointment": "Failed to create an appointment", "failed_to_link_abha_number": "Failed to link ABHA Number. Please try again later.", + "false": "False", "fast_track_testing_reason": "Fast track testing reason", "features": "Features", "feed_configurations": "Feed Configurations", @@ -1219,6 +1221,7 @@ "log_report": "Log Report", "log_update": "Log Update", "log_updates": "Log Updates", + "logged_by": "Logged by", "logged_in_as": "Logged in as", "login": "Login", "logout": "Log Out", @@ -1666,6 +1669,7 @@ "ration_card__BPL": "BPL", "ration_card__NO_CARD": "Non-card holder", "ration_card_category": "Ration Card Category", + "re_admission": "Re-Admission", "readmission": "Re-admission", "reason": "Reason", "reason_for_discontinuation": "Reason for discontinuation", @@ -2064,6 +2068,7 @@ "treatment_summary__heading": "INTERIM TREATMENT SUMMARY", "treatment_summary__print": "Print Treatment Summary", "triage_category": "Triage Category", + "true": "True", "try_again_later": "Try again later!", "try_different_abha_linking_option": "Want to try a different linking option, here are some more:", "type_any_extra_comments_here": "type any extra comments here", @@ -2131,7 +2136,7 @@ "update_available": "Update Available", "update_bed": "Update Bed", "update_department": "Update Department", - "update_encounter_details": "Update Hospitalization Details", + "update_encounter_details": "Update Encounter Details", "update_existing_facility": "Update the details of the existing facility.", "update_facility": "Update Facility", "update_facility_middleware_success": "Facility middleware updated successfully", @@ -2230,7 +2235,7 @@ "video_conference_link": "Video Conference Link", "view": "View", "view_abdm_records": "View ABDM Records", - "view_all": "view all", + "view_all": "View All", "view_all_details": "View All Details", "view_and_manage_patient_encounters": "View and manage patient encounters", "view_asset": "View Assets", diff --git a/src/components/Facility/ConsultationDetails/ObservationsList.tsx b/src/components/Facility/ConsultationDetails/ObservationsList.tsx index 980a6a1c0d6..e15278773bd 100644 --- a/src/components/Facility/ConsultationDetails/ObservationsList.tsx +++ b/src/components/Facility/ConsultationDetails/ObservationsList.tsx @@ -3,8 +3,6 @@ import { useEffect } from "react"; import { useTranslation } from "react-i18next"; import { useInView } from "react-intersection-observer"; -import CareIcon from "@/CAREUI/icons/CareIcon"; - import { Card } from "@/components/ui/card"; import { formatValue } from "@/components/Facility/ConsultationDetails/QuestionnaireResponsesList"; @@ -13,7 +11,6 @@ import routes from "@/Utils/request/api"; import query from "@/Utils/request/query"; import { HTTPError } from "@/Utils/request/types"; import { PaginatedResponse } from "@/Utils/request/types"; -import { formatDateTime } from "@/Utils/utils"; import { Encounter } from "@/types/emr/encounter"; import { Observation } from "@/types/emr/observation"; @@ -23,6 +20,59 @@ interface Props { encounter: Encounter; } +interface GroupedObservations { + [key: string]: Observation[]; +} + +function getDateKey(date: string) { + return new Date(date).toISOString().split("T")[0]; +} + +function formatDisplayDate(dateStr: string) { + const date = new Date(dateStr); + const today = new Date(); + const yesterday = new Date(today); + yesterday.setDate(yesterday.getDate() - 1); + + // Reset time parts for accurate date comparison + today.setHours(0, 0, 0, 0); + yesterday.setHours(0, 0, 0, 0); + date.setHours(0, 0, 0, 0); + + const formattedDate = date.toLocaleDateString("en-US", { + year: "numeric", + month: "long", + day: "numeric", + }); + + if (date.getTime() === today.getTime()) { + return `Today (${formattedDate})`; + } else if (date.getTime() === yesterday.getTime()) { + return `Yesterday (${formattedDate})`; + } + return formattedDate; +} + +function formatDisplayTime(dateStr: string) { + return new Date(dateStr).toLocaleTimeString("en-US", { + hour: "2-digit", + minute: "2-digit", + }); +} + +function groupObservationsByDate( + observations: Observation[], +): GroupedObservations { + return observations.reduce((groups: GroupedObservations, observation) => { + const dateKey = getDateKey(observation.effective_datetime); + if (!groups[dateKey]) { + groups[dateKey] = []; + } + groups[dateKey].push(observation); + return groups; + }, {}); +} + export default function ObservationsList(props: Props) { const { t } = useTranslation(); const patientId = props.encounter.patient.id; @@ -77,35 +127,63 @@ export default function ObservationsList(props: Props) { ); } + const groupedObservations = groupObservationsByDate(observations); + const dates = Object.keys(groupedObservations).sort().reverse(); + return (
- {observations.map((item: Observation) => ( - -
-
- - {formatDateTime(item.effective_datetime)} -
-
- {item.main_code.display || item.main_code.code} -
- {item.value.value_quantity && ( -
- {item.value.value_quantity.value}{" "} - {item.value.value_quantity.code.display} -
- )} - {item.value.value && ( -
- {formatValue(item.value.value, item.value_type)} -
- )} - {item.note && ( -
{item.note}
- )} + {dates.map((date, index) => ( +
+
+ {formatDisplayDate(date)}
- +
+ {groupedObservations[date] + .sort( + (a, b) => + new Date(b.effective_datetime).getTime() - + new Date(a.effective_datetime).getTime(), + ) + .map((item: Observation) => ( +
+
+ {formatDisplayTime(item.effective_datetime)}: +
+ +
+
+ {item.value.value && ( +
+ {formatValue(item.value.value, item.value_type)} +
+ )} + {item.value.value_quantity && ( +
+ {item.value.value_quantity.value}{" "} +
+ {item.value.value_quantity.code.display} +
+
+ )} +
+ {item.note && ( +
+ {item.note} +
+ )} +
+ {item.main_code.display || item.main_code.code} +
+
+
+
+ ))} +
+ {index < dates.length - 1 && ( +
+ )} +
))} {hasNextPage && (
diff --git a/src/components/Facility/ConsultationDetails/OverviewSideBar.tsx b/src/components/Facility/ConsultationDetails/OverviewSideBar.tsx index 1c645e4cbac..f59ba6e3da1 100644 --- a/src/components/Facility/ConsultationDetails/OverviewSideBar.tsx +++ b/src/components/Facility/ConsultationDetails/OverviewSideBar.tsx @@ -13,14 +13,14 @@ interface Props { export default function SideOverview(props: Props) { return ( -
+
- + {t("quick_access")} - + {t("observations")} @@ -28,11 +28,7 @@ export default function SideOverview(props: Props) {
- + diff --git a/src/components/Facility/ConsultationDetails/QuickAccess.tsx b/src/components/Facility/ConsultationDetails/QuickAccess.tsx index 00567707a1d..4095742730d 100644 --- a/src/components/Facility/ConsultationDetails/QuickAccess.tsx +++ b/src/components/Facility/ConsultationDetails/QuickAccess.tsx @@ -6,22 +6,18 @@ import CareIcon from "@/CAREUI/icons/CareIcon"; import { Badge } from "@/components/ui/badge"; import { Button } from "@/components/ui/button"; -import { Checkbox } from "@/components/ui/checkbox"; + +import LinkDepartmentsSheet from "@/components/Patient/LinkDepartmentsSheet"; import query from "@/Utils/request/query"; +import { Encounter } from "@/types/emr/encounter"; import questionnaireApi from "@/types/questionnaire/questionnaireApi"; interface QuickAccessProps { - facilityId: string; - patientId: string; - encounterId: string; + encounter: Encounter; } -export default function QuickAccess({ - facilityId, - patientId, - encounterId, -}: QuickAccessProps) { +export default function QuickAccess({ encounter }: QuickAccessProps) { const { t } = useTranslation(); const { data: response } = useQuery({ @@ -41,15 +37,15 @@ export default function QuickAccess({ {/* Questionnaire Section */}

{t("questionnaire")}

-
+
{questionnaireList.map((item) => ( - + {item.title} ))} @@ -57,15 +53,17 @@ export default function QuickAccess({
{/* Update Encounter Details */} -
+

{t("update_encounter_details")}

{encounterSettings.map((item) => ( -
- -
-
- {t("cardiology")} - {t("cardiology")} +
+ + {encounter.organizations.map((org) => ( + + {org.name} + + ))} +
+ } + />
@@ -101,47 +129,67 @@ export default function QuickAccess({ variant="outline" size="sm" // onClick={onTagUpdate} - className="text-xs" + className="text-sm font-semibold border-gray-400 text-gray-950" > {t("add_tags")}
-
- {t("medico_legal_case")} - {t("medico_legal_case")} +
+ + {t("medico_legal_case")} + + + {t("medico_legal_case")} +
{/* Hospitalisation Details */} -
-

- {t("hospitalisation_details")} -

-
-
- {t("admit_source")} - {t("nursing_home")} -
-
- - {t("diet_preference")} - - {t("dairy_free")} -
-
- {t("re_admission")} - {t("yes")} + {encounter.hospitalization && ( +
+

+ {t("hospitalisation_details")} +

+
+
+ {t("admit_source")} + + {t( + `encounter_admit_sources__${encounter.hospitalization?.admit_source}`, + )} + +
+
+ + {t("diet_preference")} + + + {t( + `encounter_diet_preference__${encounter.hospitalization?.diet_preference}`, + )} + +
+
+ {t("re_admission")} + + {t(`${encounter.hospitalization?.re_admission}`)} + +
+
-
- -
+
+ )}
); } diff --git a/src/components/Patient/allergy/list.tsx b/src/components/Patient/allergy/list.tsx index a4a91bae6a1..5d38925df48 100644 --- a/src/components/Patient/allergy/list.tsx +++ b/src/components/Patient/allergy/list.tsx @@ -1,9 +1,10 @@ import { useQuery } from "@tanstack/react-query"; import { t } from "i18next"; -import { PencilIcon } from "lucide-react"; import { Link } from "raviger"; import { ReactNode, useState } from "react"; +import CareIcon from "@/CAREUI/icons/CareIcon"; + import { Badge } from "@/components/ui/badge"; import { Button } from "@/components/ui/button"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; @@ -112,9 +113,13 @@ export function AllergyList({ function AllergyRow({ allergy, isEnteredInError }: AllergyRowProps) { return ( - {allergy.code.display} + + {allergy.code.display} + - - - {allergy.created_by.username} + +
+ + {allergy.created_by.username} +
); @@ -166,15 +173,27 @@ export function AllergyList({ patientId={patientId} encounterId={encounterId} > - +
- - {t("allergen")} - {t("category")} - {t("status")} - {t("criticality")} - {t("verification")} - {t("created_by")} + + + {t("allergen")} + + + {t("category")} + + + {t("status")} + + + {t("criticality")} + + + {t("verification")} + + + {t("logged_by")} + @@ -203,16 +222,19 @@ export function AllergyList({
{hasEnteredInErrorRecords && !showEnteredInError && ( -
- -
+ <> +
+
+ +
+ )} ); @@ -230,15 +252,15 @@ const AllergyListLayout = ({ children: ReactNode; }) => { return ( - - + + {t("allergies")} {facilityId && encounterId && ( - + {t("edit")} )} diff --git a/src/components/Patient/diagnosis/DiagnosisTable.tsx b/src/components/Patient/diagnosis/DiagnosisTable.tsx index d9134f6d0c8..d1504a48d61 100644 --- a/src/components/Patient/diagnosis/DiagnosisTable.tsx +++ b/src/components/Patient/diagnosis/DiagnosisTable.tsx @@ -12,7 +12,6 @@ import { import { Avatar } from "@/components/Common/Avatar"; -import { formatName } from "@/Utils/utils"; import { Diagnosis } from "@/types/emr/diagnosis/diagnosis"; export const getStatusBadgeStyle = (status: string) => { @@ -32,83 +31,88 @@ export const getStatusBadgeStyle = (status: string) => { interface DiagnosisTableProps { diagnoses: Diagnosis[]; - showHeader?: boolean; } -export function DiagnosisTable({ - diagnoses, - showHeader = true, -}: DiagnosisTableProps) { +export function DiagnosisTable({ diagnoses }: DiagnosisTableProps) { return ( - - {showHeader && ( - - - {t("diagnosis")} - {t("status")} - {t("verification")} - {t("onset")} - {t("notes")} - {t("created_by")} - - - )} +
+ + + + {t("diagnosis")} + + + {t("status")} + + + {t("verification")} + + + {t("onset")} + + + {t("notes")} + + + {t("created_by")} + + + - {diagnoses.map((diagnosis: Diagnosis, index) => { - const isEnteredInError = - diagnosis.verification_status === "entered_in_error"; - - return ( - <> - ( + + + {diagnosis.code.display} + + + + {t(diagnosis.clinical_status)} + + + + - - {diagnosis.code.display} - - - - {t(diagnosis.clinical_status)} - - - - - {t(diagnosis.verification_status)} - - - - {diagnosis.onset?.onset_datetime - ? new Date( - diagnosis.onset.onset_datetime, - ).toLocaleDateString() - : "-"} - - - {diagnosis.note || "-"} - - - - - {formatName(diagnosis.created_by)} - - - - - ); - })} + {t(diagnosis.verification_status)} + + + + {diagnosis.onset?.onset_datetime + ? new Date(diagnosis.onset.onset_datetime).toLocaleDateString() + : "-"} + + + {diagnosis.note || "-"} + + +
+ + {diagnosis.created_by.username} +
+
+
+ ))}
); diff --git a/src/components/Patient/diagnosis/list.tsx b/src/components/Patient/diagnosis/list.tsx index 40ae25b3faf..cd7e8c19fae 100644 --- a/src/components/Patient/diagnosis/list.tsx +++ b/src/components/Patient/diagnosis/list.tsx @@ -1,9 +1,10 @@ import { useQuery } from "@tanstack/react-query"; import { t } from "i18next"; -import { PencilIcon } from "lucide-react"; import { Link } from "raviger"; import { ReactNode, useState } from "react"; +import CareIcon from "@/CAREUI/icons/CareIcon"; + import { Button } from "@/components/ui/button"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { Skeleton } from "@/components/ui/skeleton"; @@ -41,7 +42,9 @@ export function DiagnosisList({ patientId={patientId} encounterId={encounterId} > - + + + ); } @@ -91,16 +94,19 @@ export function DiagnosisList({ /> {hasEnteredInErrorRecords && !showEnteredInError && ( -
- -
+ <> +
+
+ +
+ )} ); @@ -118,15 +124,15 @@ const DiagnosisListLayout = ({ children: ReactNode; }) => { return ( - - + + {t("diagnoses")} {facilityId && encounterId && ( - + {t("edit")} )} diff --git a/src/components/Patient/symptoms/SymptomTable.tsx b/src/components/Patient/symptoms/SymptomTable.tsx index b95e518d99d..bdd8b81f7c5 100644 --- a/src/components/Patient/symptoms/SymptomTable.tsx +++ b/src/components/Patient/symptoms/SymptomTable.tsx @@ -12,7 +12,6 @@ import { import { Avatar } from "@/components/Common/Avatar"; -import { formatName } from "@/Utils/utils"; import { Symptom } from "@/types/emr/symptom/symptom"; export const getStatusBadgeStyle = (status: string) => { @@ -32,89 +31,87 @@ export const getStatusBadgeStyle = (status: string) => { interface SymptomTableProps { symptoms: Symptom[]; - showHeader?: boolean; } -export function SymptomTable({ - symptoms, - showHeader = true, -}: SymptomTableProps) { +export function SymptomTable({ symptoms }: SymptomTableProps) { return ( - - {showHeader && ( - - - {t("symptom")} - {t("status")} - {t("severity")} - {t("onset")} - {t("verification")} - {t("notes")} - {t("created_by")} - - - )} +
+ + + + {t("symptom")} + + + {t("severity")} + + + {t("status")} + + + {t("verification")} + + + {t("logged_by")} + + + - {symptoms.map((symptom: Symptom, index: number) => { - const isEnteredInError = - symptom.verification_status === "entered_in_error"; - - return ( - <> - ( + + + {symptom.code.display} + + + + {t(symptom.clinical_status)} + + + + + {t(symptom.clinical_status)} + + + + - - {symptom.code.display} - - - - {t(symptom.clinical_status)} - - - - - {t(symptom.severity)} - - - - {symptom.onset?.onset_datetime - ? new Date( - symptom.onset.onset_datetime, - ).toLocaleDateString() - : "-"} - - - - {t(symptom.verification_status)} - - - - {symptom.note || "-"} - - - - - {formatName(symptom.created_by)} - - - - - ); - })} + {t(symptom.verification_status)} + + + +
+ + {symptom.created_by.username} +
+
+
+ ))}
); diff --git a/src/components/Patient/symptoms/list.tsx b/src/components/Patient/symptoms/list.tsx index d095b851330..e815a229e0d 100644 --- a/src/components/Patient/symptoms/list.tsx +++ b/src/components/Patient/symptoms/list.tsx @@ -1,9 +1,10 @@ import { useQuery } from "@tanstack/react-query"; import { t } from "i18next"; -import { PencilIcon } from "lucide-react"; import { Link } from "raviger"; import { ReactNode, useState } from "react"; +import CareIcon from "@/CAREUI/icons/CareIcon"; + import { Button } from "@/components/ui/button"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { Skeleton } from "@/components/ui/skeleton"; @@ -41,7 +42,9 @@ export function SymptomsList({ patientId={patientId} encounterId={encounterId} > - + + + ); } @@ -89,16 +92,19 @@ export function SymptomsList({ /> {hasEnteredInErrorRecords && !showEnteredInError && ( -
- -
+ <> +
+
+ +
+ )} ); @@ -116,15 +122,15 @@ const SymptomListLayout = ({ children: ReactNode; }) => { return ( - - + + {t("symptoms")} - {facilityId && ( + {facilityId && encounterId && ( - + {t("edit")} )} From eb209c5bea2f00cf20cbf76e16c7e08a65410770 Mon Sep 17 00:00:00 2001 From: Amjith Titus Date: Wed, 5 Feb 2025 12:07:52 +0530 Subject: [PATCH 04/97] Restore package-lock.json --- package-lock.json | 1260 ++------------------------------------------- 1 file changed, 46 insertions(+), 1214 deletions(-) diff --git a/package-lock.json b/package-lock.json index c131f3c2898..e8c36ab78e0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -130,7 +130,6 @@ "ts-node": "^10.9.2", "tsx": "^4.19.2", "typescript": "^5.6.3", - "unimported": "^1.31.0", "uuid": "^11.0.2", "vite": "^5.4.10", "vite-plugin-checker": "^0.8.0", @@ -4106,49 +4105,6 @@ "url": "https://github.com/sponsors/nzakas" } }, - "node_modules/@humanwhocodes/config-array": { - "version": "0.13.0", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.13.0.tgz", - "integrity": "sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==", - "deprecated": "Use @eslint/config-array instead", - "dev": true, - "license": "Apache-2.0", - "peer": true, - "dependencies": { - "@humanwhocodes/object-schema": "^2.0.3", - "debug": "^4.3.1", - "minimatch": "^3.0.5" - }, - "engines": { - "node": ">=10.10.0" - } - }, - "node_modules/@humanwhocodes/config-array/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/@humanwhocodes/config-array/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "license": "ISC", - "peer": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, "node_modules/@humanwhocodes/module-importer": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", @@ -4163,15 +4119,6 @@ "url": "https://github.com/sponsors/nzakas" } }, - "node_modules/@humanwhocodes/object-schema": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", - "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", - "deprecated": "Use @eslint/object-schema instead", - "dev": true, - "license": "BSD-3-Clause", - "peer": true - }, "node_modules/@humanwhocodes/retry": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.1.tgz", @@ -4339,23 +4286,6 @@ } } }, - "node_modules/@kwsites/file-exists": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@kwsites/file-exists/-/file-exists-1.1.1.tgz", - "integrity": "sha512-m9/5YGR18lIwxSFDwfE3oA7bWuq9kdau6ugN4H2rJeyhFQZcG9AgSHkQtSD15a8WvTgfz9aikZMrKPHvbpqFiw==", - "dev": true, - "license": "MIT", - "dependencies": { - "debug": "^4.1.1" - } - }, - "node_modules/@kwsites/promise-deferred": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@kwsites/promise-deferred/-/promise-deferred-1.1.1.tgz", - "integrity": "sha512-GaHYm+c0O9MjZRu0ongGBRbinu8gVAMd2UZjji6jVmqKtZluZnptXGWhz1E8j8D2HJ3f/yMxKAUC0b+57wncIw==", - "dev": true, - "license": "MIT" - }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -6642,13 +6572,6 @@ "undici-types": "~6.20.0" } }, - "node_modules/@types/normalize-package-data": { - "version": "2.4.4", - "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.4.tgz", - "integrity": "sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==", - "dev": true, - "license": "MIT" - }, "node_modules/@types/prop-types": { "version": "15.7.14", "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.14.tgz", @@ -7303,14 +7226,6 @@ "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@ungap/structured-clone": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.0.tgz", - "integrity": "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==", - "dev": true, - "license": "ISC", - "peer": true - }, "node_modules/@vitejs/plugin-react": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.3.4.tgz", @@ -7995,8 +7910,8 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", - "devOptional": true, "license": "MIT", + "optional": true, "dependencies": { "buffer": "^5.5.0", "inherits": "^2.0.4", @@ -8415,19 +8330,6 @@ "node": ">=8" } }, - "node_modules/cli-spinners": { - "version": "2.9.2", - "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.2.tgz", - "integrity": "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/cli-table3": { "version": "0.6.5", "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.5.tgz", @@ -8489,74 +8391,12 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "dev": true, - "license": "ISC", - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - } - }, - "node_modules/cliui/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true, - "license": "MIT" - }, - "node_modules/cliui/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/cliui/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/cliui/node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, "node_modules/clone": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==", - "devOptional": true, "license": "MIT", + "optional": true, "engines": { "node": ">=0.8" } @@ -9258,8 +9098,8 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz", "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==", - "devOptional": true, "license": "MIT", + "optional": true, "dependencies": { "clone": "^1.0.2" }, @@ -10876,48 +10716,6 @@ "dev": true, "license": "ISC" }, - "node_modules/flow-parser": { - "version": "0.156.0", - "resolved": "https://registry.npmjs.org/flow-parser/-/flow-parser-0.156.0.tgz", - "integrity": "sha512-OCE3oIixhOttaV4ahIGtxf9XfaDdxujiTnXuHu+0dvDVVDiSDJlQpgCWdDKqP0OHfFnxQKrjMamArDAXtrBtZw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/flow-remove-types": { - "version": "2.156.0", - "resolved": "https://registry.npmjs.org/flow-remove-types/-/flow-remove-types-2.156.0.tgz", - "integrity": "sha512-ivU28S1ycaVo5anxlXdIVlrmqLD81JWFADa6oUjyoQg0va4zSyZCp5OYco74VZi7nm42O/yTNv1Y5Byc7bJF1Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "flow-parser": "^0.156.0", - "pirates": "^3.0.2", - "vlq": "^0.2.1" - }, - "bin": { - "flow-node": "flow-node", - "flow-remove-types": "flow-remove-types" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/flow-remove-types/node_modules/pirates": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/pirates/-/pirates-3.0.2.tgz", - "integrity": "sha512-c5CgUJq6H2k6MJz72Ak1F5sN9n9wlSlJyEnwvpm9/y3WB4E3pHBDT2c6PEiS1vyJvq2bUxUAIu0EGf8Cx4Ic7Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "node-modules-regexp": "^1.0.0" - }, - "engines": { - "node": ">= 4" - } - }, "node_modules/for-each": { "version": "0.3.3", "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", @@ -11099,16 +10897,6 @@ "node": ">=18" } }, - "node_modules/get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true, - "license": "ISC", - "engines": { - "node": "6.* || 8.* || >= 10.*" - } - }, "node_modules/get-east-asian-width": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.3.0.tgz", @@ -11510,13 +11298,6 @@ "react-is": "^16.7.0" } }, - "node_modules/hosted-git-info": { - "version": "2.8.9", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", - "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", - "dev": true, - "license": "ISC" - }, "node_modules/html-encoding-sniffer": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-4.0.0.tgz", @@ -12137,16 +11918,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/is-interactive": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", - "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/is-map": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz", @@ -14085,16 +13856,6 @@ "webidl-conversions": "^3.0.0" } }, - "node_modules/node-modules-regexp": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz", - "integrity": "sha512-JMaRS9L4wSRIR+6PTVEikTrq/lMGEZR43a48ETeilY0Q0iMwVnccMFrUM1k+tNzmYuIU0Vh710bCUqHX+/+ctQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/node-releases": { "version": "2.0.19", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz", @@ -14114,50 +13875,6 @@ "node": ">=18" } }, - "node_modules/normalize-package-data": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", - "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "hosted-git-info": "^2.1.4", - "resolve": "^1.10.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" - } - }, - "node_modules/normalize-package-data/node_modules/resolve": { - "version": "1.22.10", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz", - "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-core-module": "^2.16.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - }, - "bin": { - "resolve": "bin/resolve" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/normalize-package-data/node_modules/semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver" - } - }, "node_modules/normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", @@ -14369,30 +14086,6 @@ "node": ">= 0.8.0" } }, - "node_modules/ora": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz", - "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "bl": "^4.1.0", - "chalk": "^4.1.0", - "cli-cursor": "^3.1.0", - "cli-spinners": "^2.5.0", - "is-interactive": "^1.0.0", - "is-unicode-supported": "^0.1.0", - "log-symbols": "^4.1.0", - "strip-ansi": "^6.0.0", - "wcwidth": "^1.0.1" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/ospath": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/ospath/-/ospath-1.2.2.tgz", @@ -14464,16 +14157,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, "node_modules/package-json-from-dist": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", @@ -15720,147 +15403,37 @@ "pify": "^2.3.0" } }, - "node_modules/read-pkg": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", - "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", - "dev": true, + "node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", "license": "MIT", + "optional": true, "dependencies": { - "@types/normalize-package-data": "^2.4.0", - "normalize-package-data": "^2.5.0", - "parse-json": "^5.0.0", - "type-fest": "^0.6.0" + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" }, "engines": { - "node": ">=8" + "node": ">= 6" } }, - "node_modules/read-pkg-up": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", - "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", - "dev": true, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", "license": "MIT", "dependencies": { - "find-up": "^4.1.0", - "read-pkg": "^5.2.0", - "type-fest": "^0.8.1" + "picomatch": "^2.2.1" }, "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=8.10.0" } }, - "node_modules/read-pkg-up/node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "license": "MIT", - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/read-pkg-up/node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-locate": "^4.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/read-pkg-up/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/read-pkg-up/node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-limit": "^2.2.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/read-pkg-up/node_modules/type-fest": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", - "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", - "dev": true, - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=8" - } - }, - "node_modules/read-pkg/node_modules/type-fest": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", - "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", - "dev": true, - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=8" - } - }, - "node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "devOptional": true, - "license": "MIT", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "license": "MIT", - "dependencies": { - "picomatch": "^2.2.1" - }, - "engines": { - "node": ">=8.10.0" - } - }, - "node_modules/recharts": { - "version": "2.15.1", - "resolved": "https://registry.npmjs.org/recharts/-/recharts-2.15.1.tgz", - "integrity": "sha512-v8PUTUlyiDe56qUj82w/EDVuzEFXwEHp9/xOowGAZwfLjB9uAy3GllQVIYMWF6nU+qibx85WF75zD7AjqoT54Q==", + "node_modules/recharts": { + "version": "2.15.1", + "resolved": "https://registry.npmjs.org/recharts/-/recharts-2.15.1.tgz", + "integrity": "sha512-v8PUTUlyiDe56qUj82w/EDVuzEFXwEHp9/xOowGAZwfLjB9uAy3GllQVIYMWF6nU+qibx85WF75zD7AjqoT54Q==", "license": "MIT", "dependencies": { "clsx": "^2.0.0", @@ -16119,16 +15692,6 @@ "dev": true, "license": "MIT" }, - "node_modules/require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/require-from-string": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", @@ -16253,69 +15816,6 @@ "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==", "license": "MIT" }, - "node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "deprecated": "Rimraf versions prior to v4 are no longer supported", - "dev": true, - "license": "ISC", - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/rimraf/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/rimraf/node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "deprecated": "Glob versions prior to v9 are no longer supported", - "dev": true, - "license": "ISC", - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/rimraf/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, "node_modules/roarr": { "version": "2.15.4", "resolved": "https://registry.npmjs.org/roarr/-/roarr-2.15.4.tgz", @@ -16851,22 +16351,6 @@ "simple-concat": "^1.0.0" } }, - "node_modules/simple-git": { - "version": "3.27.0", - "resolved": "https://registry.npmjs.org/simple-git/-/simple-git-3.27.0.tgz", - "integrity": "sha512-ivHoFS9Yi9GY49ogc6/YAi3Fl9ROnF4VyubNylgCkA+RVqLaKWnDSzXOVzya8csELIaWaYNutsEuAhZrtOjozA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@kwsites/file-exists": "^1.1.1", - "@kwsites/promise-deferred": "^1.1.1", - "debug": "^4.3.5" - }, - "funding": { - "type": "github", - "url": "https://github.com/steveukx/git-js?sponsor=1" - } - }, "node_modules/slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", @@ -16990,42 +16474,6 @@ "dev": true, "license": "MIT" }, - "node_modules/spdx-correct": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", - "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" - } - }, - "node_modules/spdx-exceptions": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", - "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==", - "dev": true, - "license": "CC-BY-3.0" - }, - "node_modules/spdx-expression-parse": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", - "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "node_modules/spdx-license-ids": { - "version": "3.0.21", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.21.tgz", - "integrity": "sha512-Bvg/8F5XephndSK3JffaRqdT+gyhfqIPwDHpX80tJrF8QQRYMo8sNMeaZ2Dp5+jhwKnUmIOyFFQfHRkjJm5nXg==", - "dev": true, - "license": "CC0-1.0" - }, "node_modules/spec-change": { "version": "1.11.11", "resolved": "https://registry.npmjs.org/spec-change/-/spec-change-1.11.11.tgz", @@ -17104,8 +16552,8 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "devOptional": true, "license": "MIT", + "optional": true, "dependencies": { "safe-buffer": "~5.2.0" } @@ -17724,19 +17172,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/term-size": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/term-size/-/term-size-2.2.1.tgz", - "integrity": "sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/terminal-size": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/terminal-size/-/terminal-size-4.0.0.tgz", @@ -17776,14 +17211,6 @@ "devOptional": true, "license": "MIT" }, - "node_modules/text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", - "dev": true, - "license": "MIT", - "peer": true - }, "node_modules/thenify": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", @@ -18323,552 +17750,46 @@ "node": ">=4" } }, - "node_modules/unimported": { - "version": "1.31.0", - "resolved": "https://registry.npmjs.org/unimported/-/unimported-1.31.0.tgz", - "integrity": "sha512-QcbdHplhQzZfis6gs+IrbuSJ3hR7pN+w78p0WzvYwxU6SVjiwGZNOAlXbo6WFghA1MWmHPchi0L/2EfHnb549A==", + "node_modules/unique-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz", + "integrity": "sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/parser": "^6.7.3", - "@typescript-eslint/typescript-estree": "^6.7.3", - "chalk": "^4.1.0", - "cosmiconfig": "^8.3.6", - "debug": "^4.3.2", - "file-entry-cache": "^6.0.1", - "flow-remove-types": "2.156.0", - "glob": "^7.1.6", - "ignore": "^5.2.4", - "json5": "^2.2.0", - "ora": "^5.3.0", - "read-pkg-up": "^7.0.1", - "resolve": "^1.20.0", - "simple-git": "^3.18.0", - "term-size": "^2.2.1", - "typescript": "^5.2.2", - "yargs": "^16.2.0" - }, - "bin": { - "unimported": "bin/unimported.js" + "crypto-random-string": "^2.0.0" }, "engines": { - "node": ">=16.0.0" + "node": ">=8" } }, - "node_modules/unimported/node_modules/@eslint/eslintrc": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", - "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", - "dev": true, + "node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", "license": "MIT", - "peer": true, - "dependencies": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^9.6.0", - "globals": "^13.19.0", - "ignore": "^5.2.0", - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "minimatch": "^3.1.2", - "strip-json-comments": "^3.1.1" - }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" + "node": ">= 10.0.0" } }, - "node_modules/unimported/node_modules/@eslint/eslintrc/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, + "node_modules/untildify": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/untildify/-/untildify-4.0.0.tgz", + "integrity": "sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==", "license": "MIT", - "peer": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/unimported/node_modules/@eslint/eslintrc/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "license": "ISC", - "peer": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, "engines": { - "node": "*" + "node": ">=8" } }, - "node_modules/unimported/node_modules/@eslint/js": { - "version": "8.57.1", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.1.tgz", - "integrity": "sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==", + "node_modules/upath": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", + "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", "dev": true, "license": "MIT", - "peer": true, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, - "node_modules/unimported/node_modules/@typescript-eslint/parser": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.21.0.tgz", - "integrity": "sha512-tbsV1jPne5CkFQCgPBcDOt30ItF7aJoZL997JSF7MhGQqOeT3svWRYxiqlfA5RUdlHN6Fi+EI9bxqbdyAUZjYQ==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "@typescript-eslint/scope-manager": "6.21.0", - "@typescript-eslint/types": "6.21.0", - "@typescript-eslint/typescript-estree": "6.21.0", - "@typescript-eslint/visitor-keys": "6.21.0", - "debug": "^4.3.4" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/unimported/node_modules/@typescript-eslint/scope-manager": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.21.0.tgz", - "integrity": "sha512-OwLUIWZJry80O99zvqXVEioyniJMa+d2GrqpUTqi5/v5D5rOrppJVBPa0yKCblcigC0/aYAzxxqQ1B+DS2RYsg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "6.21.0", - "@typescript-eslint/visitor-keys": "6.21.0" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/unimported/node_modules/@typescript-eslint/types": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.21.0.tgz", - "integrity": "sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/unimported/node_modules/@typescript-eslint/typescript-estree": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.21.0.tgz", - "integrity": "sha512-6npJTkZcO+y2/kr+z0hc4HwNfrrP4kNYh57ek7yCNlrBjWQ1Y0OS7jiZTkgumrvkX5HkEKXFZkkdFNkaW2wmUQ==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "@typescript-eslint/types": "6.21.0", - "@typescript-eslint/visitor-keys": "6.21.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "minimatch": "9.0.3", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/unimported/node_modules/@typescript-eslint/visitor-keys": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.21.0.tgz", - "integrity": "sha512-JJtkDduxLi9bivAB+cYOVMtbkqdPOhZ+ZI5LC47MIRrDV4Yn2o+ZnW10Nkmr28xRpSpdJ6Sm42Hjf2+REYXm0A==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "6.21.0", - "eslint-visitor-keys": "^3.4.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/unimported/node_modules/cosmiconfig": { - "version": "8.3.6", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.3.6.tgz", - "integrity": "sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==", - "dev": true, - "license": "MIT", - "dependencies": { - "import-fresh": "^3.3.0", - "js-yaml": "^4.1.0", - "parse-json": "^5.2.0", - "path-type": "^4.0.0" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/d-fischer" - }, - "peerDependencies": { - "typescript": ">=4.9.5" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/unimported/node_modules/doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dev": true, - "license": "Apache-2.0", - "peer": true, - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/unimported/node_modules/eslint": { - "version": "8.57.1", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.1.tgz", - "integrity": "sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==", - "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.6.1", - "@eslint/eslintrc": "^2.1.4", - "@eslint/js": "8.57.1", - "@humanwhocodes/config-array": "^0.13.0", - "@humanwhocodes/module-importer": "^1.0.1", - "@nodelib/fs.walk": "^1.2.8", - "@ungap/structured-clone": "^1.2.0", - "ajv": "^6.12.4", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.3.2", - "doctrine": "^3.0.0", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.2.2", - "eslint-visitor-keys": "^3.4.3", - "espree": "^9.6.1", - "esquery": "^1.4.2", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", - "find-up": "^5.0.0", - "glob-parent": "^6.0.2", - "globals": "^13.19.0", - "graphemer": "^1.4.0", - "ignore": "^5.2.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "is-path-inside": "^3.0.3", - "js-yaml": "^4.1.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.1.2", - "natural-compare": "^1.4.0", - "optionator": "^0.9.3", - "strip-ansi": "^6.0.1", - "text-table": "^0.2.0" - }, - "bin": { - "eslint": "bin/eslint.js" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/unimported/node_modules/eslint-scope": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", - "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", - "dev": true, - "license": "BSD-2-Clause", - "peer": true, - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/unimported/node_modules/eslint/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/unimported/node_modules/eslint/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "license": "ISC", - "peer": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/unimported/node_modules/espree": { - "version": "9.6.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", - "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", - "dev": true, - "license": "BSD-2-Clause", - "peer": true, - "dependencies": { - "acorn": "^8.9.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.4.1" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/unimported/node_modules/file-entry-cache": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", - "dev": true, - "license": "MIT", - "dependencies": { - "flat-cache": "^3.0.4" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/unimported/node_modules/flat-cache": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", - "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", - "dev": true, - "license": "MIT", - "dependencies": { - "flatted": "^3.2.9", - "keyv": "^4.5.3", - "rimraf": "^3.0.2" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/unimported/node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "deprecated": "Glob versions prior to v9 are no longer supported", - "dev": true, - "license": "ISC", - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/unimported/node_modules/glob/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/unimported/node_modules/glob/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/unimported/node_modules/globals": { - "version": "13.24.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", - "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "type-fest": "^0.20.2" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/unimported/node_modules/minimatch": { - "version": "9.0.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", - "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/unimported/node_modules/resolve": { - "version": "1.22.10", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz", - "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-core-module": "^2.16.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - }, - "bin": { - "resolve": "bin/resolve" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/unimported/node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true, - "license": "(MIT OR CC0-1.0)", - "peer": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/unique-string": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz", - "integrity": "sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==", - "dev": true, - "license": "MIT", - "dependencies": { - "crypto-random-string": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/universalify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", - "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", - "license": "MIT", - "engines": { - "node": ">= 10.0.0" - } - }, - "node_modules/untildify": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/untildify/-/untildify-4.0.0.tgz", - "integrity": "sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/upath": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", - "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4", - "yarn": "*" + "node": ">=4", + "yarn": "*" } }, "node_modules/update-browserslist-db": { @@ -19015,17 +17936,6 @@ "devOptional": true, "license": "MIT" }, - "node_modules/validate-npm-package-license": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", - "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" - } - }, "node_modules/validator": { "version": "13.12.0", "resolved": "https://registry.npmjs.org/validator/-/validator-13.12.0.tgz", @@ -19736,13 +18646,6 @@ "@esbuild/win32-x64": "0.21.5" } }, - "node_modules/vlq": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/vlq/-/vlq-0.2.3.tgz", - "integrity": "sha512-DRibZL6DsNhIgYQ+wNdWDL2SL3bKPlVrRiBqV5yuMm++op8W4kGFtaQfCs4KEJn0wBZcHVHJ3eoywX8983k1ow==", - "dev": true, - "license": "MIT" - }, "node_modules/void-elements": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-3.1.0.tgz", @@ -19872,8 +18775,8 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==", - "devOptional": true, "license": "MIT", + "optional": true, "dependencies": { "defaults": "^1.0.3" } @@ -20649,16 +19552,6 @@ "dev": true, "license": "MIT" }, - "node_modules/y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=10" - } - }, "node_modules/yallist": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", @@ -20677,67 +19570,6 @@ "node": ">= 14" } }, - "node_modules/yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "dev": true, - "license": "MIT", - "dependencies": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/yargs-parser": { - "version": "20.2.9", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", - "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=10" - } - }, - "node_modules/yargs/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true, - "license": "MIT" - }, - "node_modules/yargs/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/yargs/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/yauzl": { "version": "2.10.0", "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", From b3ba936cb3b60ce2f159ab1b54959de6e026a13e Mon Sep 17 00:00:00 2001 From: Amjith Titus Date: Wed, 5 Feb 2025 13:45:39 +0530 Subject: [PATCH 05/97] Allergy & Symptom table styling --- public/locale/en.json | 8 + src/components/Patient/allergy/list.tsx | 153 +++++++++++------- .../Patient/diagnosis/DiagnosisTable.tsx | 2 +- .../Patient/symptoms/SymptomTable.tsx | 48 +++--- .../QuestionTypes/AllergyQuestion.tsx | 68 ++++---- .../allergyIntolerance/allergyIntolerance.ts | 22 ++- src/types/emr/symptom/symptom.ts | 24 +++ 7 files changed, 209 insertions(+), 116 deletions(-) diff --git a/public/locale/en.json b/public/locale/en.json index b021a7bf8be..73d92a37ead 100644 --- a/public/locale/en.json +++ b/public/locale/en.json @@ -304,6 +304,7 @@ "add_notes": "Add notes", "add_notes_about_diagnosis": "Add notes about the diagnosis...", "add_notes_about_symptom": "Add notes about the symptom...", + "add_notes_about_the_allergy": "Add notes about the allergy", "add_organizations": "Add Organizations", "add_patient_updates": "Add Patient Updates", "add_policy": "Add Insurance Policy", @@ -1253,6 +1254,7 @@ "manage_user": "Manage User", "manufacturer": "Manufacturer", "map_acronym": "M.A.P.", + "mark_active": "Mark Active", "mark_all_as_read": "Mark all as Read", "mark_as_complete": "Mark as Complete", "mark_as_entered_in_error": "Mark as entered in error", @@ -1260,6 +1262,8 @@ "mark_as_noshow": "Mark as no-show", "mark_as_read": "Mark as Read", "mark_as_unread": "Mark as Unread", + "mark_inactive": "Mark Inactive", + "mark_resolved": "Mark Resolved", "mark_this_transfer_as_complete_question": "Are you sure you want to mark this transfer as complete? The Origin facility will no longer have access to this patient", "mark_transfer_complete_confirmation": "Are you sure you want to mark this transfer as complete? The Origin facility will no longer have access to this patient", "markdown_supported": "You can use markdown to format your facility description", @@ -1450,6 +1454,7 @@ "occupancy": "Occupancy", "occupation": "Occupation", "occupied": "Occupied", + "occurrence": "Occurrence", "old_password": "Current Password", "on": "on", "on_emergency_basis": " on emergency basis", @@ -1723,6 +1728,7 @@ "remarks_placeholder": "Enter remarks", "remission": "Remission", "remove": "Remove", + "remove_allergy": "Remove Allergy", "remove_diagnosis": "Remove Diagnosis", "remove_medication": "Remove Medication", "remove_medication_confirmation": "Are you sure you want to remove {{medication}}?", @@ -1862,6 +1868,7 @@ "search_by_username": "Search by username", "search_country": "Search country...", "search_encounters": "Search Encounters", + "search_for_allergies_to_add": "Search for allergies to add", "search_for_diagnoses_to_add": "Search for diagnoses to add", "search_for_facility": "Search for Facility", "search_for_symptoms_to_add": "Search for symptoms to add", @@ -1878,6 +1885,7 @@ "search_user_description": "Search for a user and assign a role to add them to the patient.", "searching": "Searching...", "see_attachments": "See Attachments", + "see_note": "See Note", "select": "Select", "select_additional_instructions": "Select additional instructions", "select_admit_source": "Select Admit Source", diff --git a/src/components/Patient/allergy/list.tsx b/src/components/Patient/allergy/list.tsx index 5d38925df48..784931a9bdb 100644 --- a/src/components/Patient/allergy/list.tsx +++ b/src/components/Patient/allergy/list.tsx @@ -1,13 +1,24 @@ import { useQuery } from "@tanstack/react-query"; import { t } from "i18next"; +import { + BeakerIcon, + CookingPotIcon, + HeartPulseIcon, + LeafIcon, +} from "lucide-react"; import { Link } from "raviger"; -import { ReactNode, useState } from "react"; +import { ReactNode, useEffect, useState } from "react"; import CareIcon from "@/CAREUI/icons/CareIcon"; import { Badge } from "@/components/ui/badge"; import { Button } from "@/components/ui/button"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; +import { + Popover, + PopoverContent, + PopoverTrigger, +} from "@/components/ui/popover"; import { Skeleton } from "@/components/ui/skeleton"; import { Table, @@ -21,7 +32,12 @@ import { import { Avatar } from "@/components/Common/Avatar"; import query from "@/Utils/request/query"; -import { AllergyIntolerance } from "@/types/emr/allergyIntolerance/allergyIntolerance"; +import { + ALLERGY_CLINICAL_STATUS_STYLES, + ALLERGY_CRITICALITY_STYLES, + ALLERGY_VERIFICATION_STATUS_STYLES, + AllergyIntolerance, +} from "@/types/emr/allergyIntolerance/allergyIntolerance"; import allergyIntoleranceApi from "@/types/emr/allergyIntolerance/allergyIntoleranceApi"; interface AllergyListProps { @@ -30,6 +46,13 @@ interface AllergyListProps { encounterId?: string; } +const CATEGORY_ICONS: Record = { + food: , + medication: , + environment: , + biologic: , +}; + export function AllergyList({ facilityId, patientId, @@ -81,79 +104,94 @@ export function AllergyList({ ); } - const getStatusBadgeStyle = (status: string | undefined) => { - switch (status?.toLowerCase()) { - case "active": - return "bg-green-100 text-green-800 border-green-200"; - case "inactive": - return "bg-gray-100 text-gray-800 border-gray-200"; - default: - return "bg-gray-100 text-gray-800 border-gray-200"; - } - }; - - const getCategoryBadgeStyle = (category: string) => { - switch (category?.toLowerCase()) { - case "food": - return "bg-orange-100 text-orange-800 border-orange-200"; - case "medication": - return "bg-blue-100 text-blue-800 border-blue-200"; - case "environment": - return "bg-green-100 text-green-800 border-green-200"; - default: - return "bg-gray-100 text-gray-800 border-gray-200"; - } - }; - interface AllergyRowProps { allergy: AllergyIntolerance; - isEnteredInError?: boolean; } - function AllergyRow({ allergy, isEnteredInError }: AllergyRowProps) { + function AllergyRow({ allergy }: AllergyRowProps) { + const MAX_NOTE_LENGTH = 15; + const note = allergy.note || ""; + const isLongNote = note.length > MAX_NOTE_LENGTH; + const displayNote = isLongNote + ? `${note.slice(0, MAX_NOTE_LENGTH)}..` + : note; + + useEffect(() => { + console.log( + "Allergy Note:", + allergy.note, + isLongNote, + displayNote, + note.length, + ); + }, [allergy.note, isLongNote, displayNote, note.length]); + return ( - - + + +
+ {CATEGORY_ICONS[allergy.category ?? ""]} +
+
+ {allergy.code.display} - {t(allergy.category)} + {t(allergy.clinical_status)} - {t(allergy.clinical_status)} - - - - {t(allergy.criticality)} {t(allergy.verification_status)} - + + {note && ( +
+ {displayNote} + {isLongNote && ( + + + + + +

+ {note} +

+
+
+ )} +
+ )} +
+
- - {t("allergen")} + + Cat. - - {t("category")} + + {t("allergen")} {t("status")} @@ -192,6 +230,9 @@ export function AllergyList({ {t("verification")} + {t("notes")} + + {t("logged_by")} @@ -213,11 +254,7 @@ export function AllergyList({ (allergy) => allergy.verification_status === "entered_in_error", ) .map((allergy) => ( - + ))} diff --git a/src/components/Patient/diagnosis/DiagnosisTable.tsx b/src/components/Patient/diagnosis/DiagnosisTable.tsx index d1504a48d61..5d47dd6e993 100644 --- a/src/components/Patient/diagnosis/DiagnosisTable.tsx +++ b/src/components/Patient/diagnosis/DiagnosisTable.tsx @@ -54,7 +54,7 @@ export function DiagnosisTable({ diagnoses }: DiagnosisTableProps) { {t("notes")} - {t("created_by")} + {t("logged_by")} diff --git a/src/components/Patient/symptoms/SymptomTable.tsx b/src/components/Patient/symptoms/SymptomTable.tsx index bdd8b81f7c5..99c55bdcd44 100644 --- a/src/components/Patient/symptoms/SymptomTable.tsx +++ b/src/components/Patient/symptoms/SymptomTable.tsx @@ -12,22 +12,12 @@ import { import { Avatar } from "@/components/Common/Avatar"; -import { Symptom } from "@/types/emr/symptom/symptom"; - -export const getStatusBadgeStyle = (status: string) => { - switch (status?.toLowerCase()) { - case "active": - return "bg-green-100 text-green-800 border-green-200"; - case "inactive": - return "bg-gray-100 text-gray-800 border-gray-200"; - case "resolved": - return "bg-blue-100 text-blue-800 border-blue-200"; - case "recurrence": - return "bg-orange-100 text-orange-800 border-orange-200"; - default: - return "bg-gray-100 text-gray-800 border-gray-200"; - } -}; +import { + SYMPTOM_CLINICAL_STATUS_STYLES, + SYMPTOM_SEVERITY_STYLES, + SYMPTOM_VERIFICATION_STATUS_STYLES, + Symptom, +} from "@/types/emr/symptom/symptom"; interface SymptomTableProps { symptoms: Symptom[]; @@ -71,31 +61,31 @@ export function SymptomTable({ symptoms }: SymptomTableProps) { - {t(symptom.clinical_status)} + {t(symptom.severity)} {t(symptom.clinical_status)} {t(symptom.verification_status)} diff --git a/src/components/Questionnaire/QuestionTypes/AllergyQuestion.tsx b/src/components/Questionnaire/QuestionTypes/AllergyQuestion.tsx index 8270ae98c71..a4119c68e2f 100644 --- a/src/components/Questionnaire/QuestionTypes/AllergyQuestion.tsx +++ b/src/components/Questionnaire/QuestionTypes/AllergyQuestion.tsx @@ -8,6 +8,7 @@ import { Pencil2Icon, } from "@radix-ui/react-icons"; import { useQuery } from "@tanstack/react-query"; +import { t } from "i18next"; import { BeakerIcon, CookingPotIcon, @@ -45,6 +46,7 @@ import { import ValueSetSelect from "@/components/Questionnaire/ValueSetSelect"; import query from "@/Utils/request/query"; +import { dateQueryString } from "@/Utils/utils"; import { ALLERGY_VERIFICATION_STATUS, AllergyIntolerance, @@ -105,7 +107,9 @@ function convertToAllergyRequest( verification_status: allergy.verification_status, category: allergy.category, criticality: allergy.criticality, - last_occurrence: allergy.last_occurrence, + last_occurrence: allergy.last_occurrence + ? dateQueryString(new Date(allergy.last_occurrence)) + : undefined, note: allergy.note, encounter: allergy.encounter, }; @@ -211,15 +215,15 @@ export function AllergyQuestion({ - Substance + {t("substance")} - Critical + {t("criticality")} - Status + {t("status")} - Occurrence + {t("occurrence")} @@ -315,7 +319,7 @@ export function AllergyQuestion({ } > - Mark Active + {t("mark_active")} )} {allergy.clinical_status !== "inactive" && ( @@ -327,7 +331,7 @@ export function AllergyQuestion({ } > - Mark Inactive + {t("mark_inactive")} )} {allergy.clinical_status !== "resolved" && ( @@ -339,7 +343,7 @@ export function AllergyQuestion({ } > - Mark Resolved + {t("mark_resolved")} )} @@ -348,7 +352,7 @@ export function AllergyQuestion({ onClick={() => handleRemoveAllergy(index)} > - Remove Allergy + {t("remove_allergy")} @@ -356,7 +360,9 @@ export function AllergyQuestion({
- + @@ -405,7 +413,9 @@ export function AllergyQuestion({
- + - + @@ -528,12 +540,14 @@ const AllergyTableRow = ({ disabled={disabled} > - + - Low - High - Unable to Assess + {t("low")} + {t("high")} + + {t("unable_to_assess")} + @@ -550,7 +564,7 @@ const AllergyTableRow = ({ disabled={disabled} > - + {Object.entries(ALLERGY_VERIFICATION_STATUS).map( @@ -566,7 +580,7 @@ const AllergyTableRow = ({ onUpdate?.({ last_occurrence: e.target.value })} disabled={disabled} className="h-7 text-sm w-[100px] px-1" @@ -587,14 +601,14 @@ const AllergyTableRow = ({ - {showNotes ? "Hide Notes" : "Add Notes"} + {showNotes ? t("hide_notes") : t("add_notes")} {allergy.clinical_status !== "active" && ( onUpdate?.({ clinical_status: "active" })} > - Mark Active + {t("mark_active")} )} {allergy.clinical_status !== "inactive" && ( @@ -602,7 +616,7 @@ const AllergyTableRow = ({ onClick={() => onUpdate?.({ clinical_status: "inactive" })} > - Mark Inactive + {t("mark_inactive")} )} {allergy.clinical_status !== "resolved" && ( @@ -610,7 +624,7 @@ const AllergyTableRow = ({ onClick={() => onUpdate?.({ clinical_status: "resolved" })} > - Mark Resolved + {t("mark_resolved")} )} @@ -619,7 +633,7 @@ const AllergyTableRow = ({ onClick={onRemove} > - Remove Allergy + {t("remove_allergy")} @@ -628,10 +642,10 @@ const AllergyTableRow = ({ {showNotes && ( - + onUpdate?.({ note: e.target.value })} disabled={disabled} diff --git a/src/types/emr/allergyIntolerance/allergyIntolerance.ts b/src/types/emr/allergyIntolerance/allergyIntolerance.ts index 6693664b0b5..b788729091b 100644 --- a/src/types/emr/allergyIntolerance/allergyIntolerance.ts +++ b/src/types/emr/allergyIntolerance/allergyIntolerance.ts @@ -51,4 +51,24 @@ export const ALLERGY_VERIFICATION_STATUS = { refuted: "Refuted", presumed: "Presumed", entered_in_error: "Entered in Error", -}; +} as const; + +export const ALLERGY_VERIFICATION_STATUS_STYLES = { + unconfirmed: "bg-yellow-100 text-yellow-800 border-yellow-200", + confirmed: "bg-green-100 text-green-800 border-green-200", + refuted: "bg-red-100 text-red-800 border-red-200", + presumed: "bg-blue-100 text-blue-800 border-blue-200", + entered_in_error: "bg-red-100 text-red-800 border-red-200", +} as const; + +export const ALLERGY_CLINICAL_STATUS_STYLES = { + active: "bg-green-100 text-green-800 border-green-200", + inactive: "bg-gray-100 text-gray-800 border-gray-200", + resolved: "bg-blue-100 text-blue-800 border-blue-200", +} as const; + +export const ALLERGY_CRITICALITY_STYLES = { + low: "bg-blue-100 text-blue-800 border-blue-200", + high: "bg-red-100 text-red-800 border-red-200", + unable_to_assess: "bg-gray-100 text-gray-800 border-gray-200", +} as const; diff --git a/src/types/emr/symptom/symptom.ts b/src/types/emr/symptom/symptom.ts index d064fd320e4..2d3512a5b59 100644 --- a/src/types/emr/symptom/symptom.ts +++ b/src/types/emr/symptom/symptom.ts @@ -59,3 +59,27 @@ export interface SymptomRequest { note?: string; encounter: string; } + +export const SYMPTOM_CLINICAL_STATUS_STYLES = { + active: "bg-green-100 text-green-800 border-green-200", + recurrence: "bg-yellow-100 text-yellow-800 border-yellow-200", + relapse: "bg-red-100 text-red-800 border-red-200", + inactive: "bg-gray-100 text-gray-800 border-gray-200", + remission: "bg-blue-100 text-blue-800 border-blue-200", + resolved: "bg-emerald-100 text-emerald-800 border-emerald-200", +} as const; + +export const SYMPTOM_VERIFICATION_STATUS_STYLES = { + unconfirmed: "bg-yellow-100 text-yellow-800 border-yellow-200", + provisional: "bg-orange-100 text-orange-800 border-orange-200", + differential: "bg-purple-100 text-purple-800 border-purple-200", + confirmed: "bg-green-100 text-green-800 border-green-200", + refuted: "bg-red-100 text-red-800 border-red-200", + entered_in_error: "bg-red-100 text-red-800 border-red-200", +} as const; + +export const SYMPTOM_SEVERITY_STYLES = { + severe: "bg-red-100 text-red-800 border-red-200", + moderate: "bg-yellow-100 text-yellow-800 border-yellow-200", + mild: "bg-blue-100 text-blue-800 border-blue-200", +} as const; From d4c2591da8bf2e039a0f52c768baf2b07b9c653a Mon Sep 17 00:00:00 2001 From: Amjith Titus Date: Wed, 5 Feb 2025 14:37:20 +0530 Subject: [PATCH 06/97] Diagnosis table styling --- .../Patient/diagnosis/DiagnosisTable.tsx | 174 +++++++++++------- .../Patient/symptoms/SymptomTable.tsx | 159 ++++++++++------ src/types/emr/diagnosis/diagnosis.ts | 18 ++ 3 files changed, 225 insertions(+), 126 deletions(-) diff --git a/src/components/Patient/diagnosis/DiagnosisTable.tsx b/src/components/Patient/diagnosis/DiagnosisTable.tsx index 5d47dd6e993..3f821d5d110 100644 --- a/src/components/Patient/diagnosis/DiagnosisTable.tsx +++ b/src/components/Patient/diagnosis/DiagnosisTable.tsx @@ -1,6 +1,12 @@ import { t } from "i18next"; import { Badge } from "@/components/ui/badge"; +import { Button } from "@/components/ui/button"; +import { + Popover, + PopoverContent, + PopoverTrigger, +} from "@/components/ui/popover"; import { Table, TableBody, @@ -12,22 +18,11 @@ import { import { Avatar } from "@/components/Common/Avatar"; -import { Diagnosis } from "@/types/emr/diagnosis/diagnosis"; - -export const getStatusBadgeStyle = (status: string) => { - switch (status?.toLowerCase()) { - case "active": - return "bg-green-100 text-green-800 border-green-200"; - case "inactive": - return "bg-gray-100 text-gray-800 border-gray-200"; - case "resolved": - return "bg-blue-100 text-blue-800 border-blue-200"; - case "recurrence": - return "bg-orange-100 text-orange-800 border-orange-200"; - default: - return "bg-gray-100 text-gray-800 border-gray-200"; - } -}; +import { + DIAGNOSIS_CLINICAL_STATUS_STYLES, + DIAGNOSIS_VERIFICATION_STATUS_STYLES, + Diagnosis, +} from "@/types/emr/diagnosis/diagnosis"; interface DiagnosisTableProps { diagnoses: Diagnosis[]; @@ -59,60 +54,99 @@ export function DiagnosisTable({ diagnoses }: DiagnosisTableProps) { - {diagnoses.map((diagnosis) => ( - - - {diagnosis.code.display} - - - - {t(diagnosis.clinical_status)} - - - - - {t(diagnosis.verification_status)} - - - - {diagnosis.onset?.onset_datetime - ? new Date(diagnosis.onset.onset_datetime).toLocaleDateString() - : "-"} - - - {diagnosis.note || "-"} - - -
- - {diagnosis.created_by.username} -
-
-
- ))} + {diagnoses.map((diagnosis) => { + const note = diagnosis.note || ""; + const MAX_NOTE_LENGTH = 15; + const isLongNote = note.length > MAX_NOTE_LENGTH; + const displayNote = isLongNote + ? `${note.slice(0, MAX_NOTE_LENGTH)}..` + : note; + + return ( + + + {diagnosis.code.display} + + + + {t(diagnosis.clinical_status)} + + + + + {t(diagnosis.verification_status)} + + + + {diagnosis.onset?.onset_datetime + ? new Date( + diagnosis.onset.onset_datetime, + ).toLocaleDateString() + : "-"} + + + {note ? ( +
+ + {displayNote} + + {isLongNote && ( + + + + + +

+ {note} +

+
+
+ )} +
+ ) : ( + "-" + )} +
+ +
+ + + {diagnosis.created_by.username} + +
+
+
+ ); + })}
); diff --git a/src/components/Patient/symptoms/SymptomTable.tsx b/src/components/Patient/symptoms/SymptomTable.tsx index 99c55bdcd44..76aa879c01c 100644 --- a/src/components/Patient/symptoms/SymptomTable.tsx +++ b/src/components/Patient/symptoms/SymptomTable.tsx @@ -1,6 +1,12 @@ import { t } from "i18next"; import { Badge } from "@/components/ui/badge"; +import { Button } from "@/components/ui/button"; +import { + Popover, + PopoverContent, + PopoverTrigger, +} from "@/components/ui/popover"; import { Table, TableBody, @@ -40,68 +46,109 @@ export function SymptomTable({ symptoms }: SymptomTableProps) { {t("verification")} + + {t("notes")} + {t("logged_by")} - {symptoms.map((symptom) => ( - - - {symptom.code.display} - - - - {t(symptom.severity)} - - - - - {t(symptom.clinical_status)} - - - - - {t(symptom.verification_status)} - - - -
- - {symptom.created_by.username} -
-
-
- ))} + {symptoms.map((symptom) => { + const note = symptom.note || ""; + const MAX_NOTE_LENGTH = 15; + const isLongNote = note.length > MAX_NOTE_LENGTH; + const displayNote = isLongNote + ? `${note.slice(0, MAX_NOTE_LENGTH)}..` + : note; + + return ( + + + {symptom.code.display} + + + + {t(symptom.severity)} + + + + + {t(symptom.clinical_status)} + + + + + {t(symptom.verification_status)} + + + + {note ? ( +
+ + {displayNote} + + {isLongNote && ( + + + + + +

+ {note} +

+
+
+ )} +
+ ) : ( + "-" + )} +
+ +
+ + {symptom.created_by.username} +
+
+
+ ); + })}
); diff --git a/src/types/emr/diagnosis/diagnosis.ts b/src/types/emr/diagnosis/diagnosis.ts index 29f7b250778..c9dc5035a0d 100644 --- a/src/types/emr/diagnosis/diagnosis.ts +++ b/src/types/emr/diagnosis/diagnosis.ts @@ -54,3 +54,21 @@ export interface DiagnosisRequest { note?: string; encounter: string; } + +export const DIAGNOSIS_CLINICAL_STATUS_STYLES = { + active: "bg-green-100 text-green-800 border-green-200", + recurrence: "bg-yellow-100 text-yellow-800 border-yellow-200", + relapse: "bg-red-100 text-red-800 border-red-200", + inactive: "bg-gray-100 text-gray-800 border-gray-200", + remission: "bg-blue-100 text-blue-800 border-blue-200", + resolved: "bg-emerald-100 text-emerald-800 border-emerald-200", +} as const; + +export const DIAGNOSIS_VERIFICATION_STATUS_STYLES = { + unconfirmed: "bg-yellow-100 text-yellow-800 border-yellow-200", + provisional: "bg-orange-100 text-orange-800 border-orange-200", + differential: "bg-purple-100 text-purple-800 border-purple-200", + confirmed: "bg-green-100 text-green-800 border-green-200", + refuted: "bg-red-100 text-red-800 border-red-200", + entered_in_error: "bg-red-100 text-red-800 border-red-200", +} as const; From 0e1130414a9c31baa06b842a37ccc558c9edfde7 Mon Sep 17 00:00:00 2001 From: Amjith Titus Date: Wed, 5 Feb 2025 14:56:13 +0530 Subject: [PATCH 07/97] Allergy table styling --- src/components/Patient/allergy/list.tsx | 6 +++--- src/components/Patient/symptoms/SymptomTable.tsx | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/components/Patient/allergy/list.tsx b/src/components/Patient/allergy/list.tsx index 784931a9bdb..e7a5dacd03f 100644 --- a/src/components/Patient/allergy/list.tsx +++ b/src/components/Patient/allergy/list.tsx @@ -191,7 +191,7 @@ export function AllergyList({
)} - +
{t("verification")} - + {t("notes")} - + {t("logged_by")} diff --git a/src/components/Patient/symptoms/SymptomTable.tsx b/src/components/Patient/symptoms/SymptomTable.tsx index 76aa879c01c..8fc626918e9 100644 --- a/src/components/Patient/symptoms/SymptomTable.tsx +++ b/src/components/Patient/symptoms/SymptomTable.tsx @@ -49,7 +49,7 @@ export function SymptomTable({ symptoms }: SymptomTableProps) { {t("notes")} - + {t("logged_by")} From 957a4092210c7d3fdfd295990c7324a89c9581c5 Mon Sep 17 00:00:00 2001 From: Amjith Titus Date: Thu, 6 Feb 2025 12:24:43 +0530 Subject: [PATCH 08/97] Treatment summary --- public/locale/en.json | 2 + src/Routers/routes/ConsultationRoutes.tsx | 5 + .../QuestionnaireResponsesList.tsx | 49 +-- .../Patient/MedicationStatementList.tsx | 236 +++++++++------ src/components/Patient/TreatmentSummary.tsx | 282 ++++++++++++++++++ src/components/Patient/allergy/list.tsx | 39 ++- .../Patient/diagnosis/DiagnosisTable.tsx | 12 +- src/components/Patient/diagnosis/list.tsx | 33 +- .../Patient/symptoms/SymptomTable.tsx | 12 +- src/components/Patient/symptoms/list.tsx | 34 ++- src/types/emr/encounter.ts | 12 + src/types/emr/medicationStatement.ts | 16 + 12 files changed, 600 insertions(+), 132 deletions(-) create mode 100644 src/components/Patient/TreatmentSummary.tsx diff --git a/public/locale/en.json b/public/locale/en.json index 73d92a37ead..78e6884ba28 100644 --- a/public/locale/en.json +++ b/public/locale/en.json @@ -333,6 +333,7 @@ "administered_on": "Administered on", "administration_dosage_range_error": "Dosage should be between start and target dosage", "administration_notes": "Administration Notes", + "admission_source": "Admission Source", "admit_source": "Admit Source", "admitted": "Admitted", "admitted_on": "Admitted On", @@ -1280,6 +1281,7 @@ "medication": "Medication", "medication_administration_saved": "Medicine Administration saved", "medication_taken_between": "Medication Taken Between", + "medications": "Medications", "medicine": "Medicine", "medicine_administration": "Medicine Administration", "medicine_administration_history": "Medicine Administration History", diff --git a/src/Routers/routes/ConsultationRoutes.tsx b/src/Routers/routes/ConsultationRoutes.tsx index 41fee1a8479..6bf447a9176 100644 --- a/src/Routers/routes/ConsultationRoutes.tsx +++ b/src/Routers/routes/ConsultationRoutes.tsx @@ -1,6 +1,7 @@ import QuestionnaireResponseView from "@/components/Facility/ConsultationDetails/QuestionnaireResponseView"; import EncounterQuestionnaire from "@/components/Patient/EncounterQuestionnaire"; import FileUploadPage from "@/components/Patient/FileUploadPage"; +import TreatmentSummary from "@/components/Patient/TreatmentSummary"; import { AppRoutes } from "@/Routers/AppRouter"; import { EncounterShow } from "@/pages/Encounters/EncounterShow"; @@ -11,6 +12,10 @@ const consultationRoutes: AppRoutes = { facilityId, encounterId, }) => , + "/facility/:facilityId/encounter/:encounterId/treatment-summary": ({ + facilityId, + encounterId, + }) => , "/facility/:facilityId/encounter/:encounterId/:tab": ({ facilityId, encounterId, diff --git a/src/components/Facility/ConsultationDetails/QuestionnaireResponsesList.tsx b/src/components/Facility/ConsultationDetails/QuestionnaireResponsesList.tsx index a9cb31b9307..d12fd3f717d 100644 --- a/src/components/Facility/ConsultationDetails/QuestionnaireResponsesList.tsx +++ b/src/components/Facility/ConsultationDetails/QuestionnaireResponsesList.tsx @@ -30,6 +30,8 @@ import { CreateAppointmentQuestion } from "@/types/scheduling/schedule"; interface Props { encounter?: Encounter; patientId: string; + isPrintPreview?: boolean; + onlyUnstructured?: boolean; } type ResponseValueType = { @@ -282,6 +284,8 @@ function ResponseCard({ item }: { item: QuestionnaireResponse }) { export default function QuestionnaireResponsesList({ encounter, patientId, + isPrintPreview = false, + onlyUnstructured, }: Props) { const { t } = useTranslation(); const [qParams, setQueryParams] = useQueryParams<{ page?: number }>(); @@ -292,8 +296,11 @@ export default function QuestionnaireResponsesList({ pathParams: { patientId }, queryParams: { encounter: encounter?.id, - limit: RESULTS_PER_PAGE_LIMIT, - offset: ((qParams.page ?? 1) - 1) * RESULTS_PER_PAGE_LIMIT, + limit: isPrintPreview ? 100 : RESULTS_PER_PAGE_LIMIT, + offset: isPrintPreview + ? undefined + : ((qParams.page ?? 1) - 1) * RESULTS_PER_PAGE_LIMIT, + only_unstructured: onlyUnstructured, }, }), }); @@ -322,24 +329,28 @@ export default function QuestionnaireResponsesList({ ), )} -
-
- RESULTS_PER_PAGE_LIMIT - ? "visible" - : "invisible", - )} - > - setQueryParams({ page })} - /> + {!isPrintPreview && ( +
+
+ RESULTS_PER_PAGE_LIMIT + ? "visible" + : "invisible", + )} + > + setQueryParams({ page })} + /> +
-
+ )} )}
diff --git a/src/components/Patient/MedicationStatementList.tsx b/src/components/Patient/MedicationStatementList.tsx index 39c8e334cda..702354abe95 100644 --- a/src/components/Patient/MedicationStatementList.tsx +++ b/src/components/Patient/MedicationStatementList.tsx @@ -2,9 +2,16 @@ import { useQuery } from "@tanstack/react-query"; import { useState } from "react"; import { useTranslation } from "react-i18next"; +import { cn } from "@/lib/utils"; + import { Badge } from "@/components/ui/badge"; import { Button } from "@/components/ui/button"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; +import { + Popover, + PopoverContent, + PopoverTrigger, +} from "@/components/ui/popover"; import { Skeleton } from "@/components/ui/skeleton"; import { Table, @@ -14,60 +21,56 @@ import { TableHeader, TableRow, } from "@/components/ui/table"; -import { - Tooltip, - TooltipContent, - TooltipTrigger, -} from "@/components/ui/tooltip"; + +import { Avatar } from "@/components/Common/Avatar"; import routes from "@/Utils/request/api"; import query from "@/Utils/request/query"; import { formatDateTime } from "@/Utils/utils"; +import { + MEDICATION_STATEMENT_STATUS_STYLES, + MedicationStatement, +} from "@/types/emr/medicationStatement"; interface MedicationStatementListProps { patientId: string; + className?: string; + isPrintPreview?: boolean; } interface MedicationRowProps { - statement: any; + statement: MedicationStatement; isEnteredInError?: boolean; - index: number; + isPrintPreview?: boolean; } function MedicationRow({ statement, isEnteredInError, - index, + isPrintPreview = false, }: MedicationRowProps) { + const { t } = useTranslation(); + const note = statement.note || ""; + const MAX_NOTE_LENGTH = 15; + const isLongNote = note.length > MAX_NOTE_LENGTH; + const displayNote = isLongNote ? `${note.slice(0, MAX_NOTE_LENGTH)}..` : note; + return ( - - - -

{statement.medication.display ?? statement.medication.code}

-
- -

{statement.medication.display ?? statement.medication.code}

-
-
-
- - - -

{statement.dosage_text}

-
- -

{statement.dosage_text}

-
-
+ + {statement.medication.display ?? statement.medication.code} + {statement.dosage_text} {statement.status} @@ -77,25 +80,45 @@ function MedicationRow({ .map((date) => formatDateTime(date)) .join(" - ")} - - - -

{statement.reason}

-
- -

{statement.reason}

-
-
+ {statement.reason} + + {note ? ( +
+ + {!isPrintPreview ? displayNote : note} + + {!isPrintPreview && isLongNote && ( + + + + + +

+ {note} +

+
+
+ )} +
+ ) : ( + "-" + )}
- - - -

{statement.note}

-
- -

{statement.note}

-
-
+ +
+ + {statement.created_by.username} +
); @@ -103,9 +126,11 @@ function MedicationRow({ export function MedicationStatementList({ patientId, + className, + isPrintPreview = false, }: MedicationStatementListProps) { const { t } = useTranslation(); - const [showEnteredInError, setShowEnteredInError] = useState(false); + const [showEnteredInError, setShowEnteredInError] = useState(isPrintPreview); const { data: medications, isLoading } = useQuery({ queryKey: ["medication_statements", patientId], @@ -116,11 +141,13 @@ export function MedicationStatementList({ if (isLoading) { return ( - - + + {t("ongoing_medications")} - + @@ -138,11 +165,15 @@ export function MedicationStatementList({ if (!filteredMedications?.length) { return ( - - + + {t("ongoing_medications")} - +

{t("no_ongoing_medications")}

@@ -150,52 +181,75 @@ export function MedicationStatementList({ } return ( - - + + {t("ongoing_medications")} ({filteredMedications.length}) - - + +
- - {t("medication")} - {t("dosage")} - {t("status")} - {t("medication_taken_between")} - {t("reason")} - {t("note")} + + + {t("medication")} + + + {t("dosage")} + + + {t("status")} + + + {t("medication_taken_between")} + + + {t("reason")} + + + {t("notes")} + + + {t("logged_by")} + - {filteredMedications.map((statement, index) => { - const isEnteredInError = statement.status === "entered_in_error"; - - return ( - <> - - - ); - })} + {[ + ...filteredMedications.filter( + (medication) => medication.status !== "entered_in_error", + ), + ...(showEnteredInError + ? filteredMedications.filter( + (medication) => medication.status === "entered_in_error", + ) + : []), + ].map((statement) => ( + + ))}
{hasEnteredInErrorRecords && !showEnteredInError && ( -
- -
+ <> +
+
+ +
+ )} diff --git a/src/components/Patient/TreatmentSummary.tsx b/src/components/Patient/TreatmentSummary.tsx new file mode 100644 index 00000000000..1e965ae41d3 --- /dev/null +++ b/src/components/Patient/TreatmentSummary.tsx @@ -0,0 +1,282 @@ +import careConfig from "@careConfig"; +import { useQuery } from "@tanstack/react-query"; +import { format } from "date-fns"; +import { t } from "i18next"; + +import PrintPreview from "@/CAREUI/misc/PrintPreview"; + +import QuestionnaireResponsesList from "@/components/Facility/ConsultationDetails/QuestionnaireResponsesList"; +import { MedicationsTable } from "@/components/Medicine/MedicationsTable"; +import { AllergyList } from "@/components/Patient/allergy/list"; +import { DiagnosisList } from "@/components/Patient/diagnosis/list"; +import { SymptomsList } from "@/components/Patient/symptoms/list"; + +import api from "@/Utils/request/api"; +import query from "@/Utils/request/query"; +import { formatPatientAge } from "@/Utils/utils"; +import { Encounter } from "@/types/emr/encounter"; +import medicationRequestApi from "@/types/emr/medicationRequest/medicationRequestApi"; + +import { MedicationStatementList } from "./MedicationStatementList"; + +interface TreatmentSummaryProps { + facilityId: string; + encounterId: string; +} + +export default function TreatmentSummary({ + facilityId, + encounterId, +}: TreatmentSummaryProps) { + const { data: encounter } = useQuery({ + queryKey: ["encounter", encounterId], + queryFn: query(api.encounter.get, { + pathParams: { id: encounterId }, + queryParams: { facility: facilityId }, + }), + }); + + const { data: medications } = useQuery({ + queryKey: ["medication_requests", encounter?.patient?.id], + queryFn: query(medicationRequestApi.list, { + pathParams: { patientId: encounter?.patient?.id || "" }, + queryParams: { encounter: encounterId, limit: 50, offset: 0 }, + }), + enabled: !!encounter?.patient?.id, + }); + + if (!encounter?.patient) { + return ( +
+ {t("no_patient_data_found")} +
+ ); + } + + return ( + +
+
+ {/* Header */} +
+
+
+

+ {encounter.facility?.name} +

+

+ {t("treatment_summary")} +

+
+
+ Care Logo +
+ + {/* Patient Details */} +
+
+ + + + {encounter.type?.text && ( + + )} + {encounter.department?.name && ( + + )} + {encounter.hospitalization && ( + <> + + {encounter.hospitalization.re_admission && ( + + )} + {encounter.hospitalization.discharge_disposition && ( + + )} + + )} +
+
+ + {encounter.period?.start && ( + + )} + + + {encounter.consulting_doctor && ( + + )} + {encounter.external_identifier && ( + + )} + {encounter.hospitalization?.diet_preference && ( + + )} +
+
+ + {/* Medical Information */} +
+ {/* Allergies */} + + + {/* Symptoms */} + + + {/* Diagnoses */} + + + {/* Medications */} +
+

+ {t("medications")} +

+ +
+
+ + {/* Medication Statements */} + + + {/* Questionnaire Responses Section */} +
+ +
+
+ + {/* Footer */} +
+

+ {t("generated_on")} {format(new Date(), "PPP 'at' p")} +

+
+
+
+ ); +} + +const DetailRow = ({ + label, + value, + isStrong = false, +}: { + label: string; + value?: string | null; + isStrong?: boolean; +}) => { + return ( +
+ {label} + : + + {value || "-"} + +
+ ); +}; diff --git a/src/components/Patient/allergy/list.tsx b/src/components/Patient/allergy/list.tsx index e7a5dacd03f..2351b8dfef2 100644 --- a/src/components/Patient/allergy/list.tsx +++ b/src/components/Patient/allergy/list.tsx @@ -9,6 +9,8 @@ import { import { Link } from "raviger"; import { ReactNode, useEffect, useState } from "react"; +import { cn } from "@/lib/utils"; + import CareIcon from "@/CAREUI/icons/CareIcon"; import { Badge } from "@/components/ui/badge"; @@ -44,6 +46,8 @@ interface AllergyListProps { facilityId?: string; patientId: string; encounterId?: string; + className?: string; + isPrintPreview?: boolean; } const CATEGORY_ICONS: Record = { @@ -57,8 +61,10 @@ export function AllergyList({ facilityId, patientId, encounterId, + className, + isPrintPreview = false, }: AllergyListProps) { - const [showEnteredInError, setShowEnteredInError] = useState(false); + const [showEnteredInError, setShowEnteredInError] = useState(isPrintPreview); const { data: allergies, isLoading } = useQuery({ queryKey: ["allergies", patientId, encounterId], @@ -169,8 +175,10 @@ export function AllergyList({ {note && (
- {displayNote} - {isLongNote && ( + + {!isPrintPreview ? displayNote : note} + + {!isPrintPreview && isLongNote && ( +
+
+ ))} +
+ + { + fileUpload.setFileName(e.target.value); + fileUpload.setError(null); + }} + className="ml-0.5 mb-1" + /> + {fileUpload.error && ( +

+ {fileUpload.error} +

+ )} +
+ + ) : ( + fileUpload.files.map((file, index) => ( +
+
+ + + + {file.name.length > 40 + ? `${file.name.substring(0, 30)}...` + : file.name} + + + +
+
+ + + { + fileUpload.setFileName(e.target.value, index); + fileUpload.setError(null); + }} + className="ml-0.5 mb-0.5" + /> + {!fileUpload.fileNames[index] && fileUpload.error && ( +

+ {fileUpload.error} +

+ )} +
+
+ )) + )} +
+ {fileUpload.files.length > 1 && ( +
+ setIsPdf(checked)} + disabled={fileUpload.uploading} + className="cursor-pointer" + /> + +
+ )} + +
+ + +
+ {!!fileUpload.progress && ( + + )} + + + ); +} diff --git a/src/components/Files/FilesTab.tsx b/src/components/Files/FilesTab.tsx index 0d11046948a..634831c61f1 100644 --- a/src/components/Files/FilesTab.tsx +++ b/src/components/Files/FilesTab.tsx @@ -1,28 +1,22 @@ import { useQuery } from "@tanstack/react-query"; import dayjs from "dayjs"; +import { t } from "i18next"; import { useEffect, useState } from "react"; -import { useTranslation } from "react-i18next"; + +import { cn } from "@/lib/utils"; import CareIcon, { IconName } from "@/CAREUI/icons/CareIcon"; import { Badge } from "@/components/ui/badge"; import { Button } from "@/components/ui/button"; -import { Checkbox } from "@/components/ui/checkbox"; -import { - Dialog, - DialogContent, - DialogHeader, - DialogTitle, -} from "@/components/ui/dialog"; +import { Card, CardContent } from "@/components/ui/card"; import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger, } from "@/components/ui/dropdown-menu"; -import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; -import { Progress } from "@/components/ui/progress"; import { Table, TableBody, @@ -39,35 +33,41 @@ import { TooltipTrigger, } from "@/components/ui/tooltip"; -import AudioPlayer from "@/components/Common/AudioPlayer"; import Loading from "@/components/Common/Loading"; +import ArchivedFileDialog from "@/components/Files/ArchivedFileDialog"; +import AudioPlayerDialog from "@/components/Files/AudioPlayerDialog"; +import FileUploadDialog from "@/components/Files/FileUploadDialog"; import { FileUploadModel } from "@/components/Patient/models"; import useFileManager from "@/hooks/useFileManager"; -import useFileUpload, { FileUploadReturn } from "@/hooks/useFileUpload"; +import useFileUpload from "@/hooks/useFileUpload"; import useFilters from "@/hooks/useFilters"; import { FILE_EXTENSIONS } from "@/common/constants"; import routes from "@/Utils/request/api"; import query from "@/Utils/request/query"; -import { classNames } from "@/Utils/utils"; import { usePermissions } from "@/context/PermissionContext"; +import { Encounter } from "@/types/emr/encounter"; +import { Patient } from "@/types/emr/newPatient"; export interface FilesTabProps { type: "encounter" | "patient"; facilityId: string; - encounterId?: string; patientId?: string; + encounter?: Encounter; + patient?: Patient; } export const FilesTab = (props: FilesTabProps) => { - const { encounterId, patientId, type } = props; + const { patientId, type, encounter } = props; const { qParams, updateQuery, Pagination, resultsPerPage } = useFilters({ limit: 14, }); - const { t } = useTranslation(); const [openUploadDialog, setOpenUploadDialog] = useState(false); + const [openArchivedFileDialog, setOpenArchivedFileDialog] = useState(false); + const [selectedArchivedFile, setSelectedArchivedFile] = + useState(null); const [selectedAudioFile, setSelectedAudioFile] = useState(null); const [openAudioPlayerDialog, setOpenAudioPlayerDialog] = useState(false); @@ -76,7 +76,7 @@ export const FilesTab = (props: FilesTabProps) => { const associatingId = { patient: patientId, - encounter: encounterId, + encounter: encounter?.id, }[type] || ""; const fileCategories = [ @@ -117,6 +117,7 @@ export const FilesTab = (props: FilesTabProps) => { onEdit: refetch, uploadedFiles: files?.results + .filter((file) => !file.is_archived) .slice() .reverse() .map((file) => ({ @@ -193,87 +194,128 @@ export const FilesTab = (props: FilesTabProps) => { DOCUMENT: "l-file-medical", }; - const getArchivedMessage = () => { + const getArchivedMessage = (file: FileUploadModel) => { return (
- + {t("archived")} +
); }; + const editPermission = () => { + if (type === "encounter") { + return ( + encounter && + ![ + "completed", + "cancelled", + "entered_in_error", + "discontinued", + ].includes(encounter.status) && + hasPermission("can_write_encounter") + ); + } else if (type === "patient") { + return hasPermission("can_write_patient"); + } + return false; + }; + const DetailButtons = ({ file }: { file: FileUploadModel }) => { const filetype = getFileType(file); return ( -
- {filetype === "AUDIO" && !file.is_archived && ( - - )} - {fileManager.isPreviewable(file) && ( - - )} - { - - - - - - - - - - - - {hasPermission( - type === "encounter" - ? "can_write_encounter" - : "can_write_patient", - ) && ( - - - - )} - - - } -
+ )} + {fileManager.isPreviewable(file) && ( + + )} + { + + + + + + + + + + + + + + + + + } +
+ )} + ); }; @@ -332,12 +374,7 @@ export const FilesTab = (props: FilesTabProps) => { }; const FileUploadButtons = (): JSX.Element => { - if ( - !hasPermission( - type === "encounter" ? "can_write_encounter" : "can_write_patient", - ) - ) - return <>; + if (!editPermission()) return <>; return ( @@ -362,38 +399,104 @@ export const FilesTab = (props: FilesTabProps) => { > {fileUpload.Input({ className: "hidden" })} - - + - - + ); }; - const RenderTable = () => { - return ( + const RenderCard = () => ( +
+ {files?.results && files?.results?.length > 0 ? ( + files.results.map((file) => { + const filetype = getFileType(file); + const fileName = file.name ? file.name + file.extension : ""; + + return ( + + +
+ + + +
+
+ {fileName} +
+
{filetype}
+
+
+ +
+
+
{t("date")}
+
+ {dayjs(file.created_date).format("DD MMM YYYY, hh:mm A")} +
+
+
+
{t("shared_by")}
+
+ {file.uploaded_by?.username} +
+
+
+ +
+ {file.is_archived ? ( + getArchivedMessage(file) + ) : ( + + )} +
+
+
+ ); + }) + ) : ( +
+ {t("no_files_found")} +
+ )} +
+ ); + + const RenderTable = () => ( +
@@ -421,12 +524,10 @@ export const FilesTab = (props: FilesTabProps) => { return ( { { {filetype} { {dayjs(file.created_date).format("DD MMM YYYY, hh:mm A")} { {file.uploaded_by?.username} {file.is_archived ? ( - getArchivedMessage() + getArchivedMessage(file) ) : ( )} @@ -503,8 +604,8 @@ export const FilesTab = (props: FilesTabProps) => { )}
- ); - }; +
+ ); return (
@@ -524,6 +625,11 @@ export const FilesTab = (props: FilesTabProps) => { associatingId={associatingId} />
+ { >
- {/* - {fileCategories.map((category) => ( - - {category.label} - - ))} - */}
@@ -558,6 +653,7 @@ export const FilesTab = (props: FilesTabProps) => { {fileCategories.map((category) => ( + ))} @@ -565,237 +661,3 @@ export const FilesTab = (props: FilesTabProps) => {
); }; - -const FileUploadDialog = ({ - open, - onOpenChange, - fileUpload, - associatingId, -}: { - open: boolean; - onOpenChange: (open: boolean) => void; - fileUpload: FileUploadReturn; - associatingId: string; -}) => { - const handleDialogClose = (open: boolean) => { - if (!open) { - setIsPdf(false); - } - onOpenChange(open); - }; - const { t } = useTranslation(); - const [isPdf, setIsPdf] = useState(false); - return ( - - - - - {fileUpload.files.length > 1 ? t("upload_files") : t("upload_file")} - - -
- {isPdf ? ( - <> - {fileUpload.files.map((file, index) => ( -
-
- - - - {file.name.length > 40 - ? `${file.name.substring(0, 30)}...` - : file.name} - - - -
-
- ))} -
- - { - fileUpload.setFileName(e.target.value); - fileUpload.setError(null); - }} - className="ml-0.5 mb-1" - /> - {fileUpload.error && ( -

- {fileUpload.error} -

- )} -
- - ) : ( - fileUpload.files.map((file, index) => ( -
-
- - - - {file.name.length > 40 - ? `${file.name.substring(0, 30)}...` - : file.name} - - - -
-
- - - { - fileUpload.setFileName(e.target.value, index); - fileUpload.setError(null); - }} - className="ml-0.5 mb-0.5" - /> - {!fileUpload.fileNames[index] && fileUpload.error && ( -

- {fileUpload.error} -

- )} -
-
- )) - )} -
- {fileUpload.files.length > 1 && ( -
- setIsPdf(checked)} - disabled={fileUpload.uploading} - className="cursor-pointer" - /> - -
- )} - -
- - -
- {!!fileUpload.progress && ( - - )} -
-
- ); -}; - -const AudioPlayerDialog = ({ - open, - onOpenChange, - file, - type, - associatingId, -}: { - open: boolean; - onOpenChange: (open: boolean) => void; - file: FileUploadModel | null; - type: "encounter" | "patient"; - associatingId: string; -}) => { - const { t } = useTranslation(); - const { data: fileData } = useQuery({ - queryKey: [routes.retrieveUpload, type, file?.id], - queryFn: query(routes.retrieveUpload, { - queryParams: { file_type: type, associating_id: associatingId }, - pathParams: { id: file?.id || "" }, - }), - enabled: !!file?.id, - }); - const { Player, stopPlayback } = AudioPlayer({ - src: fileData?.read_signed_url || "", - }); - return ( - { - stopPlayback(); - onOpenChange(false); - }} - aria-labelledby="audio-player-dialog" - > - - - {t("play_audio")} - - - - - ); -}; diff --git a/src/components/Patient/PatientDetailsTab/PatientFiles.tsx b/src/components/Patient/PatientDetailsTab/PatientFiles.tsx index 7f65fd8c00c..df9789b35d7 100644 --- a/src/components/Patient/PatientDetailsTab/PatientFiles.tsx +++ b/src/components/Patient/PatientDetailsTab/PatientFiles.tsx @@ -8,6 +8,7 @@ export const PatientFilesTab = (props: PatientProps) => { type="patient" facilityId={props.facilityId} patientId={props.patientData.id} + patient={props.patientData} /> ); }; diff --git a/src/pages/Encounters/tabs/EncounterFilesTab.tsx b/src/pages/Encounters/tabs/EncounterFilesTab.tsx index ff270ac9d60..25c707ade44 100644 --- a/src/pages/Encounters/tabs/EncounterFilesTab.tsx +++ b/src/pages/Encounters/tabs/EncounterFilesTab.tsx @@ -7,7 +7,7 @@ export const EncounterFilesTab = (props: EncounterTabProps) => { ); }; From 3cf5a5cc04af59411941db51e85974019a3ab2c9 Mon Sep 17 00:00:00 2001 From: Rithvik Nishad Date: Mon, 10 Feb 2025 13:29:47 +0000 Subject: [PATCH 42/97] Remove unnecessary console log in AllergyList component (#10542) --- src/components/Patient/allergy/list.tsx | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/src/components/Patient/allergy/list.tsx b/src/components/Patient/allergy/list.tsx index c3f5854be99..ddbcaaab127 100644 --- a/src/components/Patient/allergy/list.tsx +++ b/src/components/Patient/allergy/list.tsx @@ -7,7 +7,7 @@ import { LeafIcon, } from "lucide-react"; import { Link } from "raviger"; -import { ReactNode, useEffect, useState } from "react"; +import { ReactNode, useState } from "react"; import CareIcon from "@/CAREUI/icons/CareIcon"; @@ -132,16 +132,6 @@ export function AllergyList({ ? `${note.slice(0, MAX_NOTE_LENGTH)}..` : note; - useEffect(() => { - console.log( - "Allergy Note:", - allergy.note, - isLongNote, - displayNote, - note.length, - ); - }, [allergy.note, isLongNote, displayNote, note.length]); - return ( Date: Mon, 10 Feb 2025 20:57:49 +0530 Subject: [PATCH 43/97] Add missing i18n translations (#10463) --- public/locale/en.json | 14 ++++++- .../QuestionnaireResponsesList.tsx | 38 +++++++++++++------ .../QuestionTypes/DiagnosisQuestion.tsx | 16 +++++++- .../Resource/PrintResourceLetter.tsx | 2 +- src/pages/Facility/overview.tsx | 2 +- 5 files changed, 55 insertions(+), 17 deletions(-) diff --git a/public/locale/en.json b/public/locale/en.json index 53f8276d897..5fa543e8809 100644 --- a/public/locale/en.json +++ b/public/locale/en.json @@ -414,6 +414,7 @@ "assigned_facility": "Facility assigned", "assigned_to": "Assigned to", "assigned_volunteer": "Assigned Volunteer", + "at_time": "at {{time}}", "atypical_presentation_details": "Atypical presentation details", "audio__allow_permission": "Please allow microphone permission in site settings", "audio__allow_permission_button": "Click here to know how to allow", @@ -482,7 +483,7 @@ "booked_by": "Booked by", "bradycardia": "Bradycardia", "breathlessness_level": "Breathlessness level", - "by": "By", + "by_name": "by {{by}}", "camera": "Camera", "camera_bed_link_success": "Camera linked to bed successfully.", "camera_permission_denied": "Camera Permission denied", @@ -716,6 +717,8 @@ "diagnosis_already_added": "This diagnosis was already added", "diagnosis_at_discharge": "Diagnosis at Discharge", "diagnosis_empty_message": "No diagnoses recorded", + "diagnosis_status_placeholder": "Select diagnosis status", + "diagnosis_verification_placeholder": "Select verification status", "diastolic": "Diastolic", "didnt_receive_a_message": "Didn't receive a message?", "diet_preference": "Diet Preference", @@ -917,6 +920,7 @@ "encounter_suggestion__R": "Consultation", "encounter_suggestion_edit_disallowed": "Not allowed to switch to this option in edit consultation", "encounters": "Encounters", + "end_date": "End date", "end_datetime": "End Date/Time", "end_dose": "End Dose", "end_time": "End Time", @@ -951,6 +955,7 @@ "error_fetching_slots_data": "Error while fetching slots data", "error_fetching_user_data": "Error while fetching user data", "error_fetching_user_details": "Error while fetching user details: ", + "error_fetching_users_data": "Failed to load user data. Please try again later.", "error_loading_questionnaire_response": "Error loading questionnaire response", "error_updating_encounter": "Error to Updating Encounter", "error_verifying_otp": "Error while verifying OTP, Please request a new OTP", @@ -972,6 +977,7 @@ "export": "Export", "export_live_patients": "Export Live Patients", "exporting": "Exporting", + "external_id": "External ID", "external_identifier": "External Identifier", "facilities": "Facilities", "facility": "Facility", @@ -1033,6 +1039,7 @@ "file_upload_error": "Error uploading file", "file_upload_success": "File uploaded successfully", "file_uploaded": "File Uploaded Successfully", + "filed": "filed {{title}}", "files": "Files", "fill_my_details": "Fill My Details", "filter": "Filter", @@ -1291,6 +1298,7 @@ "medical_worker": "Medical Worker", "medication": "Medication", "medication_administration_saved": "Medicine Administration saved", + "medication_already_marked_as_error": "Medication already marked as entered in error", "medication_taken_between": "Medication Taken Between", "medicine": "Medicine", "medicine_administration": "Medicine Administration", @@ -1383,6 +1391,7 @@ "no_investigation": "No investigation Reports found", "no_investigation_suggestions": "No Investigation Suggestions", "no_linked_facilities": "No Linked Facilities", + "no_locations_available": "No locations available", "no_locations_found": "No locations found", "no_log_update_delta": "No changes since previous log update", "no_log_updates": "No log updates found", @@ -1441,6 +1450,7 @@ "not_eligible": "Not Eligible", "not_found": "Not Found", "not_specified": "Not Specified", + "not_started": "Not started", "not_taken": "Not Taken", "note": "Note", "notes": "Notes", @@ -1472,6 +1482,7 @@ "on_emergency_basis": " on emergency basis", "on_hold": "On Hold", "ongoing_medications": "Ongoing Medications", + "online": "Online", "only_indian_mobile_numbers_supported": "Currently only Indian numbers are supported", "onset": "Onset", "op_encounter": "OP Encounter", @@ -1488,6 +1499,7 @@ "organization_for_care_support": "Organization for Care Support", "organization_forbidden": "You don't have access to any organizations yet.", "organization_not_found": "No Organizations Found", + "organization_required": "Organization is required", "organizations": "Organizations", "organizations_fetch_error": "Error while fetching organizations", "origin_facility": "Current facility", diff --git a/src/components/Facility/ConsultationDetails/QuestionnaireResponsesList.tsx b/src/components/Facility/ConsultationDetails/QuestionnaireResponsesList.tsx index ea8ccfed412..47e040710e2 100644 --- a/src/components/Facility/ConsultationDetails/QuestionnaireResponsesList.tsx +++ b/src/components/Facility/ConsultationDetails/QuestionnaireResponsesList.tsx @@ -1,7 +1,7 @@ import { useQuery } from "@tanstack/react-query"; import { t } from "i18next"; import { useQueryParams } from "raviger"; -import { useTranslation } from "react-i18next"; +import { Trans, useTranslation } from "react-i18next"; import { cn } from "@/lib/utils"; @@ -214,19 +214,33 @@ function ResponseCard({ item }: { item: QuestionnaireResponse }) { } /> ) : ( -

- {item.questionnaire?.title} {t("filed")} -

+ }} + /> )}
- {t("at")} - {formatDateTime(item.created_date)} - {t("by")} -
- {item.created_by?.first_name || ""}{" "} - {item.created_by?.last_name || ""} - {item.created_by?.user_type && ` (${item.created_by?.user_type})`} -
+ + }} + /> + + + }} + /> +
diff --git a/src/components/Questionnaire/QuestionTypes/DiagnosisQuestion.tsx b/src/components/Questionnaire/QuestionTypes/DiagnosisQuestion.tsx index f40485d97c0..00379ae671a 100644 --- a/src/components/Questionnaire/QuestionTypes/DiagnosisQuestion.tsx +++ b/src/components/Questionnaire/QuestionTypes/DiagnosisQuestion.tsx @@ -309,7 +309,13 @@ const DiagnosisItem: React.FC = ({ disabled={disabled} > - + + {t("diagnosis_status_placeholder")} + + } + /> {DIAGNOSIS_CLINICAL_STATUS.map((status) => ( @@ -339,7 +345,13 @@ const DiagnosisItem: React.FC = ({ disabled={disabled} > - + + {t("diagnosis_verification_placeholder")} + + } + /> {DIAGNOSIS_VERIFICATION_STATUS.map((status) => ( diff --git a/src/components/Resource/PrintResourceLetter.tsx b/src/components/Resource/PrintResourceLetter.tsx index bc1a80f72a8..5fd6f82e209 100644 --- a/src/components/Resource/PrintResourceLetter.tsx +++ b/src/components/Resource/PrintResourceLetter.tsx @@ -45,7 +45,7 @@ export default function PrintResourceLetter({ id }: { id: string }) { {/* From Address */}
-
{t("From")}:
+
{t("from")}:
{data.origin_facility.name}
diff --git a/src/pages/Facility/overview.tsx b/src/pages/Facility/overview.tsx index 346a34c6c48..cf07db69e65 100644 --- a/src/pages/Facility/overview.tsx +++ b/src/pages/Facility/overview.tsx @@ -27,7 +27,7 @@ export function FacilityOverview({ facilityId }: FacilityOverviewProps) { href: `/facility/${facilityId}/users/${user?.username}/availability`, }, { - title: t("Encounters"), + title: t("encounters"), description: t("manage_facility_users"), icon: Users, href: `/facility/${facilityId}/encounters`, From 5a73bf29a8c119e7d211954ff496655183c9d246 Mon Sep 17 00:00:00 2001 From: Vysakh Premkumar <84713473+tellmeY18@users.noreply.github.com> Date: Tue, 11 Feb 2025 11:29:53 +0530 Subject: [PATCH 44/97] Added Scripts to Generate headers for CF Pages (#10535) --- .env | 1 + .gitignore | 1 + package.json | 4 ++-- scripts/generate-headers.ts | 27 +++++++++++++++++++++++++++ 4 files changed, 31 insertions(+), 2 deletions(-) create mode 100644 scripts/generate-headers.ts diff --git a/.env b/.env index 2c8b73fb65a..2e32ac97bbf 100644 --- a/.env +++ b/.env @@ -5,6 +5,7 @@ REACT_APP_META_DESCRIPTION="Revolutionizing EMR with AI: Open Healthcare Network REACT_APP_COVER_IMAGE=https://cdn.ohc.network/care_logo.svg REACT_APP_COVER_IMAGE_ALT=https://cdn.ohc.network/care_logo.svg REACT_PUBLIC_URL=https://care.ohc.network +HEADERS="/*\n Strict-Transport-Security: max-age=63072000; includeSubDomains; preload\n X-XSS-Protection: 1; mode=block\n X-Frame-Options: SAMEORIGIN\n X-Content-Type-Options: nosniff\n Referrer-Policy: strict-origin-when-cross-origin\n Permissions-Policy: geolocation=(self), microphone=()" # Care API URL without the /api prefix REACT_CARE_API_URL=https://careapi.ohc.network diff --git a/.gitignore b/.gitignore index 17e2f8f71d7..fb30d613042 100644 --- a/.gitignore +++ b/.gitignore @@ -67,3 +67,4 @@ src/pluginMap.ts # Federation Temp files /.__mf__temp public/sbom/* +public/_headers diff --git a/package.json b/package.json index a84562ddae6..8edf10ae562 100644 --- a/package.json +++ b/package.json @@ -35,7 +35,7 @@ "supported-browsers": "node ./scripts/generate-supported-browsers.mjs", "build": "npm run setup && npm run build:meta && npm run supported-browsers && npm run build:react", "setup": "tsx scripts/setup-care-apps.ts", - "postinstall": "tsx scripts/install-platform-deps.ts && tsx scripts/generate-sbom-data.ts", + "postinstall": "tsx scripts/install-platform-deps.ts && tsx scripts/generate-sbom-data.ts && tsx scripts/generate-headers.ts", "test": "snyk test", "cypress:open": "cross-env NODE_ENV=development cypress open", "cypress:run": "cross-env NODE_ENV=development cypress run", @@ -210,4 +210,4 @@ "node": ">=22.8.0" }, "packageManager": "npm@10.9.2" -} \ No newline at end of file +} diff --git a/scripts/generate-headers.ts b/scripts/generate-headers.ts new file mode 100644 index 00000000000..5dbc803370c --- /dev/null +++ b/scripts/generate-headers.ts @@ -0,0 +1,27 @@ +import { writeFile } from "fs/promises"; +import path from "path"; + +const headers = process.env.HEADERS; +const header_folder = path.join(__dirname, "..", "public"); + +async function writeHeaders() { + if (!headers) { + console.warn("HEADERS environment variable is not set."); + process.exit(0); + } + + console.log("HEADERS environment variable is set."); + const headersPath = path.join(header_folder, "_headers"); + console.log(`Writing headers to file at path: ${headersPath}`); + + try { + await writeFile(headersPath, headers, "utf-8"); + console.log("Headers written to file successfully."); + process.exit(0); + } catch (error) { + console.error("Error writing headers to file:", error); + process.exit(0); + } +} + +writeHeaders(); From ba9f30bedbdd5cf08ef5b78bc1004a148994b955 Mon Sep 17 00:00:00 2001 From: Amjith Titus Date: Tue, 11 Feb 2025 12:51:01 +0530 Subject: [PATCH 45/97] Fix loading --- src/components/Medicine/MedicationsTable.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/components/Medicine/MedicationsTable.tsx b/src/components/Medicine/MedicationsTable.tsx index 26d1431697d..1fee30a06fe 100644 --- a/src/components/Medicine/MedicationsTable.tsx +++ b/src/components/Medicine/MedicationsTable.tsx @@ -1,6 +1,7 @@ import { useQuery } from "@tanstack/react-query"; import { useTranslation } from "react-i18next"; +import { Skeleton } from "@/components/ui/skeleton"; import { Table, TableBody, @@ -55,7 +56,7 @@ export const MedicationsTable = ({ if (isLoading) { return (
- {t("no_medications_found_for_this_encounter")} +
); } From 01825f2685a14f5196496f787c987f8d3abc83ef Mon Sep 17 00:00:00 2001 From: Amjith Titus Date: Tue, 11 Feb 2025 13:12:58 +0530 Subject: [PATCH 46/97] Update src/components/Patient/TreatmentSummary.tsx Co-authored-by: Rithvik Nishad --- src/components/Patient/TreatmentSummary.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/Patient/TreatmentSummary.tsx b/src/components/Patient/TreatmentSummary.tsx index c566ce398dc..8a3c6d9c83c 100644 --- a/src/components/Patient/TreatmentSummary.tsx +++ b/src/components/Patient/TreatmentSummary.tsx @@ -27,7 +27,7 @@ export default function TreatmentSummary({ facilityId, encounterId, }: TreatmentSummaryProps) { - const { data: encounter } = useQuery({ + const { data: encounter } = useQuery({ queryKey: ["encounter", encounterId], queryFn: query(api.encounter.get, { pathParams: { id: encounterId }, From 9f223f8b3c8b2294c20a0bceefc07e741f977cb2 Mon Sep 17 00:00:00 2001 From: Shivank Kacker Date: Tue, 11 Feb 2025 13:20:58 +0530 Subject: [PATCH 47/97] Added confirmation before marking encounter as complete (#10523) --- public/locale/en.json | 1 + src/components/Patient/PatientInfoCard.tsx | 75 ++++++++++++++++------ 2 files changed, 57 insertions(+), 19 deletions(-) diff --git a/public/locale/en.json b/public/locale/en.json index 5fa543e8809..a962bbde003 100644 --- a/public/locale/en.json +++ b/public/locale/en.json @@ -1281,6 +1281,7 @@ "mark_as_noshow": "Mark as no-show", "mark_as_read": "Mark as Read", "mark_as_unread": "Mark as Unread", + "mark_encounter_as_complete_confirmation": "Are you sure you would like to mark this encounter as complete?", "mark_inactive": "Mark Inactive", "mark_resolved": "Mark Resolved", "mark_this_transfer_as_complete_question": "Are you sure you want to mark this transfer as complete? The Origin facility will no longer have access to this patient", diff --git a/src/components/Patient/PatientInfoCard.tsx b/src/components/Patient/PatientInfoCard.tsx index 499072e6669..ed4877359a5 100644 --- a/src/components/Patient/PatientInfoCard.tsx +++ b/src/components/Patient/PatientInfoCard.tsx @@ -12,10 +12,23 @@ import { Link } from "raviger"; import { useTranslation } from "react-i18next"; import { toast } from "sonner"; +import { cn } from "@/lib/utils"; + import CareIcon from "@/CAREUI/icons/CareIcon"; +import { + AlertDialog, + AlertDialogAction, + AlertDialogCancel, + AlertDialogContent, + AlertDialogDescription, + AlertDialogFooter, + AlertDialogHeader, + AlertDialogTitle, + AlertDialogTrigger, +} from "@/components/ui/alert-dialog"; import { Badge } from "@/components/ui/badge"; -import { Button } from "@/components/ui/button"; +import { Button, buttonVariants } from "@/components/ui/button"; import { DropdownMenu, DropdownMenuContent, @@ -364,24 +377,48 @@ export default function PatientInfoCard(props: PatientInfoCardProps) { className="flex w-full flex-col gap-3 lg:w-auto 2xl:flex-row" data-cy="update-encounter-button" > - - - - - - {t("actions")} - - {t("mark_as_complete")} - - - - + + + + + + + {t("actions")} + + e.preventDefault()}> + {t("mark_as_complete")} + + + + + + + + {t("mark_as_complete")} + + {t("mark_encounter_as_complete_confirmation")} + + + + + {t("cancel")} + + + {t("mark_as_complete")} + + + + )} From 23deb69dede0d4bef30dccdca44470f62c871f63 Mon Sep 17 00:00:00 2001 From: Rithvik Nishad Date: Tue, 11 Feb 2025 10:56:39 +0000 Subject: [PATCH 48/97] Fixes token not refreshing in background (#10556) --- src/Providers/AuthUserProvider.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Providers/AuthUserProvider.tsx b/src/Providers/AuthUserProvider.tsx index 2a24aea06c7..4349ff5c1ee 100644 --- a/src/Providers/AuthUserProvider.tsx +++ b/src/Providers/AuthUserProvider.tsx @@ -49,6 +49,7 @@ export default function AuthUserProvider({ queryFn: query(routes.token_refresh, { body: { refresh: refreshToken || "" }, }), + refetchIntervalInBackground: true, refetchInterval: careConfig.auth.tokenRefreshInterval, enabled: !!refreshToken && !!user, }); From b379faee82f4367bfb5dc0d1266138806c4a84c3 Mon Sep 17 00:00:00 2001 From: Rithvik Nishad Date: Tue, 11 Feb 2025 10:57:27 +0000 Subject: [PATCH 49/97] Rename schedule api file to be consistent with other api file namings (#10552) --- src/components/Patient/PatientDetailsTab/Appointments.tsx | 2 +- .../Questionnaire/QuestionTypes/AppointmentQuestion.tsx | 2 +- src/components/Users/UserAvailabilityTab.tsx | 2 +- src/pages/Appointments/AppointmentDetail.tsx | 2 +- src/pages/Appointments/AppointmentsPage.tsx | 2 +- src/pages/Appointments/BookAppointment.tsx | 2 +- src/pages/Appointments/components/AppointmentSlotPicker.tsx | 2 +- src/pages/Appointments/utils.ts | 2 +- src/pages/Scheduling/ScheduleExceptions.tsx | 2 +- .../Scheduling/components/CreateScheduleExceptionSheet.tsx | 2 +- src/pages/Scheduling/components/CreateScheduleTemplateSheet.tsx | 2 +- src/pages/Scheduling/components/EditScheduleTemplateSheet.tsx | 2 +- src/types/scheduling/{scheduleApis.ts => scheduleApi.ts} | 0 13 files changed, 12 insertions(+), 12 deletions(-) rename src/types/scheduling/{scheduleApis.ts => scheduleApi.ts} (100%) diff --git a/src/components/Patient/PatientDetailsTab/Appointments.tsx b/src/components/Patient/PatientDetailsTab/Appointments.tsx index 603b5aead0a..d0ec294fb48 100644 --- a/src/components/Patient/PatientDetailsTab/Appointments.tsx +++ b/src/components/Patient/PatientDetailsTab/Appointments.tsx @@ -20,7 +20,7 @@ import { PatientProps } from "@/components/Patient/PatientDetailsTab"; import query from "@/Utils/request/query"; import { formatDateTime, formatName } from "@/Utils/utils"; -import scheduleApis from "@/types/scheduling/scheduleApis"; +import scheduleApis from "@/types/scheduling/scheduleApi"; export const Appointments = (props: PatientProps) => { const { patientData, facilityId, patientId } = props; diff --git a/src/components/Questionnaire/QuestionTypes/AppointmentQuestion.tsx b/src/components/Questionnaire/QuestionTypes/AppointmentQuestion.tsx index dec289eedf4..4ec261ca4a4 100644 --- a/src/components/Questionnaire/QuestionTypes/AppointmentQuestion.tsx +++ b/src/components/Questionnaire/QuestionTypes/AppointmentQuestion.tsx @@ -27,7 +27,7 @@ import { } from "@/types/questionnaire/form"; import { Question } from "@/types/questionnaire/question"; import { CreateAppointmentQuestion } from "@/types/scheduling/schedule"; -import scheduleApis from "@/types/scheduling/scheduleApis"; +import scheduleApis from "@/types/scheduling/scheduleApi"; import { UserBase } from "@/types/user/user"; interface FollowUpVisitQuestionProps { diff --git a/src/components/Users/UserAvailabilityTab.tsx b/src/components/Users/UserAvailabilityTab.tsx index 5ed92fd25e8..07840422d00 100644 --- a/src/components/Users/UserAvailabilityTab.tsx +++ b/src/components/Users/UserAvailabilityTab.tsx @@ -46,7 +46,7 @@ import { ScheduleException, ScheduleTemplate, } from "@/types/scheduling/schedule"; -import scheduleApis from "@/types/scheduling/scheduleApis"; +import scheduleApis from "@/types/scheduling/scheduleApi"; import { UserBase } from "@/types/user/user"; type Props = { diff --git a/src/pages/Appointments/AppointmentDetail.tsx b/src/pages/Appointments/AppointmentDetail.tsx index c29454bfaf0..5c0624c1c2e 100644 --- a/src/pages/Appointments/AppointmentDetail.tsx +++ b/src/pages/Appointments/AppointmentDetail.tsx @@ -64,7 +64,7 @@ import { AppointmentFinalStatuses, AppointmentUpdateRequest, } from "@/types/scheduling/schedule"; -import scheduleApis from "@/types/scheduling/scheduleApis"; +import scheduleApis from "@/types/scheduling/scheduleApi"; import { AppointmentSlotPicker } from "./components/AppointmentSlotPicker"; diff --git a/src/pages/Appointments/AppointmentsPage.tsx b/src/pages/Appointments/AppointmentsPage.tsx index 27102edcc59..ae230097c06 100644 --- a/src/pages/Appointments/AppointmentsPage.tsx +++ b/src/pages/Appointments/AppointmentsPage.tsx @@ -82,7 +82,7 @@ import { AppointmentStatuses, TokenSlot, } from "@/types/scheduling/schedule"; -import scheduleApis from "@/types/scheduling/scheduleApis"; +import scheduleApis from "@/types/scheduling/scheduleApi"; interface QueryParams { practitioner: string | null; diff --git a/src/pages/Appointments/BookAppointment.tsx b/src/pages/Appointments/BookAppointment.tsx index 5a670f81e16..fb61ed487f4 100644 --- a/src/pages/Appointments/BookAppointment.tsx +++ b/src/pages/Appointments/BookAppointment.tsx @@ -25,7 +25,7 @@ import useAppHistory from "@/hooks/useAppHistory"; import mutate from "@/Utils/request/mutate"; import query from "@/Utils/request/query"; import { formatDisplayName, formatName } from "@/Utils/utils"; -import scheduleApis from "@/types/scheduling/scheduleApis"; +import scheduleApis from "@/types/scheduling/scheduleApi"; import { AppointmentSlotPicker } from "./components/AppointmentSlotPicker"; diff --git a/src/pages/Appointments/components/AppointmentSlotPicker.tsx b/src/pages/Appointments/components/AppointmentSlotPicker.tsx index 1830c9b423f..0220b47678a 100644 --- a/src/pages/Appointments/components/AppointmentSlotPicker.tsx +++ b/src/pages/Appointments/components/AppointmentSlotPicker.tsx @@ -18,7 +18,7 @@ import { useAvailabilityHeatmap, } from "@/pages/Appointments/utils"; import { TokenSlot } from "@/types/scheduling/schedule"; -import scheduleApis from "@/types/scheduling/scheduleApis"; +import scheduleApis from "@/types/scheduling/scheduleApi"; interface AppointmentSlotPickerProps { facilityId: string; diff --git a/src/pages/Appointments/utils.ts b/src/pages/Appointments/utils.ts index 50ab30c5b6f..2144524f130 100644 --- a/src/pages/Appointments/utils.ts +++ b/src/pages/Appointments/utils.ts @@ -15,7 +15,7 @@ import { AvailabilityHeatmapResponse, TokenSlot, } from "@/types/scheduling/schedule"; -import scheduleApis from "@/types/scheduling/scheduleApis"; +import scheduleApis from "@/types/scheduling/scheduleApi"; export const groupSlotsByAvailability = (slots: TokenSlot[]) => { const result: { diff --git a/src/pages/Scheduling/ScheduleExceptions.tsx b/src/pages/Scheduling/ScheduleExceptions.tsx index 7480c49a323..96e97fa177e 100644 --- a/src/pages/Scheduling/ScheduleExceptions.tsx +++ b/src/pages/Scheduling/ScheduleExceptions.tsx @@ -15,7 +15,7 @@ import Loading from "@/components/Common/Loading"; import mutate from "@/Utils/request/mutate"; import { formatTimeShort } from "@/Utils/utils"; import { ScheduleException } from "@/types/scheduling/schedule"; -import scheduleApis from "@/types/scheduling/scheduleApis"; +import scheduleApis from "@/types/scheduling/scheduleApi"; interface Props { items?: ScheduleException[]; diff --git a/src/pages/Scheduling/components/CreateScheduleExceptionSheet.tsx b/src/pages/Scheduling/components/CreateScheduleExceptionSheet.tsx index 1d050aea3cd..22883d6f75b 100644 --- a/src/pages/Scheduling/components/CreateScheduleExceptionSheet.tsx +++ b/src/pages/Scheduling/components/CreateScheduleExceptionSheet.tsx @@ -34,7 +34,7 @@ import { import mutate from "@/Utils/request/mutate"; import { Time } from "@/Utils/types"; import { dateQueryString } from "@/Utils/utils"; -import scheduleApis from "@/types/scheduling/scheduleApis"; +import scheduleApis from "@/types/scheduling/scheduleApi"; interface Props { facilityId: string; diff --git a/src/pages/Scheduling/components/CreateScheduleTemplateSheet.tsx b/src/pages/Scheduling/components/CreateScheduleTemplateSheet.tsx index d4081a965fe..daee952132e 100644 --- a/src/pages/Scheduling/components/CreateScheduleTemplateSheet.tsx +++ b/src/pages/Scheduling/components/CreateScheduleTemplateSheet.tsx @@ -44,7 +44,7 @@ import { Time } from "@/Utils/types"; import { dateQueryString } from "@/Utils/utils"; import { getSlotsPerSession, getTokenDuration } from "@/pages/Scheduling/utils"; import { ScheduleAvailabilityCreateRequest } from "@/types/scheduling/schedule"; -import scheduleApis from "@/types/scheduling/scheduleApis"; +import scheduleApis from "@/types/scheduling/scheduleApi"; interface Props { facilityId: string; diff --git a/src/pages/Scheduling/components/EditScheduleTemplateSheet.tsx b/src/pages/Scheduling/components/EditScheduleTemplateSheet.tsx index 5cdd6790bcb..16d62abc1dc 100644 --- a/src/pages/Scheduling/components/EditScheduleTemplateSheet.tsx +++ b/src/pages/Scheduling/components/EditScheduleTemplateSheet.tsx @@ -47,7 +47,7 @@ import { ScheduleAvailabilityCreateRequest, ScheduleTemplate, } from "@/types/scheduling/schedule"; -import scheduleApis from "@/types/scheduling/scheduleApis"; +import scheduleApis from "@/types/scheduling/scheduleApi"; export default function EditScheduleTemplateSheet({ template, diff --git a/src/types/scheduling/scheduleApis.ts b/src/types/scheduling/scheduleApi.ts similarity index 100% rename from src/types/scheduling/scheduleApis.ts rename to src/types/scheduling/scheduleApi.ts From 6044c4608c6fd97b8034d67e41374074d7e6b680 Mon Sep 17 00:00:00 2001 From: Bodhish Thomas Date: Tue, 11 Feb 2025 17:13:03 +0530 Subject: [PATCH 50/97] Clean up unused encounter import --- src/components/Patient/TreatmentSummary.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/components/Patient/TreatmentSummary.tsx b/src/components/Patient/TreatmentSummary.tsx index 8a3c6d9c83c..ad87eee91a6 100644 --- a/src/components/Patient/TreatmentSummary.tsx +++ b/src/components/Patient/TreatmentSummary.tsx @@ -14,7 +14,6 @@ import { SymptomsList } from "@/components/Patient/symptoms/list"; import api from "@/Utils/request/api"; import query from "@/Utils/request/query"; import { formatName, formatPatientAge } from "@/Utils/utils"; -import { Encounter } from "@/types/emr/encounter"; import { MedicationStatementList } from "./MedicationStatementList"; From 7f8f65a47b00d90e9ba09055d84ed0cb065dcbb2 Mon Sep 17 00:00:00 2001 From: Rithvik Nishad Date: Tue, 11 Feb 2025 12:19:28 +0000 Subject: [PATCH 51/97] skip unimported check in pre-commit (#10557) --- package.json | 1 - 1 file changed, 1 deletion(-) diff --git a/package.json b/package.json index 8edf10ae562..fde4e593d50 100644 --- a/package.json +++ b/package.json @@ -199,7 +199,6 @@ "*.{ts,tsx,js,jsx}": [ "prettier --write --ignore-unknown --plugin prettier-plugin-tailwindcss --plugin @trivago/prettier-plugin-sort-imports", "eslint --fix", - "unimported", "git update-index --again" ], "public/locale/*.json": [ From af4e4c17f726ccaef2527e27a12c08e4b94b799d Mon Sep 17 00:00:00 2001 From: Amjith Titus Date: Tue, 11 Feb 2025 18:10:22 +0530 Subject: [PATCH 52/97] Location Popover & History Sheet (#10540) Co-authored-by: Rithvik Nishad --- .../pageObject/Patients/PatientEncounter.ts | 8 +- public/locale/en.json | 5 + .../Location/LocationHistorySheet.tsx | 49 ++++++ src/components/Location/LocationTree.tsx | 105 ++++++++++++ src/components/Patient/PatientInfoCard.tsx | 159 +++++++++++++----- src/pages/Encounters/EncounterShow.tsx | 8 - src/types/emr/encounter.ts | 7 + src/types/location/location.ts | 1 + 8 files changed, 284 insertions(+), 58 deletions(-) create mode 100644 src/components/Location/LocationHistorySheet.tsx create mode 100644 src/components/Location/LocationTree.tsx diff --git a/cypress/pageObject/Patients/PatientEncounter.ts b/cypress/pageObject/Patients/PatientEncounter.ts index 95e3b8c1fe0..1ed9dab31cf 100644 --- a/cypress/pageObject/Patients/PatientEncounter.ts +++ b/cypress/pageObject/Patients/PatientEncounter.ts @@ -76,10 +76,10 @@ export class PatientEncounter { } clickPatientDetailsButton() { - cy.verifyAndClickElement( - '[data-cy="patient-details-button"]', - "Patient Details", - ); + cy.get('[data-cy="patient-details-button"]') + .filter(":visible") + .first() + .click(); return this; } diff --git a/public/locale/en.json b/public/locale/en.json index a962bbde003..0297e69b30c 100644 --- a/public/locale/en.json +++ b/public/locale/en.json @@ -562,6 +562,7 @@ "claim__use__claim": "Claim", "claim__use__preauthorization": "Pre Authorization", "claims": "Claims", + "class_history": "Class History", "clear": "Clear", "clear_all_filters": "Clear all filters", "clear_home_facility": "Clear Home Facility", @@ -1242,6 +1243,7 @@ "location_created": "Location Created", "location_details": "Location Details", "location_form": "Location Form", + "location_history": "Location History", "location_management": "Location Management", "location_updated": "Location Updated", "location_updated_successfully": "Location updated successfully", @@ -1482,6 +1484,7 @@ "on": "on", "on_emergency_basis": " on emergency basis", "on_hold": "On Hold", + "ongoing": "Ongoing", "ongoing_medications": "Ongoing Medications", "online": "Online", "only_indian_mobile_numbers_supported": "Currently only Indian numbers are supported", @@ -2053,6 +2056,7 @@ "state": "State", "state_reason_for_archiving": "State reason for archiving {{name}} file?", "status": "Status", + "status_history": "Status History", "stop": "Stop", "stop_recording": "Stop Recording", "stopped": "Stopped", @@ -2198,6 +2202,7 @@ "update_facility": "Update Facility", "update_facility_middleware_success": "Facility middleware updated successfully", "update_hospitalisation_details": "Update Hospitalisation Details", + "update_location": "Update Location", "update_log": "Update Log", "update_password": "Update Password", "update_patient_details": "Update Patient Details", diff --git a/src/components/Location/LocationHistorySheet.tsx b/src/components/Location/LocationHistorySheet.tsx new file mode 100644 index 00000000000..9e642c5fd89 --- /dev/null +++ b/src/components/Location/LocationHistorySheet.tsx @@ -0,0 +1,49 @@ +import { useTranslation } from "react-i18next"; + +import { ScrollArea } from "@/components/ui/scroll-area"; +import { + Sheet, + SheetContent, + SheetHeader, + SheetTitle, + SheetTrigger, +} from "@/components/ui/sheet"; + +import { LocationHistory } from "@/types/emr/encounter"; + +import { LocationTree } from "./LocationTree"; + +interface LocationHistorySheetProps { + trigger: React.ReactNode; + history: LocationHistory[]; +} + +export function LocationHistorySheet({ + trigger, + history, +}: LocationHistorySheetProps) { + const { t } = useTranslation(); + + return ( + + {trigger} + + + {t("location_history")} + + + {history.map((item, index) => ( +
+ +
+ ))} +
+
+
+ ); +} diff --git a/src/components/Location/LocationTree.tsx b/src/components/Location/LocationTree.tsx new file mode 100644 index 00000000000..d93b57d3edc --- /dev/null +++ b/src/components/Location/LocationTree.tsx @@ -0,0 +1,105 @@ +import { format } from "date-fns"; +import React from "react"; + +import CareIcon from "@/CAREUI/icons/CareIcon"; + +import { LocationList } from "@/types/location/location"; + +interface LocationPathProps { + location: LocationList; + datetime?: string; + isLatest?: boolean; + showTimeline?: boolean; +} + +interface LocationNodeProps { + location: LocationList; + isLast: boolean; + datetime?: string; + children?: React.ReactNode; +} + +function LocationNode({ + location, + isLast, + datetime, + children, +}: LocationNodeProps) { + if (!location.parent?.id) { + return ( +
+
+ + + {location.name} + +
+ {children} + {isLast && datetime && ( +
+ {format(new Date(datetime), "MMM d, yyyy h:mm a")} +
+ )} +
+ ); + } + + return ( + +
+
+ + + {location.name} + +
+ {children} + {isLast && datetime && ( +
+ {format(new Date(datetime), "MMM d, yyyy h:mm a")} +
+ )} +
+
+ ); +} + +export function LocationTree({ + location, + datetime, + isLatest, + showTimeline = false, +}: LocationPathProps) { + return ( +
+ {showTimeline && ( +
+
+
+ +
+ {!isLatest &&
} +
+ )} +
+ +
+
+ ); +} diff --git a/src/components/Patient/PatientInfoCard.tsx b/src/components/Patient/PatientInfoCard.tsx index ed4877359a5..85c99f2846b 100644 --- a/src/components/Patient/PatientInfoCard.tsx +++ b/src/components/Patient/PatientInfoCard.tsx @@ -43,6 +43,8 @@ import { } from "@/components/ui/popover"; import { Avatar } from "@/components/Common/Avatar"; +import { LocationHistorySheet } from "@/components/Location/LocationHistorySheet"; +import { LocationTree } from "@/components/Location/LocationTree"; import { PLUGIN_Component } from "@/PluginEngine"; import routes from "@/Utils/request/api"; @@ -110,7 +112,18 @@ export default function PatientInfoCard(props: PatientInfoCardProps) { className="mb-2 flex flex-col text-xl font-semibold capitalize lg:hidden" id="patient-name-consultation" > - {patient.name} + + {patient.name} + +
{formatPatientAge(patient, true)} •{" "} {t(`GENDER__${patient.gender}`)} @@ -124,7 +137,18 @@ export default function PatientInfoCard(props: PatientInfoCardProps) { className="hidden flex-row text-xl font-semibold capitalize lg:flex" id="patient-name-consultation" > - {patient.name} + + {patient.name} + +
{formatPatientAge(patient, true)} •{" "} {t(`GENDER__${patient.gender}`)} @@ -133,28 +157,28 @@ export default function PatientInfoCard(props: PatientInfoCardProps) {
- Start Date + {t("start_date")} {props.encounter.period.start ? formatDateTime(props.encounter.period.start) - : "Not started"} + : t("not_started")}
- End Date + {t("end_date")} {props.encounter.period.end ? formatDateTime(props.encounter.period.end) - : "Ongoing"} + : t("ongoing")}
{props.encounter.external_identifier && (
- Hospital Identifier + {t("hospital_identifier")} {props.encounter.external_identifier} @@ -192,7 +216,9 @@ export default function PatientInfoCard(props: PatientInfoCardProps) {
-

Status History

+

+ {t("status_history")} +

{encounter.status_history.history.map( (history, index) => (
- {props.encounter.current_location && ( - - -
- - - {props.encounter.current_location.name} - - -
-
- -
-

- Current Location -

-

- {props.encounter.current_location.name} -

-

- {props.encounter.current_location.description} -

-
- -
-
- )}
@@ -270,7 +259,9 @@ export default function PatientInfoCard(props: PatientInfoCardProps) {
-

Class History

+

+ {t(`class_history`)} +

{encounter.encounter_class_history.history.map( (history, index) => (
} /> + {props.encounter.current_location ? ( + + +
+ + + {props.encounter.current_location.name} + + +
+
+ +
+
+

+ {t("location")} +

+ + + + +
+ } + /> +
+
+ +
+ +
+ + + ) : ( + + + + {t("add_location")} + + + )}
diff --git a/src/pages/Encounters/EncounterShow.tsx b/src/pages/Encounters/EncounterShow.tsx index 1f065b6e50c..b060fcc3d2c 100644 --- a/src/pages/Encounters/EncounterShow.tsx +++ b/src/pages/Encounters/EncounterShow.tsx @@ -145,14 +145,6 @@ export const EncounterShow = (props: Props) => { )} )} */} - - {t("patient_details")} -
diff --git a/src/types/emr/encounter.ts b/src/types/emr/encounter.ts index f63a118a83f..45c6602b763 100644 --- a/src/types/emr/encounter.ts +++ b/src/types/emr/encounter.ts @@ -117,6 +117,12 @@ export type StatusHistory = { history: History[]; }; +export type LocationHistory = { + start_datetime: string; + location: LocationList; + status: string; +}; + export interface Encounter { id: string; patient: Patient; @@ -138,6 +144,7 @@ export interface Encounter { status_history: StatusHistory; organizations: FacilityOrganization[]; current_location: LocationList; + location_history: LocationHistory[]; } export interface EncounterEditRequest { diff --git a/src/types/location/location.ts b/src/types/location/location.ts index cfb16dd13c3..3738dce63f7 100644 --- a/src/types/location/location.ts +++ b/src/types/location/location.ts @@ -45,6 +45,7 @@ export interface LocationDetail extends LocationBase { export interface LocationList extends LocationBase { id: string; has_children: boolean; + parent?: LocationList; } export interface LocationWrite extends LocationBase { From 5c72e51b1155b426e6af4993fcb122a6f2f8fc96 Mon Sep 17 00:00:00 2001 From: Rithvik Nishad Date: Tue, 11 Feb 2025 12:59:05 +0000 Subject: [PATCH 53/97] Add autoComplete attribute for OTP input (#10561) --- src/components/Auth/Login.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/Auth/Login.tsx b/src/components/Auth/Login.tsx index d049cee06d9..c79eacaa7ba 100644 --- a/src/components/Auth/Login.tsx +++ b/src/components/Auth/Login.tsx @@ -626,6 +626,7 @@ const Login = (props: LoginProps) => { name="otp" type="text" value={otp} + autoComplete="one-time-code" onChange={(e) => { setOtp(e.target.value); setOtpValidationError(""); From f71742f36f28ea29ea04313dab2c534689569e0a Mon Sep 17 00:00:00 2001 From: Jacob John Jeevan <40040905+Jacobjeevan@users.noreply.github.com> Date: Tue, 11 Feb 2025 19:07:11 +0530 Subject: [PATCH 54/97] User Form: Pass in Org to GovtSelector only if Org is Govt (#10518) --- src/components/Users/UserForm.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/Users/UserForm.tsx b/src/components/Users/UserForm.tsx index ce92df7533b..5e22f64e4a9 100644 --- a/src/components/Users/UserForm.tsx +++ b/src/components/Users/UserForm.tsx @@ -271,7 +271,7 @@ export default function UserForm({ useEffect(() => { const levels: Organization[] = []; - if (org) levels.push(org); + if (org && org.org_type === "govt") levels.push(org); setSelectedLevels(levels); }, [org, organizationId]); From 2151c1a1ca16b78fcd86d1f0da207a484b723e19 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 11 Feb 2025 19:08:08 +0530 Subject: [PATCH 55/97] Update dependency lucide-react to ^0.475.0 (#10497) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- package-lock.json | 12 ++++++------ package.json | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/package-lock.json b/package-lock.json index fef9044fed8..b33b2b2fefd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "care_fe", - "version": "2.10.0", + "version": "2.11.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "care_fe", - "version": "2.10.0", + "version": "2.11.0", "hasInstallScript": true, "license": "MIT", "dependencies": { @@ -58,7 +58,7 @@ "input-otp": "^1.4.2", "jspdf": "^2.5.2", "libphonenumber-js": "^1.11.18", - "lucide-react": "^0.474.0", + "lucide-react": "^0.475.0", "markdown-it": "^14.1.0", "next-themes": "^0.4.3", "postcss-loader": "^8.1.1", @@ -13716,9 +13716,9 @@ } }, "node_modules/lucide-react": { - "version": "0.474.0", - "resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-0.474.0.tgz", - "integrity": "sha512-CmghgHkh0OJNmxGKWc0qfPJCYHASPMVSyGY8fj3xgk4v84ItqDg64JNKFZn5hC6E0vHi6gxnbCgwhyVB09wQtA==", + "version": "0.475.0", + "resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-0.475.0.tgz", + "integrity": "sha512-NJzvVu1HwFVeZ+Gwq2q00KygM1aBhy/ZrhY9FsAgJtpB+E4R7uxRk9M2iKvHa6/vNxZydIB59htha4c2vvwvVg==", "license": "ISC", "peerDependencies": { "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0" diff --git a/package.json b/package.json index fde4e593d50..62f0cb85b9a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "care_fe", - "version": "2.10.0", + "version": "2.11.0", "description": "Care is a Digital Public Good enabling TeleICU & Decentralised Administration of Healthcare Capacity across States.", "private": true, "repository": { @@ -97,7 +97,7 @@ "input-otp": "^1.4.2", "jspdf": "^2.5.2", "libphonenumber-js": "^1.11.18", - "lucide-react": "^0.474.0", + "lucide-react": "^0.475.0", "markdown-it": "^14.1.0", "next-themes": "^0.4.3", "postcss-loader": "^8.1.1", From 8699a3dea6fc4593377abc00dee7af784c5704c6 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 11 Feb 2025 19:23:08 +0530 Subject: [PATCH 56/97] Update all dependencies (minor, patch) (#10495) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- package-lock.json | 255 ++++++++++++++++++++++++---------------------- package.json | 6 +- 2 files changed, 137 insertions(+), 124 deletions(-) diff --git a/package-lock.json b/package-lock.json index b33b2b2fefd..f86ed7b53e5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "care_fe", - "version": "2.11.0", + "version": "2.12.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "care_fe", - "version": "2.11.0", + "version": "2.12.0", "hasInstallScript": true, "license": "MIT", "dependencies": { @@ -144,8 +144,8 @@ "optionalDependencies": { "@esbuild/linux-arm64": "latest", "@esbuild/linux-x64": "latest", - "@rollup/rollup-linux-arm64-gnu": "4.34.4", - "@rollup/rollup-linux-x64-gnu": "4.34.4" + "@rollup/rollup-linux-arm64-gnu": "4.34.6", + "@rollup/rollup-linux-x64-gnu": "4.34.6" } }, "node_modules/@actions/core": { @@ -3920,9 +3920,9 @@ } }, "node_modules/@eslint/js": { - "version": "9.19.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.19.0.tgz", - "integrity": "sha512-rbq9/g38qjfqFLOVPvwjIvFFdNziEC5S65jmjPw5r6A//QH+W91akh9irMwjDN8zKUTak6W9EsAv4m/7Wnw0UQ==", + "version": "9.20.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.20.0.tgz", + "integrity": "sha512-iZA07H9io9Wn836aVTytRaNqh00Sad+EamwOVJT12GTLw1VGMFV/4JaME+JjLtr9fiGaoWgYnS54wrfWsSs4oQ==", "dev": true, "license": "MIT", "engines": { @@ -5877,9 +5877,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.34.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.34.4.tgz", - "integrity": "sha512-7CwSJW+sEhM9sESEk+pEREF2JL0BmyCro8UyTq0Kyh0nu1v0QPNY3yfLPFKChzVoUmaKj8zbdgBxUhBRR+xGxg==", + "version": "4.34.6", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.34.6.tgz", + "integrity": "sha512-9RyprECbRa9zEjXLtvvshhw4CMrRa3K+0wcp3KME0zmBe1ILmvcVHnypZ/aIDXpRyfhSYSuN4EPdCCj5Du8FIA==", "cpu": [ "arm64" ], @@ -5955,9 +5955,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.34.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.34.4.tgz", - "integrity": "sha512-JGejzEfVzqc/XNiCKZj14eb6s5w8DdWlnQ5tWUbs99kkdvfq9btxxVX97AaxiUX7xJTKFA0LwoS0KU8C2faZRg==", + "version": "4.34.6", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.34.6.tgz", + "integrity": "sha512-Sht4aFvmA4ToHd2vFzwMFaQCiYm2lDFho5rPcvPBT5pCdC+GwHG6CMch4GQfmWTQ1SwRKS0dhDYb54khSrjDWw==", "cpu": [ "x64" ], @@ -6748,17 +6748,17 @@ } }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.23.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.23.0.tgz", - "integrity": "sha512-vBz65tJgRrA1Q5gWlRfvoH+w943dq9K1p1yDBY2pc+a1nbBLZp7fB9+Hk8DaALUbzjqlMfgaqlVPT1REJdkt/w==", + "version": "8.24.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.24.0.tgz", + "integrity": "sha512-aFcXEJJCI4gUdXgoo/j9udUYIHgF23MFkg09LFz2dzEmU0+1Plk4rQWv/IYKvPHAtlkkGoB3m5e6oUp+JPsNaQ==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "8.23.0", - "@typescript-eslint/type-utils": "8.23.0", - "@typescript-eslint/utils": "8.23.0", - "@typescript-eslint/visitor-keys": "8.23.0", + "@typescript-eslint/scope-manager": "8.24.0", + "@typescript-eslint/type-utils": "8.24.0", + "@typescript-eslint/utils": "8.24.0", + "@typescript-eslint/visitor-keys": "8.24.0", "graphemer": "^1.4.0", "ignore": "^5.3.1", "natural-compare": "^1.4.0", @@ -6778,9 +6778,9 @@ } }, "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/types": { - "version": "8.23.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.23.0.tgz", - "integrity": "sha512-1sK4ILJbCmZOTt9k4vkoulT6/y5CHJ1qUYxqpF1K/DBAd8+ZUL4LlSCxOssuH5m4rUaaN0uS0HlVPvd45zjduQ==", + "version": "8.24.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.24.0.tgz", + "integrity": "sha512-VacJCBTyje7HGAw7xp11q439A+zeGG0p0/p2zsZwpnMzjPB5WteaWqt4g2iysgGFafrqvyLWqq6ZPZAOCoefCw==", "dev": true, "license": "MIT", "engines": { @@ -6792,13 +6792,13 @@ } }, "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/visitor-keys": { - "version": "8.23.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.23.0.tgz", - "integrity": "sha512-oWWhcWDLwDfu++BGTZcmXWqpwtkwb5o7fxUIGksMQQDSdPW9prsSnfIOZMlsj4vBOSrcnjIUZMiIjODgGosFhQ==", + "version": "8.24.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.24.0.tgz", + "integrity": "sha512-kArLq83QxGLbuHrTMoOEWO+l2MwsNS2TGISEdx8xgqpkbytB07XmlQyQdNDrCc1ecSqx0cnmhGvpX+VBwqqSkg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.23.0", + "@typescript-eslint/types": "8.24.0", "eslint-visitor-keys": "^4.2.0" }, "engines": { @@ -6836,16 +6836,16 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "8.23.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.23.0.tgz", - "integrity": "sha512-h2lUByouOXFAlMec2mILeELUbME5SZRN/7R9Cw2RD2lRQQY08MWMM+PmVVKKJNK1aIwqTo9t/0CvOxwPbRIE2Q==", + "version": "8.24.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.24.0.tgz", + "integrity": "sha512-MFDaO9CYiard9j9VepMNa9MTcqVvSny2N4hkY6roquzj8pdCBRENhErrteaQuu7Yjn1ppk0v1/ZF9CG3KIlrTA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/scope-manager": "8.23.0", - "@typescript-eslint/types": "8.23.0", - "@typescript-eslint/typescript-estree": "8.23.0", - "@typescript-eslint/visitor-keys": "8.23.0", + "@typescript-eslint/scope-manager": "8.24.0", + "@typescript-eslint/types": "8.24.0", + "@typescript-eslint/typescript-estree": "8.24.0", + "@typescript-eslint/visitor-keys": "8.24.0", "debug": "^4.3.4" }, "engines": { @@ -6861,9 +6861,9 @@ } }, "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/types": { - "version": "8.23.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.23.0.tgz", - "integrity": "sha512-1sK4ILJbCmZOTt9k4vkoulT6/y5CHJ1qUYxqpF1K/DBAd8+ZUL4LlSCxOssuH5m4rUaaN0uS0HlVPvd45zjduQ==", + "version": "8.24.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.24.0.tgz", + "integrity": "sha512-VacJCBTyje7HGAw7xp11q439A+zeGG0p0/p2zsZwpnMzjPB5WteaWqt4g2iysgGFafrqvyLWqq6ZPZAOCoefCw==", "dev": true, "license": "MIT", "engines": { @@ -6875,14 +6875,14 @@ } }, "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree": { - "version": "8.23.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.23.0.tgz", - "integrity": "sha512-LcqzfipsB8RTvH8FX24W4UUFk1bl+0yTOf9ZA08XngFwMg4Kj8A+9hwz8Cr/ZS4KwHrmo9PJiLZkOt49vPnuvQ==", + "version": "8.24.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.24.0.tgz", + "integrity": "sha512-ITjYcP0+8kbsvT9bysygfIfb+hBj6koDsu37JZG7xrCiy3fPJyNmfVtaGsgTUSEuTzcvME5YI5uyL5LD1EV5ZQ==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.23.0", - "@typescript-eslint/visitor-keys": "8.23.0", + "@typescript-eslint/types": "8.24.0", + "@typescript-eslint/visitor-keys": "8.24.0", "debug": "^4.3.4", "fast-glob": "^3.3.2", "is-glob": "^4.0.3", @@ -6902,13 +6902,13 @@ } }, "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/visitor-keys": { - "version": "8.23.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.23.0.tgz", - "integrity": "sha512-oWWhcWDLwDfu++BGTZcmXWqpwtkwb5o7fxUIGksMQQDSdPW9prsSnfIOZMlsj4vBOSrcnjIUZMiIjODgGosFhQ==", + "version": "8.24.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.24.0.tgz", + "integrity": "sha512-kArLq83QxGLbuHrTMoOEWO+l2MwsNS2TGISEdx8xgqpkbytB07XmlQyQdNDrCc1ecSqx0cnmhGvpX+VBwqqSkg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.23.0", + "@typescript-eslint/types": "8.24.0", "eslint-visitor-keys": "^4.2.0" }, "engines": { @@ -6946,14 +6946,14 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "8.23.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.23.0.tgz", - "integrity": "sha512-OGqo7+dXHqI7Hfm+WqkZjKjsiRtFUQHPdGMXzk5mYXhJUedO7e/Y7i8AK3MyLMgZR93TX4bIzYrfyVjLC+0VSw==", + "version": "8.24.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.24.0.tgz", + "integrity": "sha512-HZIX0UByphEtdVBKaQBgTDdn9z16l4aTUz8e8zPQnyxwHBtf5vtl1L+OhH+m1FGV9DrRmoDuYKqzVrvWDcDozw==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.23.0", - "@typescript-eslint/visitor-keys": "8.23.0" + "@typescript-eslint/types": "8.24.0", + "@typescript-eslint/visitor-keys": "8.24.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -6964,9 +6964,9 @@ } }, "node_modules/@typescript-eslint/scope-manager/node_modules/@typescript-eslint/types": { - "version": "8.23.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.23.0.tgz", - "integrity": "sha512-1sK4ILJbCmZOTt9k4vkoulT6/y5CHJ1qUYxqpF1K/DBAd8+ZUL4LlSCxOssuH5m4rUaaN0uS0HlVPvd45zjduQ==", + "version": "8.24.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.24.0.tgz", + "integrity": "sha512-VacJCBTyje7HGAw7xp11q439A+zeGG0p0/p2zsZwpnMzjPB5WteaWqt4g2iysgGFafrqvyLWqq6ZPZAOCoefCw==", "dev": true, "license": "MIT", "engines": { @@ -6978,13 +6978,13 @@ } }, "node_modules/@typescript-eslint/scope-manager/node_modules/@typescript-eslint/visitor-keys": { - "version": "8.23.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.23.0.tgz", - "integrity": "sha512-oWWhcWDLwDfu++BGTZcmXWqpwtkwb5o7fxUIGksMQQDSdPW9prsSnfIOZMlsj4vBOSrcnjIUZMiIjODgGosFhQ==", + "version": "8.24.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.24.0.tgz", + "integrity": "sha512-kArLq83QxGLbuHrTMoOEWO+l2MwsNS2TGISEdx8xgqpkbytB07XmlQyQdNDrCc1ecSqx0cnmhGvpX+VBwqqSkg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.23.0", + "@typescript-eslint/types": "8.24.0", "eslint-visitor-keys": "^4.2.0" }, "engines": { @@ -7009,14 +7009,14 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "8.23.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.23.0.tgz", - "integrity": "sha512-iIuLdYpQWZKbiH+RkCGc6iu+VwscP5rCtQ1lyQ7TYuKLrcZoeJVpcLiG8DliXVkUxirW/PWlmS+d6yD51L9jvA==", + "version": "8.24.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.24.0.tgz", + "integrity": "sha512-8fitJudrnY8aq0F1wMiPM1UUgiXQRJ5i8tFjq9kGfRajU+dbPyOuHbl0qRopLEidy0MwqgTHDt6CnSeXanNIwA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/typescript-estree": "8.23.0", - "@typescript-eslint/utils": "8.23.0", + "@typescript-eslint/typescript-estree": "8.24.0", + "@typescript-eslint/utils": "8.24.0", "debug": "^4.3.4", "ts-api-utils": "^2.0.1" }, @@ -7033,9 +7033,9 @@ } }, "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/types": { - "version": "8.23.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.23.0.tgz", - "integrity": "sha512-1sK4ILJbCmZOTt9k4vkoulT6/y5CHJ1qUYxqpF1K/DBAd8+ZUL4LlSCxOssuH5m4rUaaN0uS0HlVPvd45zjduQ==", + "version": "8.24.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.24.0.tgz", + "integrity": "sha512-VacJCBTyje7HGAw7xp11q439A+zeGG0p0/p2zsZwpnMzjPB5WteaWqt4g2iysgGFafrqvyLWqq6ZPZAOCoefCw==", "dev": true, "license": "MIT", "engines": { @@ -7047,14 +7047,14 @@ } }, "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/typescript-estree": { - "version": "8.23.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.23.0.tgz", - "integrity": "sha512-LcqzfipsB8RTvH8FX24W4UUFk1bl+0yTOf9ZA08XngFwMg4Kj8A+9hwz8Cr/ZS4KwHrmo9PJiLZkOt49vPnuvQ==", + "version": "8.24.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.24.0.tgz", + "integrity": "sha512-ITjYcP0+8kbsvT9bysygfIfb+hBj6koDsu37JZG7xrCiy3fPJyNmfVtaGsgTUSEuTzcvME5YI5uyL5LD1EV5ZQ==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.23.0", - "@typescript-eslint/visitor-keys": "8.23.0", + "@typescript-eslint/types": "8.24.0", + "@typescript-eslint/visitor-keys": "8.24.0", "debug": "^4.3.4", "fast-glob": "^3.3.2", "is-glob": "^4.0.3", @@ -7074,13 +7074,13 @@ } }, "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/visitor-keys": { - "version": "8.23.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.23.0.tgz", - "integrity": "sha512-oWWhcWDLwDfu++BGTZcmXWqpwtkwb5o7fxUIGksMQQDSdPW9prsSnfIOZMlsj4vBOSrcnjIUZMiIjODgGosFhQ==", + "version": "8.24.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.24.0.tgz", + "integrity": "sha512-kArLq83QxGLbuHrTMoOEWO+l2MwsNS2TGISEdx8xgqpkbytB07XmlQyQdNDrCc1ecSqx0cnmhGvpX+VBwqqSkg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.23.0", + "@typescript-eslint/types": "8.24.0", "eslint-visitor-keys": "^4.2.0" }, "engines": { @@ -7161,16 +7161,16 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "8.23.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.23.0.tgz", - "integrity": "sha512-uB/+PSo6Exu02b5ZEiVtmY6RVYO7YU5xqgzTIVZwTHvvK3HsL8tZZHFaTLFtRG3CsV4A5mhOv+NZx5BlhXPyIA==", + "version": "8.24.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.24.0.tgz", + "integrity": "sha512-07rLuUBElvvEb1ICnafYWr4hk8/U7X9RDCOqd9JcAMtjh/9oRmcfN4yGzbPVirgMR0+HLVHehmu19CWeh7fsmQ==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", - "@typescript-eslint/scope-manager": "8.23.0", - "@typescript-eslint/types": "8.23.0", - "@typescript-eslint/typescript-estree": "8.23.0" + "@typescript-eslint/scope-manager": "8.24.0", + "@typescript-eslint/types": "8.24.0", + "@typescript-eslint/typescript-estree": "8.24.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -7185,9 +7185,9 @@ } }, "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/types": { - "version": "8.23.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.23.0.tgz", - "integrity": "sha512-1sK4ILJbCmZOTt9k4vkoulT6/y5CHJ1qUYxqpF1K/DBAd8+ZUL4LlSCxOssuH5m4rUaaN0uS0HlVPvd45zjduQ==", + "version": "8.24.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.24.0.tgz", + "integrity": "sha512-VacJCBTyje7HGAw7xp11q439A+zeGG0p0/p2zsZwpnMzjPB5WteaWqt4g2iysgGFafrqvyLWqq6ZPZAOCoefCw==", "dev": true, "license": "MIT", "engines": { @@ -7199,14 +7199,14 @@ } }, "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/typescript-estree": { - "version": "8.23.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.23.0.tgz", - "integrity": "sha512-LcqzfipsB8RTvH8FX24W4UUFk1bl+0yTOf9ZA08XngFwMg4Kj8A+9hwz8Cr/ZS4KwHrmo9PJiLZkOt49vPnuvQ==", + "version": "8.24.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.24.0.tgz", + "integrity": "sha512-ITjYcP0+8kbsvT9bysygfIfb+hBj6koDsu37JZG7xrCiy3fPJyNmfVtaGsgTUSEuTzcvME5YI5uyL5LD1EV5ZQ==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.23.0", - "@typescript-eslint/visitor-keys": "8.23.0", + "@typescript-eslint/types": "8.24.0", + "@typescript-eslint/visitor-keys": "8.24.0", "debug": "^4.3.4", "fast-glob": "^3.3.2", "is-glob": "^4.0.3", @@ -7226,13 +7226,13 @@ } }, "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/visitor-keys": { - "version": "8.23.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.23.0.tgz", - "integrity": "sha512-oWWhcWDLwDfu++BGTZcmXWqpwtkwb5o7fxUIGksMQQDSdPW9prsSnfIOZMlsj4vBOSrcnjIUZMiIjODgGosFhQ==", + "version": "8.24.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.24.0.tgz", + "integrity": "sha512-kArLq83QxGLbuHrTMoOEWO+l2MwsNS2TGISEdx8xgqpkbytB07XmlQyQdNDrCc1ecSqx0cnmhGvpX+VBwqqSkg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.23.0", + "@typescript-eslint/types": "8.24.0", "eslint-visitor-keys": "^4.2.0" }, "engines": { @@ -8971,9 +8971,9 @@ } }, "node_modules/cypress-split": { - "version": "1.24.8", - "resolved": "https://registry.npmjs.org/cypress-split/-/cypress-split-1.24.8.tgz", - "integrity": "sha512-gxsZg7Se3iy6eQuYP0w6munfRFBWP81OKc3WWTKQoxxafFWEp9gu173Nx3zoAEDUIEeYxUS1kwmZ7q5hhMN9og==", + "version": "1.24.10", + "resolved": "https://registry.npmjs.org/cypress-split/-/cypress-split-1.24.10.tgz", + "integrity": "sha512-8OPOWmOznR/+0sczoKnfDvLYN19u5jnbHYHBLI56ay55OE8WRSSJ64V8Lp/zTY+2+vGuLoplR1vyiApKGKFTPA==", "dev": true, "license": "MIT", "dependencies": { @@ -8982,7 +8982,7 @@ "console.table": "^0.10.0", "debug": "^4.3.4", "fast-shuffle": "^6.1.0", - "find-cypress-specs": "1.46.2", + "find-cypress-specs": "1.47.3", "globby": "^11.1.0", "humanize-duration": "^3.28.0" }, @@ -10134,18 +10134,18 @@ } }, "node_modules/eslint": { - "version": "9.19.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.19.0.tgz", - "integrity": "sha512-ug92j0LepKlbbEv6hD911THhoRHmbdXt2gX+VDABAW/Ir7D3nqKdv5Pf5vtlyY6HQMTEP2skXY43ueqTCWssEA==", + "version": "9.20.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.20.0.tgz", + "integrity": "sha512-aL4F8167Hg4IvsW89ejnpTwx+B/UQRzJPGgbIOl+4XqffWsahVVsLEWoZvnrVuwpWmnRd7XeXmQI1zlKcFDteA==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.12.1", "@eslint/config-array": "^0.19.0", - "@eslint/core": "^0.10.0", + "@eslint/core": "^0.11.0", "@eslint/eslintrc": "^3.2.0", - "@eslint/js": "9.19.0", + "@eslint/js": "9.20.0", "@eslint/plugin-kit": "^0.2.5", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", @@ -10368,6 +10368,19 @@ "url": "https://opencollective.com/eslint" } }, + "node_modules/eslint/node_modules/@eslint/core": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.11.0.tgz", + "integrity": "sha512-DWUB2pksgNEb6Bz2fggIy1wh6fGgZP4Xyy/Mt0QZPiloKKXerbqq9D3SBQTlCRYOrcRPu4vuz+CGjwdfqxnoWA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@types/json-schema": "^7.0.15" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, "node_modules/eslint/node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -10833,9 +10846,9 @@ } }, "node_modules/find-cypress-specs": { - "version": "1.46.2", - "resolved": "https://registry.npmjs.org/find-cypress-specs/-/find-cypress-specs-1.46.2.tgz", - "integrity": "sha512-eXvGQMftYDTbQflVX6TzJj7hA0ypO5+FfUrnMdRf1+yCu5xVY5wPv721AWp/xPBOpQXwx5jdoZRH9m95U/1c7A==", + "version": "1.47.3", + "resolved": "https://registry.npmjs.org/find-cypress-specs/-/find-cypress-specs-1.47.3.tgz", + "integrity": "sha512-IBC4VcjbRgesJKty9iBmp+V/RFoN609tfb/mO2vV6L3ZTaVLiHX+n2ubSPPjA5tYD4AS3O2GKKetvaTaVxDMFw==", "dev": true, "license": "MIT", "dependencies": { @@ -10843,7 +10856,7 @@ "arg": "^5.0.1", "console.table": "^0.10.0", "debug": "^4.3.3", - "find-test-names": "1.28.30", + "find-test-names": "1.29.4", "globby": "^11.1.0", "minimatch": "^3.0.4", "pluralize": "^8.0.0", @@ -10884,9 +10897,9 @@ } }, "node_modules/find-test-names": { - "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==", + "version": "1.29.4", + "resolved": "https://registry.npmjs.org/find-test-names/-/find-test-names-1.29.4.tgz", + "integrity": "sha512-dpZsHkCyTQKlR6qzid09f/CQ4zGtdRwjMYHlTrmXx3qlzhrxRvxE7lRSFuaiqP0e+rbUcLy6juB6Bq9ohrnEMg==", "dev": true, "license": "MIT", "dependencies": { @@ -13779,9 +13792,9 @@ } }, "node_modules/marked": { - "version": "15.0.6", - "resolved": "https://registry.npmjs.org/marked/-/marked-15.0.6.tgz", - "integrity": "sha512-Y07CUOE+HQXbVDCGl3LXggqJDbXDP2pArc2C1N1RRMN0ONiShoSsIInMd5Gsxupe7fKLpgimTV+HOJ9r7bA+pg==", + "version": "15.0.7", + "resolved": "https://registry.npmjs.org/marked/-/marked-15.0.7.tgz", + "integrity": "sha512-dgLIeKGLx5FwziAnsk4ONoGwHwGPJzselimvlVskE9XLN4Orv9u2VA3GWw/lYUqjfA0rUT/6fqKwfZJapP9BEg==", "dev": true, "license": "MIT", "bin": { @@ -14803,9 +14816,9 @@ } }, "node_modules/postcss": { - "version": "8.5.1", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.1.tgz", - "integrity": "sha512-6oz2beyjc5VMn/KV1pPw8fliQkhBXrVn1Z3TVyqZxU8kZpzEKhBdmCFqI6ZbmGtamQvQGuU1sgPTk8ZrXDD7jQ==", + "version": "8.5.2", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.2.tgz", + "integrity": "sha512-MjOadfU3Ys9KYoX0AdkBlFEF1Vx37uCCeN4ZHnmwm9FfpbsGWMZeBLMmmpY+6Ocqod7mkdZ0DT31OlbsFrLlkA==", "funding": [ { "type": "opencollective", @@ -15161,9 +15174,9 @@ } }, "node_modules/prettier": { - "version": "3.4.2", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.4.2.tgz", - "integrity": "sha512-e9MewbtFo+Fevyuxn/4rrcDAaq0IYxPGLvObpQjiZBMAzB9IGmzlnG9RZy3FFas+eBMu2vA0CszMeduow5dIuQ==", + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.5.0.tgz", + "integrity": "sha512-quyMrVt6svPS7CjQ9gKb3GLEX/rl3BCL2oa/QkNcXv4YNVBC9olt3s+H7ukto06q7B1Qz46PbrKLO34PR6vXcA==", "dev": true, "license": "MIT", "bin": { @@ -16957,9 +16970,9 @@ "license": "MIT" }, "node_modules/snyk": { - "version": "1.1295.2", - "resolved": "https://registry.npmjs.org/snyk/-/snyk-1.1295.2.tgz", - "integrity": "sha512-Unl6HD/XF2DfDEj4pySiQF5bUkc6yS/tljtO9LHgjJjfj4CRGZdNs2HmtfEJHsnda3pqBEUO71L7PXhgouzYGw==", + "version": "1.1295.3", + "resolved": "https://registry.npmjs.org/snyk/-/snyk-1.1295.3.tgz", + "integrity": "sha512-PFPetFXVMx5kt49WraLbr1Lw36jikktxQeOjaK3y/0Bjgm1e1rRjTsKYI83lINhkxUuSRBf9MCm8QUcOEYZiaw==", "dev": true, "hasInstallScript": true, "license": "Apache-2.0", diff --git a/package.json b/package.json index 62f0cb85b9a..b64f0391406 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "care_fe", - "version": "2.11.0", + "version": "2.12.0", "description": "Care is a Digital Public Good enabling TeleICU & Decentralised Administration of Healthcare Capacity across States.", "private": true, "repository": { @@ -180,8 +180,8 @@ "optionalDependencies": { "@esbuild/linux-arm64": "latest", "@esbuild/linux-x64": "latest", - "@rollup/rollup-linux-arm64-gnu": "4.34.4", - "@rollup/rollup-linux-x64-gnu": "4.34.4" + "@rollup/rollup-linux-arm64-gnu": "4.34.6", + "@rollup/rollup-linux-x64-gnu": "4.34.6" }, "browserslist": { "production": [ From 29060edfd6b68a237824991cda822128a63e61da Mon Sep 17 00:00:00 2001 From: Tanuj Nainwal <125687187+Tanuj1718@users.noreply.github.com> Date: Tue, 11 Feb 2025 22:52:04 +0530 Subject: [PATCH 57/97] Improves responsiveness of Encounter Medicines tab (#10511) --- src/components/Medicine/MedicationRequestTable/index.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/Medicine/MedicationRequestTable/index.tsx b/src/components/Medicine/MedicationRequestTable/index.tsx index 7c9e1996d87..2e811025048 100644 --- a/src/components/Medicine/MedicationRequestTable/index.tsx +++ b/src/components/Medicine/MedicationRequestTable/index.tsx @@ -114,7 +114,7 @@ export default function MedicationRequestTable({
- +
-
+
Date: Wed, 12 Feb 2025 11:44:46 +0530 Subject: [PATCH 58/97] Enhancements to Encounter Discussion/Notes | Fix Translation (#10156) --- public/locale/en.json | 5 + .../Encounters/tabs/EncounterNotesTab.tsx | 148 +++++++++++++----- 2 files changed, 110 insertions(+), 43 deletions(-) diff --git a/public/locale/en.json b/public/locale/en.json index a3ecbeca39f..137aaa0b9ad 100644 --- a/public/locale/en.json +++ b/public/locale/en.json @@ -881,6 +881,7 @@ "encounter_notes__failed_send_message": "Failed to send message", "encounter_notes__new": "New", "encounter_notes__no_discussions": "No discussions yet", + "encounter_notes__no_unused_threads": "Please enter a custom title for thread", "encounter_notes__select_create_thread": "Select or create a thread to start messaging", "encounter_notes__start_conversation": "Start the Conversation", "encounter_notes__start_new_discussion": "Start New Discussion", @@ -1006,6 +1007,7 @@ "facility_updated_successfully": "Facility updated successfully", "failed_to_create_appointment": "Failed to create an appointment", "failed_to_link_abha_number": "Failed to link ABHA Number. Please try again later.", + "failed_to_send_message": "Failed to send message", "false": "False", "fast_track_testing_reason": "Fast track testing reason", "features": "Features", @@ -1314,6 +1316,7 @@ "medicines_administered": "Medicine(s) administered", "medicines_administered_error": "Error administering medicine(s)", "member_id_required": "Member Id is required", + "messages": "Messages", "method": "Method", "middleware_hostname": "Middleware Hostname", "middleware_hostname_example": "e.g. example.ohc.network", @@ -1523,6 +1526,7 @@ "page_not_found": "Page Not Found", "pain": "Pain", "pain_chart_description": "Mark region and intensity of pain", + "participants": "Participants", "passport_number": "Passport Number", "password": "Password", "password_length_validation": "Use at least 8 characters", @@ -2103,6 +2107,7 @@ "third_party_software_licenses": "Third Party Software Licenses", "this_action_is_irreversible": "This action is irreversible. Once a file is archived it cannot be unarchived.", "this_file_has_been_archived": "This file has been archived and cannot be unarchived.", + "thread_already_exists": "Thread with this title already exists", "time": "Time", "time_slot": "Time Slot", "title": "Title", diff --git a/src/pages/Encounters/tabs/EncounterNotesTab.tsx b/src/pages/Encounters/tabs/EncounterNotesTab.tsx index 89b535134df..058606392e4 100644 --- a/src/pages/Encounters/tabs/EncounterNotesTab.tsx +++ b/src/pages/Encounters/tabs/EncounterNotesTab.tsx @@ -9,11 +9,13 @@ import { Info, Loader2, MessageCircle, + MessageSquare, MessageSquarePlus, Plus, Send, Users, } from "lucide-react"; +import { Link, usePathParams } from "raviger"; import { useEffect, useRef, useState } from "react"; import { useTranslation } from "react-i18next"; import { useInView } from "react-intersection-observer"; @@ -25,6 +27,7 @@ import { Badge } from "@/components/ui/badge"; import { Button } from "@/components/ui/button"; import { Dialog, + DialogClose, DialogContent, DialogDescription, DialogFooter, @@ -61,6 +64,7 @@ import { Thread } from "@/types/notes/threads"; const MESSAGES_LIMIT = 20; // Thread templates for quick selection + const threadTemplates = [ "Treatment Plan", "Medication Notes", @@ -118,6 +122,7 @@ const ThreadItem = ({ // Message item component const MessageItem = ({ message }: { message: Message }) => { const authUser = useAuthUser(); + const { facilityId } = usePathParams("/facility/:facilityId/*")!; const isCurrentUser = authUser?.external_id === message.created_by.id; return ( @@ -135,15 +140,19 @@ const MessageItem = ({ message }: { message: Message }) => { > - -
- -
-
+ + +
+ +
+
+

{message.created_by.username}

@@ -192,11 +201,13 @@ const NewThreadDialog = ({ onClose, onCreate, isCreating, + threadsUnused, }: { isOpen: boolean; onClose: () => void; onCreate: (title: string) => void; isCreating: boolean; + threadsUnused: string[]; }) => { const { t } = useTranslation(); const [title, setTitle] = useState(""); @@ -218,13 +229,15 @@ const NewThreadDialog = ({ - {t("encounter_notes__choose_template")} + {threadsUnused.length === 0 + ? t("encounter_notes__no_unused_threads") + : t("encounter_notes__choose_template")}
- {threadTemplates.map((template) => ( + {threadsUnused.map((template) => ( - + + + + @@ -308,6 +322,7 @@ export const EncounterNotesTab = ({ encounter }: EncounterTabProps) => { const [newMessage, setNewMessage] = useState(""); const messagesEndRef = useRef(null); const { ref, inView } = useInView(); + const [commentAdded, setCommentAdded] = useState(false); // Fetch threads const { data: threadsData, isLoading: threadsLoading } = useQuery({ @@ -318,17 +333,11 @@ export const EncounterNotesTab = ({ encounter }: EncounterTabProps) => { }), }); - // Auto-select first thread - useEffect(() => { - if (threadsData?.results.length && !selectedThread) { - setSelectedThread(threadsData.results[0].id); - } - }, [threadsData, selectedThread]); - // Fetch messages with infinite scroll const { data: messagesData, isLoading: messagesLoading, + isFetching: isFetchingMessages, hasNextPage, fetchNextPage, isFetchingNextPage, @@ -382,28 +391,63 @@ export const EncounterNotesTab = ({ encounter }: EncounterTabProps) => { onSuccess: () => { queryClient.invalidateQueries({ queryKey: ["messages", selectedThread] }); setNewMessage(""); - setTimeout(() => { - messagesEndRef.current?.scrollIntoView({ behavior: "smooth" }); - }, 100); + setCommentAdded(true); }, }); - // Handle infinite scroll + // handle scrolling to last message when new message is added + useEffect(() => { - if (inView && hasNextPage) { - fetchNextPage(); + if (commentAdded && !isFetchingMessages) { + messagesEndRef.current?.scrollIntoView(); + setCommentAdded(false); } - }, [inView, hasNextPage, fetchNextPage]); + }, [commentAdded, isFetchingMessages]); + + const [threads, setThreads] = useState([...threadTemplates]); + + // Auto-select first thread - // Scroll to bottom on initial load and thread change useEffect(() => { - if (messagesData && !messagesLoading && !isFetchingNextPage) { + if (threadsData?.results.length) { + if (!selectedThread) setSelectedThread(threadsData.results[0].id); + const threadTitles = threadsData.results.map((thread) => thread.title); + setThreads( + threads.filter((template) => !threadTitles.includes(template)), + ); + } + }, [threadsData, selectedThread]); + + // hack to scroll to bottom on initial load + + useEffect(() => { + messagesEndRef.current?.scrollIntoView(); + }, [messagesLoading]); + + // Handle infinite scroll + + useEffect(() => { + if (inView && hasNextPage) { + fetchNextPage(); messagesEndRef.current?.scrollIntoView(); } - }, [selectedThread, messagesData, messagesLoading, isFetchingNextPage]); + }, [ + inView, + hasNextPage, + fetchNextPage, + messagesData, + isFetchingNextPage, + messagesLoading, + ]); const handleCreateThread = (title: string) => { if (title.trim()) { + if ( + threadsData?.results.some((thread) => thread.title === title.trim()) + ) { + toast.error(t("thread_already_exists")); + return; + } createThreadMutation.mutate({ title: title.trim(), encounter: encounter.id, @@ -423,6 +467,7 @@ export const EncounterNotesTab = ({ encounter }: EncounterTabProps) => { } const messages = messagesData?.pages.flatMap((page) => page.results) ?? []; + const totalMessages = messagesData?.pages[0]?.count ?? 0; return (
@@ -529,8 +574,8 @@ export const EncounterNotesTab = ({ encounter }: EncounterTabProps) => { {/* Main Content */}
- {/* Mobile Header */} -
+ {/* Header */} +
{selectedThread ? (

@@ -539,10 +584,27 @@ export const EncounterNotesTab = ({ encounter }: EncounterTabProps) => { ?.title }

-
- - {messages.length} -
+ + +
+ + + {new Set(messages.map((m) => m.created_by.id)).size} + + + {totalMessages} +
+
+ +

+ {t("participants")}:{" "} + {new Set(messages.map((m) => m.created_by.id)).size} +

+

+ {t("messages")}: {totalMessages} +

+
+
) : (
@@ -550,13 +612,12 @@ export const EncounterNotesTab = ({ encounter }: EncounterTabProps) => {
)}
- {selectedThread ? ( <> {messagesLoading ? (
- +
) : ( @@ -580,17 +641,17 @@ export const EncounterNotesTab = ({ encounter }: EncounterTabProps) => { )) )} - {isFetchingNextPage && ( + {isFetchingNextPage ? (
+ ) : ( +
)} -
- {/* Message Input */}
@@ -662,6 +723,7 @@ export const EncounterNotesTab = ({ encounter }: EncounterTabProps) => { onClose={() => setShowNewThreadDialog(false)} onCreate={handleCreateThread} isCreating={createThreadMutation.isPending} + threadsUnused={threads} />
); From 98286c63dbc45a8020b9d7dd01793c720b0e7b25 Mon Sep 17 00:00:00 2001 From: Tanuj Nainwal <125687187+Tanuj1718@users.noreply.github.com> Date: Wed, 12 Feb 2025 11:48:44 +0530 Subject: [PATCH 59/97] Date handling in DOB section (#10415) --- .../Patient/PatientRegistration.tsx | 8 ++- src/components/ui/date-field.tsx | 64 ++++++++++++++++--- 2 files changed, 61 insertions(+), 11 deletions(-) diff --git a/src/components/Patient/PatientRegistration.tsx b/src/components/Patient/PatientRegistration.tsx index 9acf238d3de..14b062f38f1 100644 --- a/src/components/Patient/PatientRegistration.tsx +++ b/src/components/Patient/PatientRegistration.tsx @@ -175,7 +175,11 @@ export default function PatientRegistration( }, }); - const { mutate: updatePatient, isPending: isUpdatingPatient } = useMutation({ + const { + mutate: updatePatient, + isPending: isUpdatingPatient, + isSuccess: isUpdateSuccess, + } = useMutation({ mutationFn: mutate(routes.updatePatient, { pathParams: { id: patientId || "" }, }), @@ -291,7 +295,7 @@ export default function PatientRegistration( useNavigationPrompt( form.formState.isDirty && !isCreatingPatient && - !isUpdatingPatient && + !(isUpdatingPatient || isUpdateSuccess) && !showDuplicate, t("unsaved_changes"), ); diff --git a/src/components/ui/date-field.tsx b/src/components/ui/date-field.tsx index daeff36be5f..b82ad00c9fc 100644 --- a/src/components/ui/date-field.tsx +++ b/src/components/ui/date-field.tsx @@ -45,20 +45,25 @@ export default function DateField({ const newDay = e.target.value; setDay(newDay); + // Check if change is from spinner (stepUp/stepDown) vs keyboard input + const isFromSpinner = + e.nativeEvent instanceof InputEvent && + (e.nativeEvent as InputEvent).inputType === "insertReplacementText"; + if ( - newDay.length === 2 && + (isFromSpinner || newDay.length === 2) && parseInt(newDay) >= 1 && parseInt(newDay) <= 31 ) { - if (isValidDate(year, month, newDay) && onChange) { + const modifiedDay = isFromSpinner ? newDay.padStart(2, "0") : newDay; + if (isValidDate(year, month, modifiedDay) && onChange) { const updatedDate = new Date( parseInt(year), parseInt(month) - 1, - parseInt(newDay), + parseInt(modifiedDay), ); onChange(updatedDate); } - document.getElementById(`${id}-month-input`)?.focus(); } }; @@ -66,21 +71,27 @@ export default function DateField({ const newMonth = e.target.value; setMonth(newMonth); + // Check if change is from spinner (stepUp/stepDown) vs keyboard input + const isFromSpinner = + e.nativeEvent instanceof InputEvent && + (e.nativeEvent as InputEvent).inputType === "insertReplacementText"; + if ( - newMonth.length === 2 && + (isFromSpinner || newMonth.length === 2) && parseInt(newMonth) >= 1 && parseInt(newMonth) <= 12 ) { - if (isValidDate(year, newMonth, day) && onChange) { + const modifiedMonth = isFromSpinner + ? newMonth.padStart(2, "0") + : newMonth; + if (isValidDate(year, modifiedMonth, day) && onChange) { const updatedDate = new Date( parseInt(year), - parseInt(newMonth) - 1, + parseInt(modifiedMonth) - 1, parseInt(day), ); onChange(updatedDate); } - - document.getElementById(`${id}-year-input`)?.focus(); } }; @@ -100,6 +111,38 @@ export default function DateField({ } }; + // Handle day blur to pad single digit values + const handleDayBlur = () => { + if (day.length === 1 && parseInt(day) >= 1 && parseInt(day) <= 9) { + const paddedDay = day.padStart(2, "0"); + setDay(paddedDay); + if (isValidDate(year, month, paddedDay) && onChange) { + const updatedDate = new Date( + parseInt(year), + parseInt(month) - 1, + parseInt(paddedDay), + ); + onChange(updatedDate); + } + } + }; + + // Handle month blur to pad single digit values + const handleMonthBlur = () => { + if (month.length === 1 && parseInt(month) >= 1) { + const paddedMonth = month.padStart(2, "0"); + setMonth(paddedMonth); + if (isValidDate(year, paddedMonth, day) && onChange) { + const updatedDate = new Date( + parseInt(year), + parseInt(paddedMonth) - 1, + parseInt(day), + ); + onChange(updatedDate); + } + } + }; + return (
@@ -109,6 +152,7 @@ export default function DateField({ placeholder="DD" value={day} onChange={handleDayChange} + onBlur={handleDayBlur} min={1} max={31} id={`${id}-day-input`} @@ -124,6 +168,7 @@ export default function DateField({ placeholder="MM" value={month} onChange={handleMonthChange} + onBlur={handleMonthBlur} min={1} max={12} id={`${id}-month-input`} @@ -140,6 +185,7 @@ export default function DateField({ value={year} onChange={handleYearChange} min={1900} + max={new Date().getFullYear()} id={`${id}-year-input`} data-cy={`${id}-year-input`} disabled={disabled} From 66ef836fa68918939c09b8985c351e4a0e8c1f8d Mon Sep 17 00:00:00 2001 From: Don Xavier <98073418+DonXavierdev@users.noreply.github.com> Date: Wed, 12 Feb 2025 13:13:34 +0530 Subject: [PATCH 60/97] Refactor Breadcrumbs: Restrict to Locations. (#10539) --- public/locale/en.json | 3 + src/CAREUI/icons/Index.tsx | 2 +- src/components/Common/Breadcrumbs.tsx | 174 ------------- src/components/Common/Page.tsx | 7 +- src/components/Common/PageTitle.tsx | 39 +-- .../Patient/EncounterQuestionnaire.tsx | 5 +- src/components/Patient/FileUploadPage.tsx | 30 +-- src/components/Resource/ResourceCreate.tsx | 20 +- src/components/Resource/ResourceDetails.tsx | 6 +- .../Resource/ResourceDetailsUpdate.tsx | 6 +- src/components/Resource/ResourceList.tsx | 11 +- src/components/Users/UserHome.tsx | 14 - src/pages/Appointments/AppointmentDetail.tsx | 11 +- src/pages/Appointments/AppointmentsPage.tsx | 2 - src/pages/Encounters/EncounterList.tsx | 2 +- src/pages/Encounters/EncounterShow.tsx | 16 +- src/pages/Facility/settings/layout.tsx | 4 +- .../settings/locations/LocationView.tsx | 240 +++++++++++------- .../FacilityOrganizationIndex.tsx | 14 +- .../components/FacilityOrganizationLayout.tsx | 33 +-- .../components/OrganizationLayout.tsx | 33 +-- 21 files changed, 175 insertions(+), 497 deletions(-) delete mode 100644 src/components/Common/Breadcrumbs.tsx diff --git a/public/locale/en.json b/public/locale/en.json index 137aaa0b9ad..f4de7ad0663 100644 --- a/public/locale/en.json +++ b/public/locale/en.json @@ -1103,6 +1103,7 @@ "hide_notes": "Hide notes", "high": "High", "history": "History", + "home": "Home", "home_facility": "Home Facility", "home_facility_cleared_success": "Home Facility cleared successfully", "home_facility_updated_error": "Error while updating Home Facility", @@ -1569,6 +1570,7 @@ "patient_details": "Patient Details", "patient_details_incomplete": "Patient Details Incomplete", "patient_face": "Patient Face", + "patient_files": "Patient Files", "patient_information": "Patient Information", "patient_name": "Patient Name", "patient_name_uhid": "Patient Name/UHID", @@ -2220,6 +2222,7 @@ "update_preset_position_to_current": "Update preset's position to camera's current position", "update_record": "Update Record", "update_record_for_asset": "Update record for asset", + "update_request": "Update Request", "update_role": "Update Role", "update_shift_request": "Update Shift Request", "update_status": "Update Status", diff --git a/src/CAREUI/icons/Index.tsx b/src/CAREUI/icons/Index.tsx index ca8c315a194..59919021f8c 100644 --- a/src/CAREUI/icons/Index.tsx +++ b/src/CAREUI/icons/Index.tsx @@ -22,7 +22,7 @@ const IconIndex: React.FC = () => { return (
- + - string - .replace(/[_-]/g, " ") - .split(" ") - .map((word) => word.charAt(0).toUpperCase() + word.slice(1)) - .join(" "); - -interface BreadcrumbsProps { - replacements?: { - [key: string]: { - name?: string; - uri?: string; - style?: string; - hide?: boolean; - }; - }; - className?: string; - hideBack?: boolean; - backUrl?: string; - onBackClick?: () => boolean | void; -} - -export default function Breadcrumbs({ - replacements = {}, - className = "", - hideBack = false, - backUrl, - onBackClick, -}: BreadcrumbsProps) { - const { goBack } = useAppHistory(); - const path = usePath(); - const [showFullPath, setShowFullPath] = useState(false); - - const crumbs = path - ?.slice(1) - .split("/") - .filter((field) => replacements[field]?.hide !== true) - .map((field, i) => ({ - name: replacements[field]?.name || MENU_TAGS[field] || capitalize(field), - uri: - replacements[field]?.uri || - path - .split("/") - .slice(0, i + 2) - .join("/"), - style: replacements[field]?.style || "", - })); - - const renderCrumb = (crumb: any, index: number) => { - const isLastItem = index === crumbs!.length - 1; - return ( - -
- {!isLastItem ? ( - - ) : ( - {crumb.name} - )} -
-
- ); - }; - - return ( - - - - ); -} diff --git a/src/components/Common/Page.tsx b/src/components/Common/Page.tsx index 24b797d245f..b9079c5089e 100644 --- a/src/components/Common/Page.tsx +++ b/src/components/Common/Page.tsx @@ -33,7 +33,7 @@ export default function Page(props: PageProps) { let padding = ""; if (!props.noImplicitPadding) { - if (!props.hideBack || props.componentRight) padding = "py-0 md:px-6"; + if (props.componentRight) padding = "py-0 md:px-6"; else padding = "px-6 py-0"; } @@ -43,13 +43,8 @@ export default function Page(props: PageProps) { diff --git a/src/components/Common/PageTitle.tsx b/src/components/Common/PageTitle.tsx index cee87a8c5fb..c374124934d 100644 --- a/src/components/Common/PageTitle.tsx +++ b/src/components/Common/PageTitle.tsx @@ -1,46 +1,26 @@ import { ReactNode, useEffect, useRef } from "react"; -import Breadcrumbs from "@/components/Common/Breadcrumbs"; -import PageHeadTitle from "@/components/Common/PageHeadTitle"; +import { cn } from "@/lib/utils"; -import { classNames } from "@/Utils/utils"; +import PageHeadTitle from "@/components/Common/PageHeadTitle"; export interface PageTitleProps { title: string; className?: string; componentRight?: ReactNode; - breadcrumbs?: boolean; - crumbsReplacements?: { - [key: string]: { - name?: string; - uri?: string; - style?: string; - hide?: boolean; - }; - }; focusOnLoad?: boolean; isInsidePage?: boolean; changePageMetadata?: boolean; - // New props for Breadcrumbs - hideBack?: boolean; - backUrl?: string; hideTitleOnPage?: boolean; - onBackClick?: () => boolean | void; } export default function PageTitle({ title, className = "", componentRight = <>, - breadcrumbs = true, - crumbsReplacements = {}, focusOnLoad = false, isInsidePage = false, changePageMetadata = true, - // New props passed to Breadcrumbs - hideBack = false, - backUrl, - onBackClick, hideTitleOnPage, }: PageTitleProps) { const divRef = useRef(); @@ -54,23 +34,12 @@ export default function PageTitle({ return (
-
- {breadcrumbs && ( - - )} -
{changePageMetadata && }
+ + ; - const { data: facilityData } = useQuery({ - queryKey: ["facility", facilityId], - queryFn: query(routes.getAnyFacility, { - pathParams: { id: String(facilityId) }, - }), - enabled: !!facilityId, - }); - const { data: patientData } = useQuery({ queryKey: ["patient", related_patient], queryFn: query(routes.patient.getPatient, { @@ -167,17 +159,7 @@ export default function ResourceCreate(props: ResourceProps) { } return ( - +
diff --git a/src/components/Resource/ResourceDetails.tsx b/src/components/Resource/ResourceDetails.tsx index f684596c13a..182cd9ab514 100644 --- a/src/components/Resource/ResourceDetails.tsx +++ b/src/components/Resource/ResourceDetails.tsx @@ -123,11 +123,7 @@ export default function ResourceDetails({ } return ( - +
{/* Action Buttons */}
diff --git a/src/components/Resource/ResourceDetailsUpdate.tsx b/src/components/Resource/ResourceDetailsUpdate.tsx index 475fdd3da5c..e589a83c166 100644 --- a/src/components/Resource/ResourceDetailsUpdate.tsx +++ b/src/components/Resource/ResourceDetailsUpdate.tsx @@ -206,11 +206,7 @@ export const ResourceDetailsUpdate = (props: resourceProps) => { } return ( - +
diff --git a/src/components/Resource/ResourceList.tsx b/src/components/Resource/ResourceList.tsx index 96bab782705..83112e6a482 100644 --- a/src/components/Resource/ResourceList.tsx +++ b/src/components/Resource/ResourceList.tsx @@ -103,16 +103,7 @@ export default function ResourceList({ facilityId }: { facilityId: string }) { const resources = queryResources?.results || []; return ( - +
diff --git a/src/components/Users/UserHome.tsx b/src/components/Users/UserHome.tsx index c53aa40200a..3a78ed253ec 100644 --- a/src/components/Users/UserHome.tsx +++ b/src/components/Users/UserHome.tsx @@ -38,7 +38,6 @@ export default function UserHome(props: UserHomeProps) { if (!username) { username = authUser.username; } - const loggedInUser = username === authUser.username; const { data: userData, @@ -86,24 +85,11 @@ export default function UserHome(props: UserHomeProps) { ? `/facility/${props.facilityId}/users/${username}` : `/users/${username}`; - const usernameCrumb = { - [username]: { name: loggedInUser ? "Profile" : username }, - }; - - const hideUsersCrumb = { users: { hide: true } }; - - const crumbsReplacements = { - ...usernameCrumb, - ...(!props.facilityId && hideUsersCrumb), - }; - return ( <> { diff --git a/src/pages/Appointments/AppointmentDetail.tsx b/src/pages/Appointments/AppointmentDetail.tsx index 5c0624c1c2e..d83295d6a73 100644 --- a/src/pages/Appointments/AppointmentDetail.tsx +++ b/src/pages/Appointments/AppointmentDetail.tsx @@ -57,7 +57,6 @@ import { stringifyGeoOrganization, } from "@/Utils/utils"; import { AppointmentTokenCard } from "@/pages/Appointments/components/AppointmentTokenCard"; -import { formatAppointmentSlotTime } from "@/pages/Appointments/utils"; import { FacilityData } from "@/types/facility/facility"; import { Appointment, @@ -135,17 +134,9 @@ export default function AppointmentDetail(props: Props) { } const { patient } = appointment; - const appointmentDate = formatAppointmentSlotTime(appointment); return ( - +
+
diff --git a/src/pages/Encounters/EncounterShow.tsx b/src/pages/Encounters/EncounterShow.tsx index b060fcc3d2c..5792c749b87 100644 --- a/src/pages/Encounters/EncounterShow.tsx +++ b/src/pages/Encounters/EncounterShow.tsx @@ -97,21 +97,7 @@ export const EncounterShow = (props: Props) => { return (