Skip to main content
Glama
UploadBundlePage.tsx5.17 kB
// SPDX-FileCopyrightText: Copyright Orangebot, Inc. and Medplum contributors // SPDX-License-Identifier: Apache-2.0 import { ActionIcon, Alert, Box, Button, Code, CopyButton, Stack, Text, Title } from '@mantine/core'; import { showNotification } from '@mantine/notifications'; import '@mantine/notifications/styles.css'; import { normalizeErrorString } from '@medplum/core'; import { Document, useMedplum } from '@medplum/react'; import { IconAlertCircle, IconCheck, IconCopy } from '@tabler/icons-react'; import { useState } from 'react'; import type { JSX } from 'react'; import { RESOURCES_BUNDLE } from '../data/core/sample-bundle'; import { useAdminStatus } from '../utils/admin'; /** * This page allows you to upload sample FHIR resources including 3 patients (A, B, and C) along with their * related Observations, Diagnostic Reports, Encounters, and Communications. All resources are properly linked * through the Patient compartment. * * This is useful for testing the access control policies and for demonstrating the functionality of the system. * * @returns The upload bundle page */ export function UploadBundlePage(): JSX.Element { const medplum = useMedplum(); const [loading, setLoading] = useState(false); const [uploadedResources, setUploadedResources] = useState<string[]>([]); const { isAdmin, loading: adminLoading } = useAdminStatus(); const handleUpload = async (): Promise<void> => { setLoading(true); try { // Step 1: Create the patients const resourcesResponse = await medplum.executeBatch(RESOURCES_BUNDLE); // Combine all created resources for display const allResources = [ // ...patients.map((patient) => `Patient/${patient.id}`), ...(resourcesResponse.entry?.map((entry) => { const resource = entry.resource; if (resource) { return `${resource.resourceType}/${resource.id}`; } return 'Unknown resource'; }) || []), ].filter(Boolean); setUploadedResources(allResources); showNotification({ title: 'Success', message: `Successfully uploaded ${allResources.length} resources`, color: 'green', }); } catch (error) { console.error('Error uploading resources:', normalizeErrorString(error)); showNotification({ title: 'Error', message: normalizeErrorString(error), color: 'red', }); } finally { setLoading(false); } }; // If still checking admin status, show loading if (adminLoading) { return ( <Document> <Stack gap="lg"> <Title>Upload FHIR Resources</Title> <Text>Loading...</Text> </Stack> </Document> ); } // If user is not an admin, show access denied message if (!isAdmin) { return ( <Document> <Stack gap="lg"> <Title>Upload FHIR Resources</Title> <Alert icon={<IconAlertCircle size={16} />} title="Access Denied" color="red"> You need to be an Admin to view this page. </Alert> </Stack> </Document> ); } return ( <Document> <Stack gap="lg"> <Title>Upload FHIR Resources</Title> <Text> This page allows you to upload sample FHIR resources including 3 patients (A, B, and C) along with their related Observations, Diagnostic Reports, Encounters, and Communications. All resources are properly linked through the Patient compartment. </Text> <Button onClick={handleUpload} loading={loading} disabled={uploadedResources.length > 0}> {uploadedResources.length > 0 ? 'Resources Uploaded' : 'Upload Resources'} </Button> {uploadedResources.length > 0 && ( <Box> <Title order={3}>Uploaded Resources ({uploadedResources.length})</Title> <Text size="sm" color="dimmed"> The following resources were created: </Text> <Box style={{ maxHeight: '400px', overflow: 'auto' }}> <Code block>{uploadedResources.join('\n')}</Code> </Box> </Box> )} <Box pos="relative"> <Title order={3}>Sample Bundles</Title> <Text size="sm" color="dimmed"> These are the FHIR bundles that will be uploaded: </Text> <Title order={4} mt="md"> Resources Bundle </Title> <Box pos="relative"> <Code block>{JSON.stringify(RESOURCES_BUNDLE, null, 2)}</Code> <CopyButton value={JSON.stringify(RESOURCES_BUNDLE, null, 2)} timeout={2000}> {({ copied, copy }) => ( <ActionIcon color={copied ? 'teal' : 'gray'} variant="subtle" onClick={copy} pos="absolute" top={8} right={8} > {copied ? <IconCheck size={16} /> : <IconCopy size={16} />} </ActionIcon> )} </CopyButton> </Box> </Box> </Stack> </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