@@ -270,6 +270,7 @@ export default function InventoryLog(props: any) {
as accident.
removeLastInventoryLog(inventory[0].item_object.id)
diff --git a/src/Components/Facility/Investigations/InvestigationTable.tsx b/src/Components/Facility/Investigations/InvestigationTable.tsx
index 54e7e50bdc7..d322698779d 100644
--- a/src/Components/Facility/Investigations/InvestigationTable.tsx
+++ b/src/Components/Facility/Investigations/InvestigationTable.tsx
@@ -17,7 +17,7 @@ const TestRow = ({ data, i, onChange, showForm, value, isChanged }: any) => {
{data?.investigation_object?.name || "---"}
|
-
+ |
{showForm ? (
data?.investigation_object?.investigation_type === "Choice" ? (
{
+const findGroup = (group_id: string, groups: InvestigationGroup[]) => {
return groups.find((g) => g.external_id === group_id);
};
@@ -106,7 +106,9 @@ const Investigation = (props: {
const [selectedGroup, setSelectedGroup] = useState([]);
const [state, setState] = useReducer(testFormReducer, initialState);
const [investigations, setInvestigations] = useState([]);
- const [investigationGroups, setInvestigationGroups] = useState([]);
+ const [investigationGroups, setInvestigationGroups] = useState<
+ InvestigationGroup[]
+ >([]);
const [selectedInvestigations, setSelectedInvestigations] = useState<
InvestigationType[]
>([]);
diff --git a/src/Components/Facility/LegacyFacilityCNS.tsx b/src/Components/Facility/LegacyFacilityCNS.tsx
deleted file mode 100644
index 5b0005c9daf..00000000000
--- a/src/Components/Facility/LegacyFacilityCNS.tsx
+++ /dev/null
@@ -1,313 +0,0 @@
-import { navigate } from "raviger";
-import { useEffect, useState } from "react";
-import { useDispatch } from "react-redux";
-import CareIcon from "../../CAREUI/icons/CareIcon";
-import {
- getAllPatient,
- getPermittedFacility,
- listAssetBeds,
-} from "../../Redux/actions";
-import { classNames } from "../../Utils/utils";
-import { AssetData, AssetLocationObject } from "../Assets/AssetTypes";
-import ButtonV2, { Cancel, Submit } from "../Common/components/ButtonV2";
-import Page from "../Common/components/Page";
-import Loading from "../Common/Loading";
-import Pagination from "../Common/Pagination";
-import { PatientModel } from "../Patient/models";
-import { FacilityModel } from "./models";
-import AutocompleteFormField from "../Form/FormFields/Autocomplete";
-import { uniqBy } from "lodash-es";
-import DialogModal from "../Common/Dialog";
-import { LegacyMonitorCard } from "./LegacyMonitorCard";
-
-interface Monitor {
- patient: PatientModel;
- asset: AssetData;
- socketUrl: string;
-}
-
-const PER_PAGE_LIMIT = 6;
-const CNS_REFRESH_INTERVAL = 0.5 * 60e3;
-
-export default function LegacyFacilityCNS({
- facilityId,
-}: {
- facilityId: string;
-}) {
- const dispatch = useDispatch();
- const [isFullscreen, setIsFullscreen] = useState(false);
- const [monitors, setMonitors] = useState();
- const [facility, setFacility] = useState();
- const [currentPage, setCurrentPage] = useState(1);
- const [defaultShowAllLocation, setDefaultShowAllLocation] = useState(true);
- const searchParams = new URLSearchParams(window.location.search);
-
- // this wil set ?page=1 param in url if it is not present
- useEffect(() => {
- if (!searchParams.get("page")) {
- navigate(`/facility/${facilityId}/cns?page=1`);
- }
- }, []);
- const [location, setLocation] = useState();
- const [showSelectLocation, setShowSelectLocation] = useState(false);
-
- useEffect(() => {
- const onFullscreenChange = () =>
- setIsFullscreen(!!document.fullscreenElement);
- document.addEventListener("fullscreenchange", onFullscreenChange);
- return () =>
- document.removeEventListener("fullscreenchange", onFullscreenChange);
- }, []);
-
- useEffect(() => {
- async function fetchFacility() {
- const res = await dispatch(getPermittedFacility(facilityId || ""));
- if (res.status === 200) setFacility(res.data);
- }
- fetchFacility();
- }, [facilityId, dispatch]);
-
- useEffect(() => {
- if (!facility) return;
- const middlewareHostname = facility.middleware_address;
-
- async function fetchPatients() {
- const res = await dispatch(
- getAllPatient(
- { facility: facilityId, is_active: "True" },
- "cns-patient-list"
- )
- );
- if (res.status === 200) {
- const patients = res.data.results as PatientModel[];
- return patients.filter(
- (patient) => !!patient.last_consultation?.current_bed?.bed_object.id
- );
- }
- }
-
- async function fetchPatientMonitorAsset(patient: PatientModel) {
- const res = await dispatch(
- listAssetBeds(
- {
- bed: patient.last_consultation?.current_bed?.bed_object?.id,
- },
- `asset-bed-${patient.id}`
- )
- );
-
- if (res.status !== 200) return;
-
- const asset = res.data.results.find(
- (assetBed: any) =>
- assetBed.asset_object.meta?.asset_type === "HL7MONITOR"
- )?.asset_object as AssetData | undefined;
-
- if (!asset) return;
-
- const socketUrl = `wss://${middlewareHostname}/observations/${asset.meta?.local_ip_address}`;
-
- return { patient, asset, socketUrl } as Monitor;
- }
-
- async function fetchMonitors() {
- const patients = await fetchPatients();
- if (!patients) return;
-
- const monitors = await Promise.all(
- patients.map((patient) => fetchPatientMonitorAsset(patient))
- );
- return monitors.filter((monitor) => !!monitor) as Monitor[];
- }
-
- fetchMonitors().then((monitors) => {
- setCurrentPage(Number(searchParams.get("page")));
- setMonitors(monitors);
- });
-
- const interval = setInterval(() => {
- fetchMonitors().then(setMonitors);
- }, CNS_REFRESH_INTERVAL);
-
- return () => clearInterval(interval);
- }, [dispatch, facility, facilityId]);
-
- if (!monitors) return ;
- return (
-
- {monitors?.length > 0 ? (
- <>
- setShowSelectLocation(true)}
- >
-
- Change Location
-
- {
- if (isFullscreen) {
- document.exitFullscreen();
- } else {
- document.documentElement.requestFullscreen();
- }
- }}
- className="tooltip !h-11"
- >
-
-
- {isFullscreen ? "Exit Fullscreen" : "Fullscreen"}
-
-
- >
- ) : (
- <>
- history.go(-2)}
- >
- Go Back
-
- >
- )}
-
- {
- setCurrentPage(page);
- navigate(`/facility/${facilityId}/cns?page=${page}`);
- }}
- data={{
- totalCount: defaultShowAllLocation
- ? monitors.length
- : monitors.filter(
- (m) => m.asset.location_object.id === location?.id
- ).length,
- }}
- defaultPerPage={PER_PAGE_LIMIT}
- />
-
- }
- >
- setShowSelectLocation(false)}
- className="w-full max-w-md"
- >
- {!monitors && }
-
- setLocation(value)}
- options={
- monitors
- ? uniqBy(
- monitors.map((m) => m.asset.location_object),
- "id"
- )
- : []
- }
- isLoading={!monitors}
- optionLabel={(location) => location.name}
- optionDescription={(location) =>
- location.description +
- " (" +
- monitors.filter((m) => m.asset.location_object.id === location.id)
- .length +
- " patients)"
- }
- optionValue={(location) => location}
- disabled={!monitors}
- />
-
- {
- setDefaultShowAllLocation(true);
- setShowSelectLocation(false);
- }}
- >
- Show All Locations
-
- {
- setDefaultShowAllLocation(false);
- setShowSelectLocation(false);
- }}
- className="my-2 mr-2"
- label="Confirm"
- />
- setShowSelectLocation(false)}
- className="my-2 mr-2"
- />
-
-
-
- {monitors.length === 0 && (
-
- No patients are currently monitored
-
- )}
-
- {defaultShowAllLocation
- ? monitors
- ?.slice(
- (currentPage - 1) * PER_PAGE_LIMIT,
- currentPage * PER_PAGE_LIMIT
- )
- .map(({ patient, socketUrl, asset }) => (
-
- ))
- : monitors
- ?.filter((m) => m.asset.location_object.id === location?.id)
- ?.slice(
- (currentPage - 1) * PER_PAGE_LIMIT,
- currentPage * PER_PAGE_LIMIT
- )
- .map(({ patient, socketUrl, asset }) => (
-
- ))}
-
-
- );
-}
diff --git a/src/Components/Facility/LegacyMonitorCard.tsx b/src/Components/Facility/LegacyMonitorCard.tsx
deleted file mode 100644
index 61bff3d607b..00000000000
--- a/src/Components/Facility/LegacyMonitorCard.tsx
+++ /dev/null
@@ -1,47 +0,0 @@
-import { GENDER_TYPES } from "../../Common/constants";
-import { Link } from "raviger";
-import CareIcon from "../../CAREUI/icons/CareIcon";
-import { PatientModel } from "../Patient/models";
-import LegacyPatientVitalsCard from "../Patient/LegacyPatientVitalsCard";
-import { AssetLocationObject } from "../Assets/AssetTypes";
-import { formatAge } from "../../Utils/utils";
-
-interface MonitorCardProps {
- facilityId: string;
- patient: PatientModel;
- socketUrl: string;
- location: AssetLocationObject;
-}
-
-export const LegacyMonitorCard = ({
- facilityId,
- patient,
- socketUrl,
- location,
-}: MonitorCardProps) => {
- return (
-
-
-
- {patient.name}
-
-
- {formatAge(patient.age, patient.date_of_birth)} |{" "}
- {GENDER_TYPES.find((g) => g.id === patient.gender)?.icon}
-
-
-
- {patient.last_consultation?.current_bed?.bed_object?.name}
-
-
-
- {location.name}
-
-
-
-
- );
-};
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
-
- No locations available
-
-
-
-
-
+
+ No locations available
+
+
+
+
+
className="my-8 grid gap-3 @4xl:grid-cols-2 @6xl:grid-cols-3 @[100rem]:grid-cols-4 lg:mx-8">
{(item) => }
diff --git a/src/Components/Facility/MinQuantityList.tsx b/src/Components/Facility/MinQuantityList.tsx
index 631f432a9dc..941722bd810 100644
--- a/src/Components/Facility/MinQuantityList.tsx
+++ b/src/Components/Facility/MinQuantityList.tsx
@@ -126,6 +126,7 @@ export default function MinQuantityList(props: any) {
{inventoryItem.item_object?.default_unit?.name}
{
/>
-
+
Update
diff --git a/src/Components/Facility/PatientNotesSlideover.tsx b/src/Components/Facility/PatientNotesSlideover.tsx
index 4279e3c1877..5ecf30cfcdf 100644
--- a/src/Components/Facility/PatientNotesSlideover.tsx
+++ b/src/Components/Facility/PatientNotesSlideover.tsx
@@ -23,7 +23,6 @@ interface PatientNotesProps {
export default function PatientNotesSlideover(props: PatientNotesProps) {
const [show, setShow] = useState(true);
const [patientActive, setPatientActive] = useState(true);
- const [noteField, setNoteField] = useState("");
const [reload, setReload] = useState(false);
const [focused, setFocused] = useState(false);
@@ -37,6 +36,11 @@ export default function PatientNotesSlideover(props: PatientNotesProps) {
const { facilityId, patientId, consultationId, setShowPatientNotesPopup } =
props;
+ const localStorageKey = `patientNotesNoteField_${consultationId}`;
+ const [noteField, setNoteField] = useState(
+ localStorage.getItem(localStorageKey) || ""
+ );
+
const onAddNote = async () => {
const payload = {
note: noteField,
@@ -127,6 +131,10 @@ export default function PatientNotesSlideover(props: PatientNotesProps) {
);
+ useEffect(() => {
+ localStorage.setItem(localStorageKey, noteField);
+ }, [noteField, localStorageKey]);
+
return (
{
{formatDate(date)}
-
+
Name : {patientData.name}
- Address : {patientData.address}
+ Address : {patientData.address}
-
-
- Age :{" "}
- {formatAge(patientData.age, patientData.date_of_birth, true)}
+
+
+
+ Age :{" "}
+ {formatAge(
+ patientData.age,
+ patientData.date_of_birth,
+ true
+ )}
+
+
+ OP : {consultationData.patient_no}
+
-
- Date of admission :
+
+
+ Date of admission :
{consultationData.admitted
? formatDateTime(consultationData.encounter_date)
@@ -146,13 +156,13 @@ const TreatmentSummary = (props: any) => {
-
-
- Gender :
+
+
+ Gender :
{GENDER_TYPES.find((i) => i.id === patientData.gender)?.text}
-
+
Contact person :
{" "}
diff --git a/src/Components/Facility/models.tsx b/src/Components/Facility/models.tsx
index 16113d0c8b7..74cf6700530 100644
--- a/src/Components/Facility/models.tsx
+++ b/src/Components/Facility/models.tsx
@@ -5,7 +5,7 @@ import { AssetData, AssetLocationType } from "../Assets/AssetTypes";
import { UserBareMinimum } from "../Users/models";
import { RouteToFacility } from "../Common/RouteToFacilitySelect";
import { ConsultationDiagnosis, CreateDiagnosis } from "../Diagnosis/types";
-import { ConsultationSuggestionValue } from "../../Common/constants";
+import { ConsultationSuggestionValue, UserRole } from "../../Common/constants";
export interface LocalBodyModel {
id: number;
@@ -103,18 +103,18 @@ export interface ConsultationModel {
category?: PatientCategory;
created_date?: string;
discharge_date?: string;
- discharge_reason?: string;
+ new_discharge_reason?: number;
discharge_prescription?: NormalPrescription;
discharge_prn_prescription?: PRNPrescription;
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;
@@ -203,11 +203,11 @@ export interface InventoryItemsModel {
}
export interface LocationModel {
- id?: string;
- name?: string;
+ id: string;
+ name: string;
description?: string;
middleware_address?: string;
- location_type?: AssetLocationType;
+ location_type: AssetLocationType;
facility?: {
name: string;
};
@@ -218,8 +218,8 @@ export interface LocationModel {
export interface BedModel {
id?: string;
bed_type?: string;
- description?: string;
name?: string;
+ description?: string;
facility?: string;
location_object?: {
name: string;
@@ -228,6 +228,8 @@ export interface BedModel {
location?: string;
is_occupied?: boolean;
meta?: object;
+ created_date?: string;
+ modified_date?: string;
}
export interface CurrentBed {
@@ -494,7 +496,7 @@ export interface PatientNotesModel {
note: string;
facility: BaseFacilityModel;
created_by_object: BaseUserModel;
- user_type?: string;
+ user_type?: UserRole | "RemoteSpecialist";
created_date: string;
}
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 = FormFieldBaseProps & {
options: T[];
optionDisplay: (option: T) => React.ReactNode;
optionValue: (option: T) => string;
+ containerClassName?: string;
};
const RadioFormField = (props: Props) => {
const field = useFormFieldPropsResolver(props);
return (
-
+
{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) => {
{dailyRoundListDetailsData.rhythm_detail ?? "-"}
+
+
+ Level Of Consciousness:{" "}
+
+ {dailyRoundListDetailsData.consciousness_level
+ ? CONSCIOUSNESS_LEVEL.find(
+ (i) => i.id === dailyRoundListDetailsData.consciousness_level
+ )?.text
+ : "-"}
+
Recommend Discharge:{" "}
diff --git a/src/Components/Patient/DailyRounds.tsx b/src/Components/Patient/DailyRounds.tsx
index a9a31f2aa14..56e26dff022 100644
--- a/src/Components/Patient/DailyRounds.tsx
+++ b/src/Components/Patient/DailyRounds.tsx
@@ -1,9 +1,10 @@
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,
PATIENT_CATEGORIES,
REVIEW_AT_CHOICES,
RHYTHM_CHOICES,
@@ -22,7 +23,7 @@ import { DraftSection, useAutoSaveReducer } from "../../Utils/AutoSave";
import * as Notification from "../../Utils/Notifications";
import { formatDateTime } from "../../Utils/utils";
import BloodPressureFormField, {
- meanArterialPressure,
+ BloodPressureValidator,
} from "../Common/BloodPressureFormField";
import { SymptomsSelect } from "../Common/SymptomsSelect";
import TemperatureFormField from "../Common/TemperatureFormField";
@@ -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,12 @@ const initForm: any = {
rhythm: "0",
rhythm_detail: "",
ventilator_spo2: null,
+ consciousness_level: "UNKNOWN",
+ bp: {
+ systolic: undefined,
+ diastolic: undefined,
+ mean: undefined,
+ },
// bed: null,
};
@@ -129,10 +137,40 @@ export const DailyRounds = (props: any) => {
"ventilator_spo2",
"rhythm",
"rhythm_detail",
+ "consciousness_level",
];
- useEffect(() => {
- (async () => {
+ const fetchRoundDetails = useCallback(
+ async (status: statusType) => {
+ setIsLoading(true);
+ 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 };
+ }
+ }
+ }
+ setIsLoading(false);
if (patientId) {
const res = await dispatchAction(getPatient({ id: patientId }));
if (res.data) {
@@ -150,71 +188,20 @@ export const DailyRounds = (props: any) => {
...initialData,
action: getAction,
});
- dispatch({
- type: "set_form",
- form: {
- ...state.form,
- action: getAction,
- },
- });
+ formData = { ...formData, ...{ action: getAction } };
}
} else {
setPatientName("");
setFacilityName("");
}
- })();
- }, [dispatchAction, patientId]);
-
- const fetchRoundDetails = useCallback(
- async (status: statusType) => {
- setIsLoading(true);
- 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",
- };
- dispatch({ type: "set_form", form: data });
- setInitialData(data);
- }
- setIsLoading(false);
- }
- },
- [consultationId, id, dispatchAction]
- );
- useAbortableEffect(
- (status: statusType) => {
- if (id) {
- fetchRoundDetails(status);
- }
- },
- [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
@@ -225,12 +212,20 @@ 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,
},
- });
+ };
}
- })();
- }, [dispatchAction, consultationId, id]);
+ dispatch({ type: "set_form", form: formData });
+ setInitialData(formData);
+ },
+ [consultationId, id, dispatchAction, patientId]
+ );
+ useAbortableEffect(
+ (status: statusType) => {
+ fetchRoundDetails(status);
+ },
+ [dispatchAction, fetchRoundDetails]
+ );
const validateForm = () => {
const errors = { ...initError };
@@ -252,6 +247,14 @@ export const DailyRounds = (props: any) => {
invalidForm = true;
}
return;
+ case "bp": {
+ const error = BloodPressureValidator(state.form.bp);
+ if (error) {
+ errors.bp = error;
+ invalidForm = true;
+ }
+ return;
+ }
default:
return;
}
@@ -296,22 +299,14 @@ export const DailyRounds = (props: any) => {
if (["NORMAL", "TELEMEDICINE"].includes(state.form.rounds_type)) {
data = {
...data,
- bp:
- state.form.bp && state.form.bp.systolic && state.form.bp.diastolic
- ? {
- systolic: Number(state.form.bp.systolic),
- diastolic: Number(state.form.bp.diastolic),
- mean: parseFloat(
- meanArterialPressure(state.form.bp).toFixed(2)
- ),
- }
- : undefined,
- pulse: state.form.pulse,
- resp: Number(state.form.resp),
- temperature: state.form.temperature,
- rhythm: Number(state.form.rhythm) || 0,
+ bp: state.form.bp ?? {},
+ 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,
};
}
} else {
@@ -637,9 +632,21 @@ export const DailyRounds = (props: any) => {
+
+ ({
+ label: level.text,
+ value: level.id,
+ }))}
+ optionDisplay={(option) => option.label}
+ optionValue={(option) => option.value}
+ containerClassName="grid gap-1 grid-cols-1"
/>
>
)}
diff --git a/src/Components/Patient/FileUpload.tsx b/src/Components/Patient/FileUpload.tsx
index e1ea368af72..d1dedc5e2ff 100644
--- a/src/Components/Patient/FileUpload.tsx
+++ b/src/Components/Patient/FileUpload.tsx
@@ -276,6 +276,7 @@ export const FileUpload = (props: FileUploadProps) => {
const handleClose = () => {
setDownloadURL("");
+ setPreviewImage(null);
setFileState({
...file_state,
open: false,
@@ -1212,6 +1213,7 @@ export const FileUpload = (props: FileUploadProps) => {
{
+ setPreviewImage(null);
setModalOpenForCamera(false);
}}
className="m-2"
@@ -1272,6 +1274,7 @@ export const FileUpload = (props: FileUploadProps) => {
{
setModalOpenForCamera(false);
+ setPreviewImage(null);
}}
>
{t("submit")}
diff --git a/src/Components/Patient/LegacyPatientVitalsCard.tsx b/src/Components/Patient/LegacyPatientVitalsCard.tsx
deleted file mode 100644
index 6577e4920d4..00000000000
--- a/src/Components/Patient/LegacyPatientVitalsCard.tsx
+++ /dev/null
@@ -1,288 +0,0 @@
-import { ReactNode, useEffect, useRef, useState } from "react";
-import { useDispatch } from "react-redux";
-import { listAssetBeds, getPermittedFacility } from "../../Redux/actions";
-import { classNames } from "../../Utils/utils";
-import { AssetData } from "../Assets/AssetTypes";
-import ToolTip from "../Common/utils/Tooltip";
-import { PatientModel } from "./models";
-import Waveform, { WaveformType } from "./Waveform";
-
-export interface IPatientVitalsCardProps {
- facilityId?: string;
- patient?: PatientModel;
- socketUrl?: string;
- shrinked?: boolean;
-}
-
-const getVital = (
- patientObservations: any,
- vital: string,
- fallbackValue?: any
-) => {
- if (patientObservations) {
- const vitalValues = patientObservations[vital];
- if (vitalValues) {
- const returnValue = vitalValues?.value;
-
- if (returnValue !== undefined && returnValue !== null) {
- return returnValue;
- }
- }
- }
- if (fallbackValue) {
- return fallbackValue;
- }
- return "";
-};
-
-export default function LegacyPatientVitalsCard({
- patient,
- socketUrl,
- facilityId,
- shrinked,
-}: IPatientVitalsCardProps) {
- const wsClient = useRef();
- const [waveforms, setWaveForms] = useState(null);
- const dispatch: any = useDispatch();
- const [middlewareHostname, setMiddlewareHostname] = useState("");
- const [wsUrl, setWsUrl] = useState("");
- const [patientObservations, setPatientObservations] = useState();
- const [stats, setStats] = useState(false);
-
- useEffect(() => {
- const fetchFacility = async () => {
- const res = await dispatch(getPermittedFacility(facilityId || ""));
-
- if (res.status === 200 && res.data) {
- setMiddlewareHostname(res.data.middleware_address);
- }
- };
-
- if (facilityId) fetchFacility();
- }, [dispatch, facilityId]);
-
- useEffect(() => {
- const fetchAssetData = async () => {
- let bedAssets = await dispatch(
- listAssetBeds({
- bed: patient?.last_consultation?.current_bed?.bed_object?.id,
- })
- );
- bedAssets = {
- ...bedAssets,
- data: {
- ...bedAssets.data,
- results: bedAssets.data.results.filter((assetBed: any) =>
- assetBed.asset_object.meta?.asset_type === "HL7MONITOR"
- ? true
- : false
- ),
- },
- };
-
- if (bedAssets.data.results.length > 0) {
- const asset: AssetData = bedAssets.data.results[0].asset_object;
- if (asset?.meta?.local_ip_address) {
- setWsUrl(
- `wss://${middlewareHostname}/observations/${asset?.meta?.local_ip_address}`
- );
- }
- }
- };
-
- if (patient?.last_consultation?.current_bed?.bed_object?.id)
- fetchAssetData();
- }, [
- dispatch,
- middlewareHostname,
- patient?.last_consultation?.current_bed?.bed_object?.id,
- ]);
-
- const connectWs = (url: string) => {
- wsClient.current = new WebSocket(url);
- wsClient.current.addEventListener("message", (e) => {
- const newObservations = JSON.parse(e.data || "{}");
- if (newObservations.length > 0) {
- setWaveForms(
- newObservations.filter((o: any) => o.observation_id === "waveform")
- );
- const newObservationsMap = newObservations.reduce(
- (acc: any, curr: { observation_id: any }) => ({
- ...acc,
- [curr.observation_id]: curr,
- }),
- {}
- );
- setPatientObservations(newObservationsMap);
- }
- });
- };
-
- useEffect(() => {
- if (socketUrl || wsUrl) connectWs(socketUrl || wsUrl);
-
- return () => {
- wsClient.current?.close();
- };
- }, [wsUrl, socketUrl]);
-
- useEffect(() => {
- return () => {
- wsClient.current?.close();
- setWaveForms(null);
- };
- }, [socketUrl, patient]);
-
- type VitalType = {
- label: ReactNode;
- liveKey: string;
- vitalKey: string;
- waveformKey?: string;
- waveformColor?: string;
- waveformName?: string;
- waveformDefaultSpace?: boolean;
- wavetype?: "STREAM" | "REFRESH";
- };
-
- const vitals: VitalType[] = [
- {
- label: shrinked ? "Pulse" : "Pulse Rate",
- liveKey: "pulse-rate",
- vitalKey: "pulse",
- waveformKey: "II",
- waveformColor: "limegreen",
- waveformName: "ECG",
- wavetype: "REFRESH",
- },
- {
- label: shrinked ? "BP" : "Blood Pressure",
- liveKey: "bp",
- vitalKey: "bp",
- },
- {
- label: (
- <>
- SpO2
- >
- ),
- liveKey: "SpO2",
- vitalKey: "ventilator_spo2",
- waveformKey: "Pleth",
- waveformColor: "yellow",
- },
- {
- label: <>R. Rate>,
- liveKey: "respiratory-rate",
- vitalKey: "resp",
- waveformKey: "Respiration",
- waveformColor: "cyan",
- //waveformDefaultSpace: true
- },
- {
- label: shrinked ? "Temp. (°F)" : "Temperature (°F)",
- liveKey: "body-temperature1",
- vitalKey: "temperature",
- },
- ];
-
- return (
-
-
-
- {waveforms ? (
- <>
- {vitals.map((v, i) => {
- const waveform: any = waveforms.filter(
- (w) => w["wave-name"] === v.waveformKey
- )[0];
- return v.waveformKey && waveform ? (
- w["wave-name"] === v.waveformKey)
- .map((w) => w.data)
- .join(" "),
- }}
- title={v.waveformName || v.waveformKey}
- color={v.waveformColor}
- metrics={stats}
- classes={"h-[150px]"}
- defaultSpace={v.waveformDefaultSpace}
- wavetype={v.wavetype || "STREAM"}
- />
- ) : (
-
- );
- })}
-
-
-
-
-
- >
- ) : (
-
-
-
- No Live data at the moment!
-
-
- )}
-
-
- {vitals.map((vital, i) => {
- const liveReading = getVital(patientObservations, vital.liveKey);
- return (
-
-
- {liveReading ||
- (vital.vitalKey === "bp"
- ? `${
- patient?.last_consultation?.last_daily_round?.bp
- .systolic || "--"
- }/${
- patient?.last_consultation?.last_daily_round?.bp
- .diastolic || "--"
- }`
- : patient?.last_consultation?.last_daily_round?.[
- vital.vitalKey || ""
- ]) ||
- "--"}
-
-
-
- );
- })}
-
-
-
- );
-}
diff --git a/src/Components/Patient/ManagePatients.tsx b/src/Components/Patient/ManagePatients.tsx
index e1d982148f1..0f9a6656f67 100644
--- a/src/Components/Patient/ManagePatients.tsx
+++ b/src/Components/Patient/ManagePatients.tsx
@@ -153,7 +153,8 @@ export const PatientManager = () => {
};
const tabValue =
- qParams.last_consultation_discharge_reason || qParams.is_active === "False"
+ qParams.last_consultation__new_discharge_reason ||
+ qParams.is_active === "False"
? 1
: 0;
@@ -163,7 +164,7 @@ export const PatientManager = () => {
name: qParams.name || undefined,
patient_no: qParams.patient_no || undefined,
is_active:
- !qParams.last_consultation_discharge_reason &&
+ !qParams.last_consultation__new_discharge_reason &&
(qParams.is_active || "True"),
disease_status: qParams.disease_status || undefined,
phone_number: qParams.phone_number
@@ -204,8 +205,8 @@ export const PatientManager = () => {
qParams.last_consultation_discharge_date_after || undefined,
last_consultation_admitted_bed_type_list:
qParams.last_consultation_admitted_bed_type_list || undefined,
- last_consultation_discharge_reason:
- qParams.last_consultation_discharge_reason || undefined,
+ last_consultation__new_discharge_reason:
+ qParams.last_consultation__new_discharge_reason || undefined,
last_consultation_current_bed__location:
qParams.last_consultation_current_bed__location || undefined,
srf_id: qParams.srf_id || undefined,
@@ -352,7 +353,7 @@ export const PatientManager = () => {
qParams.age_max,
qParams.age_min,
qParams.last_consultation_admitted_bed_type_list,
- qParams.last_consultation_discharge_reason,
+ qParams.last_consultation__new_discharge_reason,
qParams.last_consultation_current_bed__location,
qParams.facility,
qParams.facility_type,
@@ -536,12 +537,9 @@ export const PatientManager = () => {
? PATIENT_CATEGORIES.find((c) => c.text === category)?.twClass
: "patient-unknown";
- return (
-
{
)}
+
+ );
+
+ if (
+ authUser.user_type === "Staff" ||
+ authUser.user_type === "StaffReadOnly"
+ ) {
+ return children;
+ }
+
+ return (
+
+ {children}
);
});
@@ -1022,10 +1033,10 @@ export const PatientManager = () => {
},
value(
"Discharge Reason",
- "last_consultation_discharge_reason",
+ "last_consultation__new_discharge_reason",
parseOptionId(
DISCHARGE_REASONS,
- qParams.last_consultation_discharge_reason
+ qParams.last_consultation__new_discharge_reason
) || ""
),
]}
diff --git a/src/Components/Patient/PatientFilter.tsx b/src/Components/Patient/PatientFilter.tsx
index 481d2dcc67b..4488aa755e1 100644
--- a/src/Components/Patient/PatientFilter.tsx
+++ b/src/Components/Patient/PatientFilter.tsx
@@ -81,8 +81,8 @@ export default function PatientFilter(props: any) {
: [],
last_consultation_current_bed__location:
filter.last_consultation_current_bed__location || "",
- last_consultation_discharge_reason:
- filter.last_consultation_discharge_reason || null,
+ last_consultation__new_discharge_reason:
+ filter.last_consultation__new_discharge_reason || null,
srf_id: filter.srf_id || null,
number_of_doses: filter.number_of_doses || null,
covin_id: filter.covin_id || null,
@@ -241,7 +241,7 @@ export default function PatientFilter(props: any) {
last_consultation_discharge_date_before,
last_consultation_discharge_date_after,
last_consultation_admitted_bed_type_list,
- last_consultation_discharge_reason,
+ last_consultation__new_discharge_reason,
last_consultation_current_bed__location,
number_of_doses,
covin_id,
@@ -298,8 +298,8 @@ export default function PatientFilter(props: any) {
age_max: age_max || "",
last_consultation_admitted_bed_type_list:
last_consultation_admitted_bed_type_list || [],
- last_consultation_discharge_reason:
- last_consultation_discharge_reason || "",
+ last_consultation__new_discharge_reason:
+ last_consultation__new_discharge_reason || "",
srf_id: srf_id || "",
number_of_doses: number_of_doses || "",
covin_id: covin_id || "",
@@ -424,16 +424,16 @@ export default function PatientFilter(props: any) {
Discharge Reason
o.id}
optionLabel={(o) => o.text}
onChange={(o) =>
setFilterState({
...filterState,
- last_consultation_discharge_reason: o,
+ last_consultation__new_discharge_reason: o,
})
}
/>
diff --git a/src/Components/Patient/PatientHome.tsx b/src/Components/Patient/PatientHome.tsx
index dc400ddc79b..22cc35a170e 100644
--- a/src/Components/Patient/PatientHome.tsx
+++ b/src/Components/Patient/PatientHome.tsx
@@ -1,7 +1,11 @@
import { navigate } from "raviger";
import { lazy, useCallback, useEffect, useState } from "react";
import { useDispatch } from "react-redux";
-import { GENDER_TYPES, SAMPLE_TEST_STATUS } from "../../Common/constants";
+import {
+ DISCHARGE_REASONS,
+ GENDER_TYPES,
+ SAMPLE_TEST_STATUS,
+} from "../../Common/constants";
import { statusType, useAbortableEffect } from "../../Common/utils";
import {
getConsultationList,
@@ -19,7 +23,12 @@ import { ConsultationModel } from "../Facility/models";
import { PatientModel, SampleTestModel } from "./models";
import { SampleTestCard } from "./SampleTestCard";
import Chip from "../../CAREUI/display/Chip";
-import { classNames, formatAge, formatDateTime } from "../../Utils/utils";
+import {
+ classNames,
+ formatAge,
+ formatDate,
+ formatDateTime,
+} from "../../Utils/utils";
import ButtonV2 from "../Common/components/ButtonV2";
import { NonReadOnlyUsers } from "../../Utils/AuthorizeFor";
import RelativeDateUserMention from "../Common/RelativeDateUserMention";
@@ -311,20 +320,18 @@ export const PatientHome = (props: any) => {
patientData.medical_history.length
) {
const medHis = patientData.medical_history;
- patientMedHis = medHis.map((item: any, idx: number) => (
-
- {item?.disease !== "NO" && (
- <>
-
- {item.disease}
-
-
- {item.details}
-
- >
- )}
-
- ));
+ patientMedHis = medHis
+ .filter((item) => item.disease !== "NO")
+ .map((item, idx) => (
+
+
+ {item.disease}
+
+
+ {item.details}
+
+
+ ));
}
let consultationList, sampleList;
@@ -572,7 +579,7 @@ export const PatientHome = (props: any) => {
Date of Birth
- {patientData?.date_of_birth}
+ {formatDate(patientData?.date_of_birth)}
@@ -758,7 +765,8 @@ export const PatientHome = (props: any) => {
- {patientData.last_consultation?.discharge_reason === "EXP" && (
+ {patientData.last_consultation?.new_discharge_reason ===
+ DISCHARGE_REASONS.find((i) => i.text == "Expired")?.id && (
- {!!consultation?.discharge_date && (
+ {consultation?.discharge_date ? (
@@ -331,7 +331,8 @@ export default function PatientInfoCard(props: {
)?.text
}{" "}
on {formatDateTime(consultation.encounter_date)},
- {consultation?.discharge_reason === "EXP" ? (
+ {consultation?.new_discharge_reason ===
+ DISCHARGE_REASONS.find((i) => i.text == "Expired")?.id ? (
{" "}
Expired on {formatDate(consultation?.death_datetime)}
@@ -346,6 +347,23 @@ export default function PatientInfoCard(props: {
+ ) : (
+
+
+ {consultation?.encounter_date && (
+
+ Admission on{" "}
+ {formatDateTime(consultation?.encounter_date)}
+
+ )}
+ {consultation?.icu_admission_date && (
+
+ , ICU Admission on{" "}
+ {formatDateTime(consultation?.icu_admission_date)}
+
+ )}
+
+
)}
@@ -362,17 +380,18 @@ export default function PatientInfoCard(props: {
Discharge Reason
- {!consultation?.discharge_reason ? (
+ {!consultation?.new_discharge_reason ? (
{consultation.suggestion === "OP"
? "OP file closed"
: "UNKNOWN"}
- ) : consultation?.discharge_reason === "EXP" ? (
+ ) : consultation?.new_discharge_reason ===
+ DISCHARGE_REASONS.find((i) => i.text == "Expired")?.id ? (
EXPIRED
) : (
DISCHARGE_REASONS.find(
- (reason) => reason.id === consultation?.discharge_reason
+ (reason) => reason.id === consultation?.new_discharge_reason
)?.text
)}
@@ -490,6 +509,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 +518,7 @@ export default function PatientInfoCard(props: {
}
onClick={() => {
if (
+ action[1] !== "Treatment Summary" &&
consultation?.admitted &&
!consultation?.current_bed &&
i === 1
diff --git a/src/Components/Patient/PatientRegister.tsx b/src/Components/Patient/PatientRegister.tsx
index 77088ef57e7..ce63d5019de 100644
--- a/src/Components/Patient/PatientRegister.tsx
+++ b/src/Components/Patient/PatientRegister.tsx
@@ -70,6 +70,7 @@ import useConfig from "../../Common/hooks/useConfig";
import { useDispatch } from "react-redux";
import { validatePincode } from "../../Common/validation";
import { FormContextValue } from "../Form/FormContext.js";
+import useAuthUser from "../../Common/hooks/useAuthUser.js";
const Loading = lazy(() => import("../Common/Loading"));
const PageTitle = lazy(() => import("../Common/PageTitle"));
@@ -180,6 +181,7 @@ const patientFormReducer = (state = initialState, action: any) => {
};
export const PatientRegister = (props: PatientRegisterProps) => {
+ const authUser = useAuthUser();
const { goBack } = useAppHistory();
const { gov_data_api_key, enable_hcx, enable_abdm } = useConfig();
const dispatchAction: any = useDispatch();
@@ -544,6 +546,7 @@ export const PatientRegister = (props: PatientRegisterProps) => {
setFacilityName("");
}
}
+
fetchFacilityName();
}, [dispatchAction, facilityId]);
@@ -953,6 +956,14 @@ export const PatientRegister = (props: PatientRegisterProps) => {
} else {
values.splice(values.indexOf(id), 1);
}
+
+ if (id !== 1 && values.includes(1)) {
+ values.splice(values.indexOf(1), 1);
+ } else if (id === 1) {
+ values.length = 0;
+ values.push(1);
+ }
+
field("medical_history").onChange({
name: "medical_history",
value: values,
@@ -1164,6 +1175,10 @@ export const PatientRegister = (props: PatientRegisterProps) => {
{
setShowImport({
show: true,
diff --git a/src/Components/Patient/models.tsx b/src/Components/Patient/models.tsx
index e1ce5d53050..fc87bedcb14 100644
--- a/src/Components/Patient/models.tsx
+++ b/src/Components/Patient/models.tsx
@@ -282,9 +282,9 @@ export interface DailyRoundsModel {
rhythm?: string;
rhythm_detail?: string;
bp?: {
- diastolic: number;
- mean: number;
- systolic: number;
+ diastolic?: number;
+ mean?: number;
+ systolic?: number;
};
pulse?: number;
resp?: number;
@@ -297,7 +297,7 @@ export interface DailyRoundsModel {
medication_given?: Array;
additional_symptoms_text?: string;
current_health?: string;
- id: string;
+ id?: string;
other_symptoms?: string;
admitted_to?: string;
patient_category?: PatientCategory;
@@ -314,7 +314,7 @@ export interface DailyRoundsModel {
| "AGITATED_OR_CONFUSED"
| "ONSET_OF_AGITATION_AND_CONFUSION"
| "UNKNOWN";
- rounds_type: (typeof DailyRoundTypes)[number];
+ rounds_type?: (typeof DailyRoundTypes)[number];
last_updated_by_telemedicine?: boolean;
created_by_telemedicine?: boolean;
created_by?: {
diff --git a/src/Components/Shifting/ShiftDetailsUpdate.tsx b/src/Components/Shifting/ShiftDetailsUpdate.tsx
index 36d2d120585..a726150c9e1 100644
--- a/src/Components/Shifting/ShiftDetailsUpdate.tsx
+++ b/src/Components/Shifting/ShiftDetailsUpdate.tsx
@@ -2,6 +2,7 @@ import * as Notification from "../../Utils/Notifications.js";
import {
BREATHLESSNESS_LEVEL,
+ DISCHARGE_REASONS,
FACILITY_TYPES,
PATIENT_CATEGORIES,
SHIFTING_CHOICES_PEACETIME,
@@ -282,7 +283,9 @@ export const ShiftDetailsUpdate = (props: patientShiftProps) => {
show={showDischargeModal}
onClose={() => setShowDischargeModal(false)}
consultationData={consultationData}
- discharge_reason="EXP"
+ new_discharge_reason={
+ DISCHARGE_REASONS.find((i) => i.text == "Expired")?.id
+ }
afterSubmit={() => {
handleSubmit(true);
}}
diff --git a/src/Components/Users/ManageUsers.tsx b/src/Components/Users/ManageUsers.tsx
index 750603ccf6f..300f9846a89 100644
--- a/src/Components/Users/ManageUsers.tsx
+++ b/src/Components/Users/ManageUsers.tsx
@@ -218,7 +218,10 @@ export default function ManageUsers() {
)}
-
+
{`${user.first_name} ${user.last_name}`}
{user.last_login && cur_online ? (
@@ -228,15 +231,12 @@ export default function ManageUsers() {
>
) : null}
{showUserDelete(authUser, user) && (
- handleDelete(user)}
>
- Delete
-
+
+
)}
diff --git a/src/Components/Users/SkillsSlideOver.tsx b/src/Components/Users/SkillsSlideOver.tsx
index 1819333451d..63353479f0d 100644
--- a/src/Components/Users/SkillsSlideOver.tsx
+++ b/src/Components/Users/SkillsSlideOver.tsx
@@ -115,12 +115,10 @@ export default ({ show, setShow, username }: IProps) => {
multiple={false}
name="skill"
disabled={!authorizeForAddSkill}
- showAll={true}
showNOptions={Infinity}
selected={selectedSkill}
setSelected={setSelectedSkill}
errors=""
- username={username}
userSkills={skills?.results || []}
/>
({ [k]: "" }))
@@ -234,15 +241,19 @@ export const UserAdd = (props: UserProps) => {
: // Exception to allow Staff to Create Doctors
defaultAllowedUserTypes;
+ // TODO: refactor lines 227 through 248 to be more readable. This is messy.
+ if (authUser.user_type === "Nurse" || authUser.user_type === "Staff") {
+ userTypes.push(USER_TYPE_OPTIONS[6]); // Temperorily allows creation of users with elevated permissions due to introduction of new roles.
+ }
+
const headerText = !userId ? "Add User" : "Update User";
const buttonText = !userId ? "Save User" : "Update Details";
- const showLocalbody = !(
- state.form.user_type === "Pharmacist" ||
- state.form.user_type === "Volunteer" ||
- state.form.user_type === "Doctor" ||
- state.form.user_type === "Staff" ||
- state.form.user_type === "StaffReadOnly"
- );
+ const showLocalbody = ![
+ "Pharmacist",
+ "Volunteer",
+ "Doctor",
+ ...STAFF_OR_NURSE_USER,
+ ].includes(state.form.user_type);
const { loading: isDistrictLoading } = useQuery(routes.getDistrictByState, {
prefetch: !!(selectedStateId > 0),
@@ -332,10 +343,8 @@ export const UserAdd = (props: UserProps) => {
case "facilities":
if (
state.form[field].length === 0 &&
- (authUser.user_type === "Staff" ||
- authUser.user_type === "StaffReadOnly") &&
- (state.form["user_type"] === "Staff" ||
- state.form["user_type"] === "StaffReadOnly")
+ STAFF_OR_NURSE_USER.includes(authUser.user_type) &&
+ STAFF_OR_NURSE_USER.includes(state.form.user_type)
) {
errors[field] =
"Please select atleast one of the facilities you are linked to";
diff --git a/src/Components/Users/UserProfile.tsx b/src/Components/Users/UserProfile.tsx
index 2dc75d33613..170de558e41 100644
--- a/src/Components/Users/UserProfile.tsx
+++ b/src/Components/Users/UserProfile.tsx
@@ -5,7 +5,7 @@ import * as Notification from "../../Utils/Notifications.js";
import LanguageSelector from "../../Components/Common/LanguageSelector";
import TextFormField from "../Form/FormFields/TextFormField";
import ButtonV2, { Submit } from "../Common/components/ButtonV2";
-import { classNames, parsePhoneNumber } from "../../Utils/utils";
+import { classNames, isValidUrl, parsePhoneNumber } from "../../Utils/utils";
import CareIcon from "../../CAREUI/icons/CareIcon";
import PhoneNumberFormField from "../Form/FormFields/PhoneNumberFormField";
import { FieldChangeEvent } from "../Form/FormFields/Utils";
@@ -27,13 +27,14 @@ type EditForm = {
age: string;
gender: GenderType;
email: string;
+ video_connect_link: string | undefined;
phoneNumber: string;
altPhoneNumber: string;
user_type: string | undefined;
doctor_qualification: string | undefined;
doctor_experience_commenced_on: number | string | undefined;
doctor_medical_council_registration: string | undefined;
- weekly_working_hours: string | undefined;
+ weekly_working_hours: string | null;
};
type ErrorForm = {
firstName: string;
@@ -41,6 +42,7 @@ type ErrorForm = {
age: string;
gender: string;
email: string;
+ video_connect_link: string | undefined;
phoneNumber: string;
altPhoneNumber: string;
user_type: string | undefined;
@@ -62,6 +64,7 @@ const initForm: EditForm = {
lastName: "",
age: "",
gender: "Male",
+ video_connect_link: "",
email: "",
phoneNumber: "",
altPhoneNumber: "",
@@ -145,6 +148,7 @@ export default function UserProfile() {
age: result.data.age?.toString() || "",
gender: result.data.gender || "Male",
email: result.data.email,
+ video_connect_link: result.data.video_connect_link,
phoneNumber: result.data.phone_number?.toString() || "",
altPhoneNumber: result.data.alt_phone_number?.toString() || "",
user_type: result.data.user_type,
@@ -249,19 +253,25 @@ export default function UserProfile() {
}
return;
case "weekly_working_hours":
- if (!states.form[field]) {
- errors[field] = "This field is required";
- invalidForm = true;
- } else if (
- Number(states.form[field]) < 0 ||
- Number(states.form[field]) > 168 ||
- !/^\d+$/.test(states.form[field] ?? "")
+ if (
+ states.form[field] &&
+ (Number(states.form[field]) < 0 ||
+ Number(states.form[field]) > 168 ||
+ !/^\d+$/.test(states.form[field] ?? ""))
) {
errors[field] =
"Average weekly working hours must be a number between 0 and 168";
invalidForm = true;
}
return;
+ case "video_connect_link":
+ if (states.form[field]) {
+ if (isValidUrl(states.form[field]) === false) {
+ errors[field] = "Please enter a valid url";
+ invalidForm = true;
+ }
+ }
+ return;
}
});
dispatch({ type: "set_error", errors });
@@ -294,6 +304,7 @@ export default function UserProfile() {
first_name: states.form.firstName,
last_name: states.form.lastName,
email: states.form.email,
+ video_connect_link: states.form.video_connect_link,
phone_number: parsePhoneNumber(states.form.phoneNumber) ?? "",
alt_phone_number: parsePhoneNumber(states.form.altPhoneNumber) ?? "",
gender: states.form.gender,
@@ -318,7 +329,11 @@ export default function UserProfile() {
states.form.user_type === "Doctor"
? states.form.doctor_medical_council_registration
: undefined,
- weekly_working_hours: states.form.weekly_working_hours,
+ weekly_working_hours:
+ states.form.weekly_working_hours &&
+ states.form.weekly_working_hours !== ""
+ ? states.form.weekly_working_hours
+ : null,
};
const { res } = await request(routes.partialUpdateUser, {
pathParams: { username: authUser.username },
@@ -575,7 +590,29 @@ export default function UserProfile() {
Average weekly working hours
- {userData?.weekly_working_hours || "-"}
+ {userData?.weekly_working_hours ?? "-"}
+
+
+
@@ -672,13 +709,18 @@ export default function UserProfile() {
)}
+
diff --git a/src/Components/Users/models.tsx b/src/Components/Users/models.tsx
index 6fa0bfb3e42..c31901b74ad 100644
--- a/src/Components/Users/models.tsx
+++ b/src/Components/Users/models.tsx
@@ -28,6 +28,7 @@ export type UserModel = UserBareMinimum & {
local_body?: number;
district?: number;
state?: number;
+ video_connect_link: string;
phone_number?: string;
alt_phone_number?: string;
gender?: GenderType;
@@ -42,7 +43,7 @@ export type UserModel = UserBareMinimum & {
doctor_qualification?: string;
doctor_experience_commenced_on?: string;
doctor_medical_council_registration?: string;
- weekly_working_hours?: string;
+ weekly_working_hours?: string | null;
};
export interface SkillObjectModel {
@@ -62,6 +63,7 @@ export interface UserAssignedModel extends UserBareMinimum {
state?: number;
phone_number?: string;
alt_phone_number?: string;
+ video_connect_link: string;
gender?: number;
age?: number;
is_superuser?: boolean;
diff --git a/src/Components/VitalsMonitor/utils.ts b/src/Components/VitalsMonitor/utils.ts
index 2e38f83b65b..21ba769dc83 100644
--- a/src/Components/VitalsMonitor/utils.ts
+++ b/src/Components/VitalsMonitor/utils.ts
@@ -1,3 +1,4 @@
+import { AssetClass, AssetData } from "../Assets/AssetTypes";
import { ChannelOptions, VitalsWaveformBase } from "./types";
/**
@@ -73,3 +74,19 @@ export const getVitalsCanvasSizeAndDuration = (
duration: DEFAULT_DURATION * (ratio / DEFAULT_RATIO),
};
};
+
+export const getVitalsMonitorSocketUrl = (asset: AssetData) => {
+ if (
+ asset.asset_class !== AssetClass.HL7MONITOR &&
+ asset.asset_class !== AssetClass.VENTILATOR
+ ) {
+ throw "getVitalsMonitorSocketUrl can be invoked only for HL7MONITOR or VENTILATOR assets";
+ }
+
+ const middleware = asset.resolved_middleware?.hostname;
+ const ipAddress = asset.meta?.local_ip_address;
+
+ if (middleware && ipAddress) {
+ return `wss://${middleware}/observations/${ipAddress}`;
+ }
+};
diff --git a/src/Locale/en/Bed.json b/src/Locale/en/Bed.json
index 7b839c2a384..b410293959b 100644
--- a/src/Locale/en/Bed.json
+++ b/src/Locale/en/Bed.json
@@ -3,5 +3,11 @@
"BED_WITH_OXYGEN_SUPPORT": "Bed with Oxygen Support",
"REGULAR": "Regular",
"ICU": "ICU",
- "ISOLATION": "Isolation"
-}
+ "ISOLATION": "Isolation",
+ "add_beds": "Add Bed(s)",
+ "update_bed": "Update Bed",
+ "bed_type": "Bed Type",
+ "make_multiple_beds_label": "Do you want to make multiple beds?",
+ "number_of_beds": "Number of beds",
+ "number_of_beds_out_of_range_error": "Number of beds cannot be greater than 100"
+}
\ No newline at end of file
diff --git a/src/Locale/en/Common.json b/src/Locale/en/Common.json
index 31528afa390..99adb77451c 100644
--- a/src/Locale/en/Common.json
+++ b/src/Locale/en/Common.json
@@ -84,6 +84,7 @@
"age": "Age",
"is": "Is",
"reason": "Reason",
+ "description": "Description",
"name": "Name",
"address": "Address",
"phone": "Phone",
@@ -160,4 +161,4 @@
"select_date": "Select date",
"DD/MM/YYYY": "DD/MM/YYYY",
"clear_all_filters": "Clear All Filters"
-}
+}
\ No newline at end of file
diff --git a/src/Locale/en/Facility.json b/src/Locale/en/Facility.json
index 5e69f8108af..aefc9c3b4a8 100644
--- a/src/Locale/en/Facility.json
+++ b/src/Locale/en/Facility.json
@@ -33,7 +33,6 @@
"asset_location": "Asset Location",
"asset_type": "Asset Type",
"asset_class": "Asset Class",
- "description": "Description",
"details_about_the_equipment": "Details about the equipment",
"working_status": "Working Status",
"why_the_asset_is_not_working": "Why the asset is not working?",
@@ -53,4 +52,4 @@
"notes": "Notes",
"create_asset": "Create Asset",
"create_add_more": "Create & Add More"
-}
+}
\ No newline at end of file
diff --git a/src/Redux/actions.tsx b/src/Redux/actions.tsx
index ddb392036c6..5caec195cd5 100644
--- a/src/Redux/actions.tsx
+++ b/src/Redux/actions.tsx
@@ -20,18 +20,6 @@ export const getPermittedFacilities = (params: object) => {
return fireRequest("getPermittedFacilities", [], params);
};
-export const getAllFacilities = (params: object) => {
- return fireRequest("getAllFacilities", [], params);
-};
-
-export const getAllSkills = (params: object) => {
- return fireRequest("getAllSkills", [], params);
-};
-
-export const getPermittedFacility = (id: number | string, key?: string) => {
- return fireRequest("getPermittedFacility", [], {}, { id: id }, key);
-};
-
export const getAnyFacility = (id: number | string, key?: string) => {
return fireRequest("getAnyFacility", [], {}, { id: id }, key);
};
@@ -109,11 +97,6 @@ export const deleteAssetBed = (asset_id: string) =>
}
);
-export const listPatientAssetBeds = (
- facility_external_id: string,
- params: object
-) => fireRequest("listPatientAssetBeds", [], params, { facility_external_id });
-
// Facility Beds
export const listFacilityBeds = (params: object) =>
fireRequest("listFacilityBeds", [], params, {});
@@ -227,15 +210,6 @@ export const downloadFacilityTriage = () => {
};
// Capacity/Triage/Doctor
-export const createCapacity = (
- id: number | undefined,
- params: object,
- pathParam: object
-) => {
- return id
- ? fireRequest("updateCapacity", [id], params, pathParam)
- : fireRequest("createCapacity", [], params, pathParam);
-};
export const createDoctor = (
id: number | undefined,
params: object,
@@ -257,26 +231,12 @@ export const getTriageInfo = (pathParam: object) => {
export const getTriageDetails = (pathParam: object) => {
return fireRequest("getTriageDetails", [], {}, pathParam);
};
-export const listCapacity = (params: object, pathParam: object) => {
- return fireRequest("getCapacity", [], params, pathParam);
-};
export const listDoctor = (params: object, pathParam: object) => {
return fireRequest("listDoctor", [], params, pathParam);
};
-export const getCapacity = (id: number, pathParam: object) => {
- return fireRequest("getCapacity", [id], {}, pathParam);
-};
-
-export const getCapacityBed = (pathParam: object) => {
- return fireRequest("getCapacityBed", [], {}, pathParam);
-};
-
export const getDoctor = (pathParam: object) => {
return fireRequest("getDoctor", [], {}, pathParam);
};
-export const deleteCapacity = (pathParam: object) => {
- return fireRequest("deleteCapacityBed", [], {}, pathParam);
-};
//Patient
export const searchPatient = (params: object) => {
@@ -379,10 +339,10 @@ export const createConsultation = (params: object) => {
export const getConsultationList = (params: object) => {
return fireRequest("getConsultationList", [], params);
};
-export const getConsultation = (id: number) => {
+export const getConsultation = (id: string) => {
return fireRequest("getConsultation", [], {}, { id: id });
};
-export const updateConsultation = (id: number, params: object) => {
+export const updateConsultation = (id: string, params: object) => {
return fireRequest("updateConsultation", [], params, { id: id });
};
//Inventory
@@ -589,9 +549,6 @@ export const updateAsset = (id: string, params: object) =>
export const operateAsset = (id: string, params: object) =>
fireRequest("operateAsset", [], params, { external_id: id });
-export const listAssetAvailability = (params: object) =>
- fireRequest("listAssetAvailability", [], params);
-
export const listPMJYPackages = (query?: string) =>
fireRequest("listPMJYPackages", [], { query });
diff --git a/src/Redux/api.tsx b/src/Redux/api.tsx
index a417861a664..4b8488cb11b 100644
--- a/src/Redux/api.tsx
+++ b/src/Redux/api.tsx
@@ -27,6 +27,8 @@ import {
AssetServiceUpdate,
AssetTransaction,
AssetUpdate,
+ AssetUptimeRecord,
+ PatientAssetBed,
} from "../Components/Assets/AssetTypes";
import {
CapacityModal,
@@ -51,6 +53,7 @@ import {
BedModel,
} from "../Components/Facility/models";
import {
+ IDeleteBedCapacity,
IDeleteExternalResult,
IExternalResult,
IExternalResultCsv,
@@ -75,6 +78,10 @@ import {
import { IComment, IResource } from "../Components/Resource/models";
import { IShift } from "../Components/Shifting/models";
import { HCXPolicyModel } from "../Components/HCX/models";
+import {
+ InvestigationGroup,
+ InvestigationType,
+} from "../Components/Facility/Investigations";
/**
* A fake function that returns an empty object casted to type T
@@ -284,6 +291,7 @@ const routes = {
getAllFacilities: {
path: "/api/v1/getallfacilities",
+ TRes: Type >(),
},
createFacility: {
@@ -394,6 +402,7 @@ const routes = {
listPatientAssetBeds: {
path: "/api/v1/facility/{facility_external_id}/patient_asset_beds/",
method: "GET",
+ TRes: Type>(),
},
// Facility Beds
@@ -405,14 +414,19 @@ const routes = {
createFacilityBed: {
path: "/api/v1/bed/",
method: "POST",
+ TBody: Type(),
+ TRes: Type(),
},
getFacilityBed: {
path: "/api/v1/bed/{external_id}/",
method: "GET",
+ TRes: Type(),
},
updateFacilityBed: {
path: "/api/v1/bed/{external_id}/",
method: "PUT",
+ TBody: Type(),
+ TRes: Type(),
},
deleteFacilityBed: {
path: "/api/v1/bed/{external_id}/",
@@ -533,6 +547,7 @@ const routes = {
createCapacity: {
path: "/api/v1/facility/{facilityId}/capacity/",
method: "POST",
+ TRes: Type(),
},
createDoctor: {
@@ -547,11 +562,13 @@ const routes = {
getCapacityBed: {
path: "/api/v1/facility/{facilityId}/capacity/{bed_id}/",
+ TRes: Type(),
},
deleteCapacityBed: {
path: "/api/v1/facility/{facilityId}/capacity/{bed_id}/",
method: "DELETE",
+ TRes: Type(),
},
listDoctor: {
@@ -563,8 +580,9 @@ const routes = {
},
updateCapacity: {
- path: "/api/v1/facility/{facilityId}/capacity",
+ path: "/api/v1/facility/{facilityId}/capacity/{bed_id}/",
method: "PUT",
+ TRes: Type(),
},
updateDoctor: {
@@ -930,10 +948,12 @@ const routes = {
listInvestigations: {
path: "/api/v1/investigation/",
method: "GET",
+ TRes: Type>(),
},
listInvestigationGroups: {
- path: "/api/v1/investigation/group",
+ path: "/api/v1/investigation/group/",
method: "GET",
+ TRes: Type>(),
},
createInvestigation: {
path: "/api/v1/consultation/{consultation_external_id}/investigation/",
@@ -1229,10 +1249,12 @@ const routes = {
listAssetAvailability: {
path: "/api/v1/asset_availability/",
method: "GET",
+ TRes: Type>(),
},
getAssetAvailability: {
path: "/api/v1/asset_availability/{id}",
method: "GET",
+ TRes: Type(),
},
// Prescription endpoints
diff --git a/src/Routers/AppRouter.tsx b/src/Routers/AppRouter.tsx
index 5e238627bc8..56d8b31573b 100644
--- a/src/Routers/AppRouter.tsx
+++ b/src/Routers/AppRouter.tsx
@@ -25,13 +25,13 @@ import AssetRoutes from "./routes/AssetRoutes";
import ResourceRoutes from "./routes/ResourceRoutes";
import ExternalResultRoutes from "./routes/ExternalResultRoutes";
import { DetailRoute } from "./types";
+import useAuthUser from "../Common/hooks/useAuthUser";
const Routes = {
"/": () => ,
...AssetRoutes,
...ConsultationRoutes,
- ...ExternalResultRoutes,
...FacilityRoutes,
...PatientRoutes,
...ResourceRoutes,
@@ -49,6 +49,7 @@ const Routes = {
};
export default function AppRouter() {
+ const authUser = useAuthUser();
const { main_logo, enable_hcx } = useConfig();
let routes = Routes;
@@ -57,6 +58,14 @@ export default function AppRouter() {
routes = { ...routes, ...HCXRoutes };
}
+ if (
+ !["Nurse", "NurseReadOnly", "Staff", "StaffReadOnly"].includes(
+ authUser.user_type
+ )
+ ) {
+ routes = { ...routes, ...ExternalResultRoutes };
+ }
+
useRedirect("/user", "/users");
const pages = useRoutes(routes) || ;
const path = usePath();
diff --git a/src/Utils/request/types.ts b/src/Utils/request/types.ts
index e22d37f3090..aed066ac81c 100644
--- a/src/Utils/request/types.ts
+++ b/src/Utils/request/types.ts
@@ -30,7 +30,7 @@ export interface RequestResult {
export interface RequestOptions {
query?: QueryParams;
body?: TBody;
- pathParams?: Record;
+ pathParams?: Record;
onResponse?: (res: RequestResult) => void;
silent?: boolean;
reattempts?: number;
diff --git a/src/Utils/utils.ts b/src/Utils/utils.ts
index df6bd46d131..c518bcffe7d 100644
--- a/src/Utils/utils.ts
+++ b/src/Utils/utils.ts
@@ -462,3 +462,12 @@ export const compareBy = (key: keyof T) => {
return a[key] < b[key] ? -1 : a[key] > b[key] ? 1 : 0;
};
};
+
+export const isValidUrl = (url?: string) => {
+ try {
+ new URL(url ?? "");
+ return true;
+ } catch {
+ return false;
+ }
+};
|