Skip to main content
Glama
ConditionList.tsx6.24 kB
// SPDX-FileCopyrightText: Copyright Orangebot, Inc. and Medplum contributors // SPDX-License-Identifier: Apache-2.0 import { Button, Flex, Modal, Card, Stack, Text } from '@mantine/core'; import type { Condition, Encounter, EncounterDiagnosis, Patient } from '@medplum/fhirtypes'; import { useEffect, useState } from 'react'; import type { JSX } from 'react'; import ConditionItem from './ConditionItem'; import ConditionModal from './ConditionModal'; import { useMedplum } from '@medplum/react'; import { getReferenceString } from '@medplum/core'; import { showErrorNotification } from '../../utils/notifications'; interface ConditionListProps { patient: Patient; encounter: Encounter; conditions: Condition[] | undefined; setConditions: (conditions: Condition[]) => void; onDiagnosisChange: (diagnosis: EncounterDiagnosis[]) => void; } export const ConditionList = (props: ConditionListProps): JSX.Element => { const { patient, encounter, conditions, setConditions, onDiagnosisChange } = props; const medplum = useMedplum(); const [opened, setOpened] = useState(false); useEffect(() => { const fetchConditions = async (): Promise<void> => { if (!encounter) { return; } const diagnosisReferences = encounter.diagnosis?.map((d) => d.condition?.reference).filter(Boolean) || []; const conditionsResult = await Promise.all( diagnosisReferences.map((ref) => medplum.readReference({ reference: ref })) ); if (conditionsResult.length > 0 && encounter?.diagnosis) { const diagnosisMap = new Map<string, number>(); const diagnosisReferences = encounter.diagnosis?.map((d) => d.condition?.reference) || []; const conditionsInDiagnosis = conditionsResult.filter((condition) => diagnosisReferences.includes(getReferenceString(condition)) ); encounter.diagnosis.forEach((diagnosis, index) => { if (diagnosis.condition?.reference) { diagnosisMap.set(diagnosis.condition.reference, diagnosis.rank || index); } }); conditionsInDiagnosis.sort((a, b) => { const aRef = getReferenceString(a); const bRef = getReferenceString(b); if (diagnosisMap.has(aRef) && diagnosisMap.has(bRef)) { const aValue = diagnosisMap.get(aRef) ?? 0; const bValue = diagnosisMap.get(bRef) ?? 0; return aValue - bValue; } if (diagnosisMap.has(aRef)) { return -1; } if (diagnosisMap.has(bRef)) { return 1; } return 0; }); setConditions(conditionsInDiagnosis as Condition[]); } }; fetchConditions().catch((err) => showErrorNotification(err)); }, [encounter, medplum, setConditions]); /* * Re-orders the conditions in the conditions array and updates the encounter diagnosis. */ const handleUpdateDiagnosis = async (condition: Condition, value: string): Promise<void> => { if (!conditions || conditions.length === 0 || !encounter) { return; } const newRank = Number(value); const maxAllowedRank = conditions.length; const validRank = Math.max(1, Math.min(newRank, maxAllowedRank)); const updatedConditions = [...conditions]; const conditionIndex = updatedConditions.findIndex((c) => getReferenceString(c) === getReferenceString(condition)); if (conditionIndex === -1) { return; } const conditionToMove = updatedConditions.splice(conditionIndex, 1)[0]; updatedConditions.splice(validRank - 1, 0, conditionToMove); setConditions(updatedConditions); onDiagnosisChange( updatedConditions.map((c, index) => ({ condition: { reference: `Condition/${c.id}` }, rank: index + 1, })) ); }; const handleRemoveDiagnosis = async (condition: Condition): Promise<void> => { if (!conditions) { return; } try { await medplum.deleteResource('Condition', condition.id as string); setConditions(conditions?.filter((c) => c.id !== condition.id)); const updatedDiagnosis = encounter.diagnosis?.filter( (d) => d.condition?.reference !== getReferenceString(condition) ); const reindexedDiagnosis = updatedDiagnosis?.map((d, index) => ({ ...d, rank: index + 1, })); setConditions(conditions?.filter((c) => c.id !== condition.id) || []); onDiagnosisChange(reindexedDiagnosis || []); } catch (err) { showErrorNotification(err); } }; const handleConditionSubmit = async (condition: Condition): Promise<void> => { try { const newCondition = await medplum.createResource(condition); if (encounter) { const updatedDiagnosis = [ ...(encounter.diagnosis || []), { condition: { reference: `Condition/${newCondition.id}` }, rank: encounter.diagnosis?.length ? encounter.diagnosis.length + 1 : 1, }, ]; setConditions([...(conditions || []), newCondition]); onDiagnosisChange(updatedDiagnosis); } } catch (err) { showErrorNotification(err); } finally { setOpened(false); } }; return ( <> <Stack gap={0}> <Text fw={600} size="lg" mb="md"> Diagnosis </Text> <Card withBorder shadow="sm"> <Stack gap="md"> {conditions && conditions.length > 0 && conditions.map((condition, idx) => ( <ConditionItem key={condition.id ?? idx} condition={condition} rank={idx + 1} total={conditions.length} onChange={handleUpdateDiagnosis} onRemove={handleRemoveDiagnosis} /> ))} <Flex> <Button onClick={() => setOpened(true)}>Add Diagnosis</Button> </Flex> </Stack> </Card> </Stack> <Modal opened={opened} onClose={() => setOpened(false)} title={'Add Diagnosis'}> <ConditionModal patient={patient} encounter={encounter} onSubmit={handleConditionSubmit} /> </Modal> </> ); };

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