Skip to main content
Glama
ResourcePage.tsx4.2 kB
// SPDX-FileCopyrightText: Copyright Orangebot, Inc. and Medplum contributors // SPDX-License-Identifier: Apache-2.0 import { Flex, Tabs, Title } from '@mantine/core'; import { showNotification } from '@mantine/notifications'; import { getDisplayString, getReferenceString, normalizeErrorString } from '@medplum/core'; import type { CoverageEligibilityRequest, Resource, ResourceType } from '@medplum/fhirtypes'; import { Document, ResourceForm, ResourceHistoryTable, ResourceTable, useMedplum } from '@medplum/react'; import { IconCircleCheck, IconCircleOff } from '@tabler/icons-react'; import { useEffect, useState } from 'react'; import type { JSX } from 'react'; import { useNavigate, useParams } from 'react-router'; import { UpdateCoverageEligibilityStatus } from '../components/actions/UpdateCoverageEligibilityStatus'; import { cleanResource } from '../components/utils'; /** * This is an example of a generic "Resource Display" page. * It uses the Medplum `<ResourceTable>` component to display a resource. * @returns A React component that displays a resource. */ export function ResourcePage(): JSX.Element | null { const medplum = useMedplum(); const navigate = useNavigate(); const { resourceType, id } = useParams(); const [resource, setResource] = useState<Resource | undefined>(undefined); const tabs = ['Details', 'Edit', 'History']; // Get the tab from the URL. If none, default to Details const tab = window.location.pathname.split('/').pop(); const currentTab = tab && tabs.map((t) => t.toLowerCase()).includes(tab) ? tab : tabs[0].toLowerCase(); useEffect(() => { const fetchResource = async (): Promise<void> => { if (resourceType && id) { try { const resourceData = await medplum.readResource(resourceType as ResourceType, id); setResource(resourceData); } catch (error) { console.error(error); } } }; fetchResource().catch((error) => console.error(error)); }, [medplum, resourceType, id]); const handleUpdateStatus = (updatedCoverageEligibility: Resource): void => { setResource(updatedCoverageEligibility); }; const handleTabChange = (newTab: string | null): void => { navigate(`/${resourceType}/${id}/${newTab ?? ''}`)?.catch(console.error); }; const handleEditSubmit = async (newResource: Resource): Promise<void> => { try { // Update the resource const updatedResource = await medplum.updateResource(cleanResource(newResource)); // Set the resource to re-render the page setResource(updatedResource); showNotification({ icon: <IconCircleCheck />, title: 'Success', message: `${resourceType} updated`, }); // Navigate back to the top of the details page navigate(`/${resourceType}/${id}`)?.catch(console.error); window.scrollTo(0, 0); } catch (err) { showNotification({ icon: <IconCircleOff />, title: 'Error', message: normalizeErrorString(err), }); } }; if (!resource) { return null; } return ( <Document key={getReferenceString(resource)}> <Flex gap="md" justify="space-between"> <Title>{getDisplayString(resource)}</Title> {resourceType === 'CoverageEligibilityRequest' ? ( <UpdateCoverageEligibilityStatus coverageEligibility={resource as CoverageEligibilityRequest} onChange={handleUpdateStatus} /> ) : null} </Flex> <Tabs value={currentTab.toLowerCase()} onChange={handleTabChange}> <Tabs.List> {tabs.map((tab) => ( <Tabs.Tab key={tab} value={tab.toLowerCase()}> {tab} </Tabs.Tab> ))} </Tabs.List> <Tabs.Panel value="details"> <ResourceTable key={`${resourceType}/${id}`} value={resource} /> </Tabs.Panel> <Tabs.Panel value="edit"> <ResourceForm defaultValue={resource} onSubmit={handleEditSubmit} /> </Tabs.Panel> <Tabs.Panel value="history"> <ResourceHistoryTable resourceType={resourceType} id={id} /> </Tabs.Panel> </Tabs> </Document> ); }

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