Skip to main content
Glama
LabListItem.tsx4.41 kB
// SPDX-FileCopyrightText: Copyright Orangebot, Inc. and Medplum contributors // SPDX-License-Identifier: Apache-2.0 import { Group, Stack, Text, Badge } from '@mantine/core'; import { formatDate, formatHumanName } from '@medplum/core'; import type { HumanName, Practitioner, ServiceRequest } from '@medplum/fhirtypes'; import type { JSX } from 'react'; import { MedplumLink, useResource } from '@medplum/react'; import cx from 'clsx'; import classes from './LabListItem.module.css'; type LabTab = 'open' | 'completed'; interface LabListItemProps { item: ServiceRequest; selectedItem: ServiceRequest | undefined; activeTab: LabTab; onItemSelect: (item: ServiceRequest) => string; } export function LabListItem(props: LabListItemProps): JSX.Element { const { item, selectedItem, activeTab, onItemSelect } = props; const isSelected = selectedItem?.id === item.id; const requester = useResource(item.requester) as Practitioner | undefined; return ( <MedplumLink to={onItemSelect(item)} underline="never"> <Group align="center" wrap="nowrap" className={cx(classes.contentContainer, { [classes.selected]: isSelected, })} > <Stack gap={0} flex={1}> <Group justify="space-between" align="flex-start"> <Text fw={700} className={classes.title} flex={1}> {getDisplayText(item)} </Text> {activeTab !== 'completed' && ( <Badge size="sm" color={getStatusColor(item.status)} variant="light"> {getStatusDisplayText(item.status)} </Badge> )} </Group> {getAdditionalInfo(item, activeTab).map((info, index) => ( <Text key={index} size="sm"> {info} </Text> ))} <Text size="sm" c="dimmed"> {getSubText(item, requester)} </Text> </Stack> </Group> </MedplumLink> ); } const getStatusColor = (status: string | undefined): string => { switch (status) { case 'active': return 'blue'; case 'draft': case 'requested': return 'yellow'; case 'on-hold': return 'orange'; case 'revoked': case 'cancelled': case 'entered-in-error': return 'red'; case 'completed': return 'green'; case 'unknown': return 'gray'; default: return 'gray'; } }; const getStatusDisplayText = (status: string | undefined): string => { switch (status) { case 'active': return 'Active'; case 'draft': return 'Draft'; case 'requested': return 'Requested'; case 'on-hold': return 'On Hold'; case 'revoked': return 'Revoked'; case 'cancelled': return 'Cancelled'; case 'entered-in-error': return 'Error'; case 'completed': return 'Completed'; case 'unknown': return 'Unknown'; default: return status || 'Unknown'; } }; const getDisplayText = (item: ServiceRequest): string => { // If there are multiple codes (2 or more), show them separated by commas if (item.code?.coding && item.code.coding.length >= 2) { return item.code.coding.map((coding) => coding.display).join(', '); } // If there's a text field and only one code, use the text field if (item.code?.text) { return item.code.text; } // Otherwise, show the first code or fallback return item.code?.coding?.[0]?.display || 'Lab Order'; }; const getSubText = (item: ServiceRequest, requester: Practitioner | undefined): string => { // Use authoredOn if available, otherwise fall back to meta.lastUpdated const date = formatDate(item.authoredOn || item.meta?.lastUpdated); if (requester?.resourceType === 'Practitioner') { return `Ordered ${date} by ${formatHumanName(requester.name?.[0] as HumanName)}`; } return `Ordered ${date}`; }; const getAdditionalInfo = (item: ServiceRequest, activeTab: LabTab): string[] => { const info: string[] = []; if (activeTab === 'completed') { // For completed items, show completion date instead of REQ # const completionDate = item.meta?.lastUpdated ? formatDate(item.meta.lastUpdated) : 'Unknown date'; info.push(`Completed ${completionDate}`); } else if (item.requisition?.value) { // For open items, show REQ # as before info.push(`REQ #${item.requisition.value}`); } return info; };

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/medplum/medplum'

If you have feedback or need assistance with the MCP directory API, please join our Discord server