diff --git a/cypress/e2e/users_spec/user_homepage.cy.ts b/cypress/e2e/users_spec/user_homepage.cy.ts index a006fe77569..3ac07dd9d9c 100644 --- a/cypress/e2e/users_spec/user_homepage.cy.ts +++ b/cypress/e2e/users_spec/user_homepage.cy.ts @@ -32,6 +32,7 @@ describe("User Homepage", () => { userPage.selectDistrict("Ernakulam"); userPage.typeInPhoneNumber(phone_number); userPage.typeInAltPhoneNumber(alt_phone_number); + userPage.selectHomeFacility("Dummy Facility 40"); userPage.applyFilter(); userPage.verifyUrlafteradvancefilter(); userPage.checkUsernameText(usernameToTest); @@ -46,6 +47,10 @@ describe("User Homepage", () => { "WhatsApp no.: +919876543219", ); userPage.verifyDataTestIdText("Role", "Role: Doctor"); + userPage.verifyDataTestIdText( + "Home Facility", + "Home Facility: Dummy Facility 40", + ); userPage.verifyDataTestIdText("District", "District: Ernakulam"); userPage.clearFilters(); userPage.verifyDataTestIdNotVisible("First Name"); @@ -53,6 +58,7 @@ describe("User Homepage", () => { userPage.verifyDataTestIdNotVisible("Phone Number"); userPage.verifyDataTestIdNotVisible("WhatsApp no."); userPage.verifyDataTestIdNotVisible("Role"); + userPage.verifyDataTestIdNotVisible("Home Facility"); userPage.verifyDataTestIdNotVisible("District"); }); diff --git a/cypress/pageobject/Users/UserSearch.ts b/cypress/pageobject/Users/UserSearch.ts index 7d85563d62c..56d1a81395d 100644 --- a/cypress/pageobject/Users/UserSearch.ts +++ b/cypress/pageobject/Users/UserSearch.ts @@ -78,6 +78,10 @@ export class UserPage { cy.get("#alt_phone_number").click().type(altPhone); } + selectHomeFacility(facility: string) { + cy.searchAndSelectOption("input[name='home_facility']", facility); + } + applyFilter() { cy.get("#apply-filter").click(); } diff --git a/src/CAREUI/misc/AuthorizedChild.tsx b/src/CAREUI/misc/AuthorizedChild.tsx index ce9ec69d546..935f0c51f3c 100644 --- a/src/CAREUI/misc/AuthorizedChild.tsx +++ b/src/CAREUI/misc/AuthorizedChild.tsx @@ -1,4 +1,7 @@ +import { ReactNode } from "react"; +import useAuthUser from "../../Common/hooks/useAuthUser"; import { useIsAuthorized } from "../../Common/hooks/useIsAuthorized"; +import useSlug from "../../Common/hooks/useSlug"; import { AuthorizedForCB } from "../../Utils/AuthorizeFor"; interface Props { @@ -12,3 +15,20 @@ const AuthorizedChild = (props: Props) => { }; export default AuthorizedChild; + +export const AuthorizedForConsultationRelatedActions = (props: { + children: ReactNode; +}) => { + const me = useAuthUser(); + const facilityId = useSlug("facility"); + + if ( + me.home_facility_object?.id === facilityId || + me.user_type === "DistrictAdmin" || + me.user_type === "StateAdmin" + ) { + return props.children; + } + + return null; +}; diff --git a/src/Common/constants.tsx b/src/Common/constants.tsx index de0ab305f48..4eb3b51d012 100644 --- a/src/Common/constants.tsx +++ b/src/Common/constants.tsx @@ -318,42 +318,6 @@ export const REVIEW_AT_CHOICES: Array = [ { id: 30 * 24 * 60, text: "1 month" }, ]; -export const SYMPTOM_CHOICES = [ - { id: 1, text: "ASYMPTOMATIC", isSingleSelect: true }, - { id: 2, text: "FEVER" }, - { id: 3, text: "SORE THROAT" }, - { id: 4, text: "COUGH" }, - { id: 5, text: "BREATHLESSNESS" }, - { id: 6, text: "MYALGIA" }, - { id: 7, text: "ABDOMINAL DISCOMFORT" }, - { id: 8, text: "VOMITING" }, - { id: 11, text: "SPUTUM" }, - { id: 12, text: "NAUSEA" }, - { id: 13, text: "CHEST PAIN" }, - { id: 14, text: "HEMOPTYSIS" }, - { id: 15, text: "NASAL DISCHARGE" }, - { id: 16, text: "BODY ACHE" }, - { id: 17, text: "DIARRHOEA" }, - { id: 18, text: "PAIN" }, - { id: 19, text: "PEDAL EDEMA" }, - { id: 20, text: "WOUND" }, - { id: 21, text: "CONSTIPATION" }, - { id: 22, text: "HEAD ACHE" }, - { id: 23, text: "BLEEDING" }, - { id: 24, text: "DIZZINESS" }, - { id: 25, text: "CHILLS" }, - { id: 26, text: "GENERAL WEAKNESS" }, - { id: 27, text: "IRRITABILITY" }, - { id: 28, text: "CONFUSION" }, - { id: 29, text: "ABDOMINAL PAIN" }, - { id: 30, text: "JOINT PAIN" }, - { id: 31, text: "REDNESS OF EYES" }, - { id: 32, text: "ANOREXIA" }, - { id: 33, text: "NEW LOSS OF TASTE" }, - { id: 34, text: "NEW LOSS OF SMELL" }, - { id: 9, text: "OTHERS" }, -]; - export const DISCHARGE_REASONS = [ { id: 1, text: "Recovered" }, { id: 2, text: "Referred" }, @@ -1308,7 +1272,7 @@ export const CONSENT_PATIENT_CODE_STATUS_CHOICES = [ { id: 1, text: "Do Not Hospitalise (DNH)" }, { id: 2, text: "Do Not Resuscitate (DNR)" }, { id: 3, text: "Comfort Care Only" }, - { id: 4, text: "Active treatment (Default)" }, + { id: 4, text: "Active treatment" }, ]; export const OCCUPATION_TYPES = [ { @@ -1404,3 +1368,5 @@ export const PATIENT_NOTES_THREADS = { Doctors: 10, Nurses: 20, } as const; + +export const RATION_CARD_CATEGORY = ["BPL", "APL", "NO_CARD"] as const; diff --git a/src/Common/hooks/useMSEplayer.ts b/src/Common/hooks/useMSEplayer.ts index 482f991bc25..39e4d356910 100644 --- a/src/Common/hooks/useMSEplayer.ts +++ b/src/Common/hooks/useMSEplayer.ts @@ -149,7 +149,6 @@ export const useMSEMediaPlayer = ({ const ws = wsRef.current; ws.binaryType = "arraybuffer"; ws.onopen = function (_event) { - console.log("Connected to ws"); onSuccess && onSuccess(undefined); }; ws.onmessage = function (event) { diff --git a/src/Components/CameraFeed/AssetBedSelect.tsx b/src/Components/CameraFeed/AssetBedSelect.tsx index 17701dccbde..715c326c35d 100644 --- a/src/Components/CameraFeed/AssetBedSelect.tsx +++ b/src/Components/CameraFeed/AssetBedSelect.tsx @@ -1,39 +1,67 @@ import { Fragment } from "react"; -import useSlug from "../../Common/hooks/useSlug"; -import routes from "../../Redux/api"; -import useQuery from "../../Utils/request/useQuery"; -import { AssetBedModel, AssetData } from "../Assets/AssetTypes"; -import { BedModel } from "../Facility/models"; +import { AssetBedModel } from "../Assets/AssetTypes"; import { Listbox, Transition } from "@headlessui/react"; import CareIcon from "../../CAREUI/icons/CareIcon"; +import { classNames } from "../../Utils/utils"; interface Props { - asset?: AssetData; - bed?: BedModel; + options: AssetBedModel[]; value?: AssetBedModel; + label?: (value: AssetBedModel) => string; onChange?: (value: AssetBedModel) => void; } -export default function AssetBedSelect(props: Props) { - const facility = useSlug("facility"); - - const { data, loading } = useQuery(routes.listAssetBeds, { - query: { - limit: 100, - facility, - asset: props.asset?.id, - bed: props.bed?.id, - }, - }); +export default function CameraPresetSelect(props: Props) { + const label = props.label ?? defaultLabel; + return ( + <> +
+ {/* Desktop View */} + {props.options + .slice(0, props.options.length > 5 ? 4 : 5) + .map((option) => ( + + ))} + {props.options.length > 5 && ( + + )} +
+
+ {/* Mobile View */} + +
+ + ); +} +export const CameraPresetDropdown = (props: Props) => { const selected = props.value; + const options = props.options.filter(({ meta }) => meta.type !== "boundary"); + + const label = props.label ?? defaultLabel; + return ( - -
- - - {selected?.bed_object.name ?? "No Preset"} + +
+ + + {selected ? label(selected) : "Select preset"} @@ -46,7 +74,7 @@ export default function AssetBedSelect(props: Props) { leaveTo="opacity-0" > - {data?.results.map((obj) => ( + {options?.map((obj) => ( @@ -63,7 +91,7 @@ export default function AssetBedSelect(props: Props) { selected ? "font-bold text-white" : "font-normal" }`} > - {obj.bed_object.name}: {obj.meta.preset_name} + {label(obj)} )} @@ -74,4 +102,8 @@ export default function AssetBedSelect(props: Props) {
); -} +}; + +const defaultLabel = ({ bed_object, meta }: AssetBedModel) => { + return `${bed_object.name}: ${meta.preset_name}`; +}; diff --git a/src/Components/CameraFeed/CameraFeed.tsx b/src/Components/CameraFeed/CameraFeed.tsx index d5ea120e126..81b526363b9 100644 --- a/src/Components/CameraFeed/CameraFeed.tsx +++ b/src/Components/CameraFeed/CameraFeed.tsx @@ -10,6 +10,8 @@ import FeedNetworkSignal from "./FeedNetworkSignal"; import NoFeedAvailable from "./NoFeedAvailable"; import FeedControls from "./FeedControls"; import Fullscreen from "../../CAREUI/misc/Fullscreen"; +import FeedWatermark from "./FeedWatermark"; +import CareIcon from "../../CAREUI/icons/CareIcon"; interface Props { children?: React.ReactNode; @@ -24,6 +26,7 @@ interface Props { // Controls constrolsDisabled?: boolean; shortcutsDisabled?: boolean; + onMove?: () => void; } export default function CameraFeed(props: Props) { @@ -76,7 +79,7 @@ export default function CameraFeed(props: Props) { }, onError: props.onStreamError, }); - }, [player.initializeStream, props.onStreamSuccess, props.onStreamError]); + }, [player.initializeStream]); // Start stream on mount useEffect(() => initializeStream(), [initializeStream]); @@ -85,18 +88,22 @@ export default function CameraFeed(props: Props) { setState("loading"); initializeStream(); }; - return ( setFullscreen(false)}>
-
+ {props.children} +
+ {props.asset.name}
@@ -108,12 +115,12 @@ export default function CameraFeed(props: Props) { />
- {props.children}
{/* Notifications */} + {player.status === "playing" && } {/* No Feed informations */} {state === "host_unreachable" && ( @@ -144,6 +151,7 @@ export default function CameraFeed(props: Props) { url={streamUrl} ref={playerRef.current as LegacyRef} controls={false} + pip={false} playsinline playing muted @@ -161,10 +169,12 @@ export default function CameraFeed(props: Props) {
) : (