From 072d70adb5aa7a7047c66f8ac94df3e9a89d87f6 Mon Sep 17 00:00:00 2001 From: felix Date: Sat, 27 Jul 2024 14:56:45 +0300 Subject: [PATCH 1/6] grouped radiology orders by patient --- src/hooks/useOrdersWorklist.ts | 3 +- src/hooks/useSearchGroupedResults.ts | 30 ++ .../approved/approved-orders.component.tsx | 143 +------ .../common/groupedOrdersTable.component.tsx | 185 ++++++++ .../common/listOrderDetails.component.tsx | 308 +++++++++++++ .../common/listOrderDetails.scss | 57 +++ .../common/radiologyProps.resource.ts | 87 ++++ .../orders-not-done.component.tsx | 242 +---------- .../referred-ordered.component.tsx | 157 +------ .../review-ordered.component.tsx | 122 +----- .../test-ordered/tests-ordered.component.tsx | 184 ++------ .../work-list/work-list.component.tsx | 403 +----------------- 12 files changed, 764 insertions(+), 1157 deletions(-) create mode 100644 src/hooks/useSearchGroupedResults.ts create mode 100644 src/radiology-tabs/common/groupedOrdersTable.component.tsx create mode 100644 src/radiology-tabs/common/listOrderDetails.component.tsx create mode 100644 src/radiology-tabs/common/listOrderDetails.scss create mode 100644 src/radiology-tabs/common/radiologyProps.resource.ts diff --git a/src/hooks/useOrdersWorklist.ts b/src/hooks/useOrdersWorklist.ts index e3ecb0b..f277180 100644 --- a/src/hooks/useOrdersWorklist.ts +++ b/src/hooks/useOrdersWorklist.ts @@ -58,7 +58,8 @@ export function useOrdersWorklist( order.concept.conceptClass.uuid === radiologyConceptClass_UUID ); } - }); + }); + const sortedOrders = orders?.sort( (a, b) => new Date(a.dateActivated).getTime() - new Date(b.dateActivated).getTime() diff --git a/src/hooks/useSearchGroupedResults.ts b/src/hooks/useSearchGroupedResults.ts new file mode 100644 index 0000000..46e0a91 --- /dev/null +++ b/src/hooks/useSearchGroupedResults.ts @@ -0,0 +1,30 @@ +import { formatDate, parseDate } from "@openmrs/esm-framework"; +import { useMemo } from "react"; +import { Result } from "../radiology-tabs/work-list/work-list.resource"; +import { GroupedOrders, ListOrdersDetailsProps } from "../radiology-tabs/common/radiologyProps.resource"; + +export function useSearchGroupedResults( + data: GroupedOrders[], + searchString: string +) { + + const searchResults = useMemo(() => { + if (searchString && searchString.trim() !== "") { + const search = searchString.toLowerCase(); + + // Normalize the search string to lowercase + const lowerSearchString = searchString.toLowerCase(); + return data.filter((orderGroup) => + orderGroup.orders.some( + (order) => + order.orderNumber.toLowerCase().includes(lowerSearchString) || + order.patient.display.toLowerCase().includes(lowerSearchString) + ) + ); + } + + return data; + }, [searchString, data]); + + return searchResults; +} diff --git a/src/radiology-tabs/approved/approved-orders.component.tsx b/src/radiology-tabs/approved/approved-orders.component.tsx index 39ecf63..ae60ee4 100644 --- a/src/radiology-tabs/approved/approved-orders.component.tsx +++ b/src/radiology-tabs/approved/approved-orders.component.tsx @@ -1,134 +1,31 @@ import React, { useMemo, useState } from "react"; import { useTranslation } from "react-i18next"; -import { - Table, - TableHead, - TableRow, - TableHeader, - TableBody, - TableCell, - DataTable, - Pagination, - DataTableSkeleton, - TableContainer, - TableToolbar, - TableToolbarContent, - TableToolbarSearch, +import { + DataTableSkeleton, } from "@carbon/react"; import { useOrdersWorklist } from "../../hooks/useOrdersWorklist"; -import { formatDate, parseDate, usePagination } from "@openmrs/esm-framework"; -import { useSearchResults } from "../../hooks/useSearchResults"; -import styles from "../test-ordered/tests-ordered.scss"; +import GroupedOrdersTable from "../common/groupedOrdersTable.component"; export const ApprovedOrders: React.FC = () => { const { t } = useTranslation(); - const [currentPageSize, setCurrentPageSize] = useState(10); const { workListEntries, isLoading } = useOrdersWorklist("", "ON_HOLD"); - const [searchString, setSearchString] = useState(""); - const searchResults = useSearchResults(workListEntries, searchString); - const { - goTo, - results: paginatedResults, - currentPage, - } = usePagination(searchResults, currentPageSize); - - const pageSizes = [10, 20, 30, 40, 50]; - - const rows = useMemo(() => { - return paginatedResults - ?.filter((item) => item.action === "NEW") - .map((entry) => ({ - ...entry, - date: ( - - {formatDate(parseDate(entry?.dateActivated))} - - ), - })); - }, [paginatedResults]); - - const tableColums = [ - { id: 0, header: t("date", "Date"), key: "date" }, - { id: 1, header: t("orderNumber", "Order Number"), key: "orderNumber" }, - { id: 2, header: t("patient", "Patient"), key: "patient" }, - { id: 4, header: t("procedure", "Procedure"), key: "procedure" }, - { id: 5, header: t("orderType", "Order type"), key: "action" }, - { id: 6, header: t("status", "Status"), key: "status" }, - { id: 8, header: t("orderer", "Orderer"), key: "orderer" }, - { id: 9, header: t("urgency", "Urgency"), key: "urgency" }, - ]; - - return isLoading ? ( - - ) : ( -
- - {({ rows, headers, getTableProps, getHeaderProps, getRowProps }) => ( - <> - - - - setSearchString(event.target.value)} - /> - - - - - - {headers.map((header) => ( - - {header.header} - - ))} - - - - {rows.map((row) => ( - - {row.cells.map((cell) => ( - {cell.value} - ))} - - ))} - -
- { - if (pageSize !== currentPageSize) { - setCurrentPageSize(pageSize); - } - if (page !== currentPage) { - goTo(page); - } - }} - /> -
- - )} -
-
- ); + if (isLoading) { + return ; + } + + return ( +
+ +
+ ); + }; diff --git a/src/radiology-tabs/common/groupedOrdersTable.component.tsx b/src/radiology-tabs/common/groupedOrdersTable.component.tsx new file mode 100644 index 0000000..9e5ff24 --- /dev/null +++ b/src/radiology-tabs/common/groupedOrdersTable.component.tsx @@ -0,0 +1,185 @@ +import React, { useMemo, useState } from "react"; +import styles from "./listOrderDetails.scss"; +import { useTranslation } from "react-i18next"; +import { formatDate, parseDate, usePagination } from "@openmrs/esm-framework"; +import { GroupedOrdersTableProps } from "./radiologyProps.resource"; +import { useSearchGroupedResults } from "../../hooks/useSearchGroupedResults"; +import { + Table, + TableHead, + TableRow, + TableHeader, + TableBody, + TableExpandRow, + TableExpandedRow, + TableExpandHeader, + TableCell, + DataTable, + DataTableSkeleton, + Pagination, + OverflowMenu, + OverflowMenuItem, + TableContainer, + TableToolbar, + TableToolbarContent, + TableToolbarSearch, + Tile, + Button, +} from "@carbon/react"; +import ListOrderDetails from "./listOrderDetails.component"; + +// render Grouped by patient Orders in radiology module +const GroupedOrdersTable: React.FC = (props) => { + const workListEntries = props.orders; + const { t } = useTranslation(); + const [currentPageSize, setCurrentPageSize] = useState(10); + const [searchString, setSearchString] = useState(""); + + function groupOrdersById(orders) { + if (orders && orders.length > 0) { + const groupedOrders = orders.reduce((acc, item) => { + if (!acc[item.patient.uuid]) { + acc[item.patient.uuid] = []; + } + acc[item.patient.uuid].push(item); + return acc; + }, {}); + + // Convert the result to an array of objects with patientId and orders + return Object.keys(groupedOrders).map((patientId) => ({ + patientId: patientId, + orders: groupedOrders[patientId], + })); + } else { + return []; + } + } + const groupedOrdersByPatient = groupOrdersById(workListEntries); + const searchResults = useSearchGroupedResults( + groupedOrdersByPatient, + searchString + ); + const { + goTo, + results: paginatedResults, + currentPage, + } = usePagination(searchResults, currentPageSize); + + const pageSizes = [10, 20, 30, 40, 50]; + const [expandedRows] = useState>(new Set()); + + const rowsdata = useMemo(() => { + return paginatedResults.map((patient) => ({ + id: patient.patientId, + patientname: patient.orders[0].patient?.display?.split("-")[1], + orders: patient.orders, + totalorders: patient.orders?.length, + })); + }, [paginatedResults]); + + const tableColumns = [ + { id: 0, header: t("patient", "Patient"), key: "patientname" }, + { id: 1, header: t("totalorders", "Total Orders"), key: "totalorders" }, + ]; + return ( +
+ + {({ rows, headers, getTableProps, getHeaderProps, getRowProps }) => ( + <> + + + + setSearchString(event.target.value)} + /> + + + + + + + {headers.map((header) => ( + + {header.header} + + ))} + + + + {rows.length > 0 ? ( + rows.map((row) => ( + + + {row.cells.map((cell) => ( + + {cell.id.endsWith("created") + ? formatDate(parseDate(cell.value)) + : cell.value} + + ))} + + + item.patientId === row.id + )} + showActions={props.showActions} + showOrderType={props.showOrderType} + showStartButton={props.showStartButton} + showStatus={props.showStatus} + /> + + + )) + ) : ( + + + No Orders Available + + + )} + +
+ { + if (pageSize !== currentPageSize) { + setCurrentPageSize(pageSize); + } + if (page !== currentPage) { + goTo(page); + } + }} + /> +
+ + )} +
+
+ ); +}; + +export default GroupedOrdersTable; diff --git a/src/radiology-tabs/common/listOrderDetails.component.tsx b/src/radiology-tabs/common/listOrderDetails.component.tsx new file mode 100644 index 0000000..da90e43 --- /dev/null +++ b/src/radiology-tabs/common/listOrderDetails.component.tsx @@ -0,0 +1,308 @@ +import React, { useMemo, useState } from "react"; +import styles from "./listOrderDetails.scss"; + +import { useTranslation } from "react-i18next"; +import { formatDate, openmrsFetch, parseDate, restBaseUrl, showModal, showNotification, showSnackbar } from "@openmrs/esm-framework"; +import { Tile } from "@carbon/react"; +import { Button } from "@carbon/react"; +import { + GroupedOrders, + ListOrdersDetailsProps, + OrderAction, +} from "./radiologyProps.resource"; +import { launchOverlay } from "../../components/overlay/hook"; +import ProcedureReportForm from "../../results/result-form.component"; + +// can render orders of a patient +const ListOrderDetails: React.FC = (props) => { + const orders = props.groupedOrders?.orders; + const patientname = orders.length > 0 ? orders[0].patient.display : "--"; + const { t } = useTranslation(); + const orderrows = useMemo(() => { + return orders + ?.filter((item) => item.action === "NEW") + .map((entry) => ({ + ...entry, + id: entry.uuid, + orderNumber: entry.orderNumber, + procedure: entry.display, + status: entry.fulfillerStatus ? entry.fulfillerStatus : "--", + urgency: entry.urgency, + orderer: entry.orderer?.display, + instructions: entry.instructions ? entry.instructions : "--", + date: ( + + {formatDate(parseDate(entry?.dateActivated))} + + ), + })); + }, [orders]); + + const StartOrder = ({ order }) => { + const [buttonStyle, setButtonStyle] = useState({ + backgroundColor: "#cccccc", + width: "10%", + height: "2%", + }); + const [isButtonDisabled, setIsButtonDisabled] = useState(false); + + const handleStartClick = async () => { + const body = { + fulfillerComment: "", + fulfillerStatus: "IN_PROGRESS", + }; + + try { + const response = await openmrsFetch( + `${restBaseUrl}/order/${order.uuid}/fulfillerdetails`, + { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify(body), + } + ); + + if (response.status === 201) { + // Check for successful POST + showSnackbar({ + isLowContrast: true, + title: t( + "statusUpdatedSuccessfully", + "Status updated successfully" + ), + kind: "success", + }); + + // Update button style on successful POST + setButtonStyle({ + backgroundColor: "#90EE90", + width: "10%", + height: "2%", + }); + + setIsButtonDisabled(true); + } else { + const errorData = await response.json(); + showNotification({ + title: t("errorUpdatingStatus", "Error updating status"), + kind: "error", + critical: true, + description: errorData.message || "Failed to update status", + }); + } + } catch (error) { + showNotification({ + title: t("errorUpdatingStatus", "Error updating status"), + kind: "error", + critical: true, + description: "Error updating status: " + error.message, + }); + } + }; + + return ( +
+ +
+ ); + }; + + + + + return ( +
+ {orderrows.map((row) => ( + + {props.showActions && ( +
+ {props.actions.map((action) => { + if (action.actionName === "add-radiology-to-worklist-dialog") { + return ( + + ); + } + if (action.actionName === "procedureReportForm") { + return ( + + ); + } + if (action.actionName === "review-radilogy-report-dialog") { + return ( + + ); + } + if (action.actionName === "radiology-reject-reason-modal") { + return ( + + ); + } + if (action.actionName === "reject-radiology-order-dialog") { + return ( + + ); + } + })} +
+ )} +
+
+

+ + {t("date", "DATE").toUpperCase()} + + {" : "} + {row.date} +

+
+ +
+

+ + {t("orderNumber", "Order Number").toUpperCase()} + + {" : "} + {row.orderNumber} +

+
+ +
+

+ + {t("procedure", "procedure").toUpperCase()} + + {" : "} + {row.procedure} +

+
+ + {props.showStatus && ( +
+

+ + {t("status", "Status").toUpperCase()} + + {" : "} + {row.status} +

+
+ )} + +
+

+ + {t("urgency", "urgency").toUpperCase()} + + {" : "} + {row.urgency} +

+
+ +
+

+ + {t("orderer", "orderer").toUpperCase()} + + {" : "} + {row.orderer} +

+
+ +
+

+ + {t("instructions", "Instructions").toUpperCase()} + + {" : "} + {row.instructions} +

+
+ + {props.showStartButton && ( +
+ +
+ )} +
+
+ ))} +
+ ); +}; + +export default ListOrderDetails; diff --git a/src/radiology-tabs/common/listOrderDetails.scss b/src/radiology-tabs/common/listOrderDetails.scss new file mode 100644 index 0000000..418ab0f --- /dev/null +++ b/src/radiology-tabs/common/listOrderDetails.scss @@ -0,0 +1,57 @@ +@use '../../../node_modules/@carbon/styles/scss/spacing'; +@use '../../../node_modules/@carbon/styles/scss/type/index'; +@import "../../../node_modules/@openmrs/esm-styleguide/src/vars"; + +.orderTile { + width: 100%; + margin: 2px 0 8px; + padding: 0 8px 0 8px; + background-color: #fff; + border-left: 4px solid var(--brand-03); + color: $text-02; + margin-bottom: 1rem !important; +} + +.ordersContainer { + display: flex; + flex-direction: column; + max-width: 100%; + margin-bottom: 1rem; + + &:global(.cds--tile) { + min-height: 3rem !important; + padding-left: 10px !important; + } +} + +.ordersContainer > :global(.cds--tile) { + min-height: 3rem !important; + padding-left: 10px !important; + margin: auto; +} + +.orderPropertyDisplay { + font-size: 15px !important; + } + + .bodyLong01 { + font-size: 13px !important; + } + + .displayValue { + color: #525252; + font-weight: bold; + } + + .actionBtns { + float: right; + margin-left: 1rem; + margin-top: 2rem; + } + .noOrdersDiv{ + background-color: #fff; + text-align: center; + font-weight:bold; + width: 100%; + } + \ No newline at end of file diff --git a/src/radiology-tabs/common/radiologyProps.resource.ts b/src/radiology-tabs/common/radiologyProps.resource.ts new file mode 100644 index 0000000..fe9d3dc --- /dev/null +++ b/src/radiology-tabs/common/radiologyProps.resource.ts @@ -0,0 +1,87 @@ +import React, { useState, useMemo, useCallback } from "react"; +import { useTranslation } from "react-i18next"; +import { Information, Microscope, TrashCan } from "@carbon/react/icons"; + +import { + DataTable, + DataTableSkeleton, + Pagination, + Table, + TableBody, + TableCell, + TableContainer, + TableHead, + TableHeader, + TableRow, + TableToolbar, + TableToolbarContent, + TableToolbarSearch, + Layer, + Tag, + Button, + Tile, + DatePicker, + DatePickerInput, + Tooltip, +} from "@carbon/react"; +import { Result } from "../work-list/work-list.resource"; +import styles from "./work-list.scss"; +import { + ConfigurableLink, + formatDate, + parseDate, + showModal, + usePagination, + showSnackbar, + showNotification, + openmrsFetch, + restBaseUrl, +} from "@openmrs/esm-framework"; +import { launchOverlay } from "../../components/overlay/hook"; +import Overlay from "../../components/overlay/overlay.component"; +import ProcedureReportForm from "../../results/result-form.component"; +import { getStatusColor } from "../../utils/functions"; +import { useOrdersWorklist } from "../../hooks/useOrdersWorklist"; + +export interface WorklistProps { + fulfillerStatus: string; +} + +export interface ResultsOrderProps { + order: Result; + patientUuid: string; +} + +export interface RejectOrderProps { + order: Result; +} + +export interface InstructionsProps { + order: Result; +} + +export interface GroupedOrders { + patientId: string; + orders: Result[]; +} +export interface GroupedOrdersTableProps { + orders: Result[]; + showStatus:boolean; + showStartButton:boolean; + showActions:boolean; + showOrderType:boolean; + actions:OrderAction[]; +} + +export interface ListOrdersDetailsProps { + groupedOrders: GroupedOrders + showStatus:boolean; + showStartButton:boolean; + showActions:boolean; + showOrderType:boolean; + actions:OrderAction[]; +} + +export interface OrderAction{ + actionName:string; +} \ No newline at end of file diff --git a/src/radiology-tabs/orders-not-done/orders-not-done.component.tsx b/src/radiology-tabs/orders-not-done/orders-not-done.component.tsx index f43dc2e..c62aeb2 100644 --- a/src/radiology-tabs/orders-not-done/orders-not-done.component.tsx +++ b/src/radiology-tabs/orders-not-done/orders-not-done.component.tsx @@ -1,259 +1,39 @@ import React, { useMemo, useState, useCallback } from "react"; import { useTranslation } from "react-i18next"; -import { Information } from "@carbon/react/icons"; import { - Table, - TableHead, - TableRow, - TableHeader, - TableBody, - TableCell, - DataTable, DataTableSkeleton, - Pagination, - TableContainer, - TableToolbar, - TableToolbarContent, - TableToolbarSearch, - Button, - Tooltip, - Layer, - Tag, - Tile, - DatePicker, - DatePickerInput, } from "@carbon/react"; import { useOrdersWorklist } from "../../hooks/useOrdersWorklist"; -import { - formatDate, - parseDate, - usePagination, - showModal, - ConfigurableLink, -} from "@openmrs/esm-framework"; -import { useSearchResults } from "../../hooks/useSearchResults"; import styles from "../test-ordered/tests-ordered.scss"; -interface RejectionProps { - order: Result; -} -import { Result } from "../work-list/work-list.resource"; -import { getStatusColor } from "../../utils/functions"; import Overlay from "../../components/overlay/overlay.component"; +import GroupedOrdersTable from "../common/groupedOrdersTable.component"; interface NotDoneProps { fulfillerStatus: string; } export const OrdersNotDone: React.FC = ({ fulfillerStatus }) => { const { t } = useTranslation(); - const [currentPageSize, setCurrentPageSize] = useState(10); const { workListEntries, isLoading, mutate } = useOrdersWorklist( "", fulfillerStatus ); - const [searchString, setSearchString] = useState(""); const [activatedOnOrAfterDate, setActivatedOnOrAfterDate] = useState(""); - const searchResults = useSearchResults(workListEntries, searchString); - const { - goTo, - results: paginatedResults, - currentPage, - } = usePagination(workListEntries, currentPageSize); - - const pageSizes = [10, 20, 30, 40, 50]; - - const tableColums = [ - { id: 0, header: t("date", "Date"), key: "date" }, - { id: 1, header: t("orderNumber", "Order Number"), key: "orderNumber" }, - { id: 2, header: t("patient", "Patient"), key: "patient" }, - { id: 4, header: t("procedure", "Procedure"), key: "procedure" }, - { id: 5, header: t("status", "Status"), key: "status" }, - { - id: 6, - header: t("fulfillerComment", "Reason Not Done"), - key: "fulfillerComment", - }, - { id: 7, header: t("urgency", "Urgency"), key: "urgency" }, - { id: 8, header: t("orderer", "Orderer"), key: "orderer" }, - ]; - - const rows = useMemo(() => { - const RejectionReason: React.FC = ({ order }) => { - const launchProcedureRejectionModal = useCallback(() => { - const dispose = showModal("radiology-reject-reason-modal", { - closeModal: () => dispose(), - order, - }); - }, [order]); - return ( - - ); - }; - const { - goTo, - results: paginatedResults, - currentPage, - } = usePagination(searchResults, currentPageSize); - - const pageSizes = [10, 20, 30, 40, 50]; - - const rows = useMemo(() => { - return paginatedResults - ?.filter((item) => item.action === "NEW") - .map((entry) => ({ - ...entry, - date: ( - - {formatDate(parseDate(entry?.dateActivated))} - - ), - actions: , - })); - }, [paginatedResults]); - - const tableColums = [ - { id: 0, header: t("date", "Date"), key: "date" }, - { id: 1, header: t("orderNumber", "Order Number"), key: "orderNumber" }, - { id: 2, header: t("patient", "Patient"), key: "patient" }, - { id: 4, header: t("procedure", "Procedure"), key: "procedure" }, - { id: 5, header: t("orderType", "Order type"), key: "action" }, - { id: 8, header: t("orderer", "Orderer"), key: "orderer" }, - { id: 9, header: t("urgency", "Urgency"), key: "urgency" }, - { id: 9, header: t("actions", "Actions"), key: "actions" }, - ]; return isLoading ? ( ) : (
- - {({ rows, headers, getTableProps, getHeaderProps, getRowProps }) => ( - <> - - - - setSearchString(event.target.value)} - /> - - - - - - {headers.map((header) => ( - - {header.header} - - ))} - - - - {rows.map((row) => ( - - {row.cells.map((cell) => ( - {cell.value} - ))} - - ))} - -
- { - if (pageSize !== currentPageSize) { - setCurrentPageSize(pageSize); - } - if (page !== currentPage) { - goTo(page); - } - }} - /> -
- - )} -
+
); }; diff --git a/src/radiology-tabs/test-ordered/tests-ordered.component.tsx b/src/radiology-tabs/test-ordered/tests-ordered.component.tsx index 48cc7fd..17d4c3a 100644 --- a/src/radiology-tabs/test-ordered/tests-ordered.component.tsx +++ b/src/radiology-tabs/test-ordered/tests-ordered.component.tsx @@ -6,6 +6,9 @@ import { TableRow, TableHeader, TableBody, + TableExpandRow, + TableExpandedRow, + TableExpandHeader, TableCell, DataTable, DataTableSkeleton, @@ -18,171 +21,32 @@ import { TableToolbarSearch, } from "@carbon/react"; import { useOrdersWorklist } from "../../hooks/useOrdersWorklist"; -import styles from "./tests-ordered.scss"; -interface RejectOrderOverflowMenuItemProps { - order: any; -} -import { - formatDate, - parseDate, - showModal, - usePagination, -} from "@openmrs/esm-framework"; -import { useSearchResults } from "../../hooks/useSearchResults"; -import PickRadiologyLabRequestActionMenu from "./pick-radiology-lab-request-menu.component"; -import RadiologyInstructionsActionMenu from "./radiology-instructions/radiology-instructions-menu.component"; +import GroupedOrdersTable from "../common/groupedOrdersTable.component"; -const RejectOrderMenuItem: React.FC = ({ - order, -}) => { - const handleRejectOrderModel = useCallback(() => { - const dispose = showModal("reject-radiology-order-dialog", { - closeModal: () => dispose(), - order, - }); - }, [order]); - return ( - - ); -}; export const TestsOrdered: React.FC = () => { const { t } = useTranslation(); - const [currentPageSize, setCurrentPageSize] = useState(10); const { workListEntries, isLoading } = useOrdersWorklist("", ""); const [searchString, setSearchString] = useState(""); - const searchResults = useSearchResults(workListEntries, searchString); - - const { - goTo, - results: paginatedResults, - currentPage, - } = usePagination(searchResults, currentPageSize); - - const pageSizes = [10, 20, 30, 40, 50]; - const [expandedRows] = useState>(new Set()); - - const rows = useMemo(() => { - return paginatedResults - ?.filter((item) => item.action === "NEW") - .map((entry) => ({ - ...entry, - date: ( - - {formatDate(parseDate(entry?.dateActivated))} - - ), - actions: ( - - true} - order={entry} - /> - - true} - /> - - ), - })); - }, [paginatedResults]); - - const tableColumns = [ - { id: 0, header: t("date", "Date"), key: "date" }, - { id: 1, header: t("orderNumber", "Order Number"), key: "orderNumber" }, - { id: 2, header: t("patient", "Patient"), key: "patient" }, - { id: 4, header: t("procedure", "Procedure"), key: "procedure" }, - { id: 6, header: t("status", "Status"), key: "status" }, - { id: 9, header: t("urgency", "Urgency"), key: "urgency" }, - { id: 8, header: t("orderer", "Orderer"), key: "orderer" }, - { id: 10, header: t("actions", "Actions"), key: "actions" }, - ]; - - return isLoading ? ( - - ) : ( -
- - {({ rows, headers, getTableProps, getHeaderProps, getRowProps }) => ( - <> - - - - setSearchString(event.target.value)} - /> - - - - - - {headers.map((header) => ( - - {header.header} - - ))} - - - - {rows.map((row) => ( - - - {row.cells.map((cell) => ( - {cell.value} - ))} - - {expandedRows.has(row.id) && ( - - - - )} - - ))} - -
- { - if (pageSize !== currentPageSize) { - setCurrentPageSize(pageSize); - } - if (page !== currentPage) { - goTo(page); - } - }} - /> -
- - )} -
-
- ); + if (isLoading) { + return ; + } + if (workListEntries.length > 0) { + return ( +
+ +
+ ); + } }; diff --git a/src/radiology-tabs/work-list/work-list.component.tsx b/src/radiology-tabs/work-list/work-list.component.tsx index 8fc3c13..a4a32a0 100644 --- a/src/radiology-tabs/work-list/work-list.component.tsx +++ b/src/radiology-tabs/work-list/work-list.component.tsx @@ -2,63 +2,16 @@ import React, { useState, useMemo, useCallback } from "react"; import { useTranslation } from "react-i18next"; import { Information, Microscope, TrashCan } from "@carbon/react/icons"; -import { - DataTable, - DataTableSkeleton, - Pagination, - Table, - TableBody, - TableCell, - TableContainer, - TableHead, - TableHeader, - TableRow, - TableToolbar, - TableToolbarContent, - TableToolbarSearch, - Layer, - Tag, - Button, - Tile, - DatePicker, - DatePickerInput, - Tooltip, +import { + DataTableSkeleton, } from "@carbon/react"; -import { Result } from "./work-list.resource"; import styles from "./work-list.scss"; -import { - ConfigurableLink, - formatDate, - parseDate, - showModal, - usePagination, - showSnackbar, - showNotification, - openmrsFetch, - restBaseUrl, -} from "@openmrs/esm-framework"; -import { launchOverlay } from "../../components/overlay/hook"; import Overlay from "../../components/overlay/overlay.component"; -import ProcedureReportForm from "../../results/result-form.component"; -import { getStatusColor } from "../../utils/functions"; import { useOrdersWorklist } from "../../hooks/useOrdersWorklist"; - -interface WorklistProps { - fulfillerStatus: string; -} - -interface ResultsOrderProps { - order: Result; - patientUuid: string; -} - -interface RejectOrderProps { - order: Result; -} - -interface InstructionsProps { - order: Result; -} +import { + WorklistProps, +} from "../common/radiologyProps.resource"; +import GroupedOrdersTable from "../common/groupedOrdersTable.component"; const WorkList: React.FC = ({ fulfillerStatus }) => { const { t } = useTranslation(); @@ -70,346 +23,26 @@ const WorkList: React.FC = ({ fulfillerStatus }) => { fulfillerStatus ); - const pageSizes = [5, 10, 15, 20, 25, 30, 35, 40, 45, 50]; - const [currentPageSize, setPageSize] = useState(10); - - const { - goTo, - results: paginatedWorkListEntries, - currentPage, - } = usePagination(workListEntries, currentPageSize); - - const RejectOrder: React.FC = ({ order }) => { - const launchRejectOrderModal = useCallback(() => { - const dispose = showModal("reject-radiology-order-dialog", { - closeModal: () => { - mutate(); - dispose(); - }, - order, - }); - }, [order]); - return ( - - - ); - }; - - // get picked orders - const columns = [ - { id: 0, header: t("date", "Date"), key: "date" }, - - { id: 1, header: t("orderNumber", "Order Number"), key: "orderNumber" }, - { id: 2, header: t("patient", "Patient"), key: "patient" }, - { id: 4, header: t("procedure", "Procedure"), key: "procedure" }, - { id: 6, header: t("status", "Status"), key: "status" }, - { id: 8, header: t("orderer", "Orderer"), key: "orderer" }, - { id: 9, header: t("urgency", "Urgency"), key: "urgency" }, - { id: 10, header: t("start", "Start"), key: "start" }, - { id: 11, header: t("actions", "Actions"), key: "actions" }, - ]; - - const tableRows = useMemo(() => { - const ResultsOrder: React.FC = ({ - order, - patientUuid, - }) => { - return ( - - ); - } - if (action.actionName === "procedureReportForm") { - return ( - - ); - } - if (action.actionName === "review-radilogy-report-dialog") { - return ( - - ); - } - if (action.actionName === "radiology-reject-reason-modal") { - return ( - - ); - } - if (action.actionName === "reject-radiology-order-dialog") { - return ( - - ); - } - })} + {props.actions + .sort((a, b) => { + // Replace 'property' with the actual property you want to sort by + if (a.displayPosition < b.displayPosition) return -1; + if (a.displayPosition > b.displayPosition) return 1; + return 0; + }) + .map((action) => { + if ( + action.actionName === "add-radiology-to-worklist-dialog" + ) { + return ( + + ); + } + if (action.actionName === "procedureReportForm") { + return ( + + ); + } + if (action.actionName === "review-radilogy-report-dialog") { + return ( + + ); + } + if (action.actionName === "radiology-reject-reason-modal") { + return ( + + ); + } + if (action.actionName === "reject-radiology-order-dialog") { + return ( + + ); + } + })} )}
diff --git a/src/radiology-tabs/common/listOrderDetails.scss b/src/radiology-tabs/common/listOrderDetails.scss index e21b77e..644b8b5 100644 --- a/src/radiology-tabs/common/listOrderDetails.scss +++ b/src/radiology-tabs/common/listOrderDetails.scss @@ -52,22 +52,4 @@ float: right; margin-left: 1rem; margin-top: 2rem; - } - .noOrdersDiv{ - background-color: #fff; - text-align: center; - font-weight:bold; - width: 100%; - } - - .ordersTableToolbar{ - position: static; - height: 3rem; - overflow: visible; - margin: 0; - } - - .ordersToolbarSearchBar{ - background-color:#f4f4f4 ; - } - \ No newline at end of file + } \ No newline at end of file diff --git a/src/radiology-tabs/common/orderDetail.component.tsx b/src/radiology-tabs/common/orderDetail.component.tsx index 0b529b7..25b06ae 100644 --- a/src/radiology-tabs/common/orderDetail.component.tsx +++ b/src/radiology-tabs/common/orderDetail.component.tsx @@ -1,5 +1,5 @@ import React from "react"; -import styles from "./listOrderDetails.scss"; +import styles from "./orderDetail.scss"; export const OrderDetail: React.FC<{ label: string; value: string | any }> = ({ label, diff --git a/src/radiology-tabs/common/orderDetail.scss b/src/radiology-tabs/common/orderDetail.scss new file mode 100644 index 0000000..592dc15 --- /dev/null +++ b/src/radiology-tabs/common/orderDetail.scss @@ -0,0 +1,15 @@ +@use '@carbon/layout'; +@use '@carbon/colors'; +@use '@openmrs/esm-styleguide/src/vars' as *; + + .bodyLong01 { + font-size: 13px !important; + } + + .displayValue { + color: #525252; + font-weight: bold; + width: layout.$spacing-05; + height: layout.$spacing-05; + } + \ No newline at end of file diff --git a/src/radiology-tabs/common/radiologyProps.resource.ts b/src/radiology-tabs/common/radiologyProps.resource.ts index 1bf66c7..831a28d 100644 --- a/src/radiology-tabs/common/radiologyProps.resource.ts +++ b/src/radiology-tabs/common/radiologyProps.resource.ts @@ -41,4 +41,5 @@ export interface ListOrdersDetailsProps { export interface OrderAction { actionName: string; + displayPosition: 0 | number; } diff --git a/src/radiology-tabs/orders-not-done/orders-not-done.component.tsx b/src/radiology-tabs/orders-not-done/orders-not-done.component.tsx index f76caeb..a13c2ca 100644 --- a/src/radiology-tabs/orders-not-done/orders-not-done.component.tsx +++ b/src/radiology-tabs/orders-not-done/orders-not-done.component.tsx @@ -9,7 +9,6 @@ interface NotDoneProps { } export const OrdersNotDone: React.FC = ({ fulfillerStatus }) => { const { workListEntries, isLoading } = useOrdersWorklist("", fulfillerStatus); - const [activatedOnOrAfterDate, setActivatedOnOrAfterDate] = useState(""); if (isLoading) { return ; @@ -25,7 +24,12 @@ export const OrdersNotDone: React.FC = ({ fulfillerStatus }) => { showStartButton={false} showActions={true} showOrderType={false} - actions={[{ actionName: "radiology-reject-reason-modal" }]} + actions={[ + { + actionName: "radiology-reject-reason-modal", + displayPosition: 1, + }, + ]} />
diff --git a/src/radiology-tabs/referred-test/referred-ordered.component.tsx b/src/radiology-tabs/referred-test/referred-ordered.component.tsx index b4f654e..fab10d3 100644 --- a/src/radiology-tabs/referred-test/referred-ordered.component.tsx +++ b/src/radiology-tabs/referred-test/referred-ordered.component.tsx @@ -1,15 +1,10 @@ -import React, { useMemo, useState } from "react"; +import React from "react"; import { useTranslation } from "react-i18next"; -import { - DataTableSkeleton, - OverflowMenu, - OverflowMenuItem, -} from "@carbon/react"; +import { DataTableSkeleton } from "@carbon/react"; import { useOrdersWorklist } from "../../hooks/useOrdersWorklist"; import GroupedOrdersTable from "../common/groupedOrdersTable.component"; export const ReferredTests: React.FC = () => { - const { t } = useTranslation(); const { workListEntries, isLoading } = useOrdersWorklist("", "EXCEPTION"); return isLoading ? ( diff --git a/src/radiology-tabs/review-ordered/review-ordered.component.tsx b/src/radiology-tabs/review-ordered/review-ordered.component.tsx index 530eb26..759e0c4 100644 --- a/src/radiology-tabs/review-ordered/review-ordered.component.tsx +++ b/src/radiology-tabs/review-ordered/review-ordered.component.tsx @@ -16,7 +16,9 @@ export const Review: React.FC = () => { showStartButton={false} showActions={true} showOrderType={true} - actions={[{ actionName: "review-radilogy-report-dialog" }]} + actions={[ + { actionName: "review-radilogy-report-dialog", displayPosition: 1 }, + ]} /> ); diff --git a/src/radiology-tabs/test-ordered/radiology-instructions/radiology-instructions.component.tsx b/src/radiology-tabs/test-ordered/radiology-instructions/radiology-instructions.component.tsx index faebbb5..1ca1c33 100644 --- a/src/radiology-tabs/test-ordered/radiology-instructions/radiology-instructions.component.tsx +++ b/src/radiology-tabs/test-ordered/radiology-instructions/radiology-instructions.component.tsx @@ -1,4 +1,4 @@ -import React, { useState } from "react"; +import React from "react"; import { Button, ModalBody, diff --git a/src/radiology-tabs/test-ordered/tests-ordered.component.tsx b/src/radiology-tabs/test-ordered/tests-ordered.component.tsx index e41fbf9..9562601 100644 --- a/src/radiology-tabs/test-ordered/tests-ordered.component.tsx +++ b/src/radiology-tabs/test-ordered/tests-ordered.component.tsx @@ -20,8 +20,11 @@ export const TestsOrdered: React.FC = () => { showActions={true} showOrderType={false} actions={[ - { actionName: "add-radiology-to-worklist-dialog" }, - { actionName: "reject-radiology-order-dialog" }, + { + actionName: "add-radiology-to-worklist-dialog", + displayPosition: 1, + }, + { actionName: "reject-radiology-order-dialog", displayPosition: 2 }, ]} /> diff --git a/src/radiology-tabs/work-list/work-list.component.tsx b/src/radiology-tabs/work-list/work-list.component.tsx index e05cb19..26d6644 100644 --- a/src/radiology-tabs/work-list/work-list.component.tsx +++ b/src/radiology-tabs/work-list/work-list.component.tsx @@ -31,8 +31,11 @@ const WorkList: React.FC = ({ fulfillerStatus }) => { showActions={true} showOrderType={false} actions={[ - { actionName: "reject-radiology-order-dialog" }, - { actionName: "procedureReportForm" }, + { actionName: "procedureReportForm", displayPosition: 1 }, + { + actionName: "reject-radiology-order-dialog", + displayPosition: 2, + }, ]} />