From 05a36979489fe879df89de7b0468035d1c4a8dde Mon Sep 17 00:00:00 2001 From: jabahum Date: Wed, 10 Jul 2024 16:28:35 +0300 Subject: [PATCH] schedule orders ui --- src/index.ts | 6 + ...schedulue-test-orders-dialog.component.tsx | 229 ++++++++++++++++++ .../pick-lab-request-menu.component.tsx | 1 - .../schedule-test-orders.component.tsx | 28 +++ .../tests-ordered-list.component.tsx | 11 +- .../patient-test-orders.component.tsx | 101 ++++---- .../patient-test-orders.scss | 1 + src/routes.json | 53 ++-- 8 files changed, 354 insertions(+), 76 deletions(-) create mode 100644 src/ordered-orders/lab-dialogs/schedulue-test-orders-dialog.component.tsx create mode 100644 src/ordered-orders/schedule-test-orders.component.tsx diff --git a/src/index.ts b/src/index.ts index 03ec8f7b..4bf7fe15 100644 --- a/src/index.ts +++ b/src/index.ts @@ -6,6 +6,7 @@ import laboratoryReferralWorkspaceComponent from "./patient-chart/laboratory-wor import laboratory from "./laboratory.component"; import laboratoryOrder from "./patient-chart/patient-laboratory-order-results.component"; import addToWorklist from "./ordered-orders/lab-dialogs/add-to-worklist-dialog.component"; +import scheduleTestOrders from "./ordered-orders/lab-dialogs/schedulue-test-orders-dialog.component"; import sendEmail from "./patient-chart/results-summary/send-email-dialog.component"; import reviewItemDialogComponent from "./reviewed-orders/dialog/review-item.component"; import rejectOrderDialogComponent from "./reject-order/reject-order-dialog.component"; @@ -70,6 +71,11 @@ export const laboratoryOrderComponent = getSyncLifecycle( export const addToWorklistDialog = getSyncLifecycle(addToWorklist, options); +export const scheduleTestOrdersDialog = getSyncLifecycle( + scheduleTestOrders, + options +); + export const sendEmailDialog = getSyncLifecycle(sendEmail, options); export const reviewItemDialog = getSyncLifecycle( diff --git a/src/ordered-orders/lab-dialogs/schedulue-test-orders-dialog.component.tsx b/src/ordered-orders/lab-dialogs/schedulue-test-orders-dialog.component.tsx new file mode 100644 index 00000000..a58e24c9 --- /dev/null +++ b/src/ordered-orders/lab-dialogs/schedulue-test-orders-dialog.component.tsx @@ -0,0 +1,229 @@ +import React, { useMemo, useState } from "react"; +import { + Button, + Form, + ModalBody, + ModalFooter, + ModalHeader, + DataTable, + Table, + TableBody, + TableCell, + TableContainer, + TableHead, + TableHeader, + TableRow, + Select, + SelectItem, + TextInput, +} from "@carbon/react"; +import { Order } from "@openmrs/esm-patient-common-lib"; +import { useTranslation } from "react-i18next"; +import styles from "./add-to-worklist-dialog.scss"; +import { + showNotification, + showSnackbar, + useLayoutType, +} from "@openmrs/esm-framework"; +import { + GenerateSpecimenId, + useReferralLocations, + useSpecimenTypes, +} from "./add-to-worklist-dialog.resource"; +import { extractErrorMessagesFromResponse } from "../../utils/functions"; +interface ScheduleTestOrdersDialogProps { + orders: Order[]; + closeModal: () => void; +} + +const ScheduleTestOrdersDialog: React.FC = ({ + orders, + closeModal, +}) => { + const { t } = useTranslation(); + const isTablet = useLayoutType() === "tablet"; + + const { specimenTypes } = useSpecimenTypes(); + const { referrals } = useReferralLocations(); + + const [specimenType, setSpecimenType] = useState(); + const [selectedReferral, setSelectedReferral] = useState(""); + const [specimenID, setSpecimenID] = useState(""); + + const tableHeaders = useMemo( + () => [ + { id: 0, header: t("test", "Test"), key: "test" }, + { id: 1, header: t("specimenId", "Specimen ID"), key: "specimenId" }, + { + id: 2, + header: t("specimenSource", "Specimen Source"), + key: "specimenSource", + }, + { id: 3, header: t("referralLab", "Referral Lab"), key: "referralLab" }, + ], + [t] + ); + + const tableRows = useMemo(() => { + return orders?.map((order) => ({ + ...order, + id: order.uuid, + test: order.display, + specimenId: ( +
+ setSpecimenID(e.target.value)} + /> +
+ ), + specimenSource: ( + + ), + referralLab: ( + + ), + })); + }, [orders]); + + const generateId = async (e, uuid: string) => { + e.preventDefault(); + GenerateSpecimenId(uuid).then( + (resp) => { + setSpecimenID(resp.data.results[0].sampleId); + showSnackbar({ + isLowContrast: true, + title: t("generatesampleID", "Generate Sample Id"), + kind: "success", + subtitle: t( + "generateSuccessfully", + "You have successfully generated a Sample Id" + ), + }); + }, + (error) => { + const errorMessages = extractErrorMessagesFromResponse(error); + + showNotification({ + title: t(`errorGeneratingId', 'Error Generating Sample Id`), + kind: "error", + critical: true, + description: errorMessages.join(", "), + }); + } + ); + }; + + return ( +
+
+ + +
+
+ +
+ + + {({ + rows, + headers, + getHeaderProps, + getRowProps, + getTableProps, + getTableContainerProps, + }) => ( + + + + + {headers.map((header) => ( + + {header.header} + + ))} + + + + {rows.map((row) => ( + + {row.cells.map((cell) => ( + + {cell.value} + + ))} + + ))} + +
+
+ )} +
+
+
+ + + + + +
+ ); +}; + +export default ScheduleTestOrdersDialog; diff --git a/src/ordered-orders/pick-lab-request-menu.component.tsx b/src/ordered-orders/pick-lab-request-menu.component.tsx index 354f47e0..cb89ea25 100644 --- a/src/ordered-orders/pick-lab-request-menu.component.tsx +++ b/src/ordered-orders/pick-lab-request-menu.component.tsx @@ -13,7 +13,6 @@ const PickLabRequestActionMenu: React.FC = ({ order, }) => { const { t } = useTranslation(); - const launchPickLabRequestModal = useCallback(() => { const dispose = showModal("add-to-worklist-dialog", { closeModal: () => dispose(), diff --git a/src/ordered-orders/schedule-test-orders.component.tsx b/src/ordered-orders/schedule-test-orders.component.tsx new file mode 100644 index 00000000..c0628aed --- /dev/null +++ b/src/ordered-orders/schedule-test-orders.component.tsx @@ -0,0 +1,28 @@ +import { Button } from "@carbon/react"; +import { showModal } from "@openmrs/esm-framework"; +import { Order } from "@openmrs/esm-patient-common-lib"; +import React, { useCallback } from "react"; + +interface ScheduleTestOrdersButtonProps { + orders: Order[]; + closeModal: () => void; +} + +const ScheduleTestOrdersButton: React.FC = ({ + orders, +}) => { + const launchPickLabRequestModal = useCallback(() => { + const dispose = showModal("schedule-test-orders-dialog", { + orders, + closeModal: () => dispose(), + }); + }, [orders]); + + return ( + + ); +}; + +export default ScheduleTestOrdersButton; diff --git a/src/ordered-orders/tests-ordered-list.component.tsx b/src/ordered-orders/tests-ordered-list.component.tsx index 85772e36..f2d8165f 100644 --- a/src/ordered-orders/tests-ordered-list.component.tsx +++ b/src/ordered-orders/tests-ordered-list.component.tsx @@ -35,12 +35,11 @@ const TestsOrderedList: React.FC = () => { const isTablet = useLayoutType() === "tablet"; const locations = useLocations(); - const { patientQueueEntries, isLoading, isError, mutate } = - usePatientQueuesList( - session?.sessionLocation?.uuid, - status, - session.user.systemId - ); + const { patientQueueEntries, isLoading, isError } = usePatientQueuesList( + session?.sessionLocation?.uuid, + status, + session.user.systemId + ); const pageSizes = [10, 20, 30, 40, 50]; const [currentPageSize, setPageSize] = useState(10); diff --git a/src/patient-test-orders/patient-test-orders.component.tsx b/src/patient-test-orders/patient-test-orders.component.tsx index 34fe636d..3a0d6140 100644 --- a/src/patient-test-orders/patient-test-orders.component.tsx +++ b/src/patient-test-orders/patient-test-orders.component.tsx @@ -9,18 +9,17 @@ import { TableHead, TableHeader, TableRow, + TableSelectAll, + TableSelectRow, } from "@carbon/react"; import { OverflowMenuVertical } from "@carbon/react/icons"; import { useTranslation } from "react-i18next"; -import { - ExtensionSlot, - useConfig, - useLayoutType, -} from "@openmrs/esm-framework"; +import { ExtensionSlot, useLayoutType } from "@openmrs/esm-framework"; import { usePatientLabOrders } from "./patient-test-orders.resource"; import styles from "./patient-test-orders.scss"; import OrderCustomOverflowMenuComponent from "../ui-components/overflow-menu.component"; +import ScheduleTestOrdersButton from "../ordered-orders/schedule-test-orders.component"; interface TestOrderProps { patientUuid: string; @@ -75,48 +74,62 @@ const TestOrders: React.FC = ({ patientUuid }) => { } return ( -
- - {({ - rows, - headers, - getHeaderProps, - getRowProps, - getTableProps, - getTableContainerProps, - }) => ( - - - - - {headers.map((header) => ( - - {header.header} - - ))} - - - - {rows.map((row) => ( - - {row.cells.map((cell) => ( - - {cell.value} - + <> +
+ + {({ + rows, + headers, + getHeaderProps, + getRowProps, + getTableProps, + getTableContainerProps, + getSelectionProps, + }) => ( + +
+ + + + {headers.map((header) => ( + + {header.header} + ))} - ))} - -
-
+ + + {rows.map((row) => ( + + + {row.cells.map((cell) => ( + + {cell.value} + + ))} + + ))} + + + + )} +
+
+
+ {orders.length > 0 && ( + true} /> )} - -
+ + ); }; diff --git a/src/patient-test-orders/patient-test-orders.scss b/src/patient-test-orders/patient-test-orders.scss index ea10c145..0bb1da66 100644 --- a/src/patient-test-orders/patient-test-orders.scss +++ b/src/patient-test-orders/patient-test-orders.scss @@ -8,6 +8,7 @@ flex-direction: column; justify-content: space-between; border: 1px solid colors.$gray-20; + margin-top: 1rem; border-bottom: none; } diff --git a/src/routes.json b/src/routes.json index 086161db..883c8f36 100644 --- a/src/routes.json +++ b/src/routes.json @@ -48,6 +48,10 @@ "name": "add-to-worklist-dialog", "component": "addToWorklistDialog" }, + { + "name": "schedule-test-orders-dialog", + "component": "scheduleTestOrdersDialog" + }, { "name": "results-summary", "component": "resultsSummaryWorkSpace" @@ -105,13 +109,13 @@ } }, { - "name": "rejected-panel-component", - "slot": "lab-panels-slot", - "component": "rejectedComponent", - "meta": { - "name": "rejectedPanelSlot", - "title": "Rejected List" - } + "name": "rejected-panel-component", + "slot": "lab-panels-slot", + "component": "rejectedComponent", + "meta": { + "name": "rejectedPanelSlot", + "title": "Rejected List" + } }, { "name": "tests-ordered-tile-component", @@ -122,16 +126,15 @@ "title": "Ordered Tests" } }, - - { - "name": "worklist-tile-component", - "slot": "lab-tiles-slot", - "component": "worklistTileComponent", - "meta": { - "name": "worklisTileSlot", - "title": "Work List" - } - }, + { + "name": "worklist-tile-component", + "slot": "lab-tiles-slot", + "component": "worklistTileComponent", + "meta": { + "name": "worklisTileSlot", + "title": "Work List" + } + }, { "name": "completed-tile-component", "slot": "lab-tiles-slot", @@ -142,13 +145,13 @@ } }, { - "name": "rejected-tile-component", - "slot": "lab-tiles-slot", - "component": "rejectedTileComponent", - "meta": { - "name": "rejectedTileSlot", - "title": "Rejected Tests" - } + "name": "rejected-tile-component", + "slot": "lab-tiles-slot", + "component": "rejectedTileComponent", + "meta": { + "name": "rejectedTileSlot", + "title": "Rejected Tests" + } }, { "name": "referred-tile-component", @@ -170,4 +173,4 @@ "slot": "order-actions-slot" } ] -} +} \ No newline at end of file