From f746576b04a63ab7acd018cf2e2ea181deb21aea Mon Sep 17 00:00:00 2001 From: konavivekramakrishna <101407963+konavivekramakrishna@users.noreply.github.com> Date: Wed, 6 Dec 2023 13:25:44 +0530 Subject: [PATCH] Added a Date/time and round type filter for log updates (#6713) * Add DailyRoundsFilterModel interface and DailyRoundsFilter component * refactored dailyRoundList * useQuery: Fix GET/HEAD cannot contain body issue * Support for filtering by `taken_at` dt range * Refactor DailyRoundsFilter and DailyRoundsList components * Refactor roundTypeOptions in DailyRoundsFilter component * Improve translations coverage and minor refactors * update slugs for request --------- Co-authored-by: rithviknishad --- .../ConsultationUpdatesTab.tsx | 29 +--- .../DailyRounds/DefaultLogUpdateCard.tsx | 3 +- .../Consultations/DailyRoundsFilter.tsx | 115 +++++++++++++++ .../Consultations/DailyRoundsList.tsx | 134 +++++++++--------- src/Components/Facility/models.tsx | 2 +- .../Form/FormFields/SelectFormField.tsx | 2 +- src/Components/Patient/models.tsx | 7 +- src/Locale/en/Common.json | 3 +- src/Locale/en/Consultation.json | 5 +- src/Utils/request/utils.ts | 5 +- 10 files changed, 201 insertions(+), 104 deletions(-) create mode 100644 src/Components/Facility/Consultations/DailyRoundsFilter.tsx diff --git a/src/Components/Facility/ConsultationDetails/ConsultationUpdatesTab.tsx b/src/Components/Facility/ConsultationDetails/ConsultationUpdatesTab.tsx index bb584ae93e6..0d8a70781da 100644 --- a/src/Components/Facility/ConsultationDetails/ConsultationUpdatesTab.tsx +++ b/src/Components/Facility/ConsultationDetails/ConsultationUpdatesTab.tsx @@ -12,13 +12,12 @@ import PrescriptionsTable from "../../Medicine/PrescriptionsTable"; import Chip from "../../../CAREUI/display/Chip"; import { formatAge, formatDate, formatDateTime } from "../../../Utils/utils"; import ReadMore from "../../Common/components/Readmore"; -import { DailyRoundsList } from "../Consultations/DailyRoundsList"; +import DailyRoundsList from "../Consultations/DailyRoundsList"; const PageTitle = lazy(() => import("../../Common/PageTitle")); export const ConsultationUpdatesTab = (props: ConsultationTabProps) => { const dispatch: any = useDispatch(); - const [showAutomatedRounds, setShowAutomatedRounds] = useState(true); const [hl7SocketUrl, setHL7SocketUrl] = useState(); const [ventilatorSocketUrl, setVentilatorSocketUrl] = useState(); const [monitorBedData, setMonitorBedData] = useState(); @@ -674,31 +673,7 @@ export const ConsultationUpdatesTab = (props: ConsultationTabProps) => {
-
- -
- setShowAutomatedRounds((s) => !s)} - /> - -
-
- +
diff --git a/src/Components/Facility/Consultations/DailyRounds/DefaultLogUpdateCard.tsx b/src/Components/Facility/Consultations/DailyRounds/DefaultLogUpdateCard.tsx index 63b5087cff8..ff738f4acb6 100644 --- a/src/Components/Facility/Consultations/DailyRounds/DefaultLogUpdateCard.tsx +++ b/src/Components/Facility/Consultations/DailyRounds/DefaultLogUpdateCard.tsx @@ -4,10 +4,11 @@ import CareIcon from "../../../../CAREUI/icons/CareIcon"; import ButtonV2 from "../../../Common/components/ButtonV2"; import { DailyRoundsModel } from "../../../Patient/models"; import LogUpdateCardAttribute from "./LogUpdateCardAttribute"; +import { ConsultationModel } from "../../models"; interface Props { round: DailyRoundsModel; - consultationData: any; + consultationData: ConsultationModel; onViewDetails: () => void; onUpdateLog?: () => void; } diff --git a/src/Components/Facility/Consultations/DailyRoundsFilter.tsx b/src/Components/Facility/Consultations/DailyRoundsFilter.tsx new file mode 100644 index 00000000000..62b8d63e824 --- /dev/null +++ b/src/Components/Facility/Consultations/DailyRoundsFilter.tsx @@ -0,0 +1,115 @@ +import { Popover, Transition } from "@headlessui/react"; +import ButtonV2 from "../../Common/components/ButtonV2"; +import { Fragment } from "react"; +import { SelectFormField } from "../../Form/FormFields/SelectFormField"; +import TextFormField from "../../Form/FormFields/TextFormField"; +import CareIcon from "../../../CAREUI/icons/CareIcon"; +import dayjs from "dayjs"; +import { useState } from "react"; +import { useTranslation } from "react-i18next"; +import { DailyRoundTypes, DailyRoundsModel } from "../../Patient/models"; +import { FieldChangeEvent } from "../../Form/FormFields/Utils"; + +type FilterState = { + rounds_type?: DailyRoundsModel["rounds_type"]; + taken_at_after?: string; + taken_at_before?: string; +}; + +interface Props { + onApply: (filter: FilterState) => void; +} + +export default function DailyRoundsFilter(props: Props) { + const { t } = useTranslation(); + const [filter, setFilter] = useState({}); + + const field = (name: keyof FilterState) => ({ + name, + value: filter[name], + onChange: (e: FieldChangeEvent) => + setFilter({ ...filter, [e.name]: e.value }), + labelClassName: "text-sm", + errorClassName: "hidden", + }); + + return ( +
+ + + + + {t("filter")} + + + + +
+
+
+ + {t("filter_by")} + +
+
+
+ t(o)} + optionValue={(o) => o} + /> + + + + + { + setFilter({}); + props.onApply({}); + }} + border + className="w-full" + > + {t("clear")} + + + + props.onApply(filter)} + border + className="w-full" + > + {t("apply")} + + +
+
+
+
+
+
+ ); +} diff --git a/src/Components/Facility/Consultations/DailyRoundsList.tsx b/src/Components/Facility/Consultations/DailyRoundsList.tsx index ffc70ddf175..2060d8657e7 100644 --- a/src/Components/Facility/Consultations/DailyRoundsList.tsx +++ b/src/Components/Facility/Consultations/DailyRoundsList.tsx @@ -6,88 +6,84 @@ import { useTranslation } from "react-i18next"; import LoadingLogUpdateCard from "./DailyRounds/LoadingCard"; import routes from "../../../Redux/api"; import PaginatedList from "../../../CAREUI/misc/PaginatedList"; +import PageTitle from "../../Common/PageTitle"; +import DailyRoundsFilter from "./DailyRoundsFilter"; +import { ConsultationModel } from "../models"; +import { useSlugs } from "../../../Common/hooks/useSlug"; -export const DailyRoundsList = (props: any) => { +interface Props { + consultation: ConsultationModel; +} + +export default function DailyRoundsList({ consultation }: Props) { + const [facilityId, patientId, consultationId] = useSlugs( + "facility", + "patient", + "consultation" + ); const { t } = useTranslation(); - const { - facilityId, - patientId, - consultationId, - consultationData, - showAutomatedRounds, - } = props; + + const consultationUrl = `/facility/${facilityId}/patient/${patientId}/consultation/${consultationId}`; return ( - {(_) => ( -
-
- - - {t("no_consultation_updates")} - - - - <> - {Array.from({ length: 3 }).map((_, i) => ( - - ))} - - - className="flex grow flex-col gap-3"> - {(item, items) => { - if (item.rounds_type === "AUTOMATED") { + {({ refetch }) => ( + <> +
+ + refetch({ query })} /> +
+ +
+
+ + + {t("no_consultation_updates")} + + + + <> + {Array.from({ length: 3 }).map((_, i) => ( + + ))} + + + className="flex grow flex-col gap-3"> + {(item, items) => { + if (item.rounds_type === "AUTOMATED") { + return ( + + ); + } + + const itemUrl = + item.rounds_type === "NORMAL" + ? `${consultationUrl}/daily-rounds/${item.id}` + : `${consultationUrl}/daily_rounds/${item.id}`; + return ( - navigate(itemUrl)} + onUpdateLog={() => navigate(`${itemUrl}/update`)} /> ); - } - return ( - { - if (item.rounds_type === "NORMAL") { - navigate( - `/facility/${facilityId}/patient/${patientId}/consultation/${consultationId}/daily-rounds/${item.id}` - ); - } else { - navigate( - `/facility/${facilityId}/patient/${patientId}/consultation/${consultationId}/daily_rounds/${item.id}` - ); - } - }} - onUpdateLog={() => { - if (item.rounds_type === "NORMAL") { - navigate( - `/facility/${facilityId}/patient/${patientId}/consultation/${consultationId}/daily-rounds/${item.id}/update` - ); - } else { - navigate( - `/facility/${facilityId}/patient/${patientId}/consultation/${consultationId}/daily_rounds/${item.id}/update` - ); - } - }} - /> - ); - }} - -
- + }} + +
+ +
-
+ )} ); -}; +} diff --git a/src/Components/Facility/models.tsx b/src/Components/Facility/models.tsx index cdc7074c145..550012603f5 100644 --- a/src/Components/Facility/models.tsx +++ b/src/Components/Facility/models.tsx @@ -107,7 +107,7 @@ export interface ConsultationModel { history_of_present_illness?: string; facility?: number; facility_name?: string; - id?: string; + id: string; modified_date?: string; other_symptoms?: string; patient?: string; diff --git a/src/Components/Form/FormFields/SelectFormField.tsx b/src/Components/Form/FormFields/SelectFormField.tsx index 3c6613bb662..5afe4f11d63 100644 --- a/src/Components/Form/FormFields/SelectFormField.tsx +++ b/src/Components/Form/FormFields/SelectFormField.tsx @@ -7,7 +7,7 @@ type OptionCallback = (option: T) => R; type SelectFormFieldProps = FormFieldBaseProps & { placeholder?: React.ReactNode; - options: T[]; + options: readonly T[]; position?: "above" | "below"; optionLabel: OptionCallback; optionSelectedLabel?: OptionCallback; diff --git a/src/Components/Patient/models.tsx b/src/Components/Patient/models.tsx index 341e13e3c80..af69d8464bc 100644 --- a/src/Components/Patient/models.tsx +++ b/src/Components/Patient/models.tsx @@ -269,6 +269,8 @@ export interface DailyRoundsOutput { quantity: number; } +export const DailyRoundTypes = ["NORMAL", "VENTILATOR", "AUTOMATED"] as const; + export interface DailyRoundsModel { ventilator_spo2?: number; spo2?: string; @@ -290,7 +292,7 @@ export interface DailyRoundsModel { medication_given?: Array; additional_symptoms_text?: string; current_health?: string; - id?: any; + id: string; other_symptoms?: string; admitted_to?: string; patient_category?: PatientCategory; @@ -299,7 +301,7 @@ export interface DailyRoundsModel { created_date?: string; modified_date?: string; taken_at?: string; - rounds_type?: "NORMAL" | "VENTILATOR" | "ICU" | "AUTOMATED"; + rounds_type: (typeof DailyRoundTypes)[number]; last_updated_by_telemedicine?: boolean; created_by_telemedicine?: boolean; created_by?: { @@ -314,6 +316,7 @@ export interface DailyRoundsModel { }; bed?: string; } + export interface FacilityNameModel { id?: string; name?: string; diff --git a/src/Locale/en/Common.json b/src/Locale/en/Common.json index 7e357bc04b5..c455e3a989a 100644 --- a/src/Locale/en/Common.json +++ b/src/Locale/en/Common.json @@ -45,6 +45,7 @@ "clear": "Clear", "apply": "Apply", "filter_by": "Filter By", + "filter": "Filter", "ordering": "Ordering", "phone_number": "Phone Number", "emergency_contact_number": "Emergency Contact Number", @@ -158,4 +159,4 @@ "clear_selection": "Clear selection", "select_date": "Select date", "DD/MM/YYYY": "DD/MM/YYYY" -} +} \ No newline at end of file diff --git a/src/Locale/en/Consultation.json b/src/Locale/en/Consultation.json index a40f03c4f24..54b587eb81e 100644 --- a/src/Locale/en/Consultation.json +++ b/src/Locale/en/Consultation.json @@ -12,5 +12,8 @@ "discharge_summary_not_ready": "Discharge summary is not ready yet.", "download_discharge_summary": "Download discharge summary", "email_discharge_summary_description": "Enter your valid email address to receive the discharge summary", - "generated_summary_caution": "This is a computer generated summary using the information captured in the CARE system." + "generated_summary_caution": "This is a computer generated summary using the information captured in the CARE system.", + "NORMAL": "Normal", + "VENTILATOR": "Critical Care", + "AUTOMATED": "Automated" } diff --git a/src/Utils/request/utils.ts b/src/Utils/request/utils.ts index ec919c79490..f22dca369f2 100644 --- a/src/Utils/request/utils.ts +++ b/src/Utils/request/utils.ts @@ -82,7 +82,10 @@ export function mergeRequestOptions( ...overrides, query: { ...options.query, ...overrides.query }, - body: { ...(options.body ?? {}), ...(overrides.body ?? {}) }, + body: (options.body || overrides.body) && { + ...(options.body ?? {}), + ...(overrides.body ?? {}), + }, pathParams: { ...options.pathParams, ...overrides.pathParams }, onResponse: (res) => {