From 7fb4185297f98f4c0ee2ecf588c5be26bb4dce2c Mon Sep 17 00:00:00 2001 From: Ashraf Mohammed <98876115+AshrafMd-1@users.noreply.github.com> Date: Wed, 17 Apr 2024 15:08:38 +0530 Subject: [PATCH 01/28] Fix Domiciliary Care discrepancy. (#7568) * Fix bug * remove extra space Co-authored-by: Ashesh <3626859+Ashesh3@users.noreply.github.com> --------- Co-authored-by: Khavin Shankar <khavinshankar@gmail.com> Co-authored-by: Ashesh <3626859+Ashesh3@users.noreply.github.com> --- src/Components/Facility/TreatmentSummary.tsx | 8 ++++++-- src/Components/Patient/PatientInfoCard.tsx | 4 +++- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/Components/Facility/TreatmentSummary.tsx b/src/Components/Facility/TreatmentSummary.tsx index d0d1658cd61..a83cb64ec66 100644 --- a/src/Components/Facility/TreatmentSummary.tsx +++ b/src/Components/Facility/TreatmentSummary.tsx @@ -78,9 +78,13 @@ const TreatmentSummary = (props: any) => { </div> <div className="col-span-1 px-3 py-2"> - <b>Date of admission : </b> + {consultationData?.suggestion === "DC" ? ( + <b>Date of domiciliary care commenced : </b> + ) : ( + <b>Date of admission : </b> + )} <span> - {consultationData?.admitted + {consultationData?.encounter_date ? formatDateTime(consultationData.encounter_date) : " --/--/----"} </span> diff --git a/src/Components/Patient/PatientInfoCard.tsx b/src/Components/Patient/PatientInfoCard.tsx index b2f00dd1cc3..cb73739b3ba 100644 --- a/src/Components/Patient/PatientInfoCard.tsx +++ b/src/Components/Patient/PatientInfoCard.tsx @@ -401,7 +401,9 @@ export default function PatientInfoCard(props: { <span className="flex"> {consultation?.encounter_date && ( <div> - Admission on:{" "} + {consultation.suggestion === "DC" + ? "Commenced on: " + : "Admitted on: "} {formatDateTime(consultation?.encounter_date)} </div> )} From 214e45f8d0377ef01b4d8a950c352b3f49942314 Mon Sep 17 00:00:00 2001 From: Ashesh <3626859+Ashesh3@users.noreply.github.com> Date: Wed, 17 Apr 2024 15:09:23 +0530 Subject: [PATCH 02/28] Remove recording indicator when recorder is stopped (#7640) --- src/Utils/useRecorder.js | 7 +++++++ src/Utils/useSegmentedRecorder.ts | 12 +++++++++--- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/src/Utils/useRecorder.js b/src/Utils/useRecorder.js index 5c9dc324ce1..585e557d787 100644 --- a/src/Utils/useRecorder.js +++ b/src/Utils/useRecorder.js @@ -7,6 +7,12 @@ const useRecorder = (handleMicPermission) => { const [recorder, setRecorder] = useState(null); const [newBlob, setNewBlob] = useState(null); + useEffect(() => { + if (!isRecording && recorder && audioURL) { + setRecorder(null); + } + }, [isRecording, recorder, audioURL]); + useEffect(() => { // Lazily obtain recorder first time we're recording. if (recorder === null) { @@ -32,6 +38,7 @@ const useRecorder = (handleMicPermission) => { if (isRecording) { recorder.start(); } else { + recorder.stream.getTracks().forEach((i) => i.stop()); recorder.stop(); } diff --git a/src/Utils/useSegmentedRecorder.ts b/src/Utils/useSegmentedRecorder.ts index d58ca67bc7c..9434ea8383c 100644 --- a/src/Utils/useSegmentedRecorder.ts +++ b/src/Utils/useSegmentedRecorder.ts @@ -2,7 +2,6 @@ import { useState, useEffect } from "react"; import * as Notify from "./Notifications"; const useSegmentedRecording = () => { - const [audioURL, setAudioURL] = useState(""); const [isRecording, setIsRecording] = useState(false); const [recorder, setRecorder] = useState<MediaRecorder | null>(null); const [audioBlobs, setAudioBlobs] = useState<Blob[]>([]); @@ -11,6 +10,12 @@ const useSegmentedRecording = () => { const bufferInterval = 1 * 1000; const splitSizeLimit = 20 * 1000000; // 20MB + useEffect(() => { + if (!isRecording && recorder && audioBlobs.length > 0) { + setRecorder(null); + } + }, [isRecording, recorder, audioBlobs]); + useEffect(() => { if (recorder === null) { if (isRecording || restart) { @@ -37,6 +42,9 @@ const useSegmentedRecording = () => { } else { if (restart) { setIsRecording(true); + } else { + recorder?.stream?.getTracks()?.forEach((i) => i?.stop()); + recorder.stop(); } recorder.state === "recording" && recorder.stop(); } @@ -96,12 +104,10 @@ const useSegmentedRecording = () => { }; const resetRecording = () => { - setAudioURL(""); setAudioBlobs([]); }; return { - audioURL, isRecording, startRecording, stopRecording, From 5326da36946e88f391a22fd3834c0959522c12ec Mon Sep 17 00:00:00 2001 From: Pranshu Aggarwal <70687348+Pranshu1902@users.noreply.github.com> Date: Wed, 17 Apr 2024 15:10:13 +0530 Subject: [PATCH 03/28] Add Restriction to redirect to facility page if user can't Create Facility (#7633) --- src/Components/Facility/FacilityCreate.tsx | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/Components/Facility/FacilityCreate.tsx b/src/Components/Facility/FacilityCreate.tsx index 8aec0861d62..3138f374e4b 100644 --- a/src/Components/Facility/FacilityCreate.tsx +++ b/src/Components/Facility/FacilityCreate.tsx @@ -18,7 +18,7 @@ import { SelectFormField, } from "../Form/FormFields/SelectFormField"; import { Popover, Transition } from "@headlessui/react"; -import { Fragment, lazy, useState } from "react"; +import { Fragment, lazy, useEffect, useState } from "react"; import Steps, { Step } from "../Common/Steps"; import { getPincodeDetails, @@ -57,6 +57,7 @@ import request from "../../Utils/request/request.js"; import routes from "../../Redux/api.js"; import useQuery from "../../Utils/request/useQuery.js"; import { RequestResult } from "../../Utils/request/types.js"; +import useAuthUser from "../../Common/hooks/useAuthUser"; const Loading = lazy(() => import("../Common/Loading")); @@ -159,6 +160,21 @@ export const FacilityCreate = (props: FacilityProps) => { const headerText = !facilityId ? "Create Facility" : "Update Facility"; const buttonText = !facilityId ? "Save Facility" : "Update Facility"; + const authUser = useAuthUser(); + useEffect(() => { + if ( + authUser && + authUser.user_type !== "StateAdmin" && + authUser.user_type !== "DistrictAdmin" && + authUser.user_type !== "DistrictLabAdmin" + ) { + navigate("/facility"); + Notification.Error({ + msg: "You don't have permission to perform this action. Contact the admin", + }); + } + }, [authUser]); + const { data: districtData, refetch: districtFetch, From 5e641e446f4a5379de185241799965eb62590919 Mon Sep 17 00:00:00 2001 From: Bodhish Thomas <bodhish@gmail.com> Date: Wed, 17 Apr 2024 15:10:54 +0530 Subject: [PATCH 04/28] Add combine action to merge dependabot prs (#7614) Co-authored-by: Mohammed Nihal <57055998+nihal467@users.noreply.github.com> --- .github/workflows/combine.yml | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 .github/workflows/combine.yml diff --git a/.github/workflows/combine.yml b/.github/workflows/combine.yml new file mode 100644 index 00000000000..d44461ff5a7 --- /dev/null +++ b/.github/workflows/combine.yml @@ -0,0 +1,23 @@ +name: Combine Dependencies + +on: workflow_dispatch + +# The minimum permissions required to run this Action +permissions: + contents: write + pull-requests: write + checks: read + +jobs: + combine-prs: + runs-on: ubuntu-latest + + steps: + - name: Combine dependencies + id: combine-dependencies + uses: github/combine-prs@v5.0.0 + with: + pr_title: Combined dependencies # The title of the pull request to create + select_label: dependencies # The label which marks PRs that should be combined. + labels: combined-dependencies # Add a label to the combined PR + ci_required: "false" # Whether or not CI should be passing to combine the PR From 821cf2a8f0e63e0af6728a31340cdb17561cfc94 Mon Sep 17 00:00:00 2001 From: Vedant Jain <129421822+jainvedant392@users.noreply.github.com> Date: Wed, 17 Apr 2024 15:20:34 +0530 Subject: [PATCH 05/28] Add Patient Filter for Review Missed (#7328) * Add Patient Filter for Review Missed * removed dotenv * modified vite.config.mts --- src/Components/Patient/ManagePatients.tsx | 2 ++ src/Components/Patient/PatientFilter.tsx | 15 +++++++++++++++ 2 files changed, 17 insertions(+) diff --git a/src/Components/Patient/ManagePatients.tsx b/src/Components/Patient/ManagePatients.tsx index 09d5a06fa32..e2890f0cc79 100644 --- a/src/Components/Patient/ManagePatients.tsx +++ b/src/Components/Patient/ManagePatients.tsx @@ -225,6 +225,7 @@ export const PatientManager = () => { diagnoses_provisional: qParams.diagnoses_provisional || undefined, diagnoses_unconfirmed: qParams.diagnoses_unconfirmed || undefined, diagnoses_differential: qParams.diagnoses_differential || undefined, + review_missed: qParams.review_missed || undefined, }; useEffect(() => { @@ -944,6 +945,7 @@ export const PatientManager = () => { kasp(), badge("COWIN ID", "covin_id"), badge("Is Antenatal", "is_antenatal"), + badge("Review Missed", "review_missed"), badge( "Is Medico-Legal Case", "last_consultation_medico_legal_case", diff --git a/src/Components/Patient/PatientFilter.tsx b/src/Components/Patient/PatientFilter.tsx index 0c0087e6d66..79a04242170 100644 --- a/src/Components/Patient/PatientFilter.tsx +++ b/src/Components/Patient/PatientFilter.tsx @@ -100,6 +100,7 @@ export default function PatientFilter(props: any) { diagnoses_provisional: filter.diagnoses_provisional || null, diagnoses_unconfirmed: filter.diagnoses_unconfirmed || null, diagnoses_differential: filter.diagnoses_differential || null, + review_missed: filter.review_missed || null, }); useQuery(routes.getAnyFacility, { @@ -203,6 +204,7 @@ export default function PatientFilter(props: any) { diagnoses_provisional, diagnoses_unconfirmed, diagnoses_differential, + review_missed, } = filterState; const data = { district: district || "", @@ -270,6 +272,7 @@ export default function PatientFilter(props: any) { diagnoses_provisional: diagnoses_provisional || "", diagnoses_unconfirmed: diagnoses_unconfirmed || "", diagnoses_differential: diagnoses_differential || "", + review_missed: review_missed || "", }; onChange(data); }; @@ -437,6 +440,18 @@ export default function PatientFilter(props: any) { } /> </div> + <div className="w-full flex-none"> + <FieldLabel className="text-sm">Review Missed</FieldLabel> + <SelectMenuV2 + placeholder="Show all" + options={["true", "false"]} + optionLabel={(o) => (o === "true" ? "Yes" : "No")} + value={filterState.review_missed} + onChange={(v) => + setFilterState({ ...filterState, review_missed: v }) + } + /> + </div> <div className="w-full flex-none"> <FieldLabel className="text-sm">Is Medico-Legal Case</FieldLabel> <SelectMenuV2 From c7372fb2ec1a280dd9e55fe3bbedf423248250d6 Mon Sep 17 00:00:00 2001 From: Aryan <92309448+Aryanshu919@users.noreply.github.com> Date: Wed, 17 Apr 2024 15:27:35 +0530 Subject: [PATCH 06/28] Fix: #7536 (#7549) --- src/Components/Form/FormFields/TextFormField.tsx | 2 +- src/Components/Patient/PatientRegister.tsx | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Components/Form/FormFields/TextFormField.tsx b/src/Components/Form/FormFields/TextFormField.tsx index 8f1ee341e34..b2a84e51595 100644 --- a/src/Components/Form/FormFields/TextFormField.tsx +++ b/src/Components/Form/FormFields/TextFormField.tsx @@ -100,7 +100,7 @@ const TextFormField = forwardRef((props: TextFormFieldProps, ref) => { ); const _trailing = trailing === trailingFocused ? ( - <div className="absolute inset-y-0 right-0 flex items-center pr-3"> + <div className="relative inset-y-0 right-0 flex items-center pr-3"> {trailing} </div> ) : ( diff --git a/src/Components/Patient/PatientRegister.tsx b/src/Components/Patient/PatientRegister.tsx index 3be6b985dda..dbc5b869e3e 100644 --- a/src/Components/Patient/PatientRegister.tsx +++ b/src/Components/Patient/PatientRegister.tsx @@ -1382,10 +1382,10 @@ export const PatientRegister = (props: PatientRegisterProps) => { {...field("age")} errorClassName="hidden" trailing={ - <p className="absolute right-16 text-xs text-gray-700 sm:text-sm"> - <p className="hidden sm:inline min-[768px]:hidden lg:inline"> + <p className="absolute right-16 mb-11 text-xs text-gray-700 sm:text-sm"> + <p className="hidden sm:inline min-[768px]:hidden lg:inline"> {field("age").value !== "" && - "Year_of_Birth:"} + "Year of Birth:"} </p> <span className="font-bold"> {field("age").value !== "" && From 997a7147f329e33eb11ff77db0af59534c97f1cc Mon Sep 17 00:00:00 2001 From: Aryan <92309448+Aryanshu919@users.noreply.github.com> Date: Wed, 17 Apr 2024 15:28:14 +0530 Subject: [PATCH 07/28] Fix: HL7 Vital Monitor error message is clipping out #7534 (#7550) --- src/Components/VitalsMonitor/HL7PatientVitalsMonitor.tsx | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Components/VitalsMonitor/HL7PatientVitalsMonitor.tsx b/src/Components/VitalsMonitor/HL7PatientVitalsMonitor.tsx index 0d5a137becc..61c62f80c70 100644 --- a/src/Components/VitalsMonitor/HL7PatientVitalsMonitor.tsx +++ b/src/Components/VitalsMonitor/HL7PatientVitalsMonitor.tsx @@ -151,9 +151,11 @@ export default function HL7PatientVitalsMonitor(props: IVitalsComponentProps) { > <CareIcon icon="l-cloud-times" - className="mb-2 animate-pulse text-4xl" + className="mb-2 animate-pulse text-4xl md:mr-36 " /> - <span className="font-bold">No incoming data from HL7 Monitor</span> + <span className="font-bold md:mr-36"> + No incoming data from HL7 Monitor + </span> </div> <div className={classNames("relative", !isOnline && "hidden")} From 7742c017b30ac0771dde8ffcaed33eb0880e3de6 Mon Sep 17 00:00:00 2001 From: Ashraf Mohammed <98876115+AshrafMd-1@users.noreply.github.com> Date: Thu, 18 Apr 2024 15:22:19 +0530 Subject: [PATCH 08/28] fix loading (#7643) --- src/Components/Patient/SampleDetails.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Components/Patient/SampleDetails.tsx b/src/Components/Patient/SampleDetails.tsx index f66805a3ded..a3d3df95c21 100644 --- a/src/Components/Patient/SampleDetails.tsx +++ b/src/Components/Patient/SampleDetails.tsx @@ -265,7 +265,7 @@ export const SampleDetails = ({ id }: DetailRoute) => { ); }; - if (isLoading) { + if (isLoading || !sampleDetails) { return <Loading />; } From c331b845a57b64b1466ea327ae712e625300e20f Mon Sep 17 00:00:00 2001 From: Pranshu Aggarwal <70687348+Pranshu1902@users.noreply.github.com> Date: Thu, 18 Apr 2024 15:33:39 +0530 Subject: [PATCH 09/28] Add option to mark notification as unread (#7553) * add option to mark notification as unread * Update src/Locale/en/Notifications.json Co-authored-by: Mohammed Nihal <57055998+nihal467@users.noreply.github.com> * fix lint errrors * fix lint with updated prettier --------- Co-authored-by: Mohammed Nihal <57055998+nihal467@users.noreply.github.com> --- .../Notifications/NotificationsList.tsx | 33 +++++++++++++++---- src/Locale/en/Notifications.json | 1 + src/Redux/api.tsx | 5 +++ 3 files changed, 32 insertions(+), 7 deletions(-) diff --git a/src/Components/Notifications/NotificationsList.tsx b/src/Components/Notifications/NotificationsList.tsx index 02cb1f4fa8b..c9e6720e6ad 100644 --- a/src/Components/Notifications/NotificationsList.tsx +++ b/src/Components/Notifications/NotificationsList.tsx @@ -46,6 +46,16 @@ const NotificationTile = ({ setIsMarkingAsRead(false); }; + const handleMarkAsUnRead = async () => { + setIsMarkingAsRead(true); + await request(routes.markNotificationAsUnRead, { + pathParams: { id: result.id }, + body: { read_at: null }, + }); + setResult({ ...result, read_at: null }); + setIsMarkingAsRead(false); + }; + const resultUrl = (event: string, data: any) => { switch (event) { case "PATIENT_CREATED": @@ -107,24 +117,33 @@ const NotificationTile = ({ </div> <div className="flex justify-end gap-2"> <ButtonV2 - className={classNames( - "bg-white px-2 py-1 font-semibold hover:bg-secondary-300", - result.read_at && "invisible", - )} + className="bg-white px-2 py-1 font-semibold hover:bg-secondary-300" variant="secondary" border ghost disabled={isMarkingAsRead} onClick={(event) => { event.stopPropagation(); - handleMarkAsRead(); + if (result.read_at) { + handleMarkAsUnRead(); + } else { + handleMarkAsRead(); + } }} > <CareIcon - icon={isMarkingAsRead ? "l-spinner" : "l-envelope-check"} + icon={ + isMarkingAsRead + ? "l-spinner" + : result.read_at + ? "l-envelope" + : "l-envelope-check" + } className={isMarkingAsRead ? "animate-spin" : ""} /> - <span className="text-xs">{t("mark_as_read")}</span> + <span className="text-xs"> + {result.read_at ? t("mark_as_unread") : t("mark_as_read")} + </span> </ButtonV2> <ButtonV2 border diff --git a/src/Locale/en/Notifications.json b/src/Locale/en/Notifications.json index 8c6255ca850..ad8dc0e20f1 100644 --- a/src/Locale/en/Notifications.json +++ b/src/Locale/en/Notifications.json @@ -1,6 +1,7 @@ { "no_notices_for_you": "No notices for you.", "mark_as_read": "Mark as Read", + "mark_as_unread": "Mark as Unread", "subscribe": "Subscribe", "subscribe_on_this_device": "Subscribe on this device", "show_unread_notifications": "Show Unread", diff --git a/src/Redux/api.tsx b/src/Redux/api.tsx index 7445cd3352f..4dd3480ec8c 100644 --- a/src/Redux/api.tsx +++ b/src/Redux/api.tsx @@ -1062,6 +1062,11 @@ const routes = { method: "PATCH", TRes: Type<NotificationData>(), }, + markNotificationAsUnRead: { + path: "/api/v1/notification/{id}/", + method: "PATCH", + TRes: Type<NotificationData>(), + }, getPublicKey: { path: "/api/v1/notification/public_key/", method: "GET", From 48db450d15e66789d0e8a33f02d3e4c0c359bc93 Mon Sep 17 00:00:00 2001 From: Khavin Shankar <khavinshankar@gmail.com> Date: Thu, 18 Apr 2024 16:22:26 +0530 Subject: [PATCH 10/28] added support for various abha qr in scan and pull (#7565) --- src/Components/ABDM/LinkABHANumberModal.tsx | 4 ++-- src/Components/ABDM/models.ts | 8 +++++--- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/Components/ABDM/LinkABHANumberModal.tsx b/src/Components/ABDM/LinkABHANumberModal.tsx index fe789e6c909..d7dfc9f60c1 100644 --- a/src/Components/ABDM/LinkABHANumberModal.tsx +++ b/src/Components/ABDM/LinkABHANumberModal.tsx @@ -194,12 +194,12 @@ const ScanABHAQRSection = ({ body: { patientId, hidn: abha?.hidn, - phr: abha?.hid, + phr: (abha?.phr ?? abha?.hid) as string, name: abha?.name, gender: abha?.gender, dob: abha?.dob.replace(/\//g, "-"), address: abha?.address, - "dist name": abha?.district_name, + "dist name": abha?.["dist name"] ?? abha?.district_name, "state name": abha?.["state name"], }, }); diff --git a/src/Components/ABDM/models.ts b/src/Components/ABDM/models.ts index 957dc9c2d17..9dc362f5cac 100644 --- a/src/Components/ABDM/models.ts +++ b/src/Components/ABDM/models.ts @@ -123,10 +123,12 @@ export interface ILinkViaQRBody { export interface ABHAQRContent { address: string; distlgd: string; - district_name: string; + district_name?: string; dob: string; - gender: "M"; - hid: string; + gender: "M" | "F" | "O"; + hid?: string; + phr?: string; + "dist name"?: string; hidn: string; mobile: string; name: string; From 78bdc551587c095dabed92b07a115c07f7f41331 Mon Sep 17 00:00:00 2001 From: Mohammed Nihal <57055998+nihal467@users.noreply.github.com> Date: Thu, 18 Apr 2024 17:57:13 +0530 Subject: [PATCH 11/28] flaky test (#7657) --- cypress/e2e/assets_spec/assets_creation.cy.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/cypress/e2e/assets_spec/assets_creation.cy.ts b/cypress/e2e/assets_spec/assets_creation.cy.ts index f8edc2bb172..cd3489a14d8 100644 --- a/cypress/e2e/assets_spec/assets_creation.cy.ts +++ b/cypress/e2e/assets_spec/assets_creation.cy.ts @@ -160,12 +160,10 @@ describe("Asset", () => { assetPage.interceptAssetCreation(); assetPage.clickCreateAsset(); assetPage.verifyAssetCreation(); - assetSearchPage.typeSearchKeyword("New Test Asset Vital"); assetSearchPage.pressEnter(); - assetPage.openCreatedAsset(); - assetPage.configureVitalAsset("Host name", "192.168.1.64"); + assetPage.configureVitalAsset("Host name", "192.168.1.20"); assetPage.clickConfigureVital(); }); From e84087a71225a70ad61b5560d8b27f898a6d648e Mon Sep 17 00:00:00 2001 From: Ashesh <3626859+Ashesh3@users.noreply.github.com> Date: Sat, 20 Apr 2024 18:05:41 +0530 Subject: [PATCH 12/28] Fix round type display and qr field (#7666) --- .../DailyRounds/LogUpdateCardAttribute.tsx | 12 ++++++++++++ src/Components/Form/FormFields/TextFormField.tsx | 2 +- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/Components/Facility/Consultations/DailyRounds/LogUpdateCardAttribute.tsx b/src/Components/Facility/Consultations/DailyRounds/LogUpdateCardAttribute.tsx index 3afed28dda8..d3e4b03be0a 100644 --- a/src/Components/Facility/Consultations/DailyRounds/LogUpdateCardAttribute.tsx +++ b/src/Components/Facility/Consultations/DailyRounds/LogUpdateCardAttribute.tsx @@ -62,6 +62,18 @@ const LogUpdateCardAttribute = <T extends keyof DailyRoundsModel>({ </div> ); + case "rounds_type": + return ( + <div className="flex flex-col items-center gap-2 md:flex-row"> + <AttributeLabel attributeKey={attributeKey} /> + <span className="text-sm font-semibold text-gray-700"> + {(attributeValue as string) === "VENTILATOR" + ? "Critical Care" + : (attributeValue as string)} + </span> + </div> + ); + default: return ( <div className="flex flex-col items-center gap-2 md:flex-row"> diff --git a/src/Components/Form/FormFields/TextFormField.tsx b/src/Components/Form/FormFields/TextFormField.tsx index b2a84e51595..8f1ee341e34 100644 --- a/src/Components/Form/FormFields/TextFormField.tsx +++ b/src/Components/Form/FormFields/TextFormField.tsx @@ -100,7 +100,7 @@ const TextFormField = forwardRef((props: TextFormFieldProps, ref) => { ); const _trailing = trailing === trailingFocused ? ( - <div className="relative inset-y-0 right-0 flex items-center pr-3"> + <div className="absolute inset-y-0 right-0 flex items-center pr-3"> {trailing} </div> ) : ( From 768a5b39b19156e59414175e03e7ff6a247c5970 Mon Sep 17 00:00:00 2001 From: Mohammed Nihal <57055998+nihal467@users.noreply.github.com> Date: Sat, 20 Apr 2024 18:47:18 +0530 Subject: [PATCH 13/28] minor case issue (#7668) --- .../Consultations/DailyRounds/LogUpdateCardAttribute.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Components/Facility/Consultations/DailyRounds/LogUpdateCardAttribute.tsx b/src/Components/Facility/Consultations/DailyRounds/LogUpdateCardAttribute.tsx index d3e4b03be0a..4e5b7408266 100644 --- a/src/Components/Facility/Consultations/DailyRounds/LogUpdateCardAttribute.tsx +++ b/src/Components/Facility/Consultations/DailyRounds/LogUpdateCardAttribute.tsx @@ -68,7 +68,7 @@ const LogUpdateCardAttribute = <T extends keyof DailyRoundsModel>({ <AttributeLabel attributeKey={attributeKey} /> <span className="text-sm font-semibold text-gray-700"> {(attributeValue as string) === "VENTILATOR" - ? "Critical Care" + ? "CRITICAL CARE" : (attributeValue as string)} </span> </div> From 518200d711904b017216457d0db39098f2e631d3 Mon Sep 17 00:00:00 2001 From: rithviknishad <mail@rithviknishad.dev> Date: Sun, 21 Apr 2024 20:21:46 +0530 Subject: [PATCH 14/28] Fixes discharge information showing incorrect label for base dosage --- src/Locale/en/Medicine.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Locale/en/Medicine.json b/src/Locale/en/Medicine.json index 95ddda7c1fd..36adc259514 100644 --- a/src/Locale/en/Medicine.json +++ b/src/Locale/en/Medicine.json @@ -2,6 +2,7 @@ "medicine": "Medicine", "route": "Route", "dosage": "Dosage", + "base_dosage": "Dosage", "start_dosage": "Start Dosage", "target_dosage": "Target Dosage", "instruction_on_titration": "Instruction on titration", @@ -58,4 +59,4 @@ "PRESCRIPTION_FREQUENCY_Q4H": "4th hourly", "PRESCRIPTION_FREQUENCY_QOD": "Alternate day", "PRESCRIPTION_FREQUENCY_QWK": "Once a week" -} +} \ No newline at end of file From a7be2efb7c64a6da71fcea2a1d75e79d9fa5ac4e Mon Sep 17 00:00:00 2001 From: rithviknishad <mail@rithviknishad.dev> Date: Sun, 21 Apr 2024 20:22:33 +0530 Subject: [PATCH 15/28] disabled discontinue/administer/edit prescription operations for discharged consultations --- .../AdministrationTable.tsx | 3 + .../AdministrationTableRow.tsx | 246 +++++++++--------- .../MedicineAdministrationSheet/index.tsx | 1 + 3 files changed, 132 insertions(+), 118 deletions(-) diff --git a/src/Components/Medicine/MedicineAdministrationSheet/AdministrationTable.tsx b/src/Components/Medicine/MedicineAdministrationSheet/AdministrationTable.tsx index b983965237a..18d27bf1651 100644 --- a/src/Components/Medicine/MedicineAdministrationSheet/AdministrationTable.tsx +++ b/src/Components/Medicine/MedicineAdministrationSheet/AdministrationTable.tsx @@ -10,9 +10,11 @@ interface Props { prescriptions: Prescription[]; pagination: ReturnType<typeof useRangePagination>; onRefetch: () => void; + readonly: boolean; } export default function MedicineAdministrationTable({ + readonly, pagination, prescriptions, onRefetch, @@ -101,6 +103,7 @@ export default function MedicineAdministrationTable({ prescription={obj} intervals={pagination.slots!} refetch={onRefetch} + readonly={readonly} /> ))} </tbody> diff --git a/src/Components/Medicine/MedicineAdministrationSheet/AdministrationTableRow.tsx b/src/Components/Medicine/MedicineAdministrationSheet/AdministrationTableRow.tsx index 50b96c9cc0f..f913286c574 100644 --- a/src/Components/Medicine/MedicineAdministrationSheet/AdministrationTableRow.tsx +++ b/src/Components/Medicine/MedicineAdministrationSheet/AdministrationTableRow.tsx @@ -19,6 +19,7 @@ interface Props { prescription: Prescription; intervals: { start: Date; end: Date }[]; refetch: () => void; + readonly: boolean; } export default function MedicineAdministrationTableRow({ @@ -54,12 +55,7 @@ export default function MedicineAdministrationTableRow({ ); return ( - <tr - className={classNames( - "group transition-all duration-200 ease-in-out", - loading ? "bg-gray-300" : "bg-white hover:bg-primary-100", - )} - > + <> {showDiscontinue && ( <DiscontinuePrescription prescription={prescription} @@ -96,42 +92,46 @@ export default function MedicineAdministrationTableRow({ onClick={() => setShowDetails(false)} label={t("close")} /> - <Submit - disabled={ - prescription.discontinued || - prescription.prescription_type === "DISCHARGE" - } - variant="danger" - onClick={() => setShowDiscontinue(true)} - > - <CareIcon icon="l-ban" className="text-lg" /> - {t("discontinue")} - </Submit> - <Submit - disabled={ - prescription.discontinued || - prescription.prescription_type === "DISCHARGE" - } - variant="secondary" - border - onClick={() => { - setShowDetails(false); - setShowEdit(true); - }} - > - <CareIcon icon="l-pen" className="text-lg" /> - {t("edit")} - </Submit> - <Submit - disabled={ - prescription.discontinued || - prescription.prescription_type === "DISCHARGE" - } - onClick={() => setShowAdminister(true)} - > - <CareIcon icon="l-syringe" className="text-lg" /> - {t("administer")} - </Submit> + {!props.readonly && ( + <> + <Submit + disabled={ + prescription.discontinued || + prescription.prescription_type === "DISCHARGE" + } + variant="danger" + onClick={() => setShowDiscontinue(true)} + > + <CareIcon icon="l-ban" className="text-lg" /> + {t("discontinue")} + </Submit> + <Submit + disabled={ + prescription.discontinued || + prescription.prescription_type === "DISCHARGE" + } + variant="secondary" + border + onClick={() => { + setShowDetails(false); + setShowEdit(true); + }} + > + <CareIcon icon="l-pen" className="text-lg" /> + {t("edit")} + </Submit> + <Submit + disabled={ + prescription.discontinued || + prescription.prescription_type === "DISCHARGE" + } + onClick={() => setShowAdminister(true)} + > + <CareIcon icon="l-syringe" className="text-lg" /> + {t("administer")} + </Submit> + </> + )} </div> </div> </DialogModal> @@ -166,93 +166,103 @@ export default function MedicineAdministrationTableRow({ /> </DialogModal> )} - <td - className="bg-gray-white sticky left-0 z-10 cursor-pointer bg-white py-3 pl-4 text-left transition-all duration-200 ease-in-out group-hover:bg-primary-100" - onClick={() => setShowDetails(true)} + <tr + className={classNames( + "group transition-all duration-200 ease-in-out", + loading ? "bg-gray-300" : "bg-white hover:bg-primary-100", + )} > - <div className="flex flex-col gap-1 lg:flex-row lg:justify-between lg:gap-2"> - <div className="flex items-center gap-2"> - <span - className={classNames( - "text-sm font-semibold", - prescription.discontinued ? "text-gray-700" : "text-gray-900", + <td + className="bg-gray-white sticky left-0 z-10 cursor-pointer bg-white py-3 pl-4 text-left transition-all duration-200 ease-in-out group-hover:bg-primary-100" + onClick={() => setShowDetails(true)} + > + <div className="flex flex-col gap-1 lg:flex-row lg:justify-between lg:gap-2"> + <div className="flex items-center gap-2"> + <span + className={classNames( + "text-sm font-semibold", + prescription.discontinued ? "text-gray-700" : "text-gray-900", + )} + > + {prescription.medicine_object?.name ?? + prescription.medicine_old} + </span> + + {prescription.discontinued && ( + <span className="hidden rounded-full border border-gray-500 bg-gray-200 px-1.5 text-xs font-medium text-gray-700 lg:block"> + {t("discontinued")} + </span> )} - > - {prescription.medicine_object?.name ?? prescription.medicine_old} - </span> - {prescription.discontinued && ( - <span className="hidden rounded-full border border-gray-500 bg-gray-200 px-1.5 text-xs font-medium text-gray-700 lg:block"> - {t("discontinued")} - </span> - )} + {prescription.route && ( + <span className="hidden rounded-full border border-blue-500 bg-blue-100 px-1.5 text-xs font-medium text-blue-700 lg:block"> + {t(prescription.route)} + </span> + )} + </div> - {prescription.route && ( - <span className="hidden rounded-full border border-blue-500 bg-blue-100 px-1.5 text-xs font-medium text-blue-700 lg:block"> - {t(prescription.route)} - </span> - )} - </div> + <div className="flex gap-1 text-xs font-semibold text-gray-900 lg:flex-col lg:px-2 lg:text-center"> + {prescription.dosage_type !== "TITRATED" ? ( + <p>{prescription.base_dosage}</p> + ) : ( + <p> + {prescription.base_dosage} - {prescription.target_dosage} + </p> + )} - <div className="flex gap-1 text-xs font-semibold text-gray-900 lg:flex-col lg:px-2 lg:text-center"> - {prescription.dosage_type !== "TITRATED" ? ( - <p>{prescription.base_dosage}</p> - ) : ( <p> - {prescription.base_dosage} - {prescription.target_dosage} + {prescription.dosage_type !== "PRN" + ? t("PRESCRIPTION_FREQUENCY_" + prescription.frequency) + : prescription.indicator} </p> - )} - - <p> - {prescription.dosage_type !== "PRN" - ? t("PRESCRIPTION_FREQUENCY_" + prescription.frequency) - : prescription.indicator} - </p> + </div> </div> - </div> - </td> + </td> - <td /> + <td /> - {/* Administration Cells */} - {props.intervals.map(({ start, end }, index) => ( - <> - <td key={`event-seperator-${index}`}> - <AdministrationEventSeperator date={start} /> - </td> + {/* Administration Cells */} + {props.intervals.map(({ start, end }, index) => ( + <> + <td key={`event-seperator-${index}`}> + <AdministrationEventSeperator date={start} /> + </td> - <td key={`event-socket-${index}`} className="text-center"> - {!data?.results ? ( - <CareIcon - icon="l-spinner" - className="animate-spin text-lg text-gray-500" - /> - ) : ( - <AdministrationEventCell - administrations={data.results} - interval={{ start, end }} - prescription={prescription} - refetch={refetch} - /> - )} - </td> - </> - ))} - <td /> + <td key={`event-socket-${index}`} className="text-center"> + {!data?.results ? ( + <CareIcon + icon="l-spinner" + className="animate-spin text-lg text-gray-500" + /> + ) : ( + <AdministrationEventCell + administrations={data.results} + interval={{ start, end }} + prescription={prescription} + refetch={refetch} + /> + )} + </td> + </> + ))} + <td /> - {/* Action Buttons */} - <td className="space-x-1 pr-2 text-right"> - <ButtonV2 - type="button" - size="small" - disabled={prescription.discontinued} - ghost - border - onClick={() => setShowAdminister(true)} - > - {t("administer")} - </ButtonV2> - </td> - </tr> + {/* Action Buttons */} + <td className="space-x-1 pr-2 text-right"> + {!props.readonly && ( + <ButtonV2 + type="button" + size="small" + disabled={prescription.discontinued} + ghost + border + onClick={() => setShowAdminister(true)} + > + {t("administer")} + </ButtonV2> + )} + </td> + </tr> + </> ); } diff --git a/src/Components/Medicine/MedicineAdministrationSheet/index.tsx b/src/Components/Medicine/MedicineAdministrationSheet/index.tsx index 41a681f26b0..4c054edcaf3 100644 --- a/src/Components/Medicine/MedicineAdministrationSheet/index.tsx +++ b/src/Components/Medicine/MedicineAdministrationSheet/index.tsx @@ -140,6 +140,7 @@ const MedicineAdministrationSheet = ({ readonly, is_prn }: Props) => { refetch(); discontinuedPrescriptions.refetch(); }} + readonly={readonly || false} /> )} </> From 6fceb4241c1c632e61759e783ebcb490018a56b0 Mon Sep 17 00:00:00 2001 From: rithviknishad <mail@rithviknishad.dev> Date: Sun, 21 Apr 2024 20:25:33 +0530 Subject: [PATCH 16/28] disallow titrated prescription for discharge --- .../Medicine/CreatePrescriptionForm.tsx | 41 ++++++++++--------- 1 file changed, 21 insertions(+), 20 deletions(-) diff --git a/src/Components/Medicine/CreatePrescriptionForm.tsx b/src/Components/Medicine/CreatePrescriptionForm.tsx index 07e8ec208d6..fcc9443eaa3 100644 --- a/src/Components/Medicine/CreatePrescriptionForm.tsx +++ b/src/Components/Medicine/CreatePrescriptionForm.tsx @@ -61,26 +61,27 @@ export default function CreatePrescriptionForm(props: { {...field("medicine_object", RequiredFieldValidator())} required /> - {props.prescription.dosage_type !== "PRN" && ( - <CheckBoxFormField - label={t("titrate_dosage")} - name="Titrate Dosage" - value={field("dosage_type").value === "TITRATED"} - onChange={(e) => { - if (e.value) { - field("dosage_type").onChange({ - name: "dosage_type", - value: "TITRATED", - }); - } else { - field("dosage_type").onChange({ - name: "dosage_type", - value: "REGULAR", - }); - } - }} - /> - )} + {props.prescription.dosage_type !== "PRN" && + props.prescription.prescription_type !== "DISCHARGE" && ( + <CheckBoxFormField + label={t("titrate_dosage")} + name="Titrate Dosage" + value={field("dosage_type").value === "TITRATED"} + onChange={(e) => { + if (e.value) { + field("dosage_type").onChange({ + name: "dosage_type", + value: "TITRATED", + }); + } else { + field("dosage_type").onChange({ + name: "dosage_type", + value: "REGULAR", + }); + } + }} + /> + )} <div className="flex flex-wrap items-center gap-x-4"> <SelectFormField className="flex-1" From 86259bff1cf02055b12123ad5f475689d37c4357 Mon Sep 17 00:00:00 2001 From: rithviknishad <mail@rithviknishad.dev> Date: Sun, 21 Apr 2024 20:35:40 +0530 Subject: [PATCH 17/28] fixes incorrect null checks for referred to facility in discharge modal --- src/Components/Facility/DischargeModal.tsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Components/Facility/DischargeModal.tsx b/src/Components/Facility/DischargeModal.tsx index 6a6b8c48ead..35e6fba1cf6 100644 --- a/src/Components/Facility/DischargeModal.tsx +++ b/src/Components/Facility/DischargeModal.tsx @@ -165,12 +165,12 @@ const DischargeModal = ({ } }; - const handleFacilitySelect = (selected: FacilityModel) => { + const handleFacilitySelect = (selected?: FacilityModel) => { setFacility(selected); setPreDischargeForm((prev) => ({ ...prev, - referred_to: selected.id ?? null, - referred_to_external: !selected.id ? selected.name : null, + referred_to: selected?.id ?? null, + referred_to_external: selected?.name || null, })); }; @@ -215,7 +215,7 @@ const DischargeModal = ({ <FacilitySelect name="referred_to" setSelected={(selected) => - handleFacilitySelect(selected as FacilityModel) + handleFacilitySelect(selected as FacilityModel | undefined) } selected={facility ?? null} showAll From e8fefad23ff60c88473a3e83f94ed13ea236e745 Mon Sep 17 00:00:00 2001 From: rithviknishad <mail@rithviknishad.dev> Date: Sun, 21 Apr 2024 20:56:29 +0530 Subject: [PATCH 18/28] fix typo --- src/Components/Facility/DischargeModal.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Components/Facility/DischargeModal.tsx b/src/Components/Facility/DischargeModal.tsx index 35e6fba1cf6..7b170379066 100644 --- a/src/Components/Facility/DischargeModal.tsx +++ b/src/Components/Facility/DischargeModal.tsx @@ -170,7 +170,7 @@ const DischargeModal = ({ setPreDischargeForm((prev) => ({ ...prev, referred_to: selected?.id ?? null, - referred_to_external: selected?.name || null, + referred_to_external: !selected?.id ? selected?.name : null, })); }; From dfede2cca5a016af91216091b4abc1d90f54b2c8 Mon Sep 17 00:00:00 2001 From: rithviknishad <mail@rithviknishad.dev> Date: Sun, 21 Apr 2024 21:08:40 +0530 Subject: [PATCH 19/28] fix archive not disabled --- .../MedicineAdministrationSheet/AdministrationEventCell.tsx | 3 +++ .../MedicineAdministrationSheet/AdministrationTableRow.tsx | 1 + src/Components/Medicine/PrescrpitionTimeline.tsx | 4 +++- 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/Components/Medicine/MedicineAdministrationSheet/AdministrationEventCell.tsx b/src/Components/Medicine/MedicineAdministrationSheet/AdministrationEventCell.tsx index aaed004127b..b13e05b5b58 100644 --- a/src/Components/Medicine/MedicineAdministrationSheet/AdministrationEventCell.tsx +++ b/src/Components/Medicine/MedicineAdministrationSheet/AdministrationEventCell.tsx @@ -12,6 +12,7 @@ interface Props { interval: { start: Date; end: Date }; prescription: Prescription; refetch: () => void; + readonly?: boolean; } export default function AdministrationEventCell({ @@ -19,6 +20,7 @@ export default function AdministrationEventCell({ interval: { start, end }, prescription, refetch, + readonly, }: Props) { const [showTimeline, setShowTimeline] = useState(false); // Check if cell belongs to an administered prescription (including start and excluding end) @@ -56,6 +58,7 @@ export default function AdministrationEventCell({ prescription={prescription} showPrescriptionDetails onRefetch={refetch} + readonly={readonly} /> </DialogModal> <button diff --git a/src/Components/Medicine/MedicineAdministrationSheet/AdministrationTableRow.tsx b/src/Components/Medicine/MedicineAdministrationSheet/AdministrationTableRow.tsx index f913286c574..7b2aa7e9ca9 100644 --- a/src/Components/Medicine/MedicineAdministrationSheet/AdministrationTableRow.tsx +++ b/src/Components/Medicine/MedicineAdministrationSheet/AdministrationTableRow.tsx @@ -240,6 +240,7 @@ export default function MedicineAdministrationTableRow({ interval={{ start, end }} prescription={prescription} refetch={refetch} + readonly={props.readonly} /> )} </td> diff --git a/src/Components/Medicine/PrescrpitionTimeline.tsx b/src/Components/Medicine/PrescrpitionTimeline.tsx index 12cf3fd4998..9422d349b3a 100644 --- a/src/Components/Medicine/PrescrpitionTimeline.tsx +++ b/src/Components/Medicine/PrescrpitionTimeline.tsx @@ -29,12 +29,14 @@ interface Props { prescription: Prescription; showPrescriptionDetails?: boolean; onRefetch?: () => void; + readonly?: boolean; } export default function PrescrpitionTimeline({ prescription, interval, onRefetch, + readonly, }: Props) { const consultation = useSlug("consultation"); const { data, refetch, loading } = useQuery( @@ -89,7 +91,7 @@ export default function PrescrpitionTimeline({ refetch(); }} isLastNode={index === events.length - 1} - hideArchive={prescription.discontinued} + hideArchive={prescription.discontinued || readonly} /> ); } From 27231f54873c45511e669be224e57bbd9c671d6c Mon Sep 17 00:00:00 2001 From: Mohammed Nihal <57055998+nihal467@users.noreply.github.com> Date: Sun, 21 Apr 2024 23:08:10 +0530 Subject: [PATCH 20/28] part-1 discharge reason --- .../e2e/patient_spec/patient_discharge.cy.ts | 83 +++++++++++++++++++ .../pageobject/Patient/PatientDischarge.ts | 23 +++++ .../ConsultationUpdatesTab.tsx | 51 ++++++------ src/Components/Form/AutoCompleteAsync.tsx | 6 +- 4 files changed, 134 insertions(+), 29 deletions(-) create mode 100644 cypress/e2e/patient_spec/patient_discharge.cy.ts create mode 100644 cypress/pageobject/Patient/PatientDischarge.ts diff --git a/cypress/e2e/patient_spec/patient_discharge.cy.ts b/cypress/e2e/patient_spec/patient_discharge.cy.ts new file mode 100644 index 00000000000..d53629e276c --- /dev/null +++ b/cypress/e2e/patient_spec/patient_discharge.cy.ts @@ -0,0 +1,83 @@ +import { afterEach, before, beforeEach, cy, describe, it } from "local-cypress"; +import LoginPage from "../../pageobject/Login/LoginPage"; +import { PatientPage } from "../../pageobject/Patient/PatientCreation"; +import PatientDischarge from "../../pageobject/Patient/PatientDischarge"; +import PatientPrescription from "../../pageobject/Patient/PatientPrescription"; + +describe("Patient Discharge based on multiple reason", () => { + const loginPage = new LoginPage(); + const patientPage = new PatientPage(); + const patientDischarge = new PatientDischarge(); + const patientPrescription = new PatientPrescription(); + const patientDischargeReason1 = "Recovered"; + const patientDischargeReason2 = "Referred"; + //const patientDischargeReason3 = "Expired"; + //const patientDischargeReason4 = "LAMA"; + const patientDischargeAdvice = "Discharge Advice"; + const patientMedicine = "ZOLE"; + const referringFacility = "Dummy Shifting Center, Ernakulam"; + const referringFreetextFacility = "Aster Mims"; + + before(() => { + loginPage.loginAsDisctrictAdmin(); + cy.saveLocalStorage(); + }); + + beforeEach(() => { + cy.restoreLocalStorage(); + cy.clearLocalStorage(/filters--.+/); + cy.awaitUrl("/patients"); + }); + + it("Discharge a recovered patient with all fields", () => { + patientPage.visitPatient("Dummy Patient 6"); + patientDischarge.clickDischarge(); + patientDischarge.selectDischargeReason(patientDischargeReason1); + patientDischarge.typeDischargeNote(patientDischargeAdvice); + // Prescribe a medicine for the patient + patientPrescription.clickAddPrescription(); + patientPrescription.interceptMedibase(); + patientPrescription.selectMedicinebox(); + patientPrescription.selectMedicine(patientMedicine); + patientPrescription.enterDosage("4"); + patientPrescription.selectDosageFrequency("Twice daily"); + cy.submitButton("Submit"); + cy.verifyNotification("Medicine prescribed"); + // submit the discharge pop-up + cy.submitButton("Confirm Discharge"); + cy.verifyNotification("Patient Discharged Successfully"); + // Verify the dashboard and discharge information + cy.verifyContentPresence("#discharge-information", [ + patientDischargeReason1, + patientDischargeAdvice, + patientMedicine, + ]); + // verify the medicine administration is blocked + }); + + it("Discharge patient with referred reason to a facility", () => { + patientPage.visitPatient("Dummy Patient 6"); + patientDischarge.clickDischarge(); + patientDischarge.selectDischargeReason(patientDischargeReason2); + patientDischarge.typeDischargeNote(patientDischargeAdvice); + // select a registrated facility from dropdown and clear + patientDischarge.typeReferringFacility(referringFacility); + patientDischarge.clickClearButton(); + // select a non-registered facility and perform the discharge + patientDischarge.typeReferringFacility(referringFreetextFacility); + cy.wait(3000); + patientDischarge.typeDischargeNote(patientDischargeAdvice); + cy.submitButton("Confirm Discharge"); + cy.verifyNotification("Patient Discharged Successfully"); + // Verify the dashboard and discharge information + cy.verifyContentPresence("#discharge-information", [ + patientDischargeReason2, + patientDischargeAdvice, + referringFreetextFacility, + ]); + }); + + afterEach(() => { + cy.saveLocalStorage(); + }); +}); diff --git a/cypress/pageobject/Patient/PatientDischarge.ts b/cypress/pageobject/Patient/PatientDischarge.ts new file mode 100644 index 00000000000..102c87c29e9 --- /dev/null +++ b/cypress/pageobject/Patient/PatientDischarge.ts @@ -0,0 +1,23 @@ +class PatientDischarge { + clickDischarge() { + cy.clickAndSelectOption("#show-more", "Discharge from CARE"); + } + + selectDischargeReason(reason: string) { + cy.clickAndSelectOption("#discharge_reason", reason); + } + + typeDischargeNote(note: string) { + cy.get("#discharge_notes").type(note); + } + + typeReferringFacility(facility: string) { + cy.searchAndSelectOption("#input[name='referred_to']", facility); + } + + clickClearButton() { + cy.get("#clear-button").click(); + } +} + +export default PatientDischarge; diff --git a/src/Components/Facility/ConsultationDetails/ConsultationUpdatesTab.tsx b/src/Components/Facility/ConsultationDetails/ConsultationUpdatesTab.tsx index 950ae89b62e..72f2b31eb78 100644 --- a/src/Components/Facility/ConsultationDetails/ConsultationUpdatesTab.tsx +++ b/src/Components/Facility/ConsultationDetails/ConsultationUpdatesTab.tsx @@ -58,24 +58,24 @@ export const ConsultationUpdatesTab = (props: ConsultationTabProps) => { listAssetBeds({ facility: props.consultationData.facility as any, bed: props.consultationData.current_bed?.bed_object.id, - }), + }) ); const assetBeds = assetBedRes?.data?.results as AssetBedModel[]; const monitorBedData = assetBeds?.find( - (i) => i.asset_object?.asset_class === AssetClass.HL7MONITOR, + (i) => i.asset_object?.asset_class === AssetClass.HL7MONITOR ); setMonitorBedData(monitorBedData); if (monitorBedData?.asset_object) { setHL7SocketUrl( - getVitalsMonitorSocketUrl(monitorBedData?.asset_object), + getVitalsMonitorSocketUrl(monitorBedData?.asset_object) ); } const consultationBedVentilator = props.consultationData?.current_bed?.assets_objects?.find( - (i) => i.asset_class === AssetClass.VENTILATOR, + (i) => i.asset_class === AssetClass.VENTILATOR ); let ventilatorBedData; @@ -86,14 +86,14 @@ export const ConsultationUpdatesTab = (props: ConsultationTabProps) => { } as AssetBedModel; } else { ventilatorBedData = assetBeds?.find( - (i) => i.asset_object.asset_class === AssetClass.VENTILATOR, + (i) => i.asset_object.asset_class === AssetClass.VENTILATOR ); } setVentilatorBedData(ventilatorBedData); if (ventilatorBedData?.asset_object) { setVentilatorSocketUrl( - getVitalsMonitorSocketUrl(ventilatorBedData?.asset_object), + getVitalsMonitorSocketUrl(ventilatorBedData?.asset_object) ); } }; @@ -202,7 +202,7 @@ export const ConsultationUpdatesTab = (props: ConsultationTabProps) => { "lg:col-span-2" }`} > - <div className="px-4 py-5 sm:p-6"> + <div className="px-4 py-5 sm:p-6" id="discharge-information"> <h3 className="text-lg font-semibold leading-relaxed text-gray-900"> Discharge Information </h3> @@ -212,8 +212,7 @@ export const ConsultationUpdatesTab = (props: ConsultationTabProps) => { <span className="font-semibold"> {DISCHARGE_REASONS.find( (d) => - d.id === - props.consultationData.new_discharge_reason, + d.id === props.consultationData.new_discharge_reason )?.text ?? "--"} </span> </div> @@ -238,7 +237,7 @@ export const ConsultationUpdatesTab = (props: ConsultationTabProps) => { <span className="font-semibold"> {props.consultationData.discharge_date ? formatDate( - props.consultationData.discharge_date, + props.consultationData.discharge_date ) : "--/--/---- --:-- --"} </span> @@ -275,7 +274,7 @@ export const ConsultationUpdatesTab = (props: ConsultationTabProps) => { <span className="font-semibold"> {props.consultationData.death_datetime ? formatDateTime( - props.consultationData.death_datetime, + props.consultationData.death_datetime ) : "--:--"} </span> @@ -296,7 +295,7 @@ export const ConsultationUpdatesTab = (props: ConsultationTabProps) => { </div> )} {[2, 4].includes( - props.consultationData.new_discharge_reason ?? 0, + props.consultationData.new_discharge_reason ?? 0 ) && ( <div className="grid gap-4"> <div> @@ -304,7 +303,7 @@ export const ConsultationUpdatesTab = (props: ConsultationTabProps) => { <span className="font-semibold"> {props.consultationData.discharge_date ? formatDateTime( - props.consultationData.discharge_date, + props.consultationData.discharge_date ) : "--/--/---- --:-- --"} </span> @@ -341,12 +340,12 @@ export const ConsultationUpdatesTab = (props: ConsultationTabProps) => { key={index} text={ SYMPTOM_CHOICES.find( - (choice) => choice.id === symptom, + (choice) => choice.id === symptom )?.text ?? "Err. Unknown" } size="small" /> - ), + ) )} </div> {props.consultationData.last_daily_round @@ -364,7 +363,7 @@ export const ConsultationUpdatesTab = (props: ConsultationTabProps) => { <span className="text-xs font-semibold leading-relaxed text-gray-800"> from{" "} {formatDate( - props.consultationData.last_daily_round.taken_at, + props.consultationData.last_daily_round.taken_at )} </span> </> @@ -380,12 +379,12 @@ export const ConsultationUpdatesTab = (props: ConsultationTabProps) => { key={index} text={ SYMPTOM_CHOICES.find( - (choice) => choice.id === symptom, + (choice) => choice.id === symptom )?.text ?? "Err. Unknown" } size="small" /> - ), + ) )} </div> {props.consultationData.other_symptoms && ( @@ -541,7 +540,7 @@ export const ConsultationUpdatesTab = (props: ConsultationTabProps) => { : formatDateTime(String(procedure.time))} </td> </tr> - ), + ) )} </tbody> </table> @@ -559,7 +558,7 @@ export const ConsultationUpdatesTab = (props: ConsultationTabProps) => { Intubation Date{" - "} <span className="font-semibold"> {formatDateTime( - props.consultationData.intubation_start_date, + props.consultationData.intubation_start_date )} </span> </div> @@ -568,7 +567,7 @@ export const ConsultationUpdatesTab = (props: ConsultationTabProps) => { <span className="font-semibold"> {props.consultationData.intubation_end_date && formatDateTime( - props.consultationData.intubation_end_date, + props.consultationData.intubation_end_date )} </span> </div> @@ -618,7 +617,7 @@ export const ConsultationUpdatesTab = (props: ConsultationTabProps) => { </span> </p> </div> - ), + ) )} </div> </div> @@ -661,7 +660,7 @@ export const ConsultationUpdatesTab = (props: ConsultationTabProps) => { {Math.sqrt( (Number(props.consultationData.weight) * Number(props.consultationData.height)) / - 3600, + 3600 ).toFixed(2)}{" "} m<sup>2</sup> </span> @@ -677,7 +676,7 @@ export const ConsultationUpdatesTab = (props: ConsultationTabProps) => { </div> {( props.consultationData.consent_records?.filter( - (record) => record.deleted !== true, + (record) => record.deleted !== true ) || [] ).length > 0 && ( <> @@ -692,13 +691,13 @@ export const ConsultationUpdatesTab = (props: ConsultationTabProps) => { <div className="font-bold"> { CONSENT_TYPE_CHOICES.find( - (c) => c.id === record.type, + (c) => c.id === record.type )?.text }{" "} {record.patient_code_status && `( ${ CONSENT_PATIENT_CODE_STATUS_CHOICES.find( - (c) => c.id === record.patient_code_status, + (c) => c.id === record.patient_code_status )?.text } )`} </div> diff --git a/src/Components/Form/AutoCompleteAsync.tsx b/src/Components/Form/AutoCompleteAsync.tsx index b7660b3dcb7..2102f254480 100644 --- a/src/Components/Form/AutoCompleteAsync.tsx +++ b/src/Components/Form/AutoCompleteAsync.tsx @@ -65,7 +65,7 @@ const AutoCompleteAsync = (props: Props) => { setData(data?.slice(0, showNOptions) || []); setLoading(false); }, debounceTime), - [fetchData, showNOptions, debounceTime], + [fetchData, showNOptions, debounceTime] ); useEffect(() => { @@ -107,7 +107,7 @@ const AutoCompleteAsync = (props: Props) => { <Combobox.Button className="absolute inset-y-0 right-0 flex items-center pr-2"> <div className="absolute right-0 top-1 mr-2 flex items-center text-lg text-secondary-900"> {hasSelection && !loading && !required && ( - <div className="tooltip"> + <div className="tooltip" id="clear-button"> <CareIcon icon="l-times-circle" className="mb-[-5px] h-4 w-4 text-gray-800 transition-colors duration-200 ease-in-out hover:text-gray-500" @@ -175,7 +175,7 @@ const AutoCompleteAsync = (props: Props) => { label={optionLabel(option)} onRemove={() => onChange( - selected.filter((item: any) => item.id !== option.id), + selected.filter((item: any) => item.id !== option.id) ) } /> From 4c1b3d4dd4a9a4128cad9073cb9d8162562a0354 Mon Sep 17 00:00:00 2001 From: Mohammed Nihal <57055998+nihal467@users.noreply.github.com> Date: Sun, 21 Apr 2024 23:08:45 +0530 Subject: [PATCH 21/28] part-1 discharge reason --- cypress/e2e/patient_spec/patient_discharge.cy.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/cypress/e2e/patient_spec/patient_discharge.cy.ts b/cypress/e2e/patient_spec/patient_discharge.cy.ts index d53629e276c..b1a0c70c5e1 100644 --- a/cypress/e2e/patient_spec/patient_discharge.cy.ts +++ b/cypress/e2e/patient_spec/patient_discharge.cy.ts @@ -52,7 +52,6 @@ describe("Patient Discharge based on multiple reason", () => { patientDischargeAdvice, patientMedicine, ]); - // verify the medicine administration is blocked }); it("Discharge patient with referred reason to a facility", () => { From 04d5f7ecf1b565e1fab892a5713892c4a2af09e1 Mon Sep 17 00:00:00 2001 From: Mohammed Nihal <57055998+nihal467@users.noreply.github.com> Date: Mon, 22 Apr 2024 00:58:04 +0530 Subject: [PATCH 22/28] fix id --- cypress/pageobject/Patient/PatientDischarge.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/cypress/pageobject/Patient/PatientDischarge.ts b/cypress/pageobject/Patient/PatientDischarge.ts index 102c87c29e9..2000354b944 100644 --- a/cypress/pageobject/Patient/PatientDischarge.ts +++ b/cypress/pageobject/Patient/PatientDischarge.ts @@ -1,6 +1,8 @@ class PatientDischarge { clickDischarge() { - cy.clickAndSelectOption("#show-more", "Discharge from CARE"); + cy.get("#show-more").scrollIntoView(); + cy.verifyAndClickElement("#show-more", "Manage Patient"); + cy.verifyAndClickElement("#show-more", "Discharge from CARE"); } selectDischargeReason(reason: string) { From cc0b17c8555a64eff6af50d75159614e643fae34 Mon Sep 17 00:00:00 2001 From: Mohammed Nihal <57055998+nihal467@users.noreply.github.com> Date: Mon, 22 Apr 2024 01:10:33 +0530 Subject: [PATCH 23/28] debug --- cypress/e2e/patient_spec/patient_discharge.cy.ts | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/cypress/e2e/patient_spec/patient_discharge.cy.ts b/cypress/e2e/patient_spec/patient_discharge.cy.ts index b1a0c70c5e1..2bbc0e59557 100644 --- a/cypress/e2e/patient_spec/patient_discharge.cy.ts +++ b/cypress/e2e/patient_spec/patient_discharge.cy.ts @@ -30,7 +30,7 @@ describe("Patient Discharge based on multiple reason", () => { }); it("Discharge a recovered patient with all fields", () => { - patientPage.visitPatient("Dummy Patient 6"); + patientPage.visitPatient("Dummy Patient 16"); patientDischarge.clickDischarge(); patientDischarge.selectDischargeReason(patientDischargeReason1); patientDischarge.typeDischargeNote(patientDischargeAdvice); @@ -43,9 +43,13 @@ describe("Patient Discharge based on multiple reason", () => { patientPrescription.selectDosageFrequency("Twice daily"); cy.submitButton("Submit"); cy.verifyNotification("Medicine prescribed"); + cy.wait(2000); + cy.closeNotification(); // submit the discharge pop-up cy.submitButton("Confirm Discharge"); + cy.wait(2000); cy.verifyNotification("Patient Discharged Successfully"); + cy.closeNotification(); // Verify the dashboard and discharge information cy.verifyContentPresence("#discharge-information", [ patientDischargeReason1, @@ -55,7 +59,7 @@ describe("Patient Discharge based on multiple reason", () => { }); it("Discharge patient with referred reason to a facility", () => { - patientPage.visitPatient("Dummy Patient 6"); + patientPage.visitPatient("Dummy Patient 15"); patientDischarge.clickDischarge(); patientDischarge.selectDischargeReason(patientDischargeReason2); patientDischarge.typeDischargeNote(patientDischargeAdvice); @@ -67,7 +71,9 @@ describe("Patient Discharge based on multiple reason", () => { cy.wait(3000); patientDischarge.typeDischargeNote(patientDischargeAdvice); cy.submitButton("Confirm Discharge"); + cy.wait(2000); cy.verifyNotification("Patient Discharged Successfully"); + cy.closeNotification(); // Verify the dashboard and discharge information cy.verifyContentPresence("#discharge-information", [ patientDischargeReason2, From e7ab4d549dc54b3da8ae9613bb9a50237b4def20 Mon Sep 17 00:00:00 2001 From: Mohammed Nihal <57055998+nihal467@users.noreply.github.com> Date: Mon, 22 Apr 2024 01:29:26 +0530 Subject: [PATCH 24/28] changed the id --- .../pageobject/Patient/PatientDischarge.ts | 2 +- src/Components/Facility/DischargeModal.tsx | 36 ++++++++++--------- 2 files changed, 20 insertions(+), 18 deletions(-) diff --git a/cypress/pageobject/Patient/PatientDischarge.ts b/cypress/pageobject/Patient/PatientDischarge.ts index 2000354b944..bcddab45902 100644 --- a/cypress/pageobject/Patient/PatientDischarge.ts +++ b/cypress/pageobject/Patient/PatientDischarge.ts @@ -14,7 +14,7 @@ class PatientDischarge { } typeReferringFacility(facility: string) { - cy.searchAndSelectOption("#input[name='referred_to']", facility); + cy.searchAndSelectOption("#facility-referredto", facility); } clickClearButton() { diff --git a/src/Components/Facility/DischargeModal.tsx b/src/Components/Facility/DischargeModal.tsx index 7b170379066..1e8fe6d4b03 100644 --- a/src/Components/Facility/DischargeModal.tsx +++ b/src/Components/Facility/DischargeModal.tsx @@ -79,7 +79,7 @@ const DischargeModal = ({ ordering: "-modified_date", use: "claim", consultation: consultationData.id, - }), + }) ); if (res?.data?.results?.length > 0) { @@ -151,8 +151,8 @@ const DischargeModal = ({ discharge: value, discharge_date: dayjs(preDischargeForm.discharge_date).toISOString(), }, - { id: consultationData.id }, - ), + { id: consultationData.id } + ) ); setIsSendingDischargeApi(false); @@ -211,19 +211,21 @@ const DischargeModal = ({ {preDischargeForm.new_discharge_reason === DISCHARGE_REASONS.find((i) => i.text == "Referred")?.id && ( <> - <FieldLabel>Referred to</FieldLabel> - <FacilitySelect - name="referred_to" - setSelected={(selected) => - handleFacilitySelect(selected as FacilityModel | undefined) - } - selected={facility ?? null} - showAll - freeText - multiple={false} - errors={errors?.referred_to} - className="mb-4" - /> + <div id="referred_to"> + <FieldLabel>Referred to</FieldLabel> + <FacilitySelect + name="referred_to" + setSelected={(selected) => + handleFacilitySelect(selected as FacilityModel | undefined) + } + selected={facility ?? null} + showAll + freeText + multiple={false} + errors={errors?.referred_to} + className="mb-4" + /> + </div> </> )} <TextAreaFormField @@ -279,7 +281,7 @@ const DischargeModal = ({ }} required min={dayjs(consultationData?.encounter_date).format( - "YYYY-MM-DDTHH:mm", + "YYYY-MM-DDTHH:mm" )} max={dayjs().format("YYYY-MM-DDTHH:mm")} error={ From 846250834c4c6ca20913fed307b34f18eeeb06ab Mon Sep 17 00:00:00 2001 From: Mohammed Nihal <57055998+nihal467@users.noreply.github.com> Date: Mon, 22 Apr 2024 17:50:58 +0530 Subject: [PATCH 25/28] FINAL part --- .../e2e/patient_spec/patient_discharge.cy.ts | 89 +++++++++++++------ .../pageobject/Patient/PatientDischarge.ts | 4 + src/Components/Facility/DischargeModal.tsx | 2 +- 3 files changed, 69 insertions(+), 26 deletions(-) diff --git a/cypress/e2e/patient_spec/patient_discharge.cy.ts b/cypress/e2e/patient_spec/patient_discharge.cy.ts index 2bbc0e59557..9c66e8c1c14 100644 --- a/cypress/e2e/patient_spec/patient_discharge.cy.ts +++ b/cypress/e2e/patient_spec/patient_discharge.cy.ts @@ -11,12 +11,14 @@ describe("Patient Discharge based on multiple reason", () => { const patientPrescription = new PatientPrescription(); const patientDischargeReason1 = "Recovered"; const patientDischargeReason2 = "Referred"; - //const patientDischargeReason3 = "Expired"; - //const patientDischargeReason4 = "LAMA"; + const patientDischargeReason3 = "Expired"; + const patientDischargeReason4 = "LAMA"; const patientDischargeAdvice = "Discharge Advice"; const patientMedicine = "ZOLE"; const referringFacility = "Dummy Shifting Center, Ernakulam"; const referringFreetextFacility = "Aster Mims"; + const patientDeathCause = "Cause Of Death"; + const doctorName = "Custom Doctor"; before(() => { loginPage.loginAsDisctrictAdmin(); @@ -29,37 +31,42 @@ describe("Patient Discharge based on multiple reason", () => { cy.awaitUrl("/patients"); }); - it("Discharge a recovered patient with all fields", () => { - patientPage.visitPatient("Dummy Patient 16"); + it("Discharge a LAMA patient in the consultation", () => { + patientPage.visitPatient("Dummy Patient 18"); patientDischarge.clickDischarge(); - patientDischarge.selectDischargeReason(patientDischargeReason1); - patientDischarge.typeDischargeNote(patientDischargeAdvice); - // Prescribe a medicine for the patient - patientPrescription.clickAddPrescription(); - patientPrescription.interceptMedibase(); - patientPrescription.selectMedicinebox(); - patientPrescription.selectMedicine(patientMedicine); - patientPrescription.enterDosage("4"); - patientPrescription.selectDosageFrequency("Twice daily"); - cy.submitButton("Submit"); - cy.verifyNotification("Medicine prescribed"); - cy.wait(2000); + patientDischarge.selectDischargeReason(patientDischargeReason4); + cy.submitButton("Confirm Discharge"); + cy.verifyNotification("Patient Discharged Successfully"); cy.closeNotification(); - // submit the discharge pop-up + // Verify the consultation dashboard reflection + cy.verifyContentPresence("#consultation-buttons", ["LAMA"]); + // verify the discharge information card + cy.verifyContentPresence("#discharge-information", [ + patientDischargeReason4, + ]); + }); + + it("Discharge a expired patient in the consultation", () => { + patientPage.visitPatient("Dummy Patient 17"); + patientDischarge.clickDischarge(); + patientDischarge.selectDischargeReason(patientDischargeReason3); + patientDischarge.typeDischargeNote(patientDeathCause); + patientDischarge.typeDoctorName(doctorName); cy.submitButton("Confirm Discharge"); - cy.wait(2000); cy.verifyNotification("Patient Discharged Successfully"); cy.closeNotification(); - // Verify the dashboard and discharge information + // Verify the consultation dashboard reflection + cy.verifyContentPresence("#consultation-buttons", ["EXPIRED"]); + // verify the discharge information card cy.verifyContentPresence("#discharge-information", [ - patientDischargeReason1, - patientDischargeAdvice, - patientMedicine, + patientDischargeReason3, + patientDeathCause, + doctorName, ]); }); it("Discharge patient with referred reason to a facility", () => { - patientPage.visitPatient("Dummy Patient 15"); + patientPage.visitPatient("Dummy Patient 16"); patientDischarge.clickDischarge(); patientDischarge.selectDischargeReason(patientDischargeReason2); patientDischarge.typeDischargeNote(patientDischargeAdvice); @@ -68,12 +75,13 @@ describe("Patient Discharge based on multiple reason", () => { patientDischarge.clickClearButton(); // select a non-registered facility and perform the discharge patientDischarge.typeReferringFacility(referringFreetextFacility); - cy.wait(3000); - patientDischarge.typeDischargeNote(patientDischargeAdvice); + cy.wait(2000); cy.submitButton("Confirm Discharge"); cy.wait(2000); cy.verifyNotification("Patient Discharged Successfully"); cy.closeNotification(); + // Verify the consultation dashboard reflection + cy.verifyContentPresence("#consultation-buttons", ["Referred"]); // Verify the dashboard and discharge information cy.verifyContentPresence("#discharge-information", [ patientDischargeReason2, @@ -82,6 +90,37 @@ describe("Patient Discharge based on multiple reason", () => { ]); }); + it("Discharge a recovered patient with all relevant fields", () => { + patientPage.visitPatient("Dummy Patient 15"); + patientDischarge.clickDischarge(); + patientDischarge.selectDischargeReason(patientDischargeReason1); + patientDischarge.typeDischargeNote(patientDischargeAdvice); + // Prescribe a medicine for the patient + patientPrescription.clickAddPrescription(); + patientPrescription.interceptMedibase(); + patientPrescription.selectMedicinebox(); + patientPrescription.selectMedicine(patientMedicine); + patientPrescription.enterDosage("4"); + patientPrescription.selectDosageFrequency("Twice daily"); + cy.submitButton("Submit"); + cy.verifyNotification("Medicine prescribed"); + cy.wait(2000); + cy.closeNotification(); + // submit the discharge pop-up + cy.submitButton("Confirm Discharge"); + cy.wait(2000); + cy.verifyNotification("Patient Discharged Successfully"); + cy.closeNotification(); + // Verify the consultation dashboard reflection + cy.verifyContentPresence("#consultation-buttons", ["Recovered"]); + // Verify the dashboard and discharge information + cy.verifyContentPresence("#discharge-information", [ + patientDischargeReason1, + patientDischargeAdvice, + patientMedicine, + ]); + }); + afterEach(() => { cy.saveLocalStorage(); }); diff --git a/cypress/pageobject/Patient/PatientDischarge.ts b/cypress/pageobject/Patient/PatientDischarge.ts index bcddab45902..eda6a379a3f 100644 --- a/cypress/pageobject/Patient/PatientDischarge.ts +++ b/cypress/pageobject/Patient/PatientDischarge.ts @@ -20,6 +20,10 @@ class PatientDischarge { clickClearButton() { cy.get("#clear-button").click(); } + + typeDoctorName(doctorName: string) { + cy.get("#death_confirmed_by").type(doctorName); + } } export default PatientDischarge; diff --git a/src/Components/Facility/DischargeModal.tsx b/src/Components/Facility/DischargeModal.tsx index 1e8fe6d4b03..d70246522c1 100644 --- a/src/Components/Facility/DischargeModal.tsx +++ b/src/Components/Facility/DischargeModal.tsx @@ -211,7 +211,7 @@ const DischargeModal = ({ {preDischargeForm.new_discharge_reason === DISCHARGE_REASONS.find((i) => i.text == "Referred")?.id && ( <> - <div id="referred_to"> + <div id="facility-referredto"> <FieldLabel>Referred to</FieldLabel> <FacilitySelect name="referred_to" From 16a5f4fa9465892df7872e33ea6047caec51047d Mon Sep 17 00:00:00 2001 From: Mohammed Nihal <57055998+nihal467@users.noreply.github.com> Date: Mon, 22 Apr 2024 18:07:11 +0530 Subject: [PATCH 26/28] fix lint error --- .../ConsultationUpdatesTab.tsx | 49 ++++++++++--------- src/Components/Facility/DischargeModal.tsx | 8 +-- src/Components/Form/AutoCompleteAsync.tsx | 4 +- 3 files changed, 31 insertions(+), 30 deletions(-) diff --git a/src/Components/Facility/ConsultationDetails/ConsultationUpdatesTab.tsx b/src/Components/Facility/ConsultationDetails/ConsultationUpdatesTab.tsx index 72f2b31eb78..f4150617f1f 100644 --- a/src/Components/Facility/ConsultationDetails/ConsultationUpdatesTab.tsx +++ b/src/Components/Facility/ConsultationDetails/ConsultationUpdatesTab.tsx @@ -58,24 +58,24 @@ export const ConsultationUpdatesTab = (props: ConsultationTabProps) => { listAssetBeds({ facility: props.consultationData.facility as any, bed: props.consultationData.current_bed?.bed_object.id, - }) + }), ); const assetBeds = assetBedRes?.data?.results as AssetBedModel[]; const monitorBedData = assetBeds?.find( - (i) => i.asset_object?.asset_class === AssetClass.HL7MONITOR + (i) => i.asset_object?.asset_class === AssetClass.HL7MONITOR, ); setMonitorBedData(monitorBedData); if (monitorBedData?.asset_object) { setHL7SocketUrl( - getVitalsMonitorSocketUrl(monitorBedData?.asset_object) + getVitalsMonitorSocketUrl(monitorBedData?.asset_object), ); } const consultationBedVentilator = props.consultationData?.current_bed?.assets_objects?.find( - (i) => i.asset_class === AssetClass.VENTILATOR + (i) => i.asset_class === AssetClass.VENTILATOR, ); let ventilatorBedData; @@ -86,14 +86,14 @@ export const ConsultationUpdatesTab = (props: ConsultationTabProps) => { } as AssetBedModel; } else { ventilatorBedData = assetBeds?.find( - (i) => i.asset_object.asset_class === AssetClass.VENTILATOR + (i) => i.asset_object.asset_class === AssetClass.VENTILATOR, ); } setVentilatorBedData(ventilatorBedData); if (ventilatorBedData?.asset_object) { setVentilatorSocketUrl( - getVitalsMonitorSocketUrl(ventilatorBedData?.asset_object) + getVitalsMonitorSocketUrl(ventilatorBedData?.asset_object), ); } }; @@ -212,7 +212,8 @@ export const ConsultationUpdatesTab = (props: ConsultationTabProps) => { <span className="font-semibold"> {DISCHARGE_REASONS.find( (d) => - d.id === props.consultationData.new_discharge_reason + d.id === + props.consultationData.new_discharge_reason, )?.text ?? "--"} </span> </div> @@ -237,7 +238,7 @@ export const ConsultationUpdatesTab = (props: ConsultationTabProps) => { <span className="font-semibold"> {props.consultationData.discharge_date ? formatDate( - props.consultationData.discharge_date + props.consultationData.discharge_date, ) : "--/--/---- --:-- --"} </span> @@ -274,7 +275,7 @@ export const ConsultationUpdatesTab = (props: ConsultationTabProps) => { <span className="font-semibold"> {props.consultationData.death_datetime ? formatDateTime( - props.consultationData.death_datetime + props.consultationData.death_datetime, ) : "--:--"} </span> @@ -295,7 +296,7 @@ export const ConsultationUpdatesTab = (props: ConsultationTabProps) => { </div> )} {[2, 4].includes( - props.consultationData.new_discharge_reason ?? 0 + props.consultationData.new_discharge_reason ?? 0, ) && ( <div className="grid gap-4"> <div> @@ -303,7 +304,7 @@ export const ConsultationUpdatesTab = (props: ConsultationTabProps) => { <span className="font-semibold"> {props.consultationData.discharge_date ? formatDateTime( - props.consultationData.discharge_date + props.consultationData.discharge_date, ) : "--/--/---- --:-- --"} </span> @@ -340,12 +341,12 @@ export const ConsultationUpdatesTab = (props: ConsultationTabProps) => { key={index} text={ SYMPTOM_CHOICES.find( - (choice) => choice.id === symptom + (choice) => choice.id === symptom, )?.text ?? "Err. Unknown" } size="small" /> - ) + ), )} </div> {props.consultationData.last_daily_round @@ -363,7 +364,7 @@ export const ConsultationUpdatesTab = (props: ConsultationTabProps) => { <span className="text-xs font-semibold leading-relaxed text-gray-800"> from{" "} {formatDate( - props.consultationData.last_daily_round.taken_at + props.consultationData.last_daily_round.taken_at, )} </span> </> @@ -379,12 +380,12 @@ export const ConsultationUpdatesTab = (props: ConsultationTabProps) => { key={index} text={ SYMPTOM_CHOICES.find( - (choice) => choice.id === symptom + (choice) => choice.id === symptom, )?.text ?? "Err. Unknown" } size="small" /> - ) + ), )} </div> {props.consultationData.other_symptoms && ( @@ -540,7 +541,7 @@ export const ConsultationUpdatesTab = (props: ConsultationTabProps) => { : formatDateTime(String(procedure.time))} </td> </tr> - ) + ), )} </tbody> </table> @@ -558,7 +559,7 @@ export const ConsultationUpdatesTab = (props: ConsultationTabProps) => { Intubation Date{" - "} <span className="font-semibold"> {formatDateTime( - props.consultationData.intubation_start_date + props.consultationData.intubation_start_date, )} </span> </div> @@ -567,7 +568,7 @@ export const ConsultationUpdatesTab = (props: ConsultationTabProps) => { <span className="font-semibold"> {props.consultationData.intubation_end_date && formatDateTime( - props.consultationData.intubation_end_date + props.consultationData.intubation_end_date, )} </span> </div> @@ -617,7 +618,7 @@ export const ConsultationUpdatesTab = (props: ConsultationTabProps) => { </span> </p> </div> - ) + ), )} </div> </div> @@ -660,7 +661,7 @@ export const ConsultationUpdatesTab = (props: ConsultationTabProps) => { {Math.sqrt( (Number(props.consultationData.weight) * Number(props.consultationData.height)) / - 3600 + 3600, ).toFixed(2)}{" "} m<sup>2</sup> </span> @@ -676,7 +677,7 @@ export const ConsultationUpdatesTab = (props: ConsultationTabProps) => { </div> {( props.consultationData.consent_records?.filter( - (record) => record.deleted !== true + (record) => record.deleted !== true, ) || [] ).length > 0 && ( <> @@ -691,13 +692,13 @@ export const ConsultationUpdatesTab = (props: ConsultationTabProps) => { <div className="font-bold"> { CONSENT_TYPE_CHOICES.find( - (c) => c.id === record.type + (c) => c.id === record.type, )?.text }{" "} {record.patient_code_status && `( ${ CONSENT_PATIENT_CODE_STATUS_CHOICES.find( - (c) => c.id === record.patient_code_status + (c) => c.id === record.patient_code_status, )?.text } )`} </div> diff --git a/src/Components/Facility/DischargeModal.tsx b/src/Components/Facility/DischargeModal.tsx index d70246522c1..c81ab2cf74e 100644 --- a/src/Components/Facility/DischargeModal.tsx +++ b/src/Components/Facility/DischargeModal.tsx @@ -79,7 +79,7 @@ const DischargeModal = ({ ordering: "-modified_date", use: "claim", consultation: consultationData.id, - }) + }), ); if (res?.data?.results?.length > 0) { @@ -151,8 +151,8 @@ const DischargeModal = ({ discharge: value, discharge_date: dayjs(preDischargeForm.discharge_date).toISOString(), }, - { id: consultationData.id } - ) + { id: consultationData.id }, + ), ); setIsSendingDischargeApi(false); @@ -281,7 +281,7 @@ const DischargeModal = ({ }} required min={dayjs(consultationData?.encounter_date).format( - "YYYY-MM-DDTHH:mm" + "YYYY-MM-DDTHH:mm", )} max={dayjs().format("YYYY-MM-DDTHH:mm")} error={ diff --git a/src/Components/Form/AutoCompleteAsync.tsx b/src/Components/Form/AutoCompleteAsync.tsx index 2102f254480..d4e686c41fa 100644 --- a/src/Components/Form/AutoCompleteAsync.tsx +++ b/src/Components/Form/AutoCompleteAsync.tsx @@ -65,7 +65,7 @@ const AutoCompleteAsync = (props: Props) => { setData(data?.slice(0, showNOptions) || []); setLoading(false); }, debounceTime), - [fetchData, showNOptions, debounceTime] + [fetchData, showNOptions, debounceTime], ); useEffect(() => { @@ -175,7 +175,7 @@ const AutoCompleteAsync = (props: Props) => { label={optionLabel(option)} onRemove={() => onChange( - selected.filter((item: any) => item.id !== option.id) + selected.filter((item: any) => item.id !== option.id), ) } /> From bed41aa3a6cc256af84bcdc064a85c4b0f7e4396 Mon Sep 17 00:00:00 2001 From: Mohammed Nihal <57055998+nihal467@users.noreply.github.com> Date: Mon, 22 Apr 2024 18:25:31 +0530 Subject: [PATCH 27/28] update patient name --- cypress/e2e/patient_spec/patient_discharge.cy.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cypress/e2e/patient_spec/patient_discharge.cy.ts b/cypress/e2e/patient_spec/patient_discharge.cy.ts index 9c66e8c1c14..34ad423d1e8 100644 --- a/cypress/e2e/patient_spec/patient_discharge.cy.ts +++ b/cypress/e2e/patient_spec/patient_discharge.cy.ts @@ -32,7 +32,7 @@ describe("Patient Discharge based on multiple reason", () => { }); it("Discharge a LAMA patient in the consultation", () => { - patientPage.visitPatient("Dummy Patient 18"); + patientPage.visitPatient("Dummy Patient 12"); patientDischarge.clickDischarge(); patientDischarge.selectDischargeReason(patientDischargeReason4); cy.submitButton("Confirm Discharge"); @@ -47,7 +47,7 @@ describe("Patient Discharge based on multiple reason", () => { }); it("Discharge a expired patient in the consultation", () => { - patientPage.visitPatient("Dummy Patient 17"); + patientPage.visitPatient("Dummy Patient 13"); patientDischarge.clickDischarge(); patientDischarge.selectDischargeReason(patientDischargeReason3); patientDischarge.typeDischargeNote(patientDeathCause); From 898afbc7406ef37098642b6bdca8c51b6f110de9 Mon Sep 17 00:00:00 2001 From: Mohammed Nihal <57055998+nihal467@users.noreply.github.com> Date: Mon, 22 Apr 2024 19:04:07 +0530 Subject: [PATCH 28/28] delete existing discharge test --- cypress/e2e/patient_spec/patient_manage.cy.ts | 8 ------ .../pageobject/Patient/PatientConsultation.ts | 28 +------------------ 2 files changed, 1 insertion(+), 35 deletions(-) diff --git a/cypress/e2e/patient_spec/patient_manage.cy.ts b/cypress/e2e/patient_spec/patient_manage.cy.ts index 35b89aedb7f..c25677d9e8b 100644 --- a/cypress/e2e/patient_spec/patient_manage.cy.ts +++ b/cypress/e2e/patient_spec/patient_manage.cy.ts @@ -58,14 +58,6 @@ describe("Patient", () => { cy.verifyNotification("Medicine prescribed"); }); - it("Discharge a patient", () => { - patientPage.visitPatient("Dummy Patient 6"); - patientConsultationPage.clickDischargePatient(); - patientConsultationPage.selectDischargeReason("Recovered"); - patientConsultationPage.addDischargeNotes("Discharge notes"); - patientConsultationPage.confirmDischarge(); - }); - afterEach(() => { cy.saveLocalStorage(); }); diff --git a/cypress/pageobject/Patient/PatientConsultation.ts b/cypress/pageobject/Patient/PatientConsultation.ts index 0a39a1f839a..87cead3fc1f 100644 --- a/cypress/pageobject/Patient/PatientConsultation.ts +++ b/cypress/pageobject/Patient/PatientConsultation.ts @@ -100,7 +100,7 @@ export class PatientConsultationPage { cy.get("button").contains("Manage Patient").click(); cy.verifyAndClickElement( "#consultation-buttons", - "Edit Consultation Details" + "Edit Consultation Details", ); cy.wait(3000); } @@ -130,30 +130,4 @@ export class PatientConsultationPage { cy.get("#add_doctor_note_button").click(); cy.wait("@postDoctorNotes").its("response.statusCode").should("eq", 201); } - - clickDischargePatient() { - cy.get("#show-more").scrollIntoView(); - cy.get("#show-more").click(); - cy.contains("p", "Discharge from CARE").click(); - } - - selectDischargeReason(reason: string) { - cy.get("#discharge_reason") - .click() - .then(() => { - cy.get("[role='option']").contains(reason).click(); - }); - } - - addDischargeNotes(notes: string) { - cy.get("#discharge_notes").type(notes); - } - - confirmDischarge() { - cy.intercept("POST", "**/api/v1/consultation/*/discharge_patient/").as( - "dischargePatient" - ); - cy.get("#submit").contains("Confirm Discharge").click(); - cy.wait("@dischargePatient").its("response.statusCode").should("eq", 200); - } }