Skip to content

Commit

Permalink
ft: add worklist dialog setup (#5)
Browse files Browse the repository at this point in the history
* fix : rename list component

* ft: add worklist set up

* ft : set worklist creation

* fix: add tests ordered empty state

* fix : empty state message
  • Loading branch information
jabahum authored Sep 26, 2023
1 parent f6223d5 commit 6703172
Show file tree
Hide file tree
Showing 15 changed files with 558 additions and 6 deletions.
6 changes: 6 additions & 0 deletions src/config-schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,15 @@ export const configSchema = {
_default: "Laboratory",
_description: "Location tag for laboratory locations.",
},
laboratorySpecimenTypeConcept: {
_type: Type.ConceptUuid,
_default: "159959AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
_description: "Concept UUID for laboratory specimen types",
},
};

export type Config = {
laboratoryQueueConcept: string;
laboratoryLocationTag: string;
laboratorySpecimenTypeConcept: string;
};
5 changes: 5 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,11 @@ export const laboratoryOrderComponent = getAsyncLifecycle(
options
);

export const addToWorklistDialog = getAsyncLifecycle(
() => import("./queue-list/lab-dialogs/add-to-worklist-dialog.component"),
options
);

export function startupApp() {
defineConfigSchema(moduleName, configSchema);
}
232 changes: 232 additions & 0 deletions src/queue-list/lab-dialogs/add-to-worklist-dialog.component.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,232 @@
import React, { useCallback, useEffect, useState } from "react";
import { MappedQueueEntry } from "../../types";
import {
Button,
ContentSwitcher,
Form,
ModalBody,
ModalFooter,
ModalHeader,
Select,
SelectItem,
Switch,
TextArea,
Grid,
Checkbox,
TextInput,
IconButton,
} from "@carbon/react";
import { useTranslation } from "react-i18next";
import { MappedPatientQueueEntry } from "../laboratory-patient-list.resource";
import styles from "./add-to-worklist-dialog.scss";
import {
navigate,
showNotification,
showToast,
useLocations,
useSession,
} from "@openmrs/esm-framework";
import { Renew } from "@carbon/react/icons";
import {
useQueueRoomLocations,
useSpecimenTypes,
} from "./add-to-worklist-dialog.resource";

interface AddToWorklistDialogProps {
queueEntry: MappedPatientQueueEntry;
closeModal: () => void;
}

const AddToWorklistDialog: React.FC<AddToWorklistDialogProps> = ({
queueEntry,
closeModal,
}) => {
const { t } = useTranslation();

const locations = useLocations();

const sessionUser = useSession();

const [selectedLocation, setSelectedLocation] = useState("");

const [preferred, setPreferred] = useState(false);

const { specimenTypes } = useSpecimenTypes();

const { queueRoomLocations } = useQueueRoomLocations(
sessionUser?.sessionLocation?.uuid
);

const [specimenType, setSpecimenType] = useState("");
const [selectedNextQueueLocation, setSelectedNextQueueLocation] = useState(
queueRoomLocations[0]?.uuid
);

const filteredlocations = queueRoomLocations?.filter(
(location) => location.uuid != selectedLocation
);

useEffect(() => {
if (locations?.length && sessionUser) {
setSelectedLocation(sessionUser?.sessionLocation?.uuid);
}
}, [locations, sessionUser]);

const pickLabRequestQueue = useCallback((event) => {
event.preventDefault();
}, []);

const onChecked = () => {
setPreferred(!preferred);
};

const GenerateID = () => {
return (
<IconButton>
<Renew />
</IconButton>
);
};
if (queueEntry && Object.keys(queueEntry)?.length > 0) {
return (
<div>
<Form onSubmit={pickLabRequestQueue}>
<ModalHeader
closeModal={closeModal}
title={t("pickRequest", "Pick Lab Request")}
/>
<ModalBody>
<div className={styles.modalBody}>
<h4 className={styles.section}>
Currently Picked : {queueEntry.name}
</h4>
<section className={styles.section}>
<div
style={{
display: "flex",
alignItems: "center",
justifyContent: "space-between",
alignContent: "stretch",
}}
>
<div className={styles.sectionTitle}>
{t("specimenID", "Specimen ID")}
</div>

<div
style={{
display: "flex",
alignItems: "center",
justifyContent: "space-between",
columnGap: "10px",
}}
>
<div style={{ width: "430px" }}>
<TextInput type="text" id="specimentID" />
</div>
<div style={{ width: "50px" }}>
<GenerateID />
</div>
</div>
</div>
</section>
<section className={styles.section}>
<div
style={{
display: "flex",
alignItems: "center",
justifyContent: "space-between",
alignContent: "stretch",
}}
>
<div className={styles.sectionTitle}>
{t("specimenType", "Specimen Type")}
</div>
<div style={{ width: "500px" }}>
<section className={styles.section}>
<Select
labelText=" Specimen Type"
id="speciment-types"
name="specimen-types"
invalidText="Required"
>
{!specimenType ? (
<SelectItem
text={t("specimenType", "Select Specimen Type")}
value=""
/>
) : null}
{specimenTypes.map((type) => (
<SelectItem
key={type.uuid}
text={type.display}
value={type.uuid}
>
{type.display}
</SelectItem>
))}
</Select>
</section>
</div>
</div>
</section>
<section
style={{
display: "flex",
alignItems: "center",
justifyContent: "space-between",
alignContent: "stretch",
}}
>
<div>
<Checkbox
checked={preferred}
onChange={onChecked}
labelText={"Referred"}
id="test-referred"
/>
</div>
{preferred && (
<div style={{ width: "500px" }}>
<section className={styles.section}>
<Select
labelText={t("location", "Location ")}
id="nextQueueLocation"
name="nextQueueLocation"
invalidText="Required"
value={selectedNextQueueLocation}
onChange={(event) =>
setSelectedNextQueueLocation(event.target.value)
}
>
{filteredlocations.map((location) => (
<SelectItem
key={location.uuid}
text={location.display}
value={location.uuid}
>
{location.display}
</SelectItem>
))}
</Select>
</section>
</div>
)}
</section>
</div>
</ModalBody>
<ModalFooter>
<Button kind="secondary" onClick={closeModal}>
{t("cancel", "Cancel")}
</Button>
<Button type="submit">
{t("pickPatient", "Pick Lab Request")}
</Button>
</ModalFooter>
</Form>
</div>
);
}
};

export default AddToWorklistDialog;
119 changes: 119 additions & 0 deletions src/queue-list/lab-dialogs/add-to-worklist-dialog.resource.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
import { FetchResponse, openmrsFetch, useConfig } from "@openmrs/esm-framework";
import { useMemo } from "react";
import useSWR from "swr";
import useSWRImmutable from "swr/immutable";

export interface QueueRoomsResponse {
uuid: string;
display: string;
name: string;
description: string;
address1: string;
address2: string;
cityvillage: string;
stateprovince: string;
country: string;
postalcode: string;
latitude: string;
longitude: string;
countydistrict: string;
address3: string;
address4: string;
address5: string;
address6: string;
parentLocation: ParentLocation;
childLocations: String[];
retired: boolean;
attributes: String[];
address7: string;
address8: string;
address9: string;
address10: string;
address11: string;
address12: string;
address13: string;
address14: string;
address15: string;
resourceVersion: string;
}

export interface ParentLocation {
uuid: string;
display: string;
name: string;
description: string;
address1: string;
address2: string;
cityVillage: string;
stateProvince: string;
country: string;
postalcode: string;
latitude: string;
longitude: string;
countydistrict: string;
address3: string;
address4: string;
address5: string;
address6: string;
parentLocation: ParentLocation;
childLocations: ChildLocations[];
retired: boolean;
attributes: String[];
address7: string;
address8: string;
address9: string;
address10: string;
address11: string;
address12: string;
address13: string;
address14: string;
address15: string;
resourceversion: string;
}

export interface ChildLocations {
uuid: string;
display: string;
}

export interface ParentLocation {
uuid: string;
display: string;
}

export function useQueueRoomLocations(currentQueueLocation: string) {
const apiUrl = `/ws/rest/v1/location/${currentQueueLocation}?v=full`;
const { data, error, isLoading } = useSWR<{ data: QueueRoomsResponse }>(
apiUrl,
openmrsFetch
);

const queueRoomLocations = useMemo(
() =>
data?.data?.parentLocation?.childLocations?.map((response) => response) ??
[],
[data?.data?.parentLocation?.childLocations]
);
return {
queueRoomLocations: queueRoomLocations ? queueRoomLocations : [],
isLoading,
error,
};
}

// get specimen types
export function useSpecimenTypes() {
const config = useConfig();
const { laboratorySpecimenTypeConcept } = config;

const apiUrl = `/ws/rest/v1/concept/${laboratorySpecimenTypeConcept}`;
const { data, error, isLoading } = useSWRImmutable<FetchResponse>(
apiUrl,
openmrsFetch
);

return {
specimenTypes: data ? data?.data?.answers : [],
isLoading,
};
}
Loading

0 comments on commit 6703172

Please sign in to comment.