import React, { useState, useEffect, useCallback } from 'react'; import { useTranslation } from 'react-i18next'; import { mutate } from 'swr'; import { ExtensionSlot, parseDate, formatDate, useLayoutType, usePatient, getPatientName, setCurrentVisit, launchWorkspaceGroup, useVisit, showToast, } from '@openmrs/esm-framework'; import { getPatientChartStore } from '@openmrs/esm-patient-common-lib'; import { Table, TableHead, TableRow, TableHeader, TableBody, TableCell, DataTableSkeleton, DataTable, TextAreaSkeleton, Button, Accordion, AccordionItem, } from '@carbon/react'; import capitalize from 'lodash-es/capitalize'; import { useParams } from 'react-router-dom'; import { Close, FolderOpen } from '@carbon/react/icons'; import { usePatientOrders } from './search.resource'; import { type Result } from '../work-list/work-list.resource'; import ActionButton from '../../shared/ui/common/action-button/action-button.component'; import { getActionsForStatus, IMAGING_ORDERS_API_URL } from './action-helpers'; import EmptyPatientSearch from './empty-search/empty-patient-search.component'; import styles from './imaging-order-search.scss'; const ImagingOrderSearch: React.FC = () => { const params = useParams<{ patientUuid: string }>(); const [patientUuid, setPatientUuid] = useState(params.patientUuid); const { orders = [], isLoading } = usePatientOrders(patientUuid); const [selectedOrder, setSelectedOrder] = useState(undefined); useEffect(() => { setPatientUuid(params.patientUuid); setSelectedOrder(undefined); }, [params.patientUuid]); const handlePatientClose = () => { if (selectedOrder) { setSelectedOrder(undefined); } else { setPatientUuid(undefined); } }; // Component mapping for the different views const views = { empty: EmptyPatientSearch, orderList: () => ( <> ), orderDetails: () => ( <> ), }; const getCurrentView = () => { if (!patientUuid) return 'empty'; if (selectedOrder) return 'orderDetails'; return 'orderList'; }; const CurrentView = views[getCurrentView()]; return (
); }; export default ImagingOrderSearch; type OrderTableProps = { imagingOrders: Array; isLoading: boolean; handleSelectOrder: (order: Result) => void; patientUuid: string; }; const OrdersTable: React.FC = ({ patientUuid, imagingOrders, isLoading, handleSelectOrder }) => { const { t } = useTranslation(); const responseSize = useLayoutType() === 'tablet' ? 'md' : 'sm'; const { activeVisit, isLoading: isLoadingVisits } = useVisit(patientUuid); const launchAddImagingOrderWorkspace = useCallback( (patientUuid: string) => { if (!activeVisit) { showToast({ kind: 'error', title: 'No active visit', description: 'Start a visit to add an imaging order.', }); return; } setCurrentVisit(patientUuid, activeVisit.uuid); launchWorkspaceGroup('add-imaging-order-workspace-group', { state: { patientUuid, }, onWorkspaceGroupLaunch: () => { const store = getPatientChartStore(); store.setState({ patientUuid, }); }, workspaceToLaunch: { name: 'add-imaging-order', }, workspaceGroupCleanup: () => { mutate((key) => typeof key === 'string' && key.startsWith(IMAGING_ORDERS_API_URL), undefined, { revalidate: true, }); const store = getPatientChartStore(); store.setState({ patientUuid: undefined, }); setCurrentVisit(null, null); }, }); }, [patientUuid, activeVisit], ); if (imagingOrders.length === 0 && !isLoading && !isLoadingVisits) { return ( <> {activeVisit ? ( launchAddImagingOrderWorkspace(patientUuid)} buttonText={t('addImagingOrder', 'Add Imaging Order')} /> ) : ( )} ); } const headers = [ { header: t('dateAndTime', 'Date and time'), key: 'dateTime' }, { header: t('orderedBy', 'Ordered By'), key: 'orderedBy' }, { header: t('imagingTest', 'Imaging Test'), key: 'imagingTest' }, { header: t('status', 'Status'), key: 'status' }, ]; const rows = imagingOrders.map((order) => ({ id: order.uuid, dateTime: formatDate(parseDate(order.dateActivated), { mode: 'standard', noToday: true }), orderedBy: order.orderer.display, imagingTest: order.concept.display, status: (
{order.fulfillerStatus ?? 'NEW'}
), })); if (isLoading || isLoadingVisits) { return ; } return (
{({ rows, headers, getTableProps, getHeaderProps, getRowProps, getCellProps }) => ( {headers.map((header) => ( {header.header} ))} {rows.map((row) => ( {row.cells.map((cell) => ( {cell.value} ))} ))}
)}
); }; type PatientHeaderProps = { patientUuid: string; handleClose: () => void; }; const PatientHeader: React.FC = ({ patientUuid, handleClose }) => { const { patient, isLoading, error } = usePatient(patientUuid); const { t } = useTranslation(); if (isLoading) { return ; } if (error) { return
{t('errorLoadingPatient', 'Error loading patient: {{error}}', { error: error.message })}
; } if (!patient) { return null; } return (
{getPatientName(patient)} · {capitalize(patient?.gender)} · {patient?.identifier?.[0]?.value}
); }; type ImagingOrderDetailsProps = { imagingOrder: Result; }; const ImagingOrderDetails: React.FC = ({ imagingOrder }) => { const { t } = useTranslation(); const currentActions = getActionsForStatus(imagingOrder); const hasImagingResults = imagingOrder.procedures.some( (procedure) => procedure.procedureReport || procedure.impressions, ); return (
{currentActions.length > 0 && (
{currentActions .sort((a, b) => a.order - b.order) .map((action) => ( ))}
)} {hasImagingResults && ( {imagingOrder.procedures.map((procedure) => (

{t('findings', 'Findings')}

{procedure.procedureReport ?? '--'}

{t('impressions', 'Impressions')}

{procedure.impressions ?? '--'}

))}
)}
); }; type ImagingOrderRowProps = { title: string; value: string; }; const ImagingOrderRow: React.FC = ({ title, value }) => { return (
{title} {value}
); };