import { DataTable, OverflowMenu, OverflowMenuItem, Pagination, Search, Table, TableBody, TableCell, TableHead, TableHeader, TableRow, } from '@carbon/react'; import { ConfigurableLink, showModal, useConfig, useDebounce, usePagination } from '@openmrs/esm-framework'; import { usePaginationInfo } from '@openmrs/esm-patient-common-lib'; import dayjs from 'dayjs'; import relativeTime from 'dayjs/plugin/relativeTime'; import startCase from 'lodash-es/startCase'; import React, { useMemo, useState } from 'react'; import { useTranslation } from 'react-i18next'; import capitalize from 'lodash-es/capitalize'; import lowerCase from 'lodash-es/lowerCase'; import { type ExpressWorkflowConfig } from '../../../config-schema'; import { spaBasePath } from '../../../constants'; import { serveQueueEntry } from '../../../hooks/useServiceQueues'; import { type QueueEntry } from '../../../types/index'; import styles from './queue-entry-table.scss'; // Extend dayjs with the relativeTime plugin dayjs.extend(relativeTime); type QueueEntryTableProps = { navigatePath?: string; queueEntries: Array; usePatientChart?: boolean; }; const QueueEntryTable: React.FC = ({ navigatePath = 'triage', queueEntries, usePatientChart, }) => { const { visitQueueNumberAttributeUuid } = useConfig(); const [searchString, setSearchString] = useState(''); const pageSize = 10; const { t } = useTranslation(); const debouncedSearchString = useDebounce(searchString, 500); const filteredQueueEntries = useMemo(() => { return queueEntries.filter((queueEntry) => { return queueEntry.patient.person.display.toLowerCase().includes(debouncedSearchString.toLowerCase()); }); }, [queueEntries, debouncedSearchString]); const { currentPage, goTo, results } = usePagination(filteredQueueEntries, pageSize); const { pageSizes } = usePaginationInfo(pageSize, queueEntries.length, currentPage, results.length); const headers = [ { header: t('name', 'Name'), key: 'patientName', }, { header: t('queueNumber', 'Queue Number'), key: 'queueNumber', }, { header: t('comingFrom', 'Coming from'), key: 'previousQueue', }, { header: t('priority', 'Priority'), key: 'priority', }, { header: t('priorityComment', 'Priority Comment'), key: 'priorityComment', }, { header: t('status', 'status'), key: 'status', }, { header: t('queue', 'Queue'), key: 'queue', }, { header: t('waitTime', 'Wait time'), key: 'waitTime', }, ]; const handleCallQueueEntry = async (queueEntry: QueueEntry) => { const queueNumber = queueEntry.visit.attributes?.filter( (attr) => attr['attributeType']?.uuid === visitQueueNumberAttributeUuid, )?.[0]; const response = await serveQueueEntry( queueEntry.queue.name, queueNumber.value, 'calling', queueEntry?.queue?.location?.uuid, ); if (response.ok) { const dispose = showModal('call-queue-entry-modal', { closeModal: () => dispose(), queueEntry, size: 'sm', }); } }; const rows = results?.map((queueEntry) => { const visitNumber = queueEntry?.visit?.attributes?.find( (attr) => attr?.attributeType?.uuid === visitQueueNumberAttributeUuid, ); const patientChartUrl = usePatientChart ? `${window.spaBase}/patient/${queueEntry.patient.uuid}/chart/Patient Summary?path=${navigatePath}` : `${spaBasePath}/${navigatePath}/${queueEntry.patient.uuid}`; return { id: queueEntry.uuid, queueNumber: visitNumber?.value ?? '--', previousQueue: startCase(queueEntry.previousQueueEntry?.queue?.display?.toLowerCase() ?? '--'), patientName: ( {startCase(queueEntry.patient.person.display.toLowerCase())} ), priority: (
{t(queueEntry?.priority?.display, capitalize(queueEntry?.priority?.display.replace('_', ' ')))}
), priorityComment: startCase(queueEntry.priorityComment?.toLowerCase() ?? '--'), status: queueEntry?.status?.display ?? '--', queue: startCase(queueEntry?.queue?.display?.toLowerCase() ?? '--'), waitTime: dayjs(queueEntry.startedAt).fromNow(), }; }); if (queueEntries.length === 0) { return
{t('noPatientsAwaiting', 'No patients awaiting service')}
; } return (
{ setSearchString(value); }} /> {({ rows, headers, getTableProps, getHeaderProps, getRowProps, getCellProps }) => ( {headers.map((header) => ( {header.header} ))} {rows.map((row, index) => ( {row.cells.map((cell) => ( {cell.value} ))} handleCallQueueEntry(results[index])} itemText={t('call', 'Call')} /> ))}
)}
{ goTo(page); }} />
); }; export default QueueEntryTable;