From 6b1ebc66c3b6fde4c1ae6045974decff80b49a30 Mon Sep 17 00:00:00 2001
From: Gokulram A <gokulram2010418@ssn.edu.in>
Date: Thu, 28 Dec 2023 06:35:29 +0530
Subject: [PATCH 01/20] Add keyboard shortcut for adding notes (#6915)

---
 .../Facility/ConsultationDoctorNotes/index.tsx | 17 +++++++++++++++++
 .../Facility/PatientNotesSlideover.tsx         | 18 +++++++++++++++++-
 2 files changed, 34 insertions(+), 1 deletion(-)

diff --git a/src/Components/Facility/ConsultationDoctorNotes/index.tsx b/src/Components/Facility/ConsultationDoctorNotes/index.tsx
index dd96ef9af1e..8e39ee04e4e 100644
--- a/src/Components/Facility/ConsultationDoctorNotes/index.tsx
+++ b/src/Components/Facility/ConsultationDoctorNotes/index.tsx
@@ -11,6 +11,8 @@ import { PatientNoteStateType } from "../models.js";
 import routes from "../../../Redux/api.js";
 import request from "../../../Utils/request/request.js";
 import useQuery from "../../../Utils/request/useQuery.js";
+import useKeyboardShortcut from "use-keyboard-shortcut";
+import { isAppleDevice } from "../../../Utils/utils.js";
 
 interface ConsultationDoctorNotesProps {
   patientId: string;
@@ -26,6 +28,7 @@ const ConsultationDoctorNotes = (props: ConsultationDoctorNotesProps) => {
   const [reload, setReload] = useState(false);
   const [facilityName, setFacilityName] = useState("");
   const [patientName, setPatientName] = useState("");
+  const [focused, setFocused] = useState(false);
 
   const initialData: PatientNoteStateType = {
     notes: [],
@@ -84,6 +87,18 @@ const ConsultationDoctorNotes = (props: ConsultationDoctorNotesProps) => {
     }
   });
 
+  useKeyboardShortcut(
+    [isAppleDevice ? "Meta" : "Shift", "Enter"],
+    () => {
+      if (focused) {
+        onAddNote();
+      }
+    },
+    {
+      ignoreInputFields: false,
+    }
+  );
+
   return (
     <Page
       title="Doctor Notes"
@@ -114,6 +129,8 @@ const ConsultationDoctorNotes = (props: ConsultationDoctorNotesProps) => {
             errorClassName="hidden"
             placeholder="Type your Note"
             disabled={!patientActive}
+            onFocus={() => setFocused(true)}
+            onBlur={() => setFocused(false)}
           />
           <ButtonV2
             onClick={onAddNote}
diff --git a/src/Components/Facility/PatientNotesSlideover.tsx b/src/Components/Facility/PatientNotesSlideover.tsx
index 8b08d9767db..4279e3c1877 100644
--- a/src/Components/Facility/PatientNotesSlideover.tsx
+++ b/src/Components/Facility/PatientNotesSlideover.tsx
@@ -2,7 +2,7 @@ import { useState, useEffect, Dispatch, SetStateAction } from "react";
 import * as Notification from "../../Utils/Notifications.js";
 import { NonReadOnlyUsers } from "../../Utils/AuthorizeFor";
 import CareIcon from "../../CAREUI/icons/CareIcon";
-import { classNames } from "../../Utils/utils";
+import { classNames, isAppleDevice } from "../../Utils/utils";
 import TextFormField from "../Form/FormFields/TextFormField";
 import ButtonV2 from "../Common/components/ButtonV2";
 import { make as Link } from "../Common/components/Link.bs";
@@ -11,6 +11,7 @@ import PatientConsultationNotesList from "./PatientConsultationNotesList";
 import request from "../../Utils/request/request";
 import routes from "../../Redux/api";
 import { PatientNoteStateType } from "./models";
+import useKeyboardShortcut from "use-keyboard-shortcut";
 
 interface PatientNotesProps {
   patientId: string;
@@ -24,6 +25,7 @@ export default function PatientNotesSlideover(props: PatientNotesProps) {
   const [patientActive, setPatientActive] = useState(true);
   const [noteField, setNoteField] = useState("");
   const [reload, setReload] = useState(false);
+  const [focused, setFocused] = useState(false);
 
   const initialData: PatientNoteStateType = {
     notes: [],
@@ -84,6 +86,18 @@ export default function PatientNotesSlideover(props: PatientNotesProps) {
     fetchPatientName();
   }, [patientId]);
 
+  useKeyboardShortcut(
+    [isAppleDevice ? "Meta" : "Shift", "Enter"],
+    () => {
+      if (focused) {
+        onAddNote();
+      }
+    },
+    {
+      ignoreInputFields: false,
+    }
+  );
+
   const notesActionIcons = (
     <div className="flex gap-1">
       {show && (
@@ -157,6 +171,8 @@ export default function PatientNotesSlideover(props: PatientNotesProps) {
               errorClassName="hidden"
               placeholder="Type your Note"
               disabled={!patientActive}
+              onFocus={() => setFocused(true)}
+              onBlur={() => setFocused(false)}
             />
             <ButtonV2
               id="add_doctor_note_button"

From 71fbb5e6ce7524cd8ca9fbb802fbb305cd707d3c Mon Sep 17 00:00:00 2001
From: Rithvik Nishad <mail@rithviknishad.dev>
Date: Thu, 28 Dec 2023 06:35:53 +0530
Subject: [PATCH 02/20] Rename encounter date field labels (#6914)

---
 src/Components/Facility/ConsultationForm.tsx | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/src/Components/Facility/ConsultationForm.tsx b/src/Components/Facility/ConsultationForm.tsx
index 72944389235..77962cc7703 100644
--- a/src/Components/Facility/ConsultationForm.tsx
+++ b/src/Components/Facility/ConsultationForm.tsx
@@ -1213,9 +1213,9 @@ export const ConsultationForm = (props: any) => {
                           A: "Date & Time of Admission to the Facility",
                           DC: "Date & Time of Domiciliary Care commencement",
                           OP: "Date & Time of Out-patient visit",
-                          DD: "Date & Time of Encounter",
-                          HI: "Date & Time of Encounter",
-                          R: "Date & Time of Encounter",
+                          DD: "Date & Time of Consultation",
+                          HI: "Date & Time of Consultation",
+                          R: "Date & Time of Consultation",
                         }[state.form.suggestion]
                       }
                       type="datetime-local"

From 72f52855285b424dc724606a4783b4c3e868a1e3 Mon Sep 17 00:00:00 2001
From: konavivekramakrishna
 <101407963+konavivekramakrishna@users.noreply.github.com>
Date: Thu, 28 Dec 2023 06:36:39 +0530
Subject: [PATCH 03/20] Support for self-healing Consultation URL  (#6893)

* added newRoute consultation/:id

* fix based on review

* minor fix

* minor fix
---
 src/Components/Facility/ConsultationDetails/index.tsx  | 10 ++++++----
 .../Facility/Consultations/DailyRoundsList.tsx         |  8 ++------
 src/Routers/routes/ConsultationRoutes.tsx              |  3 +++
 3 files changed, 11 insertions(+), 10 deletions(-)

diff --git a/src/Components/Facility/ConsultationDetails/index.tsx b/src/Components/Facility/ConsultationDetails/index.tsx
index c438fa3fca7..abc7305a00b 100644
--- a/src/Components/Facility/ConsultationDetails/index.tsx
+++ b/src/Components/Facility/ConsultationDetails/index.tsx
@@ -46,8 +46,6 @@ const symptomChoices = [...SYMPTOM_CHOICES];
 
 export interface ConsultationTabProps {
   consultationId: string;
-  facilityId: string;
-  patientId: string;
   consultationData: ConsultationModel;
   patientData: PatientModel;
 }
@@ -120,6 +118,11 @@ export const ConsultationDetails = (props: any) => {
               });
             data.symptoms_text = symptoms.join(", ");
           }
+          if (facilityId != data.facility || patientId != data.patient) {
+            navigate(
+              `/facility/${data.facility}/patient/${data.patient}/consultation/${data?.id}`
+            );
+          }
           setConsultationData(data);
           const assetRes = data?.current_bed?.bed_object?.id
             ? await dispatch(
@@ -153,6 +156,7 @@ export const ConsultationDetails = (props: any) => {
                 : "No",
               is_vaccinated: patientData.is_vaccinated ? "Yes" : "No",
             };
+
             setPatientData(data);
           }
 
@@ -184,8 +188,6 @@ export const ConsultationDetails = (props: any) => {
 
   const consultationTabProps: ConsultationTabProps = {
     consultationId,
-    facilityId,
-    patientId,
     consultationData,
     patientData,
   };
diff --git a/src/Components/Facility/Consultations/DailyRoundsList.tsx b/src/Components/Facility/Consultations/DailyRoundsList.tsx
index 46072c16dd8..3b63b60a427 100644
--- a/src/Components/Facility/Consultations/DailyRoundsList.tsx
+++ b/src/Components/Facility/Consultations/DailyRoundsList.tsx
@@ -16,14 +16,10 @@ interface Props {
 }
 
 export default function DailyRoundsList({ consultation }: Props) {
-  const [facilityId, patientId, consultationId] = useSlugs(
-    "facility",
-    "patient",
-    "consultation"
-  );
+  const [consultationId] = useSlugs("consultation");
   const { t } = useTranslation();
 
-  const consultationUrl = `/facility/${facilityId}/patient/${patientId}/consultation/${consultationId}`;
+  const consultationUrl = `/facility/${consultation.facility}/patient/${consultation.patient}/consultation/${consultation.id}`;
 
   return (
     <PaginatedList
diff --git a/src/Routers/routes/ConsultationRoutes.tsx b/src/Routers/routes/ConsultationRoutes.tsx
index 401358717eb..6dc5fa9c05d 100644
--- a/src/Routers/routes/ConsultationRoutes.tsx
+++ b/src/Routers/routes/ConsultationRoutes.tsx
@@ -121,6 +121,9 @@ export default {
       tab={"updates"}
     />
   ),
+  "/consultation/:consultationId": ({ consultationId }: any) => (
+    <ConsultationDetails consultationId={consultationId} tab={"updates"} />
+  ),
   "/facility/:facilityId/patient/:patientId/consultation/:consultationId/treatment-summary":
     ({ facilityId, patientId, consultationId }: any) => (
       <TreatmentSummary

From 95353a4f456c8671b9552b2e314b3f5da78e80e6 Mon Sep 17 00:00:00 2001
From: Pranshu Aggarwal <70687348+Pranshu1902@users.noreply.github.com>
Date: Thu, 28 Dec 2023 06:38:25 +0530
Subject: [PATCH 04/20]  Timeline style view for Daily Rounds (#6808)

* make template timeline design

* Update src/Components/Facility/Consultations/DailyRoundsList.tsx

Co-authored-by: Rithvik Nishad <rithvikn2001@gmail.com>

* Update src/Components/Facility/Consultations/DailyRoundsList.tsx

Co-authored-by: Rithvik Nishad <rithvikn2001@gmail.com>

* Update src/Components/Facility/Consultations/DailyRoundsList.tsx

Co-authored-by: Rithvik Nishad <rithvikn2001@gmail.com>

* Update src/Components/Facility/Consultations/DailyRounds/DefaultLogUpdateCard.tsx

Co-authored-by: Rithvik Nishad <rithvikn2001@gmail.com>

* Update src/Components/Facility/Consultations/DailyRounds/DefaultLogUpdateCard.tsx

Co-authored-by: Rithvik Nishad <rithvikn2001@gmail.com>

* Update src/Components/Facility/Consultations/DailyRoundsList.tsx

Co-authored-by: Rithvik Nishad <rithvikn2001@gmail.com>

* add border and user icon

* refactor

* always display time on right

* use measured at time instead of created at

* enhance UI spacing

* show user type and fix tooltip

* enhance the loader

* refactor

* complete merge

* remove empty card in loader

---------

Co-authored-by: Rithvik Nishad <rithvikn2001@gmail.com>
Co-authored-by: Aakash Singh <mail@singhaakash.dev>
---
 src/CAREUI/display/RecordMeta.tsx             |   2 +-
 src/CAREUI/display/Timeline.tsx               |  40 +++---
 src/CAREUI/misc/PaginatedList.tsx             |  43 ++++---
 .../DailyRounds/DefaultLogUpdateCard.tsx      | 116 ++++++------------
 .../VirtualNursingAssistantLogUpdateCard.tsx  |  17 +--
 .../Consultations/DailyRoundsList.tsx         |  63 +++++++---
 6 files changed, 140 insertions(+), 141 deletions(-)

diff --git a/src/CAREUI/display/RecordMeta.tsx b/src/CAREUI/display/RecordMeta.tsx
index 818553d9207..d4d32e437c8 100644
--- a/src/CAREUI/display/RecordMeta.tsx
+++ b/src/CAREUI/display/RecordMeta.tsx
@@ -37,7 +37,7 @@ const RecordMeta = ({
   let child = (
     <div className="tooltip">
       <span className="underline">{relativeTime(time)}</span>
-      <span className="tooltip-text tooltip-bottom flex -translate-x-1/2 gap-1 text-xs font-medium tracking-wider">
+      <span className="tooltip-text tooltip-left flex gap-1 text-xs font-medium tracking-wider">
         {formatDateTime(time)}
         {user && !inlineUser && (
           <span className="flex items-center gap-1">
diff --git a/src/CAREUI/display/Timeline.tsx b/src/CAREUI/display/Timeline.tsx
index 7549fbfd69f..276c437056c 100644
--- a/src/CAREUI/display/Timeline.tsx
+++ b/src/CAREUI/display/Timeline.tsx
@@ -76,23 +76,29 @@ export const TimelineNode = (props: TimelineNodeProps) => {
           >
             {props.title || (
               <TimelineNodeTitle event={props.event}>
-                <p className="flex-auto py-0.5 text-xs leading-5 text-gray-600">
-                  {props.event.by && (
-                    <span className="font-medium text-gray-900">
-                      {formatName(props.event.by)}{" "}
-                    </span>
-                  )}
-                  {props.titleSuffix
-                    ? props.titleSuffix
-                    : `${props.event.type} the ${props.name || name}.`}
-                </p>
-                {props.actions && (
-                  <TimelineNodeActions>{props.actions}</TimelineNodeActions>
-                )}
-                <RecordMeta
-                  className="flex-none py-0.5 text-xs leading-5 text-gray-500"
-                  time={props.event.timestamp}
-                />
+                <div className="flex w-full justify-between gap-2">
+                  <p className="flex-auto py-0.5 text-xs leading-5 text-gray-600 md:w-2/3">
+                    {props.event.by && (
+                      <span className="font-medium text-gray-900">
+                        {formatName(props.event.by)}{" "}
+                        {props.event.by.user_type &&
+                          `(${props.event.by.user_type}) `}
+                      </span>
+                    )}
+                    {props.titleSuffix
+                      ? props.titleSuffix
+                      : `${props.event.type} the ${props.name || name}.`}
+                  </p>
+                  <div className="md:w-fit">
+                    {props.actions && (
+                      <TimelineNodeActions>{props.actions}</TimelineNodeActions>
+                    )}
+                    <RecordMeta
+                      className="flex-none py-0.5 text-xs leading-5 text-gray-500"
+                      time={props.event.timestamp}
+                    />
+                  </div>
+                </div>
               </TimelineNodeTitle>
             )}
           </div>
diff --git a/src/CAREUI/misc/PaginatedList.tsx b/src/CAREUI/misc/PaginatedList.tsx
index 02ee0e3d90e..61c67f97ae2 100644
--- a/src/CAREUI/misc/PaginatedList.tsx
+++ b/src/CAREUI/misc/PaginatedList.tsx
@@ -7,6 +7,7 @@ import ButtonV2, {
 import CareIcon from "../icons/CareIcon";
 import { classNames } from "../../Utils/utils";
 import Pagination from "../../Components/Common/Pagination";
+import Timeline from "../display/Timeline";
 
 const DEFAULT_PER_PAGE_LIMIT = 14;
 
@@ -129,20 +130,26 @@ interface ItemsProps<TItem> {
 const Items = <TItem extends object>(props: ItemsProps<TItem>) => {
   const { loading, items } = useContextualized<TItem>();
 
+  if (loading) {
+    return null;
+  }
+
   return (
-    <ul className={props.className}>
-      {loading && props.shimmer
-        ? Array.from({ length: props.shimmerCount ?? 8 }).map((_, i) => (
-            <li key={i} className="w-full">
-              {props.shimmer}
-            </li>
-          ))
-        : items.map((item, index, items) => (
-            <li key={index} className="w-full">
-              {props.children(item, items)}
-            </li>
-          ))}
-    </ul>
+    <Timeline className="rounded-lg bg-white p-2 shadow" name="log update">
+      <ul className={props.className}>
+        {loading && props.shimmer
+          ? Array.from({ length: props.shimmerCount ?? 8 }).map((_, i) => (
+              <li key={i} className="w-full">
+                {props.shimmer}
+              </li>
+            ))
+          : items.map((item, index, items) => (
+              <li key={index} className="w-full">
+                {props.children(item, items)}
+              </li>
+            ))}
+      </ul>
+    </Timeline>
   );
 };
 
@@ -153,8 +160,16 @@ interface PaginatorProps {
   hideIfSinglePage?: boolean;
 }
 
-const Paginator = ({ className, hideIfSinglePage }: PaginatorProps) => {
+const Paginator = <TItem extends object>({
+  className,
+  hideIfSinglePage,
+}: PaginatorProps) => {
   const { data, perPage, currentPage, setPage } = useContextualized<object>();
+  const { loading } = useContextualized<TItem>();
+
+  if (loading) {
+    return null;
+  }
 
   if (hideIfSinglePage && (data?.count ?? 0) <= perPage) {
     return null;
diff --git a/src/Components/Facility/Consultations/DailyRounds/DefaultLogUpdateCard.tsx b/src/Components/Facility/Consultations/DailyRounds/DefaultLogUpdateCard.tsx
index a0a4f2280cf..4cb90c900b1 100644
--- a/src/Components/Facility/Consultations/DailyRounds/DefaultLogUpdateCard.tsx
+++ b/src/Components/Facility/Consultations/DailyRounds/DefaultLogUpdateCard.tsx
@@ -1,5 +1,4 @@
 import { useTranslation } from "react-i18next";
-import RecordMeta from "../../../../CAREUI/display/RecordMeta";
 import CareIcon from "../../../../CAREUI/icons/CareIcon";
 import ButtonV2 from "../../../Common/components/ButtonV2";
 import { DailyRoundsModel } from "../../../Patient/models";
@@ -12,87 +11,48 @@ interface Props {
   onViewDetails: () => void;
   onUpdateLog?: () => void;
 }
-
-const getName = (item: any) => {
-  return `${item?.first_name} ${item?.last_name} (${item?.user_type})`;
-};
-
 const DefaultLogUpdateCard = ({ round, ...props }: Props) => {
   const { t } = useTranslation();
-  const telemedicine_doctor_update =
-    round.created_by_telemedicine || round.last_updated_by_telemedicine;
-
-  const by = props.consultationData.assigned_to_object || round.created_by;
 
   return (
-    <div
-      className={`flex w-full flex-col gap-4 rounded-lg p-4 shadow @container ${
-        telemedicine_doctor_update ? "bg-purple-200" : "bg-white"
-      }`}
-    >
-      <div className="flex flex-col items-start gap-1">
-        <div className="flex w-min items-center gap-2 rounded-full border bg-gray-50 text-gray-500">
-          <div className="rounded-full bg-gray-100 px-1.5 py-0.5">
-            <CareIcon className="care-l-user-nurse text-lg" />
-          </div>
-          <span className="flex gap-1 whitespace-nowrap pr-3 text-sm tracking-wider">
-            <span className="font-semibold">{`${by?.first_name} ${by?.last_name}`}</span>
-            <span className="hidden font-medium @xs:block">
-              ({by?.user_type})
-            </span>
-          </span>
-        </div>
-        <span className="flex gap-1 text-xs text-gray-700">
-          {t("created")} <RecordMeta time={round.created_date} />
-        </span>
-      </div>
-      <div className="flex flex-col gap-2">
-        {!telemedicine_doctor_update && round?.last_edited_by && (
-          <LogUpdateCardAttribute
-            attributeKey={"Updated By" as any}
-            attributeValue={getName(round.last_edited_by)}
-          />
-        )}
-        <LogUpdateCardAttribute
-          attributeKey={"Round Type" as any}
-          attributeValue={t(round.rounds_type)}
-        />
-        <LogUpdateCardAttribute
-          attributeKey="patient_category"
-          attributeValue={round.patient_category}
-        />
-        <LogUpdateCardAttribute
-          attributeKey="physical_examination_info"
-          attributeValue={round.physical_examination_info}
-        />
-        <LogUpdateCardAttribute
-          attributeKey="other_details"
-          attributeValue={round.other_details}
-        />
-
-        <div className="mt-2 flex flex-col space-x-0 space-y-2 @xs:flex-row @xs:space-x-2 @xs:space-y-0">
-          <ButtonV2
-            variant="secondary"
-            border
-            ghost
-            onClick={props.onViewDetails}
-          >
-            <CareIcon className="care-l-eye text-lg" />
-            <span>{t("view_details")}</span>
-          </ButtonV2>
-          {props.onUpdateLog && (
-            <ButtonV2
-              variant="secondary"
-              border
-              ghost
-              className="tooltip"
-              onClick={props.onUpdateLog}
-            >
-              <CareIcon className="care-l-pen text-lg" />
-              <span>{t("update_log")}</span>
-            </ButtonV2>
-          )}
-        </div>
+    <div className="flex w-full flex-col gap-4 rounded-lg border border-gray-400 p-4 @container">
+      <LogUpdateCardAttribute
+        attributeKey={"Round Type" as any}
+        attributeValue={t(round.rounds_type)}
+      />
+      <LogUpdateCardAttribute
+        attributeKey="patient_category"
+        attributeValue={round.patient_category}
+      />
+      <LogUpdateCardAttribute
+        attributeKey="physical_examination_info"
+        attributeValue={round.physical_examination_info}
+      />
+      <LogUpdateCardAttribute
+        attributeKey="other_details"
+        attributeValue={round.other_details}
+      />
+      <div className="mt-2 flex items-center gap-2">
+        <ButtonV2
+          variant="secondary"
+          border
+          ghost
+          size="small"
+          onClick={props.onViewDetails}
+        >
+          <CareIcon className="care-l-eye text-lg" />
+          <span>{t("view_details")}</span>
+        </ButtonV2>
+        <ButtonV2
+          variant="secondary"
+          border
+          ghost
+          size="small"
+          onClick={props.onUpdateLog}
+        >
+          <CareIcon className="care-l-pen text-lg" />
+          <span>{t("update_log")}</span>
+        </ButtonV2>
       </div>
     </div>
   );
diff --git a/src/Components/Facility/Consultations/DailyRounds/VirtualNursingAssistantLogUpdateCard.tsx b/src/Components/Facility/Consultations/DailyRounds/VirtualNursingAssistantLogUpdateCard.tsx
index 00f33790675..505c2f326fa 100644
--- a/src/Components/Facility/Consultations/DailyRounds/VirtualNursingAssistantLogUpdateCard.tsx
+++ b/src/Components/Facility/Consultations/DailyRounds/VirtualNursingAssistantLogUpdateCard.tsx
@@ -1,6 +1,4 @@
 import { useTranslation } from "react-i18next";
-import RecordMeta from "../../../../CAREUI/display/RecordMeta";
-import CareIcon from "../../../../CAREUI/icons/CareIcon";
 import { DailyRoundsModel } from "../../../Patient/models";
 import LogUpdateCardAttribute from "./LogUpdateCardAttribute";
 
@@ -67,20 +65,7 @@ const VirtualNursingAssistantLogUpdateCard = (props: Props) => {
   const diffKeys = Object.keys(diff);
 
   return (
-    <div className="flex w-full flex-col gap-4 rounded-lg border border-green-300 bg-white p-4 shadow shadow-primary-500/20">
-      <div className="flex flex-col items-start gap-1">
-        <div className="flex w-min items-center gap-2 rounded-full border bg-green-50 text-primary-400">
-          <div className="rounded-full bg-green-100 px-1.5 py-0.5">
-            <CareIcon className="care-l-robot text-lg" />
-          </div>
-          <span className="whitespace-nowrap pr-3 text-sm font-semibold tracking-wider">
-            {t("virtual_nursing_assistant")}
-          </span>
-        </div>
-        <span className="flex gap-1 text-xs text-gray-700">
-          {t("created")} <RecordMeta time={props.round.created_date} />
-        </span>
-      </div>
+    <div className="flex w-full flex-col gap-4 rounded-lg border border-green-300 bg-white p-4 shadow-primary-500/20">
       <div className="flex flex-col gap-1">
         {diffKeys.length > 0 ? (
           Object.keys(diff).map((key) => (
diff --git a/src/Components/Facility/Consultations/DailyRoundsList.tsx b/src/Components/Facility/Consultations/DailyRoundsList.tsx
index 3b63b60a427..828a41c8c24 100644
--- a/src/Components/Facility/Consultations/DailyRoundsList.tsx
+++ b/src/Components/Facility/Consultations/DailyRoundsList.tsx
@@ -10,6 +10,7 @@ import PageTitle from "../../Common/PageTitle";
 import DailyRoundsFilter from "./DailyRoundsFilter";
 import { ConsultationModel } from "../models";
 import { useSlugs } from "../../../Common/hooks/useSlug";
+import { TimelineNode } from "../../../CAREUI/display/Timeline";
 
 interface Props {
   consultation: ConsultationModel;
@@ -41,20 +42,34 @@ export default function DailyRoundsList({ consultation }: Props) {
                 </span>
               </PaginatedList.WhenEmpty>
               <PaginatedList.WhenLoading>
-                <>
-                  {Array.from({ length: 3 }).map((_, i) => (
-                    <LoadingLogUpdateCard key={i} />
-                  ))}
-                </>
+                <LoadingLogUpdateCard />
               </PaginatedList.WhenLoading>
               <PaginatedList.Items<DailyRoundsModel> className="flex grow flex-col gap-3">
                 {(item, items) => {
                   if (item.rounds_type === "AUTOMATED") {
                     return (
-                      <VirtualNursingAssistantLogUpdateCard
-                        round={item}
-                        previousRound={items[items.indexOf(item) + 1]}
-                      />
+                      <TimelineNode
+                        event={{
+                          type: "created",
+                          timestamp: item.taken_at?.toString() ?? "",
+                          by: {
+                            user_type: "",
+                            first_name: "Virtual",
+                            last_name: "Assistant",
+                            username: "",
+                            id: "",
+                            email: "",
+                            last_login: "",
+                          },
+                          icon: "l-robot",
+                        }}
+                        isLast={items.indexOf(item) == items.length - 1}
+                      >
+                        <VirtualNursingAssistantLogUpdateCard
+                          round={item}
+                          previousRound={items[items.indexOf(item) + 1]}
+                        />
+                      </TimelineNode>
                     );
                   }
 
@@ -65,12 +80,30 @@ export default function DailyRoundsList({ consultation }: Props) {
                     : `${consultationUrl}/daily_rounds/${item.id}`;
 
                   return (
-                    <DefaultLogUpdateCard
-                      round={item}
-                      consultationData={consultation}
-                      onViewDetails={() => navigate(itemUrl)}
-                      onUpdateLog={() => navigate(`${itemUrl}/update`)}
-                    />
+                    <TimelineNode
+                      event={{
+                        type: "created",
+                        timestamp: item.taken_at?.toString() ?? "",
+                        by: {
+                          user_type: item.created_by?.user_type ?? "",
+                          first_name: item.created_by?.first_name ?? "",
+                          last_name: item.created_by?.last_name ?? "",
+                          username: "",
+                          id: "",
+                          email: "",
+                          last_login: "",
+                        },
+                        icon: "l-user-nurse",
+                      }}
+                      isLast={items.indexOf(item) == items.length - 1}
+                    >
+                      <DefaultLogUpdateCard
+                        round={item}
+                        consultationData={consultation}
+                        onViewDetails={() => navigate(itemUrl)}
+                        onUpdateLog={() => navigate(`${itemUrl}/update`)}
+                      />
+                    </TimelineNode>
                   );
                 }}
               </PaginatedList.Items>

From 4a6569851b7df95794d4f6031d71eda7c583e696 Mon Sep 17 00:00:00 2001
From: Mohammed Nihal <57055998+nihal467@users.noreply.github.com>
Date: Thu, 28 Dec 2023 06:40:23 +0530
Subject: [PATCH 05/20] facility pagination and redirection (#6912)

---
 .../e2e/facility_spec/facility_homepage.cy.ts | 35 +++++++++-
 cypress/e2e/facility_spec/locations.cy.ts     | 69 +++++++++++--------
 .../pageobject/Facility/FacilityCreation.ts   |  4 ++
 cypress/pageobject/Facility/FacilityHome.ts   | 43 ++++++++++++
 .../pageobject/Facility/FacilityLocation.ts   |  6 +-
 cypress/pageobject/Users/ManageUserPage.ts    |  1 +
 src/Components/Facility/FacilityCard.tsx      |  2 +
 7 files changed, 128 insertions(+), 32 deletions(-)

diff --git a/cypress/e2e/facility_spec/facility_homepage.cy.ts b/cypress/e2e/facility_spec/facility_homepage.cy.ts
index 3d916b4ba47..7269c3a2581 100644
--- a/cypress/e2e/facility_spec/facility_homepage.cy.ts
+++ b/cypress/e2e/facility_spec/facility_homepage.cy.ts
@@ -5,6 +5,7 @@ import FacilityHome from "../../pageobject/Facility/FacilityHome";
 import ManageUserPage from "../../pageobject/Users/ManageUserPage";
 import FacilityPage from "../../pageobject/Facility/FacilityCreation";
 import { UserPage } from "../../pageobject/Users/UserSearch";
+import { AssetPagination } from "../../pageobject/Asset/AssetPagination";
 
 describe("Facility Homepage Function", () => {
   const loginPage = new LoginPage();
@@ -12,6 +13,7 @@ describe("Facility Homepage Function", () => {
   const facilityPage = new FacilityPage();
   const manageUserPage = new ManageUserPage();
   const userPage = new UserPage();
+  const assetPagination = new AssetPagination();
   const facilitiesAlias = "downloadFacilitiesCSV";
   const capacitiesAlias = "downloadCapacitiesCSV";
   const doctorsAlias = "downloadDoctorsCSV";
@@ -19,6 +21,7 @@ describe("Facility Homepage Function", () => {
   const facilityname = "Dummy Facility 1";
   const statename = "Kerala";
   const district = "Ernakulam";
+  const localbody = "Aikaranad";
   const facilitytype = "Private Hospital";
 
   before(() => {
@@ -31,24 +34,52 @@ describe("Facility Homepage Function", () => {
     cy.awaitUrl("/facility");
   });
 
+  it("Verify the Facility card button redirection", () => {
+    // view cns button
+    facilityHome.clickViewCnsButton();
+    facilityHome.verifyCnsUrl();
+    facilityHome.navigateBack();
+    // view notify button
+    facilityHome.clickFacilityNotifyButton();
+    facilityHome.verifyAndCloseNotifyModal();
+    // view facility button
+    facilityHome.clickViewFacilityDetails();
+    facilityPage.getFacilityName().should("be.visible");
+    facilityHome.verifyFacilityDetailsUrl();
+    facilityHome.navigateBack();
+    // view patient button
+    manageUserPage.clickFacilityPatients();
+    facilityHome.verifyPatientListVisibility();
+    facilityHome.verifyPatientListUrl();
+    facilityHome.navigateBack();
+    // occupancy badge
+    facilityHome.verifyOccupancyBadgeVisibility();
+  });
+
   it("Verify the functionality of advance filter", () => {
     userPage.clickAdvancedFilters();
     facilityPage.selectState(statename);
     facilityPage.selectDistrict(district);
-    // facilityPage.selectLocalBody("Anthikad Grama"); current dummy data have issue in local body
+    facilityPage.selectLocalBody(localbody);
     facilityPage.clickUpdateFacilityType(facilitytype);
     userPage.applyFilter();
     facilityPage.verifyStateBadgeContent(statename);
     facilityPage.verifyDistrictBadgeContent(district);
+    facilityPage.verifyLocalBodyBadgeContent(localbody);
     facilityPage.verifyFacilityTypeBadgeContent(facilitytype);
     manageUserPage.assertFacilityInCard(facilityname);
     userPage.clearFilters();
     userPage.verifyDataTestIdNotVisible("State");
     userPage.verifyDataTestIdNotVisible("District");
     userPage.verifyDataTestIdNotVisible("Facility type");
+    userPage.verifyDataTestIdNotVisible("Local Body");
   });
 
-  it("Search a facility in homepage", () => {
+  it("Search a facility in homepage and pagination", () => {
+    // pagination of the facility page
+    assetPagination.navigateToNextPage();
+    assetPagination.navigateToPreviousPage();
+    // search for a facility
     manageUserPage.typeFacilitySearch(facilityname);
     facilityPage.verifyFacilityBadgeContent(facilityname);
     manageUserPage.assertFacilityInCard(facilityname);
diff --git a/cypress/e2e/facility_spec/locations.cy.ts b/cypress/e2e/facility_spec/locations.cy.ts
index 26364048ca2..b9d26ee3100 100644
--- a/cypress/e2e/facility_spec/locations.cy.ts
+++ b/cypress/e2e/facility_spec/locations.cy.ts
@@ -3,6 +3,7 @@ import { AssetPage } from "../../pageobject/Asset/AssetCreation";
 import { UserCreationPage } from "../../pageobject/Users/UserCreation";
 import FacilityPage from "../../pageobject/Facility/FacilityCreation";
 import FacilityLocation from "../../pageobject/Facility/FacilityLocation";
+import FacilityHome from "../../pageobject/Facility/FacilityHome";
 // import { AssetPagination } from "../../pageobject/Asset/AssetPagination";
 
 describe("Location Management Section", () => {
@@ -10,6 +11,7 @@ describe("Location Management Section", () => {
   const userCreationPage = new UserCreationPage();
   const facilityPage = new FacilityPage();
   const facilityLocation = new FacilityLocation();
+  const facilityHome = new FacilityHome();
   // const assetPagination = new AssetPagination();
   const EXPECTED_LOCATION_ERROR_MESSAGES = [
     "Name is required",
@@ -27,7 +29,7 @@ describe("Location Management Section", () => {
   const locationModifiedDescription = "Test Modified Description";
   const locationModifiedType = "ICU";
   const locationModifiedMiddleware = "dev-middleware.coronasafe.live";
-  const bedName = "Test Bed";
+  const bedName = "Test-Bed";
   const bedDescrption = "test description";
   const bedType = "ICU";
   const bedStatus = "Vacant";
@@ -56,6 +58,42 @@ describe("Location Management Section", () => {
     cy.get("[id=location-management]").click();
   });
 
+  it("Add a Bed to facility location along with duplication and deleting a bed", () => {
+    // mandatory field verification in bed creation
+    facilityLocation.clickManageBedButton();
+    facilityLocation.clickAddBedButton();
+    assetPage.clickassetupdatebutton();
+    userCreationPage.verifyErrorMessages(EXPECTED_BED_ERROR_MESSAGES);
+    // create a new single bed and verify
+    facilityLocation.enterBedName(bedName);
+    facilityLocation.enterBedDescription(bedDescrption);
+    facilityLocation.selectBedType(bedType);
+    assetPage.clickassetupdatebutton();
+    // Verify the bed creation
+    facilityLocation.verifyBedNameBadge(bedName);
+    facilityLocation.verifyBedBadge(bedType);
+    facilityLocation.verifyBedBadge(bedStatus);
+    // Try to create duplication bed and verify the error
+    facilityLocation.clickAddBedButton();
+    facilityLocation.enterBedName(bedName);
+    facilityLocation.selectBedType(bedType);
+    assetPage.clickassetupdatebutton();
+    facilityLocation.verifyNotification(
+      "Name - Bed with same name already exists in location"
+    );
+    facilityHome.verifyAndCloseNotifyModal();
+    // edit the created bed
+    facilityLocation.clickEditBedButton();
+    facilityLocation.enterBedName(bedModifiedName);
+    facilityLocation.enterBedDescription(bedModifiedDescrption);
+    facilityLocation.selectBedType(bedModifiedType);
+    assetPage.clickassetupdatebutton();
+    // verify the modification
+    facilityLocation.verifyBedNameBadge(bedModifiedName);
+    facilityLocation.verifyBedBadge(bedModifiedType);
+    facilityLocation.verifyBedBadge(bedStatus);
+  });
+
   it("Adds Location to a facility and modify it", () => {
     // add a new location form mandatory error
     facilityLocation.clickAddNewLocationButton();
@@ -86,7 +124,7 @@ describe("Location Management Section", () => {
     facilityLocation.verifyLocationMiddleware(locationModifiedMiddleware);
   });
 
-  it("Add Multiple Bed to a facility location and delete a bed", () => {
+  it("Multiple Bed to a facility location and delete a bed", () => {
     // create multiple bed and verify
     facilityLocation.clickManageBedButton();
     facilityLocation.clickAddBedButton();
@@ -120,33 +158,6 @@ describe("Location Management Section", () => {
   //   assetPagination.navigateToPreviousPage();
   // }); need to be unblocked upon issue #6906 is solved
 
-  it("Add Single Bed to a facility location and modify it", () => {
-    // mandatory field verification in bed creation
-    facilityLocation.clickManageBedButton();
-    facilityLocation.clickAddBedButton();
-    assetPage.clickassetupdatebutton();
-    userCreationPage.verifyErrorMessages(EXPECTED_BED_ERROR_MESSAGES);
-    // create a new single bed and verify
-    facilityLocation.enterBedName(bedName);
-    facilityLocation.enterBedDescription(bedDescrption);
-    facilityLocation.selectBedType(bedType);
-    assetPage.clickassetupdatebutton();
-    // Verify the bed creation
-    facilityLocation.verifyBedNameBadge(bedName);
-    facilityLocation.verifyBedBadge(bedType);
-    facilityLocation.verifyBedBadge(bedStatus);
-    // edit the created bed
-    facilityLocation.clickEditBedButton();
-    facilityLocation.enterBedName(bedModifiedName);
-    facilityLocation.enterBedDescription(bedModifiedDescrption);
-    facilityLocation.selectBedType(bedModifiedType);
-    assetPage.clickassetupdatebutton();
-    // verify the modification
-    facilityLocation.verifyBedNameBadge(bedModifiedName);
-    facilityLocation.verifyBedBadge(bedModifiedType);
-    facilityLocation.verifyBedBadge(bedStatus);
-  });
-
   afterEach(() => {
     cy.saveLocalStorage();
   });
diff --git a/cypress/pageobject/Facility/FacilityCreation.ts b/cypress/pageobject/Facility/FacilityCreation.ts
index 608dd9c357b..e3639388620 100644
--- a/cypress/pageobject/Facility/FacilityCreation.ts
+++ b/cypress/pageobject/Facility/FacilityCreation.ts
@@ -337,6 +337,10 @@ class FacilityPage {
     cy.get("[data-testid='District']").should("contain", expectedText);
   }
 
+  verifyLocalBodyBadgeContent(expectedText: string) {
+    cy.get("[data-testid='Local Body']").should("contain", expectedText);
+  }
+
   verifyFacilityTypeBadgeContent(expectedText: string) {
     cy.get("[data-testid='Facility type']").should("contain", expectedText);
   }
diff --git a/cypress/pageobject/Facility/FacilityHome.ts b/cypress/pageobject/Facility/FacilityHome.ts
index 04dfe94d002..03f2be9b19b 100644
--- a/cypress/pageobject/Facility/FacilityHome.ts
+++ b/cypress/pageobject/Facility/FacilityHome.ts
@@ -23,6 +23,49 @@ class FacilityHome {
     cy.intercept("GET", `**/api/v1/facility/?csv${queryParam}`).as(alias);
   }
 
+  clickViewCnsButton() {
+    cy.get("#view-cns-button").first().click();
+  }
+
+  verifyCnsUrl() {
+    cy.url().should("include", "/cns");
+  }
+
+  clickFacilityNotifyButton() {
+    cy.get("#facility-notify").first().click();
+  }
+
+  verifyFacilityDetailsUrl() {
+    cy.url().should("match", /\/facility\/[\w-]+/);
+  }
+
+  verifyPatientListVisibility() {
+    cy.get("#patient-name-list").scrollIntoView();
+    cy.get("#patient-name-list").should("be.visible");
+  }
+
+  verifyPatientListUrl() {
+    cy.url().should("match", /\/patients\?facility=.+/);
+  }
+
+  verifyOccupancyBadgeVisibility() {
+    cy.get("#occupany-badge").should("be.visible");
+  }
+
+  verifyAndCloseNotifyModal() {
+    cy.get("#cancel").should("be.visible");
+    cy.get("#cancel").click();
+  }
+
+  navigateBack() {
+    cy.go(-1);
+  }
+
+  clickViewFacilityDetails() {
+    cy.get("#facility-details").should("be.visible");
+    cy.get("#facility-details").first().click();
+  }
+
   verifyDownload(alias: string) {
     cy.wait(`@${alias}`).its("response.statusCode").should("eq", 200);
   }
diff --git a/cypress/pageobject/Facility/FacilityLocation.ts b/cypress/pageobject/Facility/FacilityLocation.ts
index d3eebdaf4ff..8924119510f 100644
--- a/cypress/pageobject/Facility/FacilityLocation.ts
+++ b/cypress/pageobject/Facility/FacilityLocation.ts
@@ -32,6 +32,10 @@ class FacilityLocation {
     cy.get("#location-type").contains(type);
   }
 
+  verifyNotification(message: string) {
+    cy.get(".pnotify-container").should("contain", message).and("be.visible");
+  }
+
   verifyLocationDescription(description: string) {
     cy.get("#view-location-description").contains(description);
   }
@@ -49,7 +53,7 @@ class FacilityLocation {
   }
 
   enterBedName(name: string) {
-    cy.get("#bed-name").clear().click().type(name);
+    cy.get("#bed-name").click().clear().click().type(name);
   }
 
   enterBedDescription(description: string) {
diff --git a/cypress/pageobject/Users/ManageUserPage.ts b/cypress/pageobject/Users/ManageUserPage.ts
index d3f7e17e7d5..2d1ebbc14f0 100644
--- a/cypress/pageobject/Users/ManageUserPage.ts
+++ b/cypress/pageobject/Users/ManageUserPage.ts
@@ -103,6 +103,7 @@ export class ManageUserPage {
   }
 
   clickFacilityPatients() {
+    cy.get("#facility-patients").should("be.visible");
     cy.get("#facility-patients").click();
   }
 
diff --git a/src/Components/Facility/FacilityCard.tsx b/src/Components/Facility/FacilityCard.tsx
index c34fed49a6e..1424a657de4 100644
--- a/src/Components/Facility/FacilityCard.tsx
+++ b/src/Components/Facility/FacilityCard.tsx
@@ -98,6 +98,7 @@ export const FacilityCard = (props: { facility: any; userType: any }) => {
                       {facility.name}
                     </Link>
                     <ButtonV2
+                      id="view-cns-button"
                       href={`/facility/${facility.id}/cns`}
                       border
                       ghost
@@ -160,6 +161,7 @@ export const FacilityCard = (props: { facility: any; userType: any }) => {
                 <div className="flex w-full flex-wrap justify-between gap-2 py-2">
                   <div className="flex flex-wrap gap-2">
                     <div
+                      id="occupany-badge"
                       className={`tooltip button-size-default ml-auto flex w-fit items-center justify-center rounded-md px-2 ${
                         facility.patient_count / facility.bed_count > 0.85
                           ? "button-danger-border bg-red-500"

From 283504d89f1171207e5529cc6e552fc706ba4b5a Mon Sep 17 00:00:00 2001
From: Gampa Sri Harsh <114745442+sriharsh05@users.noreply.github.com>
Date: Thu, 28 Dec 2023 06:40:44 +0530
Subject: [PATCH 06/20] Replace all window.location.reload() with data refetch.
 (#6892)

* replaced window.location.reload with appropriate fetchdata function in patient discharge

* replaced window.location.reload with appropriate refetch while updating facility cover image

* replaced window.location.reload with appropriate refetch in assetImportModal

* replaced wimdow.location.reload with appropriate refecth in update app

* Reverted changes made related to UpdatableApp

* removed unnecessary data fetch calls
---
 src/Components/Assets/AssetImportModal.tsx    |  5 +--
 src/Components/Assets/AssetsList.tsx          |  3 +-
 .../Facility/CoverImageEditModal.tsx          |  2 --
 src/Components/Facility/DischargeModal.tsx    |  7 ++---
 src/Components/Facility/FacilityHome.tsx      | 31 ++++++++++---------
 src/Components/Patient/PatientInfoCard.tsx    |  8 ++++-
 6 files changed, 30 insertions(+), 26 deletions(-)

diff --git a/src/Components/Assets/AssetImportModal.tsx b/src/Components/Assets/AssetImportModal.tsx
index 02fe1d90265..adab83c744c 100644
--- a/src/Components/Assets/AssetImportModal.tsx
+++ b/src/Components/Assets/AssetImportModal.tsx
@@ -22,9 +22,10 @@ interface Props {
   open: boolean;
   onClose: (() => void) | undefined;
   facility: FacilityModel;
+  onUpdate?: (() => void) | undefined;
 }
 
-const AssetImportModal = ({ open, onClose, facility }: Props) => {
+const AssetImportModal = ({ open, onClose, facility, onUpdate }: Props) => {
   const [isImporting, setIsImporting] = useState(false);
   const [selectedFile, setSelectedFile] = useState<any>();
   const [preview, setPreview] =
@@ -170,7 +171,7 @@ const AssetImportModal = ({ open, onClose, facility }: Props) => {
       Notification.Success({ msg: "Assets imported successfully" });
       await sleep(1000);
       setIsImporting(false);
-      window.location.reload();
+      onUpdate?.();
     } else {
       Notification.Error({ msg: "Error importing some assets" });
       await sleep(1000);
diff --git a/src/Components/Assets/AssetsList.tsx b/src/Components/Assets/AssetsList.tsx
index 447bff1c1d0..3fc9c9f9f14 100644
--- a/src/Components/Assets/AssetsList.tsx
+++ b/src/Components/Assets/AssetsList.tsx
@@ -69,7 +69,7 @@ const AssetsList = () => {
       qParams.warranty_amc_end_of_validity_after || "",
   };
 
-  const { loading } = useQuery(routes.listAssets, {
+  const { refetch: assetsFetch, loading } = useQuery(routes.listAssets, {
     query: params,
     onResponse: ({ res, data }) => {
       if (res?.status === 200 && data) {
@@ -436,6 +436,7 @@ const AssetsList = () => {
               return f;
             });
           }}
+          onUpdate={assetsFetch}
           facility={facility}
         />
       )}
diff --git a/src/Components/Facility/CoverImageEditModal.tsx b/src/Components/Facility/CoverImageEditModal.tsx
index a1394c6441f..4d723214604 100644
--- a/src/Components/Facility/CoverImageEditModal.tsx
+++ b/src/Components/Facility/CoverImageEditModal.tsx
@@ -123,7 +123,6 @@ const CoverImageEditModal = ({
       );
       if (response.status === 200) {
         Success({ msg: "Cover image updated." });
-        window.location.reload();
       } else {
         Notification.Error({
           msg: "Something went wrong!",
@@ -148,7 +147,6 @@ const CoverImageEditModal = ({
     const res = await dispatch(deleteFacilityCoverImage(facility.id as any));
     if (res.statusCode === 204) {
       Success({ msg: "Cover image deleted" });
-      window.location.reload();
     }
 
     onDelete && onDelete();
diff --git a/src/Components/Facility/DischargeModal.tsx b/src/Components/Facility/DischargeModal.tsx
index 46bdf866e90..a15af4d3883 100644
--- a/src/Components/Facility/DischargeModal.tsx
+++ b/src/Components/Facility/DischargeModal.tsx
@@ -50,10 +50,7 @@ const DischargeModal = ({
   show,
   onClose,
   consultationData,
-  afterSubmit = () => {
-    onClose();
-    window.location.reload();
-  },
+  afterSubmit,
   discharge_reason = "",
   discharge_notes = "",
   discharge_date = dayjs().format("YYYY-MM-DDTHH:mm"),
@@ -163,7 +160,7 @@ const DischargeModal = ({
         msg: "Patient Discharged Successfully",
       });
 
-      afterSubmit();
+      afterSubmit?.();
     }
   };
 
diff --git a/src/Components/Facility/FacilityHome.tsx b/src/Components/Facility/FacilityHome.tsx
index b36a3a7b36d..2341d231675 100644
--- a/src/Components/Facility/FacilityHome.tsx
+++ b/src/Components/Facility/FacilityHome.tsx
@@ -54,19 +54,20 @@ export const FacilityHome = (props: any) => {
 
   useMessageListener((data) => console.log(data));
 
-  const { data: facilityData, loading: isLoading } = useQuery(
-    routes.getPermittedFacility,
-    {
-      pathParams: {
-        id: facilityId,
-      },
-      onResponse: ({ res }) => {
-        if (!res?.ok) {
-          navigate("/not-found");
-        }
-      },
-    }
-  );
+  const {
+    data: facilityData,
+    loading: isLoading,
+    refetch: facilityFetch,
+  } = useQuery(routes.getPermittedFacility, {
+    pathParams: {
+      id: facilityId,
+    },
+    onResponse: ({ res }) => {
+      if (!res?.ok) {
+        navigate("/not-found");
+      }
+    },
+  });
 
   const handleDeleteClose = () => {
     setOpenDeleteDialog(false);
@@ -139,10 +140,10 @@ export const FacilityHome = (props: any) => {
         onSave={() =>
           facilityData?.read_cover_image_url
             ? setImageKey(Date.now())
-            : window.location.reload()
+            : facilityFetch()
         }
         onClose={() => setEditCoverImage(false)}
-        onDelete={() => window.location.reload()}
+        onDelete={() => facilityFetch()}
         facility={facilityData ?? ({} as FacilityModel)}
       />
       {hasCoverImage ? (
diff --git a/src/Components/Patient/PatientInfoCard.tsx b/src/Components/Patient/PatientInfoCard.tsx
index b9d1d256566..c5087f13dda 100644
--- a/src/Components/Patient/PatientInfoCard.tsx
+++ b/src/Components/Patient/PatientInfoCard.tsx
@@ -141,7 +141,13 @@ export default function PatientInfoCard(props: {
           />
           <DischargeModal
             show={openDischargeDialog}
-            onClose={() => setOpenDischargeDialog(false)}
+            onClose={() => {
+              setOpenDischargeDialog(false);
+            }}
+            afterSubmit={() => {
+              setOpenDischargeDialog(false);
+              props.fetchPatientData?.({ aborted: false });
+            }}
             consultationData={consultation}
           />
         </>

From 3c008b28d616c50d930a9c00184cb6afc682f497 Mon Sep 17 00:00:00 2001
From: Gampa Sri Harsh <114745442+sriharsh05@users.noreply.github.com>
Date: Thu, 28 Dec 2023 06:54:09 +0530
Subject: [PATCH 07/20] Replaced useDipatch with useQuery/request in
 FacilityCreate and HospitalList files (#6591)

* Replaced useDipatch with useQuery/request in FacilityCreate and HospitalList files

* fix failing api calls

* replace function with request calls with useQuery

* remove useState variables and used variables from useQuery

* fix facility pincode issue

* fix longitude and latitude for facility and optimized code

* Fixed ward list bug

* fix auto fill for pincode bug

* remove duplicate request

* fix total facility card loading state

* fix clear filter badges bug
---
 src/Components/Facility/FacilityCreate.tsx | 313 +++++++++------------
 src/Components/Facility/HospitalList.tsx   | 153 +++-------
 src/Components/Facility/models.tsx         |  23 +-
 src/Redux/api.tsx                          |  14 +-
 src/Utils/request/useQuery.ts              |   4 +-
 5 files changed, 210 insertions(+), 297 deletions(-)

diff --git a/src/Components/Facility/FacilityCreate.tsx b/src/Components/Facility/FacilityCreate.tsx
index e9547d5dddd..c9f40b5d1ef 100644
--- a/src/Components/Facility/FacilityCreate.tsx
+++ b/src/Components/Facility/FacilityCreate.tsx
@@ -5,9 +5,7 @@ import {
   CapacityModal,
   DistrictModel,
   DoctorModal,
-  LocalBodyModel,
-  StateModel,
-  WardModel,
+  FacilityRequest,
 } from "./models";
 import { DraftSection, useAutoSaveReducer } from "../../Utils/AutoSave.js";
 import {
@@ -20,19 +18,8 @@ import {
   SelectFormField,
 } from "../Form/FormFields/SelectFormField";
 import { Popover, Transition } from "@headlessui/react";
-import { Fragment, lazy, useCallback, useState } from "react";
+import { Fragment, lazy, useState } from "react";
 import Steps, { Step } from "../Common/Steps";
-import {
-  createFacility,
-  getDistrictByState,
-  getLocalbodyByDistrict,
-  getPermittedFacility,
-  getStates,
-  getWardByLocalBody,
-  listCapacity,
-  listDoctor,
-  updateFacility,
-} from "../../Redux/actions";
 import {
   getPincodeDetails,
   includesIgnoreCase,
@@ -45,7 +32,6 @@ import {
   validateLongitude,
   validatePincode,
 } from "../../Common/validation";
-import { statusType, useAbortableEffect } from "../../Common/utils";
 
 import { BedCapacity } from "./BedCapacity";
 import BedTypeCard from "./BedTypeCard";
@@ -65,9 +51,12 @@ import TextFormField from "../Form/FormFields/TextFormField";
 import { navigate } from "raviger";
 import useAppHistory from "../../Common/hooks/useAppHistory";
 import useConfig from "../../Common/hooks/useConfig";
-import { useDispatch } from "react-redux";
 import { useTranslation } from "react-i18next";
 import { PhoneNumberValidator } from "../Form/FieldValidators.js";
+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";
 
 const Loading = lazy(() => import("../Common/Loading"));
 
@@ -149,7 +138,6 @@ const facilityCreateReducer = (state = initialState, action: FormAction) => {
 export const FacilityCreate = (props: FacilityProps) => {
   const { t } = useTranslation();
   const { gov_data_api_key, kasp_string, kasp_enabled } = useConfig();
-  const dispatchAction: any = useDispatch();
   const { facilityId } = props;
 
   const [state, dispatch] = useAutoSaveReducer<FacilityForm>(
@@ -157,14 +145,6 @@ export const FacilityCreate = (props: FacilityProps) => {
     initialState
   );
   const [isLoading, setIsLoading] = useState(false);
-  const [isStateLoading, setIsStateLoading] = useState(false);
-  const [isDistrictLoading, setIsDistrictLoading] = useState(false);
-  const [isLocalbodyLoading, setIsLocalbodyLoading] = useState(false);
-  const [isWardLoading, setIsWardLoading] = useState(false);
-  const [states, setStates] = useState<StateModel[]>([]);
-  const [districts, setDistricts] = useState<DistrictModel[]>([]);
-  const [localBodies, setLocalBodies] = useState<LocalBodyModel[]>([]);
-  const [ward, setWard] = useState<WardModel[]>([]);
   const [currentStep, setCurrentStep] = useState(1);
   const [createdFacilityId, setCreatedFacilityId] = useState("");
   const [showAutoFilledPincode, setShowAutoFilledPincode] = useState(false);
@@ -172,39 +152,32 @@ export const FacilityCreate = (props: FacilityProps) => {
   const [doctorData, setDoctorData] = useState<Array<DoctorModal>>([]);
   const [bedCapacityKey, setBedCapacityKey] = useState(0);
   const [docCapacityKey, setDocCapacityKey] = useState(0);
+  const [stateId, setStateId] = useState<number>();
+  const [districtId, setDistrictId] = useState<number>();
+  const [localBodyId, setLocalBodyId] = useState<number>();
   const { goBack } = useAppHistory();
   const headerText = !facilityId ? "Create Facility" : "Update Facility";
   const buttonText = !facilityId ? "Save Facility" : "Update Facility";
 
-  const fetchDistricts = useCallback(
-    async (id: number) => {
-      if (id > 0) {
-        setIsDistrictLoading(true);
-        const districtList = await dispatchAction(getDistrictByState({ id }));
-        if (districtList) {
-          setDistricts([...districtList.data]);
-        }
-        setIsDistrictLoading(false);
-        return districtList ? [...districtList.data] : [];
-      }
-    },
-    [dispatchAction]
-  );
-
-  const fetchLocalBody = useCallback(
-    async (id: number) => {
-      if (id > 0) {
-        setIsLocalbodyLoading(true);
-        const localBodyList = await dispatchAction(
-          getLocalbodyByDistrict({ id })
-        );
-        setIsLocalbodyLoading(false);
-        if (localBodyList) {
-          setLocalBodies([...localBodyList.data]);
-        }
-      }
+  const {
+    data: districtData,
+    refetch: districtFetch,
+    loading: isDistrictLoading,
+  } = useQuery(routes.getDistrictByState, {
+    pathParams: {
+      id: String(stateId),
     },
-    [dispatchAction]
+    prefetch: !!stateId,
+  });
+
+  const { data: localbodyData, loading: isLocalbodyLoading } = useQuery(
+    routes.getLocalbodyByDistrict,
+    {
+      pathParams: {
+        id: String(districtId),
+      },
+      prefetch: !!districtId,
+    }
   );
 
   const getSteps = (): Step[] => {
@@ -244,89 +217,66 @@ export const FacilityCreate = (props: FacilityProps) => {
     ];
   };
 
-  const fetchWards = useCallback(
-    async (id: number) => {
-      if (id > 0) {
-        setIsWardLoading(true);
-        const wardList = await dispatchAction(getWardByLocalBody({ id }));
-        setIsWardLoading(false);
-        if (wardList) {
-          setWard([...wardList.data.results]);
-        }
-      }
-    },
-    [dispatchAction]
+  const { data: wardData, loading: isWardLoading } = useQuery(
+    routes.getWardByLocalBody,
+    {
+      pathParams: {
+        id: String(localBodyId),
+      },
+      prefetch: !!localBodyId,
+    }
   );
 
-  const fetchData = useCallback(
-    async (status: statusType) => {
+  useQuery(routes.getPermittedFacility, {
+    pathParams: {
+      id: facilityId!,
+    },
+    prefetch: !!facilityId,
+    onResponse: ({ res, data }) => {
       if (facilityId) {
         setIsLoading(true);
-        const res = await dispatchAction(getPermittedFacility(facilityId));
-        if (!status.aborted && res.data) {
+        if (res?.ok && data) {
           const formData = {
-            facility_type: res.data.facility_type,
-            name: res.data.name,
-            state: res.data.state ? res.data.state : 0,
-            district: res.data.district ? res.data.district : 0,
-            local_body: res.data.local_body ? res.data.local_body : 0,
-            features: res.data.features || [],
-            ward: res.data.ward_object ? res.data.ward_object.id : 0,
-            kasp_empanelled: res.data.kasp_empanelled
-              ? String(res.data.kasp_empanelled)
-              : "false",
-            address: res.data.address,
-            pincode: res.data.pincode,
-            phone_number:
-              res.data.phone_number.length == 10
-                ? "+91" + res.data.phone_number
-                : res.data.phone_number,
-            latitude: res.data.latitude || "",
-            longitude: res.data.longitude || "",
-            type_b_cylinders: res.data.type_b_cylinders,
-            type_c_cylinders: res.data.type_c_cylinders,
-            type_d_cylinders: res.data.type_d_cylinders,
-            expected_type_b_cylinders: res.data.expected_type_b_cylinders,
-            expected_type_c_cylinders: res.data.expected_type_c_cylinders,
-            expected_type_d_cylinders: res.data.expected_type_d_cylinders,
-            expected_oxygen_requirement: res.data.expected_oxygen_requirement,
-            oxygen_capacity: res.data.oxygen_capacity,
+            facility_type: data.facility_type ? data.facility_type : "",
+            name: data.name ? data.name : "",
+            state: data.state ? data.state : 0,
+            district: data.district ? data.district : 0,
+            local_body: data.local_body ? data.local_body : 0,
+            features: data.features || [],
+            ward: data.ward_object ? data.ward_object.id : 0,
+            kasp_empanelled: "",
+            address: data.address ? data.address : "",
+            pincode: data.pincode ? data.pincode : "",
+            phone_number: data.phone_number
+              ? data.phone_number.length == 10
+                ? "+91" + data.phone_number
+                : data.phone_number
+              : "",
+            latitude: data ? String(data.latitude) : "",
+            longitude: data ? String(data.longitude) : "",
+            type_b_cylinders: data.type_b_cylinders,
+            type_c_cylinders: data.type_c_cylinders,
+            type_d_cylinders: data.type_d_cylinders,
+            expected_type_b_cylinders: data.expected_type_b_cylinders,
+            expected_type_c_cylinders: data.expected_type_c_cylinders,
+            expected_type_d_cylinders: data.expected_type_d_cylinders,
+            expected_oxygen_requirement: data.expected_oxygen_requirement,
+            oxygen_capacity: data.oxygen_capacity,
           };
           dispatch({ type: "set_form", form: formData });
-          Promise.all([
-            fetchDistricts(res.data.state),
-            fetchLocalBody(res.data.district),
-            fetchWards(res.data.local_body),
-          ]);
+          setStateId(data.state);
+          setDistrictId(data.district);
+          setLocalBodyId(data.local_body);
         } else {
           navigate(`/facility/${facilityId}`);
         }
         setIsLoading(false);
       }
     },
-    [dispatchAction, facilityId, fetchDistricts, fetchLocalBody, fetchWards]
-  );
-
-  const fetchStates = useCallback(
-    async (status: statusType) => {
-      setIsStateLoading(true);
-      const statesRes = await dispatchAction(getStates());
-      if (!status.aborted && statesRes.data.results) {
-        setStates([...statesRes.data.results]);
-      }
-      setIsStateLoading(false);
-    },
-    [dispatchAction]
-  );
+  });
 
-  useAbortableEffect(
-    (status: statusType) => {
-      if (facilityId) {
-        fetchData(status);
-      }
-      fetchStates(status);
-    },
-    [dispatch, fetchData]
+  const { data: stateData, loading: isStateLoading } = useQuery(
+    routes.statesList
   );
 
   const handleChange = (e: FieldChangeEvent<unknown>) => {
@@ -357,12 +307,15 @@ export const FacilityCreate = (props: FacilityProps) => {
     const pincodeDetails = await getPincodeDetails(e.value, gov_data_api_key);
     if (!pincodeDetails) return;
 
-    const matchedState = states.find((state) => {
+    const matchedState = (stateData ? stateData.results : []).find((state) => {
       return includesIgnoreCase(state.name, pincodeDetails.statename);
     });
     if (!matchedState) return;
 
-    const fetchedDistricts = await fetchDistricts(matchedState.id);
+    const newDistrictDataResult: RequestResult<DistrictModel[]> =
+      await districtFetch({ pathParams: { id: String(matchedState.id) } });
+    const fetchedDistricts: DistrictModel[] = newDistrictDataResult.data || [];
+
     if (!fetchedDistricts) return;
 
     const matchedDistrict = fetchedDistricts.find((district) => {
@@ -380,7 +333,7 @@ export const FacilityCreate = (props: FacilityProps) => {
       },
     });
 
-    fetchLocalBody(matchedDistrict.id);
+    setDistrictId(matchedDistrict.id);
     setShowAutoFilledPincode(true);
     setTimeout(() => {
       setShowAutoFilledPincode(false);
@@ -478,19 +431,18 @@ export const FacilityCreate = (props: FacilityProps) => {
     console.log(state.form);
     if (validated) {
       setIsLoading(true);
-      const data = {
+      const data: FacilityRequest = {
         facility_type: state.form.facility_type,
         name: state.form.name,
         district: state.form.district,
         state: state.form.state,
         address: state.form.address,
-        pincode: state.form.pincode,
         local_body: state.form.local_body,
         features: state.form.features,
         ward: state.form.ward,
-        kasp_empanelled: JSON.parse(state.form.kasp_empanelled),
-        latitude: state.form.latitude || null,
-        longitude: state.form.longitude || null,
+        pincode: state.form.pincode,
+        latitude: state.form.latitude,
+        longitude: state.form.longitude,
         phone_number: parsePhoneNumber(state.form.phone_number),
         oxygen_capacity: state.form.oxygen_capacity
           ? state.form.oxygen_capacity
@@ -519,18 +471,26 @@ export const FacilityCreate = (props: FacilityProps) => {
           ? state.form.expected_type_d_cylinders
           : 0,
       };
-      const res = await dispatchAction(
-        facilityId ? updateFacility(facilityId, data) : createFacility(data)
-      );
 
-      if (res && (res.status === 200 || res.status === 201) && res.data) {
-        const id = res.data.id;
+      const { res, data: requestData } = facilityId
+        ? await request(routes.updateFacility, {
+            body: data,
+            pathParams: {
+              id: facilityId,
+            },
+          })
+        : await request(routes.createFacility, {
+            body: data,
+          });
+
+      if (res?.ok && requestData) {
+        const id = requestData.id;
         dispatch({ type: "set_form", form: initForm });
         if (!facilityId) {
           Notification.Success({
             msg: "Facility added successfully",
           });
-          setCreatedFacilityId(id);
+          setCreatedFacilityId(String(id));
           setCurrentStep(2);
         } else {
           Notification.Success({
@@ -538,11 +498,6 @@ export const FacilityCreate = (props: FacilityProps) => {
           });
           navigate(`/facility/${facilityId}`);
         }
-      } else {
-        if (res?.data)
-          Notification.Error({
-            msg: "Something went wrong: " + (res.data.detail || ""),
-          });
       }
       setIsLoading(false);
     }
@@ -605,11 +560,11 @@ export const FacilityCreate = (props: FacilityProps) => {
                 lastUpdated={res.modified_date}
                 removeBedType={removeCurrentBedType}
                 handleUpdate={async () => {
-                  const capacityRes = await dispatchAction(
-                    listCapacity({}, { facilityId: createdFacilityId })
-                  );
-                  if (capacityRes && capacityRes.data) {
-                    setCapacityData(capacityRes.data.results);
+                  const { res, data } = await request(routes.getCapacity, {
+                    pathParams: { facilityId: createdFacilityId },
+                  });
+                  if (res?.ok && data) {
+                    setCapacityData(data.results);
                   }
                 }}
               />
@@ -642,11 +597,11 @@ export const FacilityCreate = (props: FacilityProps) => {
               facilityId={createdFacilityId || ""}
               key={`bed_${data.id}`}
               handleUpdate={async () => {
-                const doctorRes = await dispatchAction(
-                  listDoctor({}, { facilityId: createdFacilityId })
-                );
-                if (doctorRes && doctorRes.data) {
-                  setDoctorData(doctorRes.data.results);
+                const { res, data } = await request(routes.listDoctor, {
+                  pathParams: { facilityId: createdFacilityId },
+                });
+                if (res?.ok && data) {
+                  setDoctorData(data.results);
                 }
               }}
               {...data}
@@ -688,11 +643,11 @@ export const FacilityCreate = (props: FacilityProps) => {
                 navigate(`/facility/${createdFacilityId}`);
               }}
               handleUpdate={async () => {
-                const doctorRes = await dispatchAction(
-                  listDoctor({}, { facilityId: createdFacilityId })
-                );
-                if (doctorRes && doctorRes.data) {
-                  setDoctorData(doctorRes.data.results);
+                const { res, data } = await request(routes.listDoctor, {
+                  pathParams: { facilityId: createdFacilityId },
+                });
+                if (res?.ok && data) {
+                  setDoctorData(data.results);
                 }
               }}
             />
@@ -725,11 +680,11 @@ export const FacilityCreate = (props: FacilityProps) => {
                 setCurrentStep(3);
               }}
               handleUpdate={async () => {
-                const capacityRes = await dispatchAction(
-                  listCapacity({}, { facilityId: createdFacilityId })
-                );
-                if (capacityRes && capacityRes.data) {
-                  setCapacityData(capacityRes.data.results);
+                const { res, data } = await request(routes.getCapacity, {
+                  pathParams: { facilityId: createdFacilityId },
+                });
+                if (res?.ok && data) {
+                  setCapacityData(data.results);
                 }
               }}
             />
@@ -760,11 +715,9 @@ export const FacilityCreate = (props: FacilityProps) => {
                 <DraftSection
                   handleDraftSelect={(newState: any) => {
                     dispatch({ type: "set_state", state: newState });
-                    Promise.all([
-                      fetchDistricts(newState.form.state),
-                      fetchLocalBody(newState.form.district),
-                      fetchWards(newState.form.local_body),
-                    ]);
+                    setStateId(newState.form.state);
+                    setDistrictId(newState.form.district);
+                    setLocalBodyId(newState.form.local_body);
                   }}
                   formData={state.form}
                 />
@@ -809,13 +762,13 @@ export const FacilityCreate = (props: FacilityProps) => {
                     placeholder="Choose State"
                     className={isStateLoading ? "animate-pulse" : ""}
                     disabled={isStateLoading}
-                    options={states}
+                    options={stateData ? stateData.results : []}
                     optionLabel={(o) => o.name}
                     optionValue={(o) => o.id}
                     onChange={(event) => {
                       handleChange(event);
                       if (!event) return;
-                      fetchDistricts(event.value);
+                      setStateId(event.value);
                     }}
                   />
                   <SelectFormField
@@ -824,13 +777,13 @@ export const FacilityCreate = (props: FacilityProps) => {
                     required
                     className={isDistrictLoading ? "animate-pulse" : ""}
                     disabled={isDistrictLoading}
-                    options={districts}
+                    options={districtData ? districtData : []}
                     optionLabel={(o) => o.name}
                     optionValue={(o) => o.id}
                     onChange={(event) => {
                       handleChange(event);
                       if (!event) return;
-                      fetchLocalBody(event.value);
+                      setDistrictId(event.value);
                     }}
                   />
                   <SelectFormField
@@ -839,13 +792,13 @@ export const FacilityCreate = (props: FacilityProps) => {
                     className={isLocalbodyLoading ? "animate-pulse" : ""}
                     disabled={isLocalbodyLoading}
                     placeholder="Choose Local Body"
-                    options={localBodies}
+                    options={localbodyData ? localbodyData : []}
                     optionLabel={(o) => o.name}
                     optionValue={(o) => o.id}
                     onChange={(event) => {
                       handleChange(event);
                       if (!event) return;
-                      fetchWards(event.value);
+                      setLocalBodyId(event.value);
                     }}
                   />
                   <SelectFormField
@@ -854,12 +807,14 @@ export const FacilityCreate = (props: FacilityProps) => {
                     className={isWardLoading ? "animate-pulse" : ""}
                     disabled={isWardLoading}
                     placeholder="Choose Ward"
-                    options={ward.sort(compareBy("number")).map((e) => {
-                      return {
-                        id: e.id,
-                        name: e.number + ": " + e.name,
-                      };
-                    })}
+                    options={(wardData ? wardData.results : [])
+                      .sort(compareBy("number"))
+                      .map((e) => {
+                        return {
+                          id: e.id,
+                          name: e.number + ": " + e.name,
+                        };
+                      })}
                     optionLabel={(o) => o.name}
                     optionValue={(o) => o.id}
                   />
diff --git a/src/Components/Facility/HospitalList.tsx b/src/Components/Facility/HospitalList.tsx
index ffdc1f4ed12..075ad8de39e 100644
--- a/src/Components/Facility/HospitalList.tsx
+++ b/src/Components/Facility/HospitalList.tsx
@@ -3,14 +3,8 @@ import {
   downloadFacilityCapacity,
   downloadFacilityDoctors,
   downloadFacilityTriage,
-  getDistrict,
-  getLocalBody,
-  getPermittedFacilities,
-  getState,
 } from "../../Redux/actions";
-import { statusType, useAbortableEffect } from "../../Common/utils";
-import { lazy, useCallback, useState } from "react";
-import { useDispatch } from "react-redux";
+import { lazy } from "react";
 import { AdvancedFilterButton } from "../../CAREUI/interactive/FiltersSlideover";
 import CountBlock from "../../CAREUI/display/Count";
 import ExportMenu from "../Common/Export";
@@ -25,6 +19,8 @@ import { navigate } from "raviger";
 import useFilters from "../../Common/hooks/useFilters";
 import { useTranslation } from "react-i18next";
 import useAuthUser from "../../Common/hooks/useAuthUser";
+import useQuery from "../../Utils/request/useQuery";
+import routes from "../../Redux/api";
 
 const Loading = lazy(() => import("../Common/Loading"));
 
@@ -39,21 +35,14 @@ export const HospitalList = () => {
   } = useFilters({
     limit: 14,
   });
-  const dispatchAction: any = useDispatch();
-  const [data, setData] = useState<Array<FacilityModel>>([]);
   let manageFacilities: any = null;
-  const [isLoading, setIsLoading] = useState(false);
-  const [totalCount, setTotalCount] = useState(0);
-  const [stateName, setStateName] = useState("");
-  const [districtName, setDistrictName] = useState("");
-  const [localbodyName, setLocalbodyName] = useState("");
   const { user_type } = useAuthUser();
   const { t } = useTranslation();
 
-  const fetchData = useCallback(
-    async (status: statusType) => {
-      setIsLoading(true);
-      const params = {
+  const { data: permittedData, loading: isLoading } = useQuery(
+    routes.getPermittedFacilities,
+    {
+      query: {
         limit: resultsPerPage,
         page: qParams.page || 1,
         offset: (qParams.page ? qParams.page - 1 : 0) * resultsPerPage,
@@ -63,92 +52,30 @@ export const HospitalList = () => {
         local_body: qParams.local_body,
         facility_type: qParams.facility_type,
         kasp_empanelled: qParams.kasp_empanelled,
-      };
-
-      const res = await dispatchAction(getPermittedFacilities(params));
-      if (!status.aborted) {
-        if (res && res.data) {
-          setData(res.data.results);
-          setTotalCount(res.data.count);
-        }
-        setIsLoading(false);
-      }
-    },
-    [
-      qParams.page,
-      qParams.search,
-      qParams.state,
-      qParams.district,
-      qParams.local_body,
-      qParams.facility_type,
-      qParams.kasp_empanelled,
-      dispatchAction,
-    ]
-  );
-
-  useAbortableEffect(
-    (status: statusType) => {
-      fetchData(status);
-    },
-    [fetchData]
-  );
-
-  const fetchStateName = useCallback(
-    async (status: statusType) => {
-      const res =
-        Number(qParams.state) &&
-        (await dispatchAction(getState(qParams.state)));
-      if (!status.aborted) {
-        setStateName(res?.data?.name);
-      }
-    },
-    [dispatchAction, qParams.state]
-  );
-
-  useAbortableEffect(
-    (status: statusType) => {
-      fetchStateName(status);
-    },
-    [fetchStateName]
-  );
-
-  const fetchDistrictName = useCallback(
-    async (status: statusType) => {
-      const res =
-        Number(qParams.district) &&
-        (await dispatchAction(getDistrict(qParams.district)));
-      if (!status.aborted) {
-        setDistrictName(res?.data?.name);
-      }
-    },
-    [dispatchAction, qParams.district]
+      },
+    }
   );
 
-  useAbortableEffect(
-    (status: statusType) => {
-      fetchDistrictName(status);
+  const { data: stateData } = useQuery(routes.getState, {
+    pathParams: {
+      id: qParams.state,
     },
-    [fetchDistrictName]
-  );
+    prefetch: qParams.state !== undefined,
+  });
 
-  const fetchLocalbodyName = useCallback(
-    async (status: statusType) => {
-      const res =
-        Number(qParams.local_body) &&
-        (await dispatchAction(getLocalBody({ id: qParams.local_body })));
-      if (!status.aborted) {
-        setLocalbodyName(res?.data?.name);
-      }
+  const { data: districtData } = useQuery(routes.getDistrict, {
+    pathParams: {
+      id: qParams.district,
     },
-    [dispatchAction, qParams.local_body]
-  );
+    prefetch: qParams.district !== undefined,
+  });
 
-  useAbortableEffect(
-    (status: statusType) => {
-      fetchLocalbodyName(status);
+  const { data: localBodyData } = useQuery(routes.getLocalBody, {
+    pathParams: {
+      id: qParams.local_body,
     },
-    [fetchLocalbodyName]
-  );
+    prefetch: qParams.local_body !== undefined,
+  });
 
   const findFacilityTypeById = (id: number) => {
     const facility_type = FACILITY_TYPES.find((type) => type.id == id);
@@ -167,8 +94,8 @@ export const HospitalList = () => {
   };
 
   let facilityList: JSX.Element[] = [];
-  if (data && data.length) {
-    facilityList = data.map((facility: FacilityModel) => (
+  if (permittedData && permittedData.results.length) {
+    facilityList = permittedData.results.map((facility: FacilityModel) => (
       <FacilityCard
         key={facility.id!}
         facility={facility}
@@ -177,18 +104,18 @@ export const HospitalList = () => {
     ));
   }
 
-  if (isLoading || !data) {
+  if (isLoading || !permittedData) {
     manageFacilities = <Loading />;
-  } else if (data && data.length) {
+  } else if (permittedData.results && permittedData.results.length) {
     manageFacilities = (
       <>
         <div className="grid gap-4 md:grid-cols-1 lg:grid-cols-2">
           {facilityList}
         </div>
-        <Pagination totalCount={totalCount} />
+        <Pagination totalCount={permittedData.count} />
       </>
     );
-  } else if (data && data.length === 0) {
+  } else if (permittedData.results && permittedData.results.length === 0) {
     manageFacilities = hasFiltersApplied(qParams) ? (
       <div className="w-full rounded-lg bg-white p-3">
         <div className="mt-4 flex w-full  justify-center text-2xl font-bold text-gray-600">
@@ -246,7 +173,7 @@ export const HospitalList = () => {
       <div className="mt-4 gap-2 lg:flex">
         <CountBlock
           text="Total Facilities"
-          count={totalCount}
+          count={permittedData ? permittedData.count : 0}
           loading={isLoading}
           icon="l-hospital"
           className="flex-1"
@@ -266,9 +193,21 @@ export const HospitalList = () => {
       <FilterBadges
         badges={({ badge, value, kasp }) => [
           badge("Facility/District Name", "search"),
-          value("State", "state", stateName),
-          value("District", "district", districtName),
-          value("Local Body", "local_body", localbodyName),
+          value(
+            "State",
+            "state",
+            qParams.state && stateData ? stateData.name : ""
+          ),
+          value(
+            "District",
+            "district",
+            qParams.district && districtData ? districtData.name : ""
+          ),
+          value(
+            "Local Body",
+            "local_body",
+            qParams.local_body && localBodyData ? localBodyData.name : ""
+          ),
           value(
             "Facility type",
             "facility_type",
diff --git a/src/Components/Facility/models.tsx b/src/Components/Facility/models.tsx
index c4a5196511d..90191e3321f 100644
--- a/src/Components/Facility/models.tsx
+++ b/src/Components/Facility/models.tsx
@@ -65,6 +65,7 @@ export interface FacilityModel {
   district?: number;
   local_body?: number;
   ward?: number;
+  pincode?: string;
 }
 
 export interface CapacityModal {
@@ -241,6 +242,13 @@ export interface CurrentBed {
   meta: Record<string, any>;
 }
 
+// Voluntarily made as `type` for it to achieve type-safety when used with
+// `useAsyncOptions<ICD11DiagnosisModel>`
+export type ICD11DiagnosisModel = {
+  id: string;
+  label: string;
+};
+
 export type ABGPlotsFields =
   | "ph"
   | "pco2"
@@ -447,13 +455,6 @@ export interface CreateBedBody {
   bed: string;
 }
 
-// Voluntarily made as `type` for it to achieve type-safety when used with
-// `useAsyncOptions<ICD11DiagnosisModel>`
-export type ICD11DiagnosisModel = {
-  id: string;
-  label: string;
-};
-
 // Patient Notes Model
 export interface BaseFacilityModel {
   id: string;
@@ -513,3 +514,11 @@ export type IFacilityNotificationResponse = {
 export type IUserFacilityRequest = {
   facility: string;
 };
+
+export type FacilityRequest = Omit<FacilityModel, "location"> & {
+  latitude?: string;
+  longitude?: string;
+  kasp_empanelled?: boolean;
+  patient_count?: string;
+  bed_count?: string;
+};
diff --git a/src/Redux/api.tsx b/src/Redux/api.tsx
index 9634036e6c4..80d5a630bea 100644
--- a/src/Redux/api.tsx
+++ b/src/Redux/api.tsx
@@ -41,10 +41,12 @@ import {
   IFacilityNotificationRequest,
   IFacilityNotificationResponse,
   IUserFacilityRequest,
+  LocalBodyModel,
   PatientStatsModel,
+  FacilityRequest,
+  StateModel,
   WardModel,
   LocationModel,
-  StateModel,
   PatientNotesModel,
 } from "../Components/Facility/models";
 import {
@@ -286,12 +288,14 @@ const routes = {
   createFacility: {
     path: "/api/v1/facility/",
     method: "POST",
+    TRes: Type<FacilityModel>(),
+    TBody: Type<FacilityRequest>(),
   },
 
   getPermittedFacility: {
     path: "/api/v1/facility/{id}/",
     method: "GET",
-    TRes: Type<FacilityModel>(),
+    TRes: Type<FacilityRequest>(),
   },
 
   getAnyFacility: {
@@ -301,8 +305,10 @@ const routes = {
   },
 
   updateFacility: {
-    path: "/api/v1/facility",
+    path: "/api/v1/facility/{id}/",
     method: "PUT",
+    TRes: Type<FacilityModel>(),
+    TBody: Type<FacilityRequest>(),
   },
 
   partialUpdateFacility: {
@@ -680,6 +686,7 @@ const routes = {
 
   getState: {
     path: "/api/v1/state/{id}/",
+    TRes: Type<StateModel>(),
   },
 
   // Districts
@@ -711,6 +718,7 @@ const routes = {
   // Local Body
   getLocalBody: {
     path: "/api/v1/local_body/{id}/",
+    TRes: Type<LocalBodyModel>(),
   },
   getAllLocalBody: {
     path: "/api/v1/local_body/",
diff --git a/src/Utils/request/useQuery.ts b/src/Utils/request/useQuery.ts
index 2dab2910278..97d1b565f2f 100644
--- a/src/Utils/request/useQuery.ts
+++ b/src/Utils/request/useQuery.ts
@@ -31,8 +31,10 @@ export default function useQuery<TData>(
           : options;
 
       setLoading(true);
-      setResponse(await request(route, resolvedOptions));
+      const response = await request(route, resolvedOptions);
+      setResponse(response);
       setLoading(false);
+      return response;
     },
     [route, JSON.stringify(options)]
   );

From cfe001120d5d9c56c09c99f1f6c6430ebc42da67 Mon Sep 17 00:00:00 2001
From: Ashesh <3626859+Ashesh3@users.noreply.github.com>
Date: Thu, 28 Dec 2023 06:55:04 +0530
Subject: [PATCH 08/20] Refactor middleware hostname usage in CameraFeed
 components (#6875)

---
 .../Assets/AssetType/HL7Monitor.tsx           | 41 ++++++-------------
 .../Assets/AssetType/ONVIFCamera.tsx          | 33 +++++----------
 src/Components/Assets/AssetTypes.tsx          |  6 +++
 src/Components/CameraFeed/CameraFeed.tsx      |  3 +-
 .../CameraFeed/CameraFeedWithBedPresets.tsx   |  2 -
 .../CentralLiveMonitoring/index.tsx           |  8 +---
 src/Components/CameraFeed/utils.ts            |  4 +-
 src/Components/Common/FilePreviewDialog.tsx   |  2 +-
 .../Facility/CentralNursingStation.tsx        |  3 +-
 .../Facility/Consultations/Feed.tsx           | 33 +++++----------
 10 files changed, 46 insertions(+), 89 deletions(-)

diff --git a/src/Components/Assets/AssetType/HL7Monitor.tsx b/src/Components/Assets/AssetType/HL7Monitor.tsx
index b4fefbc90b2..86b9565e536 100644
--- a/src/Components/Assets/AssetType/HL7Monitor.tsx
+++ b/src/Components/Assets/AssetType/HL7Monitor.tsx
@@ -1,5 +1,5 @@
 import { SyntheticEvent, useEffect, useState } from "react";
-import { AssetData } from "../AssetTypes";
+import { AssetData, ResolvedMiddleware } from "../AssetTypes";
 import * as Notification from "../../../Utils/Notifications.js";
 import MonitorConfigure from "../configure/MonitorConfigure";
 import Loading from "../../Common/Loading";
@@ -13,7 +13,6 @@ import VentilatorPatientVitalsMonitor from "../../VitalsMonitor/VentilatorPatien
 import useAuthUser from "../../../Common/hooks/useAuthUser";
 import request from "../../../Utils/request/request";
 import routes from "../../../Redux/api";
-import useQuery from "../../../Utils/request/useQuery";
 
 interface HL7MonitorProps {
   assetId: string;
@@ -22,27 +21,20 @@ interface HL7MonitorProps {
 }
 
 const HL7Monitor = (props: HL7MonitorProps) => {
-  const { assetId, asset, facilityId } = props;
+  const { assetId, asset } = props;
   const [assetType, setAssetType] = useState("");
   const [middlewareHostname, setMiddlewareHostname] = useState("");
-  const [facilityMiddlewareHostname, setFacilityMiddlewareHostname] =
-    useState("");
+  const [resolvedMiddleware, setResolvedMiddleware] =
+    useState<ResolvedMiddleware>();
   const [isLoading, setIsLoading] = useState(true);
   const [localipAddress, setLocalIPAddress] = useState("");
   const [ipadrdress_error, setIpAddress_error] = useState("");
   const authUser = useAuthUser();
-  const { data: facility, loading } = useQuery(routes.getPermittedFacility, {
-    pathParams: { id: facilityId },
-    onResponse: ({ res, data }) => {
-      if (res?.status === 200 && data && data.middleware_address) {
-        setFacilityMiddlewareHostname(data.middleware_address);
-      }
-    },
-  });
 
   useEffect(() => {
     setAssetType(asset?.asset_class);
     setMiddlewareHostname(asset?.meta?.middleware_hostname);
+    setResolvedMiddleware(asset?.resolved_middleware);
     setLocalIPAddress(asset?.meta?.local_ip_address);
     setIsLoading(false);
   }, [asset]);
@@ -76,10 +68,7 @@ const HL7Monitor = (props: HL7MonitorProps) => {
     }
   };
 
-  const fallbackMiddleware =
-    asset?.location_object?.middleware_address || facilityMiddlewareHostname;
-
-  if (isLoading || loading || !facility) return <Loading />;
+  if (isLoading) return <Loading />;
   return (
     <div className="mx-auto flex w-full xl:mt-8">
       <div className="mx-auto flex flex-col gap-4 xl:flex-row-reverse">
@@ -94,23 +83,21 @@ const HL7Monitor = (props: HL7MonitorProps) => {
                     label={
                       <div className="flex flex-row gap-1">
                         <p>Middleware Hostname</p>
-                        {!middlewareHostname && (
+                        {resolvedMiddleware?.source != "asset" && (
                           <div className="tooltip">
                             <CareIcon
                               icon="l-info-circle"
                               className="tooltip text-indigo-500 hover:text-indigo-600"
                             />
                             <span className="tooltip-text w-56 whitespace-normal">
-                              Middleware hostname sourced from{" "}
-                              {asset?.location_object?.middleware_address
-                                ? "asset location"
-                                : "asset facility"}
+                              Middleware hostname sourced from asset{" "}
+                              {resolvedMiddleware?.source}
                             </span>
                           </div>
                         )}
                       </div>
                     }
-                    placeholder={fallbackMiddleware}
+                    placeholder={resolvedMiddleware?.hostname}
                     value={middlewareHostname}
                     onChange={(e) => setMiddlewareHostname(e.value)}
                     errorClassName="hidden"
@@ -140,16 +127,12 @@ const HL7Monitor = (props: HL7MonitorProps) => {
 
         {assetType === "HL7MONITOR" && (
           <HL7PatientVitalsMonitor
-            socketUrl={`wss://${
-              middlewareHostname || fallbackMiddleware
-            }/observations/${localipAddress}`}
+            socketUrl={`wss://${resolvedMiddleware?.hostname}/observations/${localipAddress}`}
           />
         )}
         {assetType === "VENTILATOR" && (
           <VentilatorPatientVitalsMonitor
-            socketUrl={`wss://${
-              middlewareHostname || fallbackMiddleware
-            }/observations/${localipAddress}`}
+            socketUrl={`wss://${resolvedMiddleware?.hostname}/observations/${localipAddress}`}
           />
         )}
       </div>
diff --git a/src/Components/Assets/AssetType/ONVIFCamera.tsx b/src/Components/Assets/AssetType/ONVIFCamera.tsx
index 44d4d372d73..86b7199cdac 100644
--- a/src/Components/Assets/AssetType/ONVIFCamera.tsx
+++ b/src/Components/Assets/AssetType/ONVIFCamera.tsx
@@ -1,5 +1,5 @@
 import { useEffect, useState } from "react";
-import { AssetData } from "../AssetTypes";
+import { AssetData, ResolvedMiddleware } from "../AssetTypes";
 import * as Notification from "../../../Utils/Notifications.js";
 import { BedModel } from "../../Facility/models";
 import axios from "axios";
@@ -29,8 +29,8 @@ const ONVIFCamera = ({ assetId, facilityId, asset, onUpdated }: Props) => {
   const [isLoading, setIsLoading] = useState(true);
   const [assetType, setAssetType] = useState("");
   const [middlewareHostname, setMiddlewareHostname] = useState("");
-  const [facilityMiddlewareHostname, setFacilityMiddlewareHostname] =
-    useState("");
+  const [resolvedMiddleware, setResolvedMiddleware] =
+    useState<ResolvedMiddleware>();
   const [cameraAddress, setCameraAddress] = useState("");
   const [ipadrdress_error, setIpAddress_error] = useState("");
   const [username, setUsername] = useState("");
@@ -47,20 +47,11 @@ const ONVIFCamera = ({ assetId, facilityId, asset, onUpdated }: Props) => {
     pathParams: { id: facilityId },
   });
   const authUser = useAuthUser();
-  useEffect(() => {
-    if (facility?.middleware_address) {
-      setFacilityMiddlewareHostname(facility.middleware_address);
-    }
-  }, [facility, facilityId]);
-
-  const fallbackMiddleware =
-    asset?.location_object?.middleware_address || facilityMiddlewareHostname;
-
-  const currentMiddleware = middlewareHostname || fallbackMiddleware;
 
   useEffect(() => {
     if (asset) {
       setAssetType(asset?.asset_class);
+      setResolvedMiddleware(asset?.resolved_middleware);
       const cameraConfig = getCameraConfig(asset);
       setMiddlewareHostname(cameraConfig.middleware_hostname);
       setCameraAddress(cameraConfig.hostname);
@@ -79,7 +70,7 @@ const ONVIFCamera = ({ assetId, facilityId, asset, onUpdated }: Props) => {
       const data = {
         meta: {
           asset_type: "CAMERA",
-          middleware_hostname: middlewareHostname, // TODO: remove this infavour of facility.middleware_address
+          middleware_hostname: middlewareHostname,
           local_ip_address: cameraAddress,
           camera_access_key: `${username}:${password}:${streamUuid}`,
         },
@@ -110,7 +101,7 @@ const ONVIFCamera = ({ assetId, facilityId, asset, onUpdated }: Props) => {
     try {
       setLoadingAddPreset(true);
       const presetData = await axios.get(
-        `https://${currentMiddleware}/status?hostname=${config.hostname}&port=${config.port}&username=${config.username}&password=${config.password}`
+        `https://${resolvedMiddleware?.hostname}/status?hostname=${config.hostname}&port=${config.port}&username=${config.username}&password=${config.password}`
       );
 
       const { res } = await request(routes.createAssetBed, {
@@ -151,23 +142,21 @@ const ONVIFCamera = ({ assetId, facilityId, asset, onUpdated }: Props) => {
               label={
                 <div className="flex flex-row gap-1">
                   <p>Middleware Hostname</p>
-                  {!middlewareHostname && (
+                  {resolvedMiddleware?.source != "asset" && (
                     <div className="tooltip">
                       <CareIcon
                         icon="l-info-circle"
                         className="tooltip text-indigo-500 hover:text-indigo-600"
                       />
                       <span className="tooltip-text w-56 whitespace-normal">
-                        Middleware hostname sourced from{" "}
-                        {asset?.location_object?.middleware_address
-                          ? "asset location"
-                          : "asset facility"}
+                        Middleware hostname sourced from asset{" "}
+                        {resolvedMiddleware?.source}
                       </span>
                     </div>
                   )}
                 </div>
               }
-              placeholder={fallbackMiddleware}
+              placeholder={resolvedMiddleware?.hostname}
               value={middlewareHostname}
               onChange={({ value }) => setMiddlewareHostname(value)}
             />
@@ -225,7 +214,7 @@ const ONVIFCamera = ({ assetId, facilityId, asset, onUpdated }: Props) => {
           addPreset={addPreset}
           isLoading={loadingAddPreset}
           refreshPresetsHash={refreshPresetsHash}
-          facilityMiddlewareHostname={currentMiddleware}
+          facilityMiddlewareHostname={resolvedMiddleware?.hostname || ""}
         />
       ) : null}
     </div>
diff --git a/src/Components/Assets/AssetTypes.tsx b/src/Components/Assets/AssetTypes.tsx
index 97334f6af49..436c9370dd8 100644
--- a/src/Components/Assets/AssetTypes.tsx
+++ b/src/Components/Assets/AssetTypes.tsx
@@ -72,6 +72,11 @@ export interface AssetService {
   note: string;
 }
 
+export interface ResolvedMiddleware {
+  hostname: string;
+  source: "asset" | "location" | "facility";
+}
+
 export interface AssetData {
   id: string;
   name: string;
@@ -93,6 +98,7 @@ export interface AssetData {
   qr_code_id: string;
   manufacturer: string;
   warranty_amc_end_of_validity: string;
+  resolved_middleware?: ResolvedMiddleware;
   last_service: AssetService;
   meta?: {
     [key: string]: any;
diff --git a/src/Components/CameraFeed/CameraFeed.tsx b/src/Components/CameraFeed/CameraFeed.tsx
index 4ec039e4e70..6e2d8647c83 100644
--- a/src/Components/CameraFeed/CameraFeed.tsx
+++ b/src/Components/CameraFeed/CameraFeed.tsx
@@ -14,7 +14,6 @@ import Fullscreen from "../../CAREUI/misc/Fullscreen";
 interface Props {
   children?: React.ReactNode;
   asset: AssetData;
-  fallbackMiddleware: string; // TODO: remove this in favour of `asset.resolved_middleware.hostname` once https://github.com/coronasafe/care/pull/1741 is merged
   preset?: PTZPayload;
   silent?: boolean;
   className?: string;
@@ -29,7 +28,7 @@ interface Props {
 
 export default function CameraFeed(props: Props) {
   const playerRef = useRef<HTMLVideoElement | ReactPlayer | null>(null);
-  const streamUrl = getStreamUrl(props.asset, props.fallbackMiddleware);
+  const streamUrl = getStreamUrl(props.asset);
 
   const player = usePlayer(streamUrl, playerRef);
   const operate = useOperateCamera(props.asset.id, props.silent);
diff --git a/src/Components/CameraFeed/CameraFeedWithBedPresets.tsx b/src/Components/CameraFeed/CameraFeedWithBedPresets.tsx
index b52071a8597..386b93325b0 100644
--- a/src/Components/CameraFeed/CameraFeedWithBedPresets.tsx
+++ b/src/Components/CameraFeed/CameraFeedWithBedPresets.tsx
@@ -5,7 +5,6 @@ import AssetBedSelect from "./AssetBedSelect";
 
 interface Props {
   asset: AssetData;
-  fallbackMiddleware?: string;
 }
 
 export default function LocationFeedTile(props: Props) {
@@ -14,7 +13,6 @@ export default function LocationFeedTile(props: Props) {
   return (
     <CameraFeed
       asset={props.asset}
-      fallbackMiddleware={props.fallbackMiddleware as string}
       silent
       preset={preset?.meta.position}
       shortcutsDisabled
diff --git a/src/Components/CameraFeed/CentralLiveMonitoring/index.tsx b/src/Components/CameraFeed/CentralLiveMonitoring/index.tsx
index d83b01201b9..d2e7fd89494 100644
--- a/src/Components/CameraFeed/CentralLiveMonitoring/index.tsx
+++ b/src/Components/CameraFeed/CentralLiveMonitoring/index.tsx
@@ -67,13 +67,7 @@ export default function CentralLiveMonitoring(props: { facilityId: string }) {
           <div className="mt-1 grid grid-cols-1 place-content-center gap-1 lg:grid-cols-2 3xl:grid-cols-3">
             {data.results.map((asset) => (
               <div className="text-clip" key={asset.id}>
-                <LocationFeedTile
-                  asset={asset}
-                  fallbackMiddleware={
-                    asset.location_object.middleware_address ||
-                    facilityQuery.data?.middleware_address
-                  }
-                />
+                <LocationFeedTile asset={asset} />
               </div>
             ))}
           </div>
diff --git a/src/Components/CameraFeed/utils.ts b/src/Components/CameraFeed/utils.ts
index b5b8920fd5a..e2793d76b41 100644
--- a/src/Components/CameraFeed/utils.ts
+++ b/src/Components/CameraFeed/utils.ts
@@ -17,9 +17,9 @@ export const calculateVideoDelay = (
   return playedDuration - video.currentTime;
 };
 
-export const getStreamUrl = (asset: AssetData, fallbackMiddleware?: string) => {
+export const getStreamUrl = (asset: AssetData) => {
   const config = getCameraConfig(asset);
-  const host = config.middleware_hostname || fallbackMiddleware;
+  const host = asset.resolved_middleware?.hostname;
   const uuid = config.accessKey;
 
   return isIOS
diff --git a/src/Components/Common/FilePreviewDialog.tsx b/src/Components/Common/FilePreviewDialog.tsx
index 90dde50a249..cb16337b238 100644
--- a/src/Components/Common/FilePreviewDialog.tsx
+++ b/src/Components/Common/FilePreviewDialog.tsx
@@ -192,7 +192,7 @@ const FilePreviewDialog = (props: FilePreviewProps) => {
                           />
                         ) : (
                           <iframe
-                            sandbox
+                            sandbox=""
                             title="Source Files"
                             src={fileUrl}
                             className="mx-auto h-5/6 w-5/6 border-2 border-black bg-white md:my-6 md:w-4/6"
diff --git a/src/Components/Facility/CentralNursingStation.tsx b/src/Components/Facility/CentralNursingStation.tsx
index 601f579e8d0..9e8febe88fd 100644
--- a/src/Components/Facility/CentralNursingStation.tsx
+++ b/src/Components/Facility/CentralNursingStation.tsx
@@ -86,8 +86,7 @@ export default function CentralNursingStation({ facilityId }: Props) {
       setTotalCount(res.data.count);
       setData(
         entries.map(({ patient, asset, bed }) => {
-          const middleware =
-            asset.meta?.middleware_hostname || facilityObj?.middleware_address;
+          const middleware = asset.resolved_middleware?.hostname;
           const local_ip_address = asset.meta?.local_ip_address;
 
           return {
diff --git a/src/Components/Facility/Consultations/Feed.tsx b/src/Components/Facility/Consultations/Feed.tsx
index fcd6d50360f..22953103089 100644
--- a/src/Components/Facility/Consultations/Feed.tsx
+++ b/src/Components/Facility/Consultations/Feed.tsx
@@ -27,6 +27,7 @@ import { triggerGoal } from "../../../Integrations/Plausible.js";
 import useAuthUser from "../../../Common/hooks/useAuthUser.js";
 import Spinner from "../../Common/Spinner.js";
 import useQuery from "../../../Utils/request/useQuery.js";
+import { ResolvedMiddleware } from "../../Assets/AssetTypes.js";
 
 interface IFeedProps {
   facilityId: string;
@@ -35,7 +36,7 @@ interface IFeedProps {
 
 const PATIENT_DEFAULT_PRESET = "Patient View".trim().toLowerCase();
 
-export const Feed: React.FC<IFeedProps> = ({ consultationId, facilityId }) => {
+export const Feed: React.FC<IFeedProps> = ({ consultationId }) => {
   const dispatch: any = useDispatch();
 
   const videoWrapper = useRef<HTMLDivElement>(null);
@@ -55,25 +56,10 @@ export const Feed: React.FC<IFeedProps> = ({ consultationId, facilityId }) => {
   const [isFullscreen, setFullscreen] = useFullscreen();
   const [videoStartTime, setVideoStartTime] = useState<Date | null>(null);
   const [statusReported, setStatusReported] = useState(false);
-  const [facilityMiddlewareHostname, setFacilityMiddlewareHostname] =
-    useState("");
+  const [resolvedMiddleware, setResolvedMiddleware] =
+    useState<ResolvedMiddleware>();
   const authUser = useAuthUser();
 
-  useQuery(routes.getPermittedFacility, {
-    pathParams: { id: facilityId || "" },
-    onResponse: ({ res, data }) => {
-      if (res && res.status === 200 && data && data.middleware_address) {
-        setFacilityMiddlewareHostname(data.middleware_address);
-      }
-    },
-  });
-
-  const fallbackMiddleware =
-    cameraAsset.location_middleware || facilityMiddlewareHostname;
-
-  const currentMiddleware =
-    cameraAsset.middleware_address || fallbackMiddleware;
-
   useEffect(() => {
     if (cameraState) {
       setCameraState({
@@ -136,6 +122,9 @@ export const Feed: React.FC<IFeedProps> = ({ consultationId, facilityId }) => {
                   bedAssets.data.results[0].asset_object.location_object
                     ?.middleware_address,
               });
+              setResolvedMiddleware(
+                bedAssets.data.results[0].asset_object.resolved_middleware
+              );
               setCameraConfig(bedAssets.data.results[0].meta);
               setCameraState({
                 ...bedAssets.data.results[0].meta.position,
@@ -173,8 +162,8 @@ export const Feed: React.FC<IFeedProps> = ({ consultationId, facilityId }) => {
   );
 
   const url = !isIOS
-    ? `wss://${currentMiddleware}/stream/${cameraAsset?.accessKey}/channel/0/mse?uuid=${cameraAsset?.accessKey}&channel=0`
-    : `https://${currentMiddleware}/stream/${cameraAsset?.accessKey}/channel/0/hls/live/index.m3u8?uuid=${cameraAsset?.accessKey}&channel=0`;
+    ? `wss://${resolvedMiddleware?.hostname}/stream/${cameraAsset?.accessKey}/channel/0/mse?uuid=${cameraAsset?.accessKey}&channel=0`
+    : `https://${resolvedMiddleware?.hostname}/stream/${cameraAsset?.accessKey}/channel/0/hls/live/index.m3u8?uuid=${cameraAsset?.accessKey}&channel=0`;
 
   const {
     startStream,
@@ -185,7 +174,7 @@ export const Feed: React.FC<IFeedProps> = ({ consultationId, facilityId }) => {
     : // eslint-disable-next-line react-hooks/rules-of-hooks
       useMSEMediaPlayer({
         config: {
-          middlewareHostname: currentMiddleware,
+          middlewareHostname: resolvedMiddleware?.hostname ?? "",
           ...cameraAsset,
         },
         url,
@@ -254,7 +243,7 @@ export const Feed: React.FC<IFeedProps> = ({ consultationId, facilityId }) => {
       });
       getBedPresets(cameraAsset);
     }
-  }, [cameraAsset, currentMiddleware]);
+  }, [cameraAsset, resolvedMiddleware?.hostname]);
 
   useEffect(() => {
     let tId: any;

From 988e383a6246695d4638e30f5ed813189a4755ae Mon Sep 17 00:00:00 2001
From: Onkar Jadhav <56870381+Omkar76@users.noreply.github.com>
Date: Thu, 28 Dec 2023 06:58:49 +0530
Subject: [PATCH 09/20] Fix mispositioned active link indicator (#6880)

* Fix mispositioned active link indicator

* Make indicator height 26% of link element height.

* Extract 'navItemCount' as variable
---
 src/Components/Common/Sidebar/Sidebar.tsx     |  56 +++-----
 src/Components/Common/Sidebar/SidebarItem.tsx | 126 ++++++++++--------
 2 files changed, 85 insertions(+), 97 deletions(-)

diff --git a/src/Components/Common/Sidebar/Sidebar.tsx b/src/Components/Common/Sidebar/Sidebar.tsx
index 10b5c6d04fa..fa809571772 100644
--- a/src/Components/Common/Sidebar/Sidebar.tsx
+++ b/src/Components/Common/Sidebar/Sidebar.tsx
@@ -55,61 +55,36 @@ const StatelessSidebar = ({
   const { dashboard_url } = useConfig();
 
   const indicatorRef = useRef<HTMLDivElement>(null);
+  const activeLinkRef = useRef<HTMLAnchorElement>(null);
   const [lastIndicatorPosition, setLastIndicatorPosition] = useState(0);
   const [isOverflowVisible, setOverflowVisisble] = useState(false);
 
   useEffect(() => {
     if (!indicatorRef.current) return;
     const index = NavItems.findIndex((item) => item.to === activeLink);
+    const navItemCount = NavItems.length + 2; // +2 for notification and dashboard
     if (index !== -1) {
       // Haha math go brrrrrrrrr
 
       const e = indicatorRef.current;
-
-      const itemHeight = 44;
-      const bottomItemOffset = 2;
-
-      const indexDifference = index - lastIndicatorPosition;
-      e.style.display = "block";
-
-      if (indexDifference > 0) {
-        e.style.top = lastIndicatorPosition * itemHeight + 16 + "px";
-        e.style.bottom = "auto";
+      const itemHeight = activeLinkRef.current?.clientHeight || 0;
+      if (lastIndicatorPosition > index) {
+        e.style.top = `${itemHeight * (index + 0.37)}px`;
+        setTimeout(() => {
+          e.style.bottom = `${itemHeight * (navItemCount - 0.63 - index)}px`;
+        }, 50);
       } else {
-        e.style.bottom =
-          itemHeight * (NavItems.length + bottomItemOffset) -
-          lastIndicatorPosition * itemHeight -
-          28 +
-          "px";
-        e.style.top = "auto";
+        e.style.bottom = `${itemHeight * (navItemCount - 0.63 - index)}px`;
+        setTimeout(() => {
+          e.style.top = `${itemHeight * (index + 0.37)}px`;
+        }, 50);
       }
-
-      const variableHeight = Math.min(
-        Math.abs(indexDifference) * itemHeight,
-        70
-      );
-
-      e.style.height = `${variableHeight}px`;
-      setTimeout(() => {
-        if (!e) return;
-        if (indexDifference > 0) {
-          e.style.top = index * itemHeight + 16 + "px";
-          e.style.bottom = "auto";
-        } else {
-          e.style.bottom =
-            itemHeight * (NavItems.length + bottomItemOffset) -
-            index * itemHeight -
-            28 +
-            "px";
-          e.style.top = "auto";
-        }
-        e.style.height = "0.75rem";
-        setLastIndicatorPosition(index);
-      }, 300);
+      setLastIndicatorPosition(index);
     } else {
       indicatorRef.current.style.display = "none";
     }
-  }, [activeLink]);
+  }, [activeLink, lastIndicatorPosition]);
+
   const handleOverflow = (value: boolean) => {
     setOverflowVisisble(value);
   };
@@ -147,6 +122,7 @@ const StatelessSidebar = ({
           {NavItems.map((i) => {
             return (
               <Item
+                ref={i.to === activeLink ? activeLinkRef : undefined}
                 key={i.text}
                 {...i}
                 icon={<CareIcon className={`${i.icon} h-5`} />}
diff --git a/src/Components/Common/Sidebar/SidebarItem.tsx b/src/Components/Common/Sidebar/SidebarItem.tsx
index e13a1452125..20ffec4217e 100644
--- a/src/Components/Common/Sidebar/SidebarItem.tsx
+++ b/src/Components/Common/Sidebar/SidebarItem.tsx
@@ -2,10 +2,12 @@ import { Link } from "raviger";
 import { useTranslation } from "react-i18next";
 import CareIcon from "../../../CAREUI/icons/CareIcon";
 import useAppHistory from "../../../Common/hooks/useAppHistory";
+import React, { forwardRef, Ref } from "react";
 
 export type SidebarIcon = React.ReactNode;
 
 type SidebarItemProps = {
+  ref?: React.Ref<HTMLAnchorElement>;
   text: string;
   icon: SidebarIcon;
   external?: true | undefined;
@@ -14,74 +16,84 @@ type SidebarItemProps = {
   handleOverflow?: any;
 } & ({ to: string; do?: undefined } | { to?: string; do: () => void });
 
-type SidebarItemBaseProps = SidebarItemProps & { shrinked?: boolean };
-const SidebarItemBase = ({
-  shrinked,
-  external,
-  ...props
-}: SidebarItemBaseProps) => {
-  const { t } = useTranslation();
-  const { resetHistory } = useAppHistory();
+type SidebarItemBaseProps = SidebarItemProps & {
+  shrinked?: boolean;
+  ref: Ref<HTMLAnchorElement>;
+};
+
+const SidebarItemBase = forwardRef(
+  (
+    { shrinked, external, ...props }: SidebarItemBaseProps,
+    ref: Ref<HTMLAnchorElement>
+  ) => {
+    const { t } = useTranslation();
+    const { resetHistory } = useAppHistory();
 
-  return (
-    <Link
-      className={`tooltip relative ml-1  mr-3 h-full min-h-[40px] flex-1 cursor-pointer rounded-lg text-white transition-all duration-200 ease-in-out md:h-11 md:flex-none
+    return (
+      <Link
+        ref={ref}
+        className={`tooltip relative ml-1  mr-3 h-full min-h-[40px] flex-1 cursor-pointer rounded-lg text-white transition-all duration-200 ease-in-out md:h-11 md:flex-none
         ${
           props.selected
             ? "bg-primary-900 font-bold"
             : "bg-primary-800 font-normal hover:bg-primary-700"
         }`}
-      target={external && "_blank"}
-      rel={external && "noreferrer"}
-      href={props.to ?? ""}
-      onClick={props.do ?? resetHistory}
-      onMouseEnter={() => {
-        props.handleOverflow(true);
-      }}
-      onMouseLeave={() => {
-        props.handleOverflow(false);
-      }}
-    >
-      <span className={`tooltip-text tooltip-right ${!shrinked && "hidden"}`}>
-        {t(props.text)}
-      </span>
-      <div
-        className={`flex h-full items-center ${
-          shrinked ? "justify-center" : "justify-start pl-5 pr-4"
-        } transition-all duration-200 ease-in-out`}
+        target={external && "_blank"}
+        rel={external && "noreferrer"}
+        href={props.to ?? ""}
+        onClick={props.do ?? resetHistory}
+        onMouseEnter={() => {
+          props.handleOverflow(true);
+        }}
+        onMouseLeave={() => {
+          props.handleOverflow(false);
+        }}
       >
-        <div className="flex-none text-lg">{props.icon}</div>
-        <span
-          className={`${
-            shrinked ? "hidden" : "grow"
-          } flex w-full items-center pl-4 text-sm tracking-wide`}
-        >
+        <span className={`tooltip-text tooltip-right ${!shrinked && "hidden"}`}>
           {t(props.text)}
         </span>
-        {external && !shrinked && (
-          <CareIcon className="care-l-external-link-alt text-lg" />
-        )}
-      </div>
-
-      {!!props.badgeCount && (
-        <span
-          className={`absolute flex items-center justify-center bg-primary-500 font-semibold text-white ${
-            shrinked
-              ? "right-3 top-0.5 h-4 w-5 rounded-md text-[9px]"
-              : "inset-y-0 right-4 my-auto h-6 rounded-md px-2 text-xs"
-          } z-10 animate-pulse transition-all duration-200 ease-in-out`}
+        <div
+          className={`flex h-full items-center ${
+            shrinked ? "justify-center" : "justify-start pl-5 pr-4"
+          } transition-all duration-200 ease-in-out`}
         >
-          {props.badgeCount > 9 ? "9+" : props.badgeCount}
-        </span>
-      )}
-    </Link>
-  );
-};
+          <div className="flex-none text-lg">{props.icon}</div>
+          <span
+            className={`${
+              shrinked ? "hidden" : "grow"
+            } flex w-full items-center pl-4 text-sm tracking-wide`}
+          >
+            {t(props.text)}
+          </span>
+          {external && !shrinked && (
+            <CareIcon className="care-l-external-link-alt text-lg" />
+          )}
+        </div>
+
+        {!!props.badgeCount && (
+          <span
+            className={`absolute flex items-center justify-center bg-primary-500 font-semibold text-white ${
+              shrinked
+                ? "right-3 top-0.5 h-4 w-5 rounded-md text-[9px]"
+                : "inset-y-0 right-4 my-auto h-6 rounded-md px-2 text-xs"
+            } z-10 animate-pulse transition-all duration-200 ease-in-out`}
+          >
+            {props.badgeCount > 9 ? "9+" : props.badgeCount}
+          </span>
+        )}
+      </Link>
+    );
+  }
+);
 
-export const SidebarItem = (props: SidebarItemProps) => (
-  <SidebarItemBase {...props} />
+export const SidebarItem = forwardRef(
+  (props: SidebarItemProps, ref: Ref<HTMLAnchorElement>) => (
+    <SidebarItemBase {...props} ref={ref} />
+  )
 );
 
-export const ShrinkedSidebarItem = (props: SidebarItemProps) => (
-  <SidebarItemBase shrinked {...props} />
+export const ShrinkedSidebarItem = forwardRef(
+  (props: SidebarItemProps, ref: Ref<HTMLAnchorElement>) => (
+    <SidebarItemBase shrinked ref={ref} {...props} />
+  )
 );

From 8a9234feac7cfbe6eaed5fde410774308a20adfe Mon Sep 17 00:00:00 2001
From: Rithvik Nishad <mail@rithviknishad.dev>
Date: Thu, 28 Dec 2023 14:01:12 +0530
Subject: [PATCH 10/20] Migrate Bed Management to `useQuery` and move
 pagination state to query params (#6909)

* fixes #6906; migrate Bed Management to `useQuery`

* uncommented related test

* handle the auto-fill delay

* handle the google map delay

* revert vite

---------

Co-authored-by: Mohammed Nihal <57055998+nihal467@users.noreply.github.com>
Co-authored-by: Khavin Shankar <khavinshankar@gmail.com>
---
 cypress/e2e/facility_spec/locations.cy.ts     |  34 ++---
 .../pageobject/Facility/FacilityCreation.ts   |   3 +
 src/Components/Facility/BedManagement.tsx     | 127 +++++-------------
 src/Redux/api.tsx                             |   3 +
 4 files changed, 58 insertions(+), 109 deletions(-)

diff --git a/cypress/e2e/facility_spec/locations.cy.ts b/cypress/e2e/facility_spec/locations.cy.ts
index b9d26ee3100..d6377ba97c3 100644
--- a/cypress/e2e/facility_spec/locations.cy.ts
+++ b/cypress/e2e/facility_spec/locations.cy.ts
@@ -3,16 +3,18 @@ import { AssetPage } from "../../pageobject/Asset/AssetCreation";
 import { UserCreationPage } from "../../pageobject/Users/UserCreation";
 import FacilityPage from "../../pageobject/Facility/FacilityCreation";
 import FacilityLocation from "../../pageobject/Facility/FacilityLocation";
+import { AssetPagination } from "../../pageobject/Asset/AssetPagination";
 import FacilityHome from "../../pageobject/Facility/FacilityHome";
-// import { AssetPagination } from "../../pageobject/Asset/AssetPagination";
+
 
 describe("Location Management Section", () => {
   const assetPage = new AssetPage();
   const userCreationPage = new UserCreationPage();
   const facilityPage = new FacilityPage();
   const facilityLocation = new FacilityLocation();
+  const assetPagination = new AssetPagination();
   const facilityHome = new FacilityHome();
-  // const assetPagination = new AssetPagination();
+
   const EXPECTED_LOCATION_ERROR_MESSAGES = [
     "Name is required",
     "Location Type is required",
@@ -37,7 +39,7 @@ describe("Location Management Section", () => {
   const bedModifiedDescrption = "test modified description";
   const bedModifiedType = "Isolation";
   const numberOfBeds = 10;
-  //  const numberOfModifiedBeds = 25;
+  const numberOfModifiedBeds = 25;
 
   before(() => {
     cy.loginByApi("devdistrictadmin", "Coronasafe@123");
@@ -144,19 +146,19 @@ describe("Location Management Section", () => {
     facilityLocation.deleteBedRequest();
   });
 
-  // it("Add Multiple Bed to a facility location and verify pagination", () => {
-  //   // bed creation
-  //   facilityLocation.clickManageBedButton();
-  //   facilityLocation.clickAddBedButton();
-  //   facilityLocation.enterBedName(bedModifiedName);
-  //   facilityLocation.enterBedDescription(bedModifiedDescrption);
-  //   facilityLocation.selectBedType(bedModifiedType);
-  //   facilityLocation.setMultipleBeds(numberOfModifiedBeds);
-  //   assetPage.clickassetupdatebutton();
-  //   // pagination
-  //   assetPagination.navigateToNextPage();
-  //   assetPagination.navigateToPreviousPage();
-  // }); need to be unblocked upon issue #6906 is solved
+  it("Add Multiple Bed to a facility location and verify pagination", () => {
+    // bed creation
+    facilityLocation.clickManageBedButton();
+    facilityLocation.clickAddBedButton();
+    facilityLocation.enterBedName(bedModifiedName);
+    facilityLocation.enterBedDescription(bedModifiedDescrption);
+    facilityLocation.selectBedType(bedModifiedType);
+    facilityLocation.setMultipleBeds(numberOfModifiedBeds);
+    assetPage.clickassetupdatebutton();
+    // pagination
+    assetPagination.navigateToNextPage();
+    assetPagination.navigateToPreviousPage();
+  });
 
   afterEach(() => {
     cy.saveLocalStorage();
diff --git a/cypress/pageobject/Facility/FacilityCreation.ts b/cypress/pageobject/Facility/FacilityCreation.ts
index e3639388620..2d6aa9ff375 100644
--- a/cypress/pageobject/Facility/FacilityCreation.ts
+++ b/cypress/pageobject/Facility/FacilityCreation.ts
@@ -299,6 +299,7 @@ class FacilityPage {
     cy.intercept("https://maps.googleapis.com/maps/api/mapsjs/*").as("mapApi");
     cy.wait("@mapApi").its("response.statusCode").should("eq", 200);
     cy.get("input#pac-input").type(location).type("{enter}");
+    cy.wait(2000);
     cy.get("div#map-close").click();
   }
 
@@ -418,6 +419,7 @@ class FacilityPage {
   selectStateOnPincode(stateName) {
     this.getStateElement()
       .scrollIntoView()
+      .wait(2000)
       .should("be.visible")
       .then(($element) => {
         const text = $element.text();
@@ -431,6 +433,7 @@ class FacilityPage {
   selectDistrictOnPincode(districtName) {
     this.getDistrictElement()
       .scrollIntoView()
+      .wait(2000)
       .should("be.visible")
       .then(($element) => {
         const text = $element.text();
diff --git a/src/Components/Facility/BedManagement.tsx b/src/Components/Facility/BedManagement.tsx
index 3c786bdce25..68e9fade43d 100644
--- a/src/Components/Facility/BedManagement.tsx
+++ b/src/Components/Facility/BedManagement.tsx
@@ -1,14 +1,4 @@
-import { lazy, useCallback, useState } from "react";
-
-import { useDispatch } from "react-redux";
-import { statusType, useAbortableEffect } from "../../Common/utils";
-import {
-  getAnyFacility,
-  getFacilityAssetLocation,
-  listFacilityBeds,
-  deleteFacilityBed,
-} from "../../Redux/actions";
-import Pagination from "../Common/Pagination";
+import { lazy, useState } from "react";
 import ButtonV2 from "../Common/components/ButtonV2";
 import { BedModel } from "./models";
 import { ReactElement } from "react";
@@ -18,6 +8,10 @@ import BedDeleteDialog from "./BedDeleteDialog";
 import { NonReadOnlyUsers } from "../../Utils/AuthorizeFor";
 import CareIcon from "../../CAREUI/icons/CareIcon";
 import Page from "../Common/components/Page";
+import request from "../../Utils/request/request";
+import routes from "../../Redux/api";
+import useQuery from "../../Utils/request/useQuery";
+import useFilters from "../../Common/hooks/useFilters";
 const Loading = lazy(() => import("../Common/Loading"));
 
 interface BedManagementProps {
@@ -47,8 +41,6 @@ const BedRow = (props: BedRowProps) => {
     bedType,
     isOccupied,
   } = props;
-
-  const dispatchAction: any = useDispatch();
   const [bedData, setBedData] = useState<{
     show: boolean;
     name: string;
@@ -62,15 +54,11 @@ const BedRow = (props: BedRowProps) => {
   };
 
   const handleDeleteConfirm = async () => {
-    const res = await dispatchAction(deleteFacilityBed(id));
-    if (res?.status === 204) {
-      Notification.Success({
-        msg: "Bed deleted successfully",
-      });
-    } else {
-      Notification.Error({
-        msg: "Error while deleting Bed: " + (res?.data?.detail || ""),
-      });
+    const { res } = await request(routes.deleteFacilityBed, {
+      pathParams: { external_id: id },
+    });
+    if (res?.ok) {
+      Notification.Success({ msg: "Bed deleted successfully" });
     }
     setBedData({ show: false, name: "" });
     triggerRerender();
@@ -158,83 +146,41 @@ const BedRow = (props: BedRowProps) => {
 
 export const BedManagement = (props: BedManagementProps) => {
   const { facilityId, locationId } = props;
-  const dispatchAction: any = useDispatch();
-  const [isLoading, setIsLoading] = useState(false);
   let bed: ReactElement | null = null;
   let BedList: ReactElement[] | ReactElement = [];
-  const [beds, setBeds] = useState<BedModel[]>([]);
-  const [offset, setOffset] = useState(0);
-  const [currentPage, setCurrentPage] = useState(1);
-  const [totalCount, setTotalCount] = useState(0);
-  const [rerender, setRerender] = useState(false);
-  const [facilityName, setFacilityName] = useState("");
-  const [locationName, setLocationName] = useState("");
-  const limit = 14;
-
-  const triggerRerender = () => {
-    setRerender(!rerender);
-  };
-
-  const fetchData = useCallback(
-    async (status: statusType) => {
-      setIsLoading(true);
-      const facility = await dispatchAction(getAnyFacility(facilityId));
-
-      setFacilityName(facility?.data?.name || "");
+  const { qParams, Pagination, resultsPerPage } = useFilters({});
 
-      const location = await dispatchAction(
-        getFacilityAssetLocation(facilityId, locationId)
-      );
-
-      setLocationName(location?.data?.name || "");
-
-      const res = await dispatchAction(
-        listFacilityBeds({
-          limit,
-          offset,
-          facility: facilityId,
-          location: locationId,
-        })
-      );
-      if (!status.aborted) {
-        if (res?.data) {
-          setBeds(res.data.results);
-          setTotalCount(res.data.count);
-        }
-        setIsLoading(false);
-      }
+  const { data: location } = useQuery(routes.getFacilityAssetLocation, {
+    pathParams: {
+      facility_external_id: facilityId,
+      external_id: locationId,
     },
-    [dispatchAction, offset, rerender, facilityId, locationId]
-  );
-
-  useAbortableEffect(
-    (status: statusType) => {
-      fetchData(status);
+  });
+
+  const { loading, data, refetch } = useQuery(routes.listFacilityBeds, {
+    query: {
+      facility: facilityId,
+      location: locationId,
+      limit: resultsPerPage,
+      offset: (qParams.page ? qParams.page - 1 : 0) * resultsPerPage,
     },
-    [fetchData]
-  );
-
-  const handlePagination = (page: number, limit: number) => {
-    const offset = (page - 1) * limit;
-    setCurrentPage(page);
-    setOffset(offset);
-  };
+  });
 
-  if (beds && beds.length) {
-    BedList = beds.map((bedItem: BedModel) => (
+  if (data?.results.length) {
+    BedList = data.results.map((bedItem: BedModel) => (
       <BedRow
         id={bedItem.id ?? ""}
         facilityId={facilityId ?? ""}
         name={bedItem.name ?? ""}
         description={bedItem.description ?? ""}
         bedType={bedItem.bed_type ?? ""}
-        triggerRerender={triggerRerender}
+        triggerRerender={refetch}
         key={locationId ?? ""}
         locationId={locationId ?? ""}
         isOccupied={bedItem.is_occupied ?? false}
       />
     ));
-  } else if (beds && beds.length === 0) {
+  } else if (data?.results.length === 0) {
     BedList = (
       <p className="flex w-full justify-center border-b border-gray-200 bg-white p-5 text-center text-2xl font-bold text-gray-500">
         No beds available in this location
@@ -242,25 +188,20 @@ export const BedManagement = (props: BedManagementProps) => {
     );
   }
 
-  if (beds) {
+  if (data?.results.length) {
     bed = (
       <>
         <div className="mt-5 flex grow flex-wrap bg-white p-4">{BedList}</div>
-        {totalCount > limit && (
+        {data.count && (
           <div className="mt-4 flex w-full justify-center">
-            <Pagination
-              cPage={currentPage}
-              defaultPerPage={limit}
-              data={{ totalCount }}
-              onChange={handlePagination}
-            />
+            <Pagination totalCount={data.count} />
           </div>
         )}
       </>
     );
   }
 
-  if (isLoading || !beds) {
+  if (loading) {
     return <Loading />;
   }
 
@@ -268,9 +209,9 @@ export const BedManagement = (props: BedManagementProps) => {
     <Page
       title="Bed Management"
       crumbsReplacements={{
-        [facilityId]: { name: facilityName },
+        [facilityId]: { name: location?.facility?.name },
         [locationId]: {
-          name: locationName,
+          name: location?.name,
           uri: `/facility/${facilityId}/location`,
         },
       }}
diff --git a/src/Redux/api.tsx b/src/Redux/api.tsx
index 80d5a630bea..2b8d4f8f51b 100644
--- a/src/Redux/api.tsx
+++ b/src/Redux/api.tsx
@@ -48,6 +48,7 @@ import {
   WardModel,
   LocationModel,
   PatientNotesModel,
+  BedModel,
 } from "../Components/Facility/models";
 import {
   IDeleteExternalResult,
@@ -399,6 +400,7 @@ const routes = {
   listFacilityBeds: {
     path: "/api/v1/bed/",
     method: "GET",
+    TRes: Type<PaginatedResponse<BedModel>>(),
   },
   createFacilityBed: {
     path: "/api/v1/bed/",
@@ -415,6 +417,7 @@ const routes = {
   deleteFacilityBed: {
     path: "/api/v1/bed/{external_id}/",
     method: "DELETE",
+    TRes: Type<Record<string, never>>(),
   },
 
   // Consultation beds

From 36fa6e34968b7f0e19f63091f65c30eacbcf19f8 Mon Sep 17 00:00:00 2001
From: Ashesh <3626859+Ashesh3@users.noreply.github.com>
Date: Thu, 28 Dec 2023 14:06:20 +0530
Subject: [PATCH 11/20] Fix latitude and longitude handling in FacilityCreate
 component (#6934)

---
 src/Components/Facility/FacilityCreate.tsx | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/Components/Facility/FacilityCreate.tsx b/src/Components/Facility/FacilityCreate.tsx
index c9f40b5d1ef..9fbe89035c4 100644
--- a/src/Components/Facility/FacilityCreate.tsx
+++ b/src/Components/Facility/FacilityCreate.tsx
@@ -252,8 +252,8 @@ export const FacilityCreate = (props: FacilityProps) => {
                 ? "+91" + data.phone_number
                 : data.phone_number
               : "",
-            latitude: data ? String(data.latitude) : "",
-            longitude: data ? String(data.longitude) : "",
+            latitude: data.latitude ? String(data.latitude) : "",
+            longitude: data.longitude ? String(data.longitude) : "",
             type_b_cylinders: data.type_b_cylinders,
             type_c_cylinders: data.type_c_cylinders,
             type_d_cylinders: data.type_d_cylinders,

From 4a497688142a4a8f440b657e06bfd83bace147d4 Mon Sep 17 00:00:00 2001
From: Ashraf Mohammed <98876115+AshrafMd-1@users.noreply.github.com>
Date: Thu, 28 Dec 2023 17:04:46 +0530
Subject: [PATCH 12/20] Add OP number to treatment summary. (#6898)

* add op

* Add correct borders in treatment summary

* Update TreatmentSummary.tsx

* add space

* add extra cols
---
 src/Components/Facility/TreatmentSummary.tsx | 34 +++++++++++++-------
 1 file changed, 22 insertions(+), 12 deletions(-)

diff --git a/src/Components/Facility/TreatmentSummary.tsx b/src/Components/Facility/TreatmentSummary.tsx
index 8291e0e8ba4..8f1589cdf6f 100644
--- a/src/Components/Facility/TreatmentSummary.tsx
+++ b/src/Components/Facility/TreatmentSummary.tsx
@@ -122,22 +122,32 @@ const TreatmentSummary = (props: any) => {
             <div className="text-right font-bold">{formatDate(date)}</div>
 
             <div className="mb-5 mt-2 border border-gray-800">
-              <div className="grid border-b-2 border-gray-800 print:grid-cols-3 sm:grid-cols-3">
+              <div className="grid border-b-2 border-gray-800 print:grid-cols-3 sm:grid-cols-2 print:md:grid-cols-3">
                 <div className="col-span-1 border-b-2 border-gray-800 px-3 py-2 print:border-b-0 print:border-r-2 sm:border-b-0 sm:border-r-2">
                   <b>Name :</b> {patientData.name}
                 </div>
                 <div className="col-span-1 px-3 py-2">
-                  <b>Address :</b> {patientData.address}
+                  <b>Address : </b> {patientData.address}
                 </div>
               </div>
 
-              <div className="grid border-b-2 border-gray-800 print:grid-cols-3 sm:grid-cols-2 md:grid-cols-3">
-                <div className="col-span-1 border-b-2 border-gray-800 px-3 py-2 print:border-b-0 print:border-r-2 sm:border-r-2 md:border-b-0 ">
-                  <b>Age :</b>{" "}
-                  {formatAge(patientData.age, patientData.date_of_birth, true)}
+              <div className="grid border-b-2 border-gray-800 print:grid-cols-3 sm:grid-cols-2 print:md:grid-cols-3">
+                <div className="col-span-1 grid print:grid-cols-2 sm:grid-cols-2 ">
+                  <div className="col-span-1 border-b-2 border-gray-800 px-3 py-2 print:border-b-0 print:border-r-2 sm:border-b-0 sm:border-r-2">
+                    <b>Age :</b>{" "}
+                    {formatAge(
+                      patientData.age,
+                      patientData.date_of_birth,
+                      true
+                    )}
+                  </div>
+                  <div className="col-span-1 border-b-2 border-gray-800 px-3 py-2 print:border-b-0 print:border-r-2 sm:border-b-0 sm:border-r-2">
+                    <b>OP :</b> {consultationData.patient_no}
+                  </div>
                 </div>
-                <div className="col-span-1 border-b-2 border-gray-800 px-3 py-2 print:border-b-0  md:border-b-0 ">
-                  <b>Date of admission :</b>
+
+                <div className="col-span-1 px-3 py-2">
+                  <b>Date of admission : </b>
                   <span>
                     {consultationData.admitted
                       ? formatDateTime(consultationData.encounter_date)
@@ -146,13 +156,13 @@ const TreatmentSummary = (props: any) => {
                 </div>
               </div>
 
-              <div className="grid border-b-2 border-gray-800 print:grid-cols-3 sm:grid-cols-2 md:grid-cols-3">
-                <div className="col-span-1 border-b-2 border-gray-800 px-3 py-2 print:border-b-0 print:border-r-2 sm:border-r-2 md:border-b-0">
-                  <b>Gender :</b>
+              <div className="grid border-b-2 border-gray-800 print:grid-cols-3 sm:grid-cols-2 print:md:grid-cols-3">
+                <div className="col-span-1 border-b-2 border-gray-800 px-3 py-2 print:border-b-0 print:border-r-2 sm:border-b-0 sm:border-r-2">
+                  <b>Gender : </b>
                   {GENDER_TYPES.find((i) => i.id === patientData.gender)?.text}
                 </div>
 
-                <div className="col-span-1 border-b-2 border-gray-800 px-3 py-2 print:border-b-0  md:border-b-0 ">
+                <div className="col-span-1 px-3 py-2">
                   <b>Contact person :</b>
                   <span>
                     {" "}

From 22f36fd6ba73ee2d8754564f090ad0b16f689079 Mon Sep 17 00:00:00 2001
From: Ashesh <3626859+Ashesh3@users.noreply.github.com>
Date: Thu, 28 Dec 2023 17:07:31 +0530
Subject: [PATCH 13/20] Add consciousness level options for normal daily round
 type (#6935)

---
 src/Common/constants.tsx                      | 13 ++++++++++++
 .../Form/FormFields/RadioFormField.tsx        |  3 ++-
 .../Patient/DailyRoundListDetails.tsx         | 16 +++++++++++++-
 src/Components/Patient/DailyRounds.tsx        | 21 +++++++++++++++++--
 4 files changed, 49 insertions(+), 4 deletions(-)

diff --git a/src/Common/constants.tsx b/src/Common/constants.tsx
index 23c02e389f3..f472e8b193c 100644
--- a/src/Common/constants.tsx
+++ b/src/Common/constants.tsx
@@ -300,6 +300,19 @@ export const DISCHARGE_REASONS = [
   { id: "LAMA", text: "LAMA" },
 ];
 
+export const CONSCIOUSNESS_LEVEL = [
+  { id: "UNRESPONSIVE", text: "Unresponsive" },
+  { id: "RESPONDS_TO_PAIN", text: "Responds to Pain" },
+  { id: "RESPONDS_TO_VOICE", text: "Responds to Voice" },
+  { id: "ALERT", text: "Alert" },
+  { id: "AGITATED_OR_CONFUSED", text: "Agitated or Confused" },
+  {
+    id: "Onset of Agitation and Confusion",
+    text: "Onset of Agitation and Confusion",
+  },
+  { id: "UNKNOWN", text: "Unknown" },
+];
+
 export const LINES_CATHETER_CHOICES: Array<OptionsType> = [
   { id: 1, text: "CVP catheter " },
   { id: 2, text: "Arterial Line" },
diff --git a/src/Components/Form/FormFields/RadioFormField.tsx b/src/Components/Form/FormFields/RadioFormField.tsx
index 3d1a9b7d8ac..905986d62af 100644
--- a/src/Components/Form/FormFields/RadioFormField.tsx
+++ b/src/Components/Form/FormFields/RadioFormField.tsx
@@ -5,13 +5,14 @@ type Props<T> = FormFieldBaseProps<string> & {
   options: T[];
   optionDisplay: (option: T) => React.ReactNode;
   optionValue: (option: T) => string;
+  containerClassName?: string;
 };
 
 const RadioFormField = <T,>(props: Props<T>) => {
   const field = useFormFieldPropsResolver(props);
   return (
     <FormField field={field}>
-      <div className="flex gap-4 p-4">
+      <div className={props.containerClassName || "flex gap-4 p-4"}>
         {props.options.map((option, idx) => {
           const value = props.optionValue(option);
           const optionId = `${props.name}-${idx}`;
diff --git a/src/Components/Patient/DailyRoundListDetails.tsx b/src/Components/Patient/DailyRoundListDetails.tsx
index 9ac68a20ca7..8f313c0a51d 100644
--- a/src/Components/Patient/DailyRoundListDetails.tsx
+++ b/src/Components/Patient/DailyRoundListDetails.tsx
@@ -1,6 +1,10 @@
 import { lazy, useCallback, useState } from "react";
 import { useDispatch } from "react-redux";
-import { CURRENT_HEALTH_CHANGE, SYMPTOM_CHOICES } from "../../Common/constants";
+import {
+  CONSCIOUSNESS_LEVEL,
+  CURRENT_HEALTH_CHANGE,
+  SYMPTOM_CHOICES,
+} from "../../Common/constants";
 import { statusType, useAbortableEffect } from "../../Common/utils";
 import { getConsultationDailyRoundsDetails } from "../../Redux/actions";
 import { DailyRoundsModel } from "./models";
@@ -183,6 +187,16 @@ export const DailyRoundListDetails = (props: any) => {
             </span>
             {dailyRoundListDetailsData.rhythm_detail ?? "-"}
           </div>
+          <div className="md:col-span-2">
+            <span className="font-semibold leading-relaxed">
+              Level Of Consciousness:{" "}
+            </span>
+            {dailyRoundListDetailsData.consciousness_level
+              ? CONSCIOUSNESS_LEVEL.find(
+                  (i) => i.id === dailyRoundListDetailsData.consciousness_level
+                )?.text
+              : "-"}
+          </div>
           <div>
             <span className="font-semibold leading-relaxed">
               Recommend Discharge:{" "}
diff --git a/src/Components/Patient/DailyRounds.tsx b/src/Components/Patient/DailyRounds.tsx
index a9a31f2aa14..2b8bec1a75f 100644
--- a/src/Components/Patient/DailyRounds.tsx
+++ b/src/Components/Patient/DailyRounds.tsx
@@ -4,6 +4,7 @@ import dayjs from "dayjs";
 import { lazy, useCallback, useEffect, useState } from "react";
 import { useDispatch } from "react-redux";
 import {
+  CONSCIOUSNESS_LEVEL,
   PATIENT_CATEGORIES,
   REVIEW_AT_CHOICES,
   RHYTHM_CHOICES,
@@ -35,6 +36,7 @@ import TextAreaFormField from "../Form/FormFields/TextAreaFormField";
 import TextFormField from "../Form/FormFields/TextFormField";
 import { FieldChangeEvent } from "../Form/FormFields/Utils";
 import PatientCategorySelect from "./PatientCategorySelect";
+import RadioFormField from "../Form/FormFields/RadioFormField";
 const Loading = lazy(() => import("../Common/Loading"));
 
 const initForm: any = {
@@ -59,6 +61,7 @@ const initForm: any = {
   rhythm: "0",
   rhythm_detail: "",
   ventilator_spo2: null,
+  consciousness_level: "Unknown",
   // bed: null,
 };
 
@@ -129,6 +132,7 @@ export const DailyRounds = (props: any) => {
     "ventilator_spo2",
     "rhythm",
     "rhythm_detail",
+    "consciousness_level",
   ];
 
   useEffect(() => {
@@ -312,6 +316,7 @@ export const DailyRounds = (props: any) => {
             rhythm: Number(state.form.rhythm) || 0,
             rhythm_detail: state.form.rhythm_detail,
             ventilator_spo2: state.form.ventilator_spo2,
+            consciousness_level: state.form.consciousness_level,
           };
         }
       } else {
@@ -637,9 +642,21 @@ export const DailyRounds = (props: any) => {
 
                 <TextAreaFormField
                   {...field("rhythm_detail")}
-                  className="md:col-span-2"
+                  className="md:col-span-1"
                   label="Rhythm Description"
-                  rows={5}
+                  rows={7}
+                />
+
+                <RadioFormField
+                  label="Level Of Consciousness"
+                  {...field("consciousness_level")}
+                  options={CONSCIOUSNESS_LEVEL.map((level) => ({
+                    label: level.text,
+                    value: level.id,
+                  }))}
+                  optionDisplay={(option) => option.label}
+                  optionValue={(option) => option.value}
+                  containerClassName="grid gap-1 grid-cols-1"
                 />
               </>
             )}

From 8197f29b3109b653d09cd131614ebd7f442becdb Mon Sep 17 00:00:00 2001
From: Ashesh <3626859+Ashesh3@users.noreply.github.com>
Date: Fri, 29 Dec 2023 17:57:03 +0530
Subject: [PATCH 14/20] Fix empty state in LocationManagement and BedManagement
 (#6937)

* Fix empty state in LocationManagement

* Refactor BedManagement component
---
 src/CAREUI/misc/PaginatedList.tsx             |  2 +-
 src/Components/Facility/BedManagement.tsx     | 24 +++++++++----------
 .../Facility/LocationManagement.tsx           | 14 +++++------
 3 files changed, 19 insertions(+), 21 deletions(-)

diff --git a/src/CAREUI/misc/PaginatedList.tsx b/src/CAREUI/misc/PaginatedList.tsx
index 61c67f97ae2..1487d69e4fa 100644
--- a/src/CAREUI/misc/PaginatedList.tsx
+++ b/src/CAREUI/misc/PaginatedList.tsx
@@ -130,7 +130,7 @@ interface ItemsProps<TItem> {
 const Items = <TItem extends object>(props: ItemsProps<TItem>) => {
   const { loading, items } = useContextualized<TItem>();
 
-  if (loading) {
+  if (loading || items.length === 0) {
     return null;
   }
 
diff --git a/src/Components/Facility/BedManagement.tsx b/src/Components/Facility/BedManagement.tsx
index 68e9fade43d..d8799f1fbc5 100644
--- a/src/Components/Facility/BedManagement.tsx
+++ b/src/Components/Facility/BedManagement.tsx
@@ -182,24 +182,22 @@ export const BedManagement = (props: BedManagementProps) => {
     ));
   } else if (data?.results.length === 0) {
     BedList = (
-      <p className="flex w-full justify-center border-b border-gray-200 bg-white p-5 text-center text-2xl font-bold text-gray-500">
+      <p className="flex w-full justify-center bg-white p-5 text-center text-2xl font-bold text-gray-500">
         No beds available in this location
       </p>
     );
   }
 
-  if (data?.results.length) {
-    bed = (
-      <>
-        <div className="mt-5 flex grow flex-wrap bg-white p-4">{BedList}</div>
-        {data.count && (
-          <div className="mt-4 flex w-full justify-center">
-            <Pagination totalCount={data.count} />
-          </div>
-        )}
-      </>
-    );
-  }
+  bed = (
+    <>
+      <div className="mt-5 flex grow flex-wrap bg-white p-4">{BedList}</div>
+      {Boolean(data?.count && data.count > 0) && (
+        <div className="mt-4 flex w-full justify-center">
+          <Pagination totalCount={data?.count ?? 0} />
+        </div>
+      )}
+    </>
+  );
 
   if (loading) {
     return <Loading />;
diff --git a/src/Components/Facility/LocationManagement.tsx b/src/Components/Facility/LocationManagement.tsx
index b7a758c5055..93a08794c82 100644
--- a/src/Components/Facility/LocationManagement.tsx
+++ b/src/Components/Facility/LocationManagement.tsx
@@ -46,14 +46,14 @@ export default function LocationManagement({ facilityId }: Props) {
               Add New Location
             </ButtonV2>
           </div>
-          <PaginatedList.WhenEmpty className="flex w-full justify-center border-b border-gray-200 bg-white p-5 text-center text-2xl font-bold text-gray-500">
-            <span>No locations available</span>
-          </PaginatedList.WhenEmpty>
-
-          <PaginatedList.WhenLoading>
-            <Loading />
-          </PaginatedList.WhenLoading>
           <div className="w-full @container">
+            <PaginatedList.WhenEmpty className="flex w-full justify-center border-b border-gray-200 bg-white p-5 text-center text-2xl font-bold text-gray-500">
+              <span>No locations available</span>
+            </PaginatedList.WhenEmpty>
+
+            <PaginatedList.WhenLoading>
+              <Loading />
+            </PaginatedList.WhenLoading>
             <PaginatedList.Items<LocationModel> className="my-8 grid gap-3 @4xl:grid-cols-2 @6xl:grid-cols-3 @[100rem]:grid-cols-4 lg:mx-8">
               {(item) => <Location {...item} />}
             </PaginatedList.Items>

From 096905d645fa4c0b4fef9e14537961f1639e1502 Mon Sep 17 00:00:00 2001
From: Rithvik Nishad <mail@rithviknishad.dev>
Date: Fri, 29 Dec 2023 23:20:27 +0530
Subject: [PATCH 15/20] fixes not found errors in investigation and other type
 errors (#6948)

---
 src/Components/Facility/ConsultationDetails/index.tsx | 4 ++++
 src/Components/Facility/models.tsx                    | 4 ++--
 2 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/src/Components/Facility/ConsultationDetails/index.tsx b/src/Components/Facility/ConsultationDetails/index.tsx
index abc7305a00b..c6cc9e02275 100644
--- a/src/Components/Facility/ConsultationDetails/index.tsx
+++ b/src/Components/Facility/ConsultationDetails/index.tsx
@@ -46,6 +46,8 @@ const symptomChoices = [...SYMPTOM_CHOICES];
 
 export interface ConsultationTabProps {
   consultationId: string;
+  facilityId: string;
+  patientId: string;
   consultationData: ConsultationModel;
   patientData: PatientModel;
 }
@@ -189,6 +191,8 @@ export const ConsultationDetails = (props: any) => {
   const consultationTabProps: ConsultationTabProps = {
     consultationId,
     consultationData,
+    patientId: consultationData.patient,
+    facilityId: consultationData.facility,
     patientData,
   };
 
diff --git a/src/Components/Facility/models.tsx b/src/Components/Facility/models.tsx
index 90191e3321f..c3ac910970c 100644
--- a/src/Components/Facility/models.tsx
+++ b/src/Components/Facility/models.tsx
@@ -109,12 +109,12 @@ export interface ConsultationModel {
   discharge_notes?: string;
   examination_details?: string;
   history_of_present_illness?: string;
-  facility?: number;
+  facility: string;
   facility_name?: string;
   id: string;
   modified_date?: string;
   other_symptoms?: string;
-  patient?: string;
+  patient: string;
   treatment_plan?: string;
   referred_to?: FacilityModel["id"];
   referred_to_object?: FacilityModel;

From 06a2afdbc875ab63e691900c23f039e8d64cc759 Mon Sep 17 00:00:00 2001
From: Ashesh <3626859+Ashesh3@users.noreply.github.com>
Date: Fri, 29 Dec 2023 23:20:57 +0530
Subject: [PATCH 16/20] Update consciousness level constants (#6947)

---
 src/Common/constants.tsx               |   2 +-
 src/Components/Patient/DailyRounds.tsx | 103 +++++++++++--------------
 2 files changed, 45 insertions(+), 60 deletions(-)

diff --git a/src/Common/constants.tsx b/src/Common/constants.tsx
index f472e8b193c..647c77ecf57 100644
--- a/src/Common/constants.tsx
+++ b/src/Common/constants.tsx
@@ -307,7 +307,7 @@ export const CONSCIOUSNESS_LEVEL = [
   { id: "ALERT", text: "Alert" },
   { id: "AGITATED_OR_CONFUSED", text: "Agitated or Confused" },
   {
-    id: "Onset of Agitation and Confusion",
+    id: "ONSET_OF_AGITATION_AND_CONFUSION",
     text: "Onset of Agitation and Confusion",
   },
   { id: "UNKNOWN", text: "Unknown" },
diff --git a/src/Components/Patient/DailyRounds.tsx b/src/Components/Patient/DailyRounds.tsx
index 2b8bec1a75f..4def8ed74eb 100644
--- a/src/Components/Patient/DailyRounds.tsx
+++ b/src/Components/Patient/DailyRounds.tsx
@@ -1,7 +1,7 @@
 import { navigate } from "raviger";
 
 import dayjs from "dayjs";
-import { lazy, useCallback, useEffect, useState } from "react";
+import { lazy, useCallback, useState } from "react";
 import { useDispatch } from "react-redux";
 import {
   CONSCIOUSNESS_LEVEL,
@@ -61,7 +61,7 @@ const initForm: any = {
   rhythm: "0",
   rhythm_detail: "",
   ventilator_spo2: null,
-  consciousness_level: "Unknown",
+  consciousness_level: "UNKNOWN",
   // bed: null,
 };
 
@@ -135,40 +135,6 @@ export const DailyRounds = (props: any) => {
     "consciousness_level",
   ];
 
-  useEffect(() => {
-    (async () => {
-      if (patientId) {
-        const res = await dispatchAction(getPatient({ id: patientId }));
-        if (res.data) {
-          setPatientName(res.data.name);
-          setFacilityName(res.data.facility_object.name);
-          setConsultationSuggestion(res.data.last_consultation?.suggestion);
-          setPreviousReviewInterval(
-            Number(res.data.last_consultation.review_interval)
-          );
-          const getAction =
-            TELEMEDICINE_ACTIONS.find((action) => action.id === res.data.action)
-              ?.text || "NO_ACTION";
-          setPreviousAction(getAction);
-          setInitialData({
-            ...initialData,
-            action: getAction,
-          });
-          dispatch({
-            type: "set_form",
-            form: {
-              ...state.form,
-              action: getAction,
-            },
-          });
-        }
-      } else {
-        setPatientName("");
-        setFacilityName("");
-      }
-    })();
-  }, [dispatchAction, patientId]);
-
   const fetchRoundDetails = useCallback(
     async (status: statusType) => {
       setIsLoading(true);
@@ -176,6 +142,8 @@ export const DailyRounds = (props: any) => {
         getConsultationDailyRoundsDetails({ consultationId, id })
       );
 
+      let formData: any = {};
+
       if (!status.aborted) {
         if (res?.data) {
           const data = {
@@ -191,34 +159,41 @@ export const DailyRounds = (props: any) => {
               "0",
             admitted_to: res.data.admitted_to ? res.data.admitted_to : "Select",
           };
-          dispatch({ type: "set_form", form: data });
-          setInitialData(data);
+          formData = { ...formData, ...data };
         }
         setIsLoading(false);
       }
-    },
-    [consultationId, id, dispatchAction]
-  );
-  useAbortableEffect(
-    (status: statusType) => {
-      if (id) {
-        fetchRoundDetails(status);
+      if (patientId) {
+        const res = await dispatchAction(getPatient({ id: patientId }));
+        if (res.data) {
+          setPatientName(res.data.name);
+          setFacilityName(res.data.facility_object.name);
+          setConsultationSuggestion(res.data.last_consultation?.suggestion);
+          setPreviousReviewInterval(
+            Number(res.data.last_consultation.review_interval)
+          );
+          const getAction =
+            TELEMEDICINE_ACTIONS.find((action) => action.id === res.data.action)
+              ?.text || "NO_ACTION";
+          setPreviousAction(getAction);
+          setInitialData({
+            ...initialData,
+            action: getAction,
+          });
+          formData = { ...formData, ...{ action: getAction } };
+        }
+      } else {
+        setPatientName("");
+        setFacilityName("");
       }
-    },
-    [dispatchAction, fetchRoundDetails]
-  );
-
-  useEffect(() => {
-    (async () => {
       if (consultationId && !id) {
         const res = await dispatchAction(
           getDailyReport({ limit: 1, offset: 0 }, { consultationId })
         );
         setHasPreviousLog(res.data.count > 0);
-        dispatch({
-          type: "set_form",
-          form: {
-            ...state.form,
+        formData = {
+          ...formData,
+          ...{
             patient_category: res.data.patient_category
               ? PATIENT_CATEGORIES.find(
                   (i) => i.text === res.data.patient_category
@@ -229,12 +204,22 @@ export const DailyRounds = (props: any) => {
                 RHYTHM_CHOICES.find((i) => i.text === res.data.rhythm)?.id) ||
               "0",
             temperature: parseFloat(res.data.temperature),
-            // clone_last: res.data.count > 0 ? true : false,
           },
-        });
+        };
+      }
+      dispatch({ type: "set_form", form: formData });
+      setInitialData(formData);
+    },
+    [consultationId, id, dispatchAction, patientId]
+  );
+  useAbortableEffect(
+    (status: statusType) => {
+      if (id) {
+        fetchRoundDetails(status);
       }
-    })();
-  }, [dispatchAction, consultationId, id]);
+    },
+    [dispatchAction, fetchRoundDetails]
+  );
 
   const validateForm = () => {
     const errors = { ...initError };

From 1085e0f083125a466170df5470eb3ad33d2e4285 Mon Sep 17 00:00:00 2001
From: Rithvik Nishad <mail@rithviknishad.dev>
Date: Fri, 29 Dec 2023 23:47:55 +0530
Subject: [PATCH 17/20] fix resp. rate from being 0 instead of null when unset
 (#6949)

* fix resp. rate from being 0 instead of null

* fix relative time alignment
---
 src/CAREUI/display/RecordMeta.tsx      | 8 +++++---
 src/Components/Patient/DailyRounds.tsx | 4 ++--
 2 files changed, 7 insertions(+), 5 deletions(-)

diff --git a/src/CAREUI/display/RecordMeta.tsx b/src/CAREUI/display/RecordMeta.tsx
index d4d32e437c8..5e1e117f9d6 100644
--- a/src/CAREUI/display/RecordMeta.tsx
+++ b/src/CAREUI/display/RecordMeta.tsx
@@ -1,7 +1,8 @@
 import CareIcon from "../icons/CareIcon";
 import {
-  formatDateTime,
+  formatDate,
   formatName,
+  formatTime,
   isUserOnline,
   relativeTime,
 } from "../../Utils/utils";
@@ -37,8 +38,9 @@ const RecordMeta = ({
   let child = (
     <div className="tooltip">
       <span className="underline">{relativeTime(time)}</span>
-      <span className="tooltip-text tooltip-left flex gap-1 text-xs font-medium tracking-wider">
-        {formatDateTime(time)}
+      <span className="tooltip-text tooltip-bottom flex -translate-x-1/2 gap-1 text-xs font-medium tracking-wider">
+        {formatTime(time)} <br />
+        {formatDate(time)}
         {user && !inlineUser && (
           <span className="flex items-center gap-1">
             by
diff --git a/src/Components/Patient/DailyRounds.tsx b/src/Components/Patient/DailyRounds.tsx
index 4def8ed74eb..06431457b0e 100644
--- a/src/Components/Patient/DailyRounds.tsx
+++ b/src/Components/Patient/DailyRounds.tsx
@@ -296,9 +296,9 @@ export const DailyRounds = (props: any) => {
                   }
                 : undefined,
             pulse: state.form.pulse,
-            resp: Number(state.form.resp),
+            resp: state.form.resp,
             temperature: state.form.temperature,
-            rhythm: Number(state.form.rhythm) || 0,
+            rhythm: state.form.rhythm || 0,
             rhythm_detail: state.form.rhythm_detail,
             ventilator_spo2: state.form.ventilator_spo2,
             consciousness_level: state.form.consciousness_level,

From 8aea0cc9139c507b83784986d9d2c4eec7a7baf6 Mon Sep 17 00:00:00 2001
From: Rithvik Nishad <mail@rithviknishad.dev>
Date: Sat, 30 Dec 2023 15:41:36 +0530
Subject: [PATCH 18/20] fix has previous log update not being filled (#6951)

---
 src/Components/Patient/DailyRounds.tsx | 51 +++++++++++++-------------
 1 file changed, 26 insertions(+), 25 deletions(-)

diff --git a/src/Components/Patient/DailyRounds.tsx b/src/Components/Patient/DailyRounds.tsx
index 06431457b0e..ec2f070aa20 100644
--- a/src/Components/Patient/DailyRounds.tsx
+++ b/src/Components/Patient/DailyRounds.tsx
@@ -138,31 +138,34 @@ export const DailyRounds = (props: any) => {
   const fetchRoundDetails = useCallback(
     async (status: statusType) => {
       setIsLoading(true);
-      const res = await dispatchAction(
-        getConsultationDailyRoundsDetails({ consultationId, id })
-      );
-
-      let formData: any = {};
+      let formData: any = initialData;
+      if (id) {
+        const res = await dispatchAction(
+          getConsultationDailyRoundsDetails({ consultationId, id })
+        );
 
-      if (!status.aborted) {
-        if (res?.data) {
-          const data = {
-            ...res.data,
-            patient_category: res.data.patient_category
-              ? PATIENT_CATEGORIES.find(
-                  (i) => i.text === res.data.patient_category
-                )?.id ?? ""
-              : "",
-            rhythm:
-              (res.data.rhythm &&
-                RHYTHM_CHOICES.find((i) => i.text === res.data.rhythm)?.id) ||
-              "0",
-            admitted_to: res.data.admitted_to ? res.data.admitted_to : "Select",
-          };
-          formData = { ...formData, ...data };
+        if (!status.aborted) {
+          if (res?.data) {
+            const data = {
+              ...res.data,
+              patient_category: res.data.patient_category
+                ? PATIENT_CATEGORIES.find(
+                    (i) => i.text === res.data.patient_category
+                  )?.id ?? ""
+                : "",
+              rhythm:
+                (res.data.rhythm &&
+                  RHYTHM_CHOICES.find((i) => i.text === res.data.rhythm)?.id) ||
+                "0",
+              admitted_to: res.data.admitted_to
+                ? res.data.admitted_to
+                : "Select",
+            };
+            formData = { ...formData, ...data };
+          }
         }
-        setIsLoading(false);
       }
+      setIsLoading(false);
       if (patientId) {
         const res = await dispatchAction(getPatient({ id: patientId }));
         if (res.data) {
@@ -214,9 +217,7 @@ export const DailyRounds = (props: any) => {
   );
   useAbortableEffect(
     (status: statusType) => {
-      if (id) {
-        fetchRoundDetails(status);
-      }
+      fetchRoundDetails(status);
     },
     [dispatchAction, fetchRoundDetails]
   );

From c5c86aa594e11e832b18cc6fa906ce04d7e041f7 Mon Sep 17 00:00:00 2001
From: Rithvik Nishad <mail@rithviknishad.dev>
Date: Sat, 30 Dec 2023 22:41:29 +0530
Subject: [PATCH 19/20] fix daily rounds vital fields not clearing (#6954)

* fix daily rounds vital fields not clearing

* Fix blood pressure form field and daily rounds component

* Fix default blood pressure values in DailyRounds component

* Fix handling of negative values in blood pressure

---------

Co-authored-by: Ashesh3 <3626859+Ashesh3@users.noreply.github.com>
---
 .../Common/BloodPressureFormField.tsx         |  9 ++--
 .../Facility/Consultations/Mews.tsx           |  1 +
 .../Patient/DailyRoundListDetails.tsx         | 10 +++-
 src/Components/Patient/DailyRounds.tsx        | 50 +++++++++++++++----
 4 files changed, 53 insertions(+), 17 deletions(-)

diff --git a/src/Components/Common/BloodPressureFormField.tsx b/src/Components/Common/BloodPressureFormField.tsx
index ed0557ae8e3..3ff2774b900 100644
--- a/src/Components/Common/BloodPressureFormField.tsx
+++ b/src/Components/Common/BloodPressureFormField.tsx
@@ -21,7 +21,7 @@ export default function BloodPressureFormField(props: Props) {
       name: field.name,
       value: {
         ...field.value,
-        [event.name]: event.value,
+        [event.name]: event.value ?? -1,
       },
     });
   };
@@ -35,9 +35,10 @@ export default function BloodPressureFormField(props: Props) {
     <FormField
       field={{
         ...field,
-        labelSuffix: map ? (
-          <span className="font-medium">MAP: {map.toFixed(1)}</span>
-        ) : undefined,
+        labelSuffix:
+          map && map !== -1 ? (
+            <span className="font-medium">MAP: {map.toFixed(1)}</span>
+          ) : undefined,
       }}
     >
       <div className="flex flex-row items-center">
diff --git a/src/Components/Facility/Consultations/Mews.tsx b/src/Components/Facility/Consultations/Mews.tsx
index 6b8e7de806e..5160e42f9f2 100644
--- a/src/Components/Facility/Consultations/Mews.tsx
+++ b/src/Components/Facility/Consultations/Mews.tsx
@@ -26,6 +26,7 @@ const getHeartRateScore = (value?: number) => {
 
 const getSystolicBPScore = (value?: number) => {
   if (typeof value !== "number") return;
+  if (value === -1) return;
 
   if (value <= 70) return 3;
   if (value <= 80) return 2;
diff --git a/src/Components/Patient/DailyRoundListDetails.tsx b/src/Components/Patient/DailyRoundListDetails.tsx
index 8f313c0a51d..0a73607d688 100644
--- a/src/Components/Patient/DailyRoundListDetails.tsx
+++ b/src/Components/Patient/DailyRoundListDetails.tsx
@@ -158,14 +158,20 @@ export const DailyRoundListDetails = (props: any) => {
                 <span className="font-semibold leading-relaxed">
                   Systolic:{" "}
                 </span>
-                {dailyRoundListDetailsData.bp?.systolic ?? "-"}
+                {dailyRoundListDetailsData.bp?.systolic &&
+                dailyRoundListDetailsData.bp?.systolic !== -1
+                  ? dailyRoundListDetailsData.bp?.systolic
+                  : "-"}
               </div>
               <div className="flex">
                 {" "}
                 <span className="font-semibold leading-relaxed">
                   Diastolic:
                 </span>
-                {dailyRoundListDetailsData.bp?.diastolic ?? "-"}
+                {dailyRoundListDetailsData.bp?.diastolic &&
+                dailyRoundListDetailsData.bp?.diastolic !== -1
+                  ? dailyRoundListDetailsData.bp?.diastolic
+                  : "-"}
               </div>
             </div>
           </div>
diff --git a/src/Components/Patient/DailyRounds.tsx b/src/Components/Patient/DailyRounds.tsx
index ec2f070aa20..c12aea42bee 100644
--- a/src/Components/Patient/DailyRounds.tsx
+++ b/src/Components/Patient/DailyRounds.tsx
@@ -62,6 +62,11 @@ const initForm: any = {
   rhythm_detail: "",
   ventilator_spo2: null,
   consciousness_level: "UNKNOWN",
+  bp: {
+    systolic: -1,
+    diastolic: -1,
+    mean: -1,
+  },
   // bed: null,
 };
 
@@ -242,6 +247,18 @@ export const DailyRounds = (props: any) => {
             invalidForm = true;
           }
           return;
+        case "bp":
+          if (
+            (state.form.bp?.systolic &&
+              state.form.bp?.diastolic &&
+              state.form.bp.systolic !== -1 &&
+              state.form.bp.diastolic === -1) ||
+            (state.form.bp.systolic === -1 && state.form.bp.diastolic !== -1)
+          ) {
+            errors.bp = "Please enter both systolic and diastolic values";
+            invalidForm = true;
+          }
+          return;
         default:
           return;
       }
@@ -287,21 +304,32 @@ export const DailyRounds = (props: any) => {
           data = {
             ...data,
             bp:
-              state.form.bp && state.form.bp.systolic && state.form.bp.diastolic
+              state.form.bp?.systolic !== -1 && state.form.bp?.diastolic !== -1
                 ? {
-                    systolic: Number(state.form.bp.systolic),
-                    diastolic: Number(state.form.bp.diastolic),
-                    mean: parseFloat(
-                      meanArterialPressure(state.form.bp).toFixed(2)
-                    ),
+                    systolic: state.form.bp?.systolic
+                      ? Number(state.form.bp?.systolic)
+                      : -1,
+                    diastolic: state.form.bp?.diastolic
+                      ? Number(state.form.bp?.diastolic)
+                      : -1,
+                    mean:
+                      state.form.bp?.systolic && state.form.bp?.diastolic
+                        ? parseFloat(
+                            meanArterialPressure(state.form.bp).toFixed(2)
+                          )
+                        : -1,
                   }
-                : undefined,
-            pulse: state.form.pulse,
-            resp: state.form.resp,
-            temperature: state.form.temperature,
+                : {
+                    systolic: -1,
+                    diastolic: -1,
+                    mean: -1,
+                  },
+            pulse: state.form.pulse ?? null,
+            resp: state.form.resp ?? null,
+            temperature: state.form.temperature ?? null,
             rhythm: state.form.rhythm || 0,
             rhythm_detail: state.form.rhythm_detail,
-            ventilator_spo2: state.form.ventilator_spo2,
+            ventilator_spo2: state.form.ventilator_spo2 ?? null,
             consciousness_level: state.form.consciousness_level,
           };
         }

From f066a3659beb2ba899a226a465b06922b2207d69 Mon Sep 17 00:00:00 2001
From: Ashesh <3626859+Ashesh3@users.noreply.github.com>
Date: Sat, 30 Dec 2023 22:57:23 +0530
Subject: [PATCH 20/20] Fix conditional logic in PatientInfoCard (#6955)

---
 src/Components/Patient/PatientInfoCard.tsx | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/src/Components/Patient/PatientInfoCard.tsx b/src/Components/Patient/PatientInfoCard.tsx
index c5087f13dda..eb589667ece 100644
--- a/src/Components/Patient/PatientInfoCard.tsx
+++ b/src/Components/Patient/PatientInfoCard.tsx
@@ -490,6 +490,7 @@ export default function PatientInfoCard(props: {
                           key={i}
                           className="dropdown-item-primary pointer-events-auto m-2 flex cursor-pointer items-center justify-start gap-2 rounded border-0 p-2 text-sm font-normal transition-all duration-200 ease-in-out"
                           href={
+                            action[1] !== "Treatment Summary" &&
                             consultation?.admitted &&
                             !consultation?.current_bed &&
                             i === 1
@@ -498,6 +499,7 @@ export default function PatientInfoCard(props: {
                           }
                           onClick={() => {
                             if (
+                              action[1] !== "Treatment Summary" &&
                               consultation?.admitted &&
                               !consultation?.current_bed &&
                               i === 1