Skip to content

Commit

Permalink
Merge branch 'develop' into doctors-log-update
Browse files Browse the repository at this point in the history
  • Loading branch information
khavinshankar authored May 28, 2024
2 parents 4c1c035 + 54a3244 commit 9205375
Show file tree
Hide file tree
Showing 65 changed files with 3,253 additions and 1,159 deletions.
6 changes: 6 additions & 0 deletions cypress/e2e/users_spec/user_homepage.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -46,13 +47,18 @@ 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");
userPage.verifyDataTestIdNotVisible("Last Name");
userPage.verifyDataTestIdNotVisible("Phone Number");
userPage.verifyDataTestIdNotVisible("WhatsApp no.");
userPage.verifyDataTestIdNotVisible("Role");
userPage.verifyDataTestIdNotVisible("Home Facility");
userPage.verifyDataTestIdNotVisible("District");
});

Expand Down
4 changes: 4 additions & 0 deletions cypress/pageobject/Users/UserSearch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}
Expand Down
20 changes: 20 additions & 0 deletions src/CAREUI/misc/AuthorizedChild.tsx
Original file line number Diff line number Diff line change
@@ -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 {
Expand All @@ -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;
};
40 changes: 3 additions & 37 deletions src/Common/constants.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -318,42 +318,6 @@ export const REVIEW_AT_CHOICES: Array<OptionsType> = [
{ 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" },
Expand Down Expand Up @@ -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 = [
{
Expand Down Expand Up @@ -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;
1 change: 0 additions & 1 deletion src/Common/hooks/useMSEplayer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
84 changes: 58 additions & 26 deletions src/Components/CameraFeed/AssetBedSelect.tsx
Original file line number Diff line number Diff line change
@@ -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 (
<>
<div className="hidden gap-2 whitespace-nowrap pr-2 md:flex">
{/* Desktop View */}
{props.options
.slice(0, props.options.length > 5 ? 4 : 5)
.map((option) => (
<button
className={classNames(
"rounded-xl border px-2 py-0.5 text-xs transition-all duration-200 ease-in-out hover:bg-zinc-600",
props.value?.id === option.id
? "border-white bg-zinc-100 font-bold text-black"
: "border-white/50 text-zinc-100",
)}
onClick={() => props.onChange?.(option)}
>
{label(option)}
</button>
))}
{props.options.length > 5 && (
<CameraPresetDropdown {...props} options={props.options.slice(4)} />
)}
</div>
<div className="md:hidden">
{/* Mobile View */}
<CameraPresetDropdown {...props} />
</div>
</>
);
}

export const CameraPresetDropdown = (props: Props) => {
const selected = props.value;

const options = props.options.filter(({ meta }) => meta.type !== "boundary");

const label = props.label ?? defaultLabel;

return (
<Listbox value={selected} onChange={props.onChange} disabled={loading}>
<div className="relative">
<Listbox.Button className="relative w-full cursor-default pr-6 text-right text-xs text-zinc-400 focus:outline-none disabled:cursor-not-allowed disabled:bg-transparent disabled:text-zinc-700 sm:text-sm">
<span className="block truncate">
{selected?.bed_object.name ?? "No Preset"}
<Listbox value={selected} onChange={props.onChange}>
<div className="relative flex-1">
<Listbox.Button className="relative w-full cursor-default pr-6 text-left text-xs text-white focus:outline-none disabled:cursor-not-allowed disabled:bg-transparent disabled:text-zinc-700 sm:text-sm md:pl-2">
<span
className={classNames(
"block truncate",
!selected && "text-gray-500",
)}
>
{selected ? label(selected) : "Select preset"}
</span>
<span className="pointer-events-none absolute inset-y-0 right-0 mt-1 flex items-center">
<CareIcon icon="l-angle-down" className="text-lg text-zinc-500" />
Expand All @@ -46,7 +74,7 @@ export default function AssetBedSelect(props: Props) {
leaveTo="opacity-0"
>
<Listbox.Options className="absolute z-20 mt-1 max-h-48 w-full overflow-auto rounded-b-lg bg-zinc-900/75 py-1 text-base shadow-lg ring-1 ring-white/5 backdrop-blur-sm focus:outline-none sm:text-sm md:max-h-60">
{data?.results.map((obj) => (
{options?.map((obj) => (
<Listbox.Option
key={obj.id}
className={({ active }) =>
Expand All @@ -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)}
</span>
</>
)}
Expand All @@ -74,4 +102,8 @@ export default function AssetBedSelect(props: Props) {
</div>
</Listbox>
);
}
};

const defaultLabel = ({ bed_object, meta }: AssetBedModel) => {
return `${bed_object.name}: ${meta.preset_name}`;
};
21 changes: 16 additions & 5 deletions src/Components/CameraFeed/CameraFeed.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -24,6 +26,7 @@ interface Props {
// Controls
constrolsDisabled?: boolean;
shortcutsDisabled?: boolean;
onMove?: () => void;
}

export default function CameraFeed(props: Props) {
Expand Down Expand Up @@ -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]);
Expand All @@ -85,18 +88,22 @@ export default function CameraFeed(props: Props) {
setState("loading");
initializeStream();
};

return (
<Fullscreen fullscreen={isFullscreen} onExit={() => setFullscreen(false)}>
<div
className={classNames(
"flex flex-col overflow-clip rounded-xl bg-black",
"flex max-h-screen flex-col overflow-clip rounded-xl bg-black",
props.className,
)}
>
<div className="flex items-center justify-between bg-zinc-900 px-4 py-0.5">
<div className="flex items-center gap-1 md:gap-2">
{props.children}
<div className="flex w-full items-center justify-end gap-1 md:gap-4">
<span className="text-xs font-semibold text-white md:text-sm">
<CareIcon
icon="l-video"
className="hidden pr-2 text-base text-zinc-400 md:inline-block"
/>
{props.asset.name}
</span>
<div className={state === "loading" ? "animate-pulse" : ""}>
Expand All @@ -108,12 +115,12 @@ export default function CameraFeed(props: Props) {
/>
</div>
</div>
{props.children}
</div>

<div className="group relative aspect-video">
{/* Notifications */}
<FeedAlert state={state} />
{player.status === "playing" && <FeedWatermark />}

{/* No Feed informations */}
{state === "host_unreachable" && (
Expand Down Expand Up @@ -144,6 +151,7 @@ export default function CameraFeed(props: Props) {
url={streamUrl}
ref={playerRef.current as LegacyRef<ReactPlayer>}
controls={false}
pip={false}
playsinline
playing
muted
Expand All @@ -161,10 +169,12 @@ export default function CameraFeed(props: Props) {
</div>
) : (
<video
onContextMenu={(e) => e.preventDefault()}
className="absolute inset-0 w-full"
id="mse-video"
autoPlay
muted
disablePictureInPicture
playsInline
onPlay={player.onPlayCB}
onEnded={() => player.setStatus("stop")}
Expand All @@ -180,6 +190,7 @@ export default function CameraFeed(props: Props) {
setFullscreen={setFullscreen}
onReset={resetStream}
onMove={async (data) => {
props.onMove?.();
setState("moving");
const { res } = await operate({ type: "relative_move", data });
setTimeout(() => {
Expand Down
24 changes: 18 additions & 6 deletions src/Components/CameraFeed/CameraFeedWithBedPresets.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,23 @@
import { useState } from "react";
import { AssetBedModel, AssetData } from "../Assets/AssetTypes";
import CameraFeed from "./CameraFeed";
import AssetBedSelect from "./AssetBedSelect";
import useQuery from "../../Utils/request/useQuery";
import routes from "../../Redux/api";
import useSlug from "../../Common/hooks/useSlug";
import { CameraPresetDropdown } from "./AssetBedSelect";

interface Props {
asset: AssetData;
}

export default function LocationFeedTile(props: Props) {
const facility = useSlug("facility");
const [preset, setPreset] = useState<AssetBedModel>();

const { data, loading } = useQuery(routes.listAssetBeds, {
query: { limit: 100, facility, asset: props.asset?.id },
});

return (
<CameraFeed
asset={props.asset}
Expand All @@ -18,11 +26,15 @@ export default function LocationFeedTile(props: Props) {
shortcutsDisabled
>
<div className="w-64">
<AssetBedSelect
asset={props.asset}
value={preset}
onChange={setPreset}
/>
{loading ? (
<span>loading presets...</span>
) : (
<CameraPresetDropdown
options={data?.results ?? []}
value={preset}
onChange={setPreset}
/>
)}
</div>
</CameraFeed>
);
Expand Down
Loading

0 comments on commit 9205375

Please sign in to comment.