@medplum/react 0.10.2 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (133) hide show
  1. package/dist/cjs/AttachmentButton.d.ts +2 -0
  2. package/dist/cjs/CalendarInput.d.ts +0 -1
  3. package/dist/cjs/CheckboxFormSection.d.ts +0 -1
  4. package/dist/cjs/DescriptionList.d.ts +0 -1
  5. package/dist/cjs/DiagnosticReportDisplay.d.ts +0 -1
  6. package/dist/cjs/Document.d.ts +0 -1
  7. package/dist/cjs/FhirPathTable.d.ts +0 -1
  8. package/dist/cjs/FormSection.d.ts +0 -1
  9. package/dist/cjs/MedplumLink.d.ts +2 -4
  10. package/dist/cjs/QuestionnaireBuilder.d.ts +0 -1
  11. package/dist/cjs/QuestionnaireForm.d.ts +0 -1
  12. package/dist/cjs/RequestGroupDisplay.d.ts +0 -1
  13. package/dist/cjs/ResourceBadge.d.ts +0 -1
  14. package/dist/cjs/ResourceBlame.d.ts +0 -1
  15. package/dist/cjs/ResourceDiff.d.ts +0 -1
  16. package/dist/cjs/ResourceDiffTable.d.ts +0 -2
  17. package/dist/cjs/ResourceName.d.ts +2 -1
  18. package/dist/cjs/ResourceTimeline.d.ts +0 -1
  19. package/dist/cjs/Scheduler.d.ts +0 -1
  20. package/dist/cjs/SearchControl.d.ts +0 -1
  21. package/dist/cjs/SearchFilterEditor.d.ts +0 -1
  22. package/dist/cjs/Timeline.d.ts +0 -1
  23. package/dist/cjs/auth/AuthenticationForm.d.ts +1 -0
  24. package/dist/cjs/auth/RegisterForm.d.ts +0 -1
  25. package/dist/cjs/auth/SignInForm.d.ts +1 -1
  26. package/dist/cjs/index.js +1247 -907
  27. package/dist/cjs/index.js.map +1 -1
  28. package/dist/cjs/index.min.js +1 -1
  29. package/dist/cjs/index.min.js.map +1 -1
  30. package/dist/cjs/stories/DescriptionList.stories.d.ts +5 -0
  31. package/dist/esm/AttachmentArrayInput.js +2 -2
  32. package/dist/esm/AttachmentArrayInput.js.map +1 -1
  33. package/dist/esm/AttachmentButton.d.ts +2 -0
  34. package/dist/esm/AttachmentButton.js +4 -1
  35. package/dist/esm/AttachmentButton.js.map +1 -1
  36. package/dist/esm/BackboneElementInput.js +2 -1
  37. package/dist/esm/BackboneElementInput.js.map +1 -1
  38. package/dist/esm/CalendarInput.d.ts +0 -1
  39. package/dist/esm/CalendarInput.js +39 -2
  40. package/dist/esm/CalendarInput.js.map +1 -1
  41. package/dist/esm/CheckboxFormSection.d.ts +0 -1
  42. package/dist/esm/CheckboxFormSection.js +5 -5
  43. package/dist/esm/CheckboxFormSection.js.map +1 -1
  44. package/dist/esm/DescriptionList.d.ts +0 -1
  45. package/dist/esm/DescriptionList.js +23 -1
  46. package/dist/esm/DescriptionList.js.map +1 -1
  47. package/dist/esm/DiagnosticReportDisplay.d.ts +0 -1
  48. package/dist/esm/DiagnosticReportDisplay.js +40 -22
  49. package/dist/esm/DiagnosticReportDisplay.js.map +1 -1
  50. package/dist/esm/Document.d.ts +0 -1
  51. package/dist/esm/Document.js +7 -2
  52. package/dist/esm/Document.js.map +1 -1
  53. package/dist/esm/ErrorBoundary.js +2 -1
  54. package/dist/esm/ErrorBoundary.js.map +1 -1
  55. package/dist/esm/FhirPathTable.d.ts +0 -1
  56. package/dist/esm/FhirPathTable.js +5 -5
  57. package/dist/esm/FhirPathTable.js.map +1 -1
  58. package/dist/esm/FormSection.d.ts +0 -1
  59. package/dist/esm/FormSection.js +3 -11
  60. package/dist/esm/FormSection.js.map +1 -1
  61. package/dist/esm/MedplumLink.d.ts +2 -4
  62. package/dist/esm/MedplumLink.js +11 -8
  63. package/dist/esm/MedplumLink.js.map +1 -1
  64. package/dist/esm/PlanDefinitionBuilder.js +41 -10
  65. package/dist/esm/PlanDefinitionBuilder.js.map +1 -1
  66. package/dist/esm/QuestionnaireBuilder.d.ts +0 -1
  67. package/dist/esm/QuestionnaireBuilder.js +78 -31
  68. package/dist/esm/QuestionnaireBuilder.js.map +1 -1
  69. package/dist/esm/QuestionnaireForm.d.ts +0 -1
  70. package/dist/esm/QuestionnaireForm.js +26 -16
  71. package/dist/esm/QuestionnaireForm.js.map +1 -1
  72. package/dist/esm/RequestGroupDisplay.d.ts +0 -1
  73. package/dist/esm/RequestGroupDisplay.js +8 -7
  74. package/dist/esm/RequestGroupDisplay.js.map +1 -1
  75. package/dist/esm/ResourceBadge.d.ts +0 -1
  76. package/dist/esm/ResourceBadge.js +2 -1
  77. package/dist/esm/ResourceBadge.js.map +1 -1
  78. package/dist/esm/ResourceBlame.d.ts +0 -1
  79. package/dist/esm/ResourceBlame.js +59 -10
  80. package/dist/esm/ResourceBlame.js.map +1 -1
  81. package/dist/esm/ResourceDiff.d.ts +0 -1
  82. package/dist/esm/ResourceDiff.js +13 -2
  83. package/dist/esm/ResourceDiff.js.map +1 -1
  84. package/dist/esm/ResourceDiffTable.d.ts +0 -2
  85. package/dist/esm/ResourceDiffTable.js +25 -3
  86. package/dist/esm/ResourceDiffTable.js.map +1 -1
  87. package/dist/esm/ResourceForm.js +6 -5
  88. package/dist/esm/ResourceForm.js.map +1 -1
  89. package/dist/esm/ResourceInput.js +22 -1
  90. package/dist/esm/ResourceInput.js.map +1 -1
  91. package/dist/esm/ResourceName.d.ts +2 -1
  92. package/dist/esm/ResourceName.js +5 -2
  93. package/dist/esm/ResourceName.js.map +1 -1
  94. package/dist/esm/ResourcePropertyDisplay.js +6 -6
  95. package/dist/esm/ResourcePropertyDisplay.js.map +1 -1
  96. package/dist/esm/ResourceTimeline.d.ts +0 -1
  97. package/dist/esm/ResourceTimeline.js +78 -25
  98. package/dist/esm/ResourceTimeline.js.map +1 -1
  99. package/dist/esm/Scheduler.d.ts +0 -1
  100. package/dist/esm/Scheduler.js +20 -4
  101. package/dist/esm/Scheduler.js.map +1 -1
  102. package/dist/esm/SearchControl.d.ts +0 -1
  103. package/dist/esm/SearchControl.js +33 -18
  104. package/dist/esm/SearchControl.js.map +1 -1
  105. package/dist/esm/SearchFilterEditor.d.ts +0 -1
  106. package/dist/esm/SearchFilterEditor.js +2 -2
  107. package/dist/esm/SearchFilterEditor.js.map +1 -1
  108. package/dist/esm/Timeline.d.ts +0 -1
  109. package/dist/esm/Timeline.js +13 -16
  110. package/dist/esm/Timeline.js.map +1 -1
  111. package/dist/esm/auth/AuthenticationForm.d.ts +1 -0
  112. package/dist/esm/auth/AuthenticationForm.js +6 -3
  113. package/dist/esm/auth/AuthenticationForm.js.map +1 -1
  114. package/dist/esm/auth/ChooseProfileForm.js +3 -3
  115. package/dist/esm/auth/ChooseProfileForm.js.map +1 -1
  116. package/dist/esm/auth/NewProjectForm.js +3 -3
  117. package/dist/esm/auth/NewProjectForm.js.map +1 -1
  118. package/dist/esm/auth/NewUserForm.js +4 -3
  119. package/dist/esm/auth/NewUserForm.js.map +1 -1
  120. package/dist/esm/auth/RegisterForm.d.ts +0 -1
  121. package/dist/esm/auth/RegisterForm.js.map +1 -1
  122. package/dist/esm/auth/SignInForm.d.ts +1 -1
  123. package/dist/esm/auth/SignInForm.js +1 -1
  124. package/dist/esm/auth/SignInForm.js.map +1 -1
  125. package/dist/esm/index.min.js +1 -1
  126. package/dist/esm/index.min.js.map +1 -1
  127. package/dist/esm/stories/DescriptionList.stories.d.ts +5 -0
  128. package/package.json +35 -24
  129. package/rollup.config.mjs +111 -0
  130. package/dist/cjs/defaulttheme.css +0 -192
  131. package/dist/cjs/styles.css +0 -528
  132. package/dist/esm/defaulttheme.css +0 -192
  133. package/dist/esm/styles.css +0 -528
@@ -1 +1 @@
1
- {"version":3,"file":"RequestGroupDisplay.js","sources":["../../src/RequestGroupDisplay.tsx"],"sourcesContent":["import { Button } from '@mantine/core';\nimport { formatDateTime, getReferenceString } from '@medplum/core';\nimport { Bundle, BundleEntry, Reference, RequestGroup, Resource, Task } from '@medplum/fhirtypes';\nimport React, { useEffect, useState } from 'react';\nimport { useMedplum } from './MedplumProvider';\nimport { ResourceName } from './ResourceName';\nimport { StatusBadge } from './StatusBadge';\nimport { useResource } from './useResource';\n\nimport './RequestGroupDisplay.css';\n\nexport interface RequestGroupDisplayProps {\n value?: RequestGroup | Reference<RequestGroup>;\n onStart: (task: Task, input: Reference) => void;\n onEdit: (task: Task, input: Reference, output: Reference) => void;\n}\n\nexport function RequestGroupDisplay(props: RequestGroupDisplayProps): JSX.Element | null {\n const medplum = useMedplum();\n const requestGroup = useResource(props.value);\n const [startedLoading, setStartedLoading] = useState(false);\n const [responseBundle, setResponseBundle] = useState<Bundle>();\n\n useEffect(() => {\n if (requestGroup && !startedLoading) {\n medplum.executeBatch(buildBatchRequest(requestGroup)).then(setResponseBundle).catch(console.log);\n setStartedLoading(true);\n }\n }, [medplum, requestGroup, startedLoading]);\n\n if (!requestGroup || !responseBundle) {\n return null;\n }\n\n return (\n <div className=\"medplum-request-group\">\n {requestGroup.action?.map((action, index) => {\n const task = action.resource && findBundleEntry(action.resource as Reference<Task>);\n const taskInput = task?.input?.[0]?.valueReference;\n const taskOutput = task?.output?.[0]?.valueReference;\n return (\n <div className=\"medplum-request-group-task\" key={`action-${index}`}>\n <div className=\"medplum-request-group-task-checkmark\">{task?.status === 'completed' ? '🗹' : '☐'}</div>\n <div className=\"medplum-request-group-task-details\">\n <div className=\"medplum-request-group-task-title\">{action.title}</div>\n {action.description && <div>{action.description}</div>}\n <div>\n Last edited by&nbsp;\n <ResourceName value={task?.meta?.author as Reference} />\n &nbsp;on&nbsp;\n {formatDateTime(task?.meta?.lastUpdated)}\n </div>\n <div>\n Status: <StatusBadge status={task?.status || 'unknown'} />\n </div>\n </div>\n <div className=\"medplum-request-group-task-actions\">\n {taskInput && !taskOutput && <Button onClick={() => props.onStart(task, taskInput)}>Start</Button>}\n {taskInput && taskOutput && (\n <Button onClick={() => props.onEdit(task, taskInput, taskOutput)}>Edit</Button>\n )}\n </div>\n </div>\n );\n })}\n </div>\n );\n\n function buildBatchRequest(request: RequestGroup): Bundle {\n const batchEntries = [] as BundleEntry[];\n if (request.action) {\n for (const action of request.action) {\n if (action.resource?.reference) {\n batchEntries.push({ request: { method: 'GET', url: action.resource.reference } });\n }\n }\n }\n\n return {\n resourceType: 'Bundle',\n type: 'batch',\n entry: batchEntries,\n };\n }\n\n function findBundleEntry<T extends Resource>(reference: Reference<T>): T | undefined {\n for (const entry of responseBundle?.entry as BundleEntry[]) {\n if (entry.resource && reference.reference === getReferenceString(entry.resource)) {\n return entry.resource as T;\n }\n }\n return undefined;\n }\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"RequestGroupDisplay.js","sources":["../../src/RequestGroupDisplay.tsx"],"sourcesContent":["import { Button, Grid, Text } from '@mantine/core';\nimport { formatDateTime, getReferenceString } from '@medplum/core';\nimport { Bundle, BundleEntry, Reference, RequestGroup, Resource, Task } from '@medplum/fhirtypes';\nimport { IconCheckbox, IconSquare } from '@tabler/icons';\nimport React, { useEffect, useState } from 'react';\nimport { useMedplum } from './MedplumProvider';\nimport { ResourceName } from './ResourceName';\nimport { StatusBadge } from './StatusBadge';\nimport { useResource } from './useResource';\n\nexport interface RequestGroupDisplayProps {\n value?: RequestGroup | Reference<RequestGroup>;\n onStart: (task: Task, input: Reference) => void;\n onEdit: (task: Task, input: Reference, output: Reference) => void;\n}\n\nexport function RequestGroupDisplay(props: RequestGroupDisplayProps): JSX.Element | null {\n const medplum = useMedplum();\n const requestGroup = useResource(props.value);\n const [startedLoading, setStartedLoading] = useState(false);\n const [responseBundle, setResponseBundle] = useState<Bundle>();\n\n useEffect(() => {\n if (requestGroup && !startedLoading) {\n medplum.executeBatch(buildBatchRequest(requestGroup)).then(setResponseBundle).catch(console.log);\n setStartedLoading(true);\n }\n }, [medplum, requestGroup, startedLoading]);\n\n if (!requestGroup || !responseBundle) {\n return null;\n }\n\n return (\n <Grid>\n {requestGroup.action?.map((action, index) => {\n const task = action.resource && findBundleEntry(action.resource as Reference<Task>);\n const taskInput = task?.input?.[0]?.valueReference;\n const taskOutput = task?.output?.[0]?.valueReference;\n return (\n <React.Fragment key={`action-${index}`}>\n <Grid.Col span={1} p=\"md\">\n {task?.status === 'completed' ? <IconCheckbox /> : <IconSquare color=\"gray\" />}\n </Grid.Col>\n <Grid.Col span={9} p=\"xs\">\n <Text weight={500}>{action.title}</Text>\n {action.description && <div>{action.description}</div>}\n <div>\n Last edited by&nbsp;\n <ResourceName value={task?.meta?.author as Reference} />\n &nbsp;on&nbsp;\n {formatDateTime(task?.meta?.lastUpdated)}\n </div>\n <div>\n Status: <StatusBadge status={task?.status || 'unknown'} />\n </div>\n </Grid.Col>\n <Grid.Col span={2} p=\"md\">\n {taskInput && !taskOutput && <Button onClick={() => props.onStart(task, taskInput)}>Start</Button>}\n {taskInput && taskOutput && (\n <Button onClick={() => props.onEdit(task, taskInput, taskOutput)}>Edit</Button>\n )}\n </Grid.Col>\n </React.Fragment>\n );\n })}\n </Grid>\n );\n\n function buildBatchRequest(request: RequestGroup): Bundle {\n const batchEntries = [] as BundleEntry[];\n if (request.action) {\n for (const action of request.action) {\n if (action.resource?.reference) {\n batchEntries.push({ request: { method: 'GET', url: action.resource.reference } });\n }\n }\n }\n\n return {\n resourceType: 'Bundle',\n type: 'batch',\n entry: batchEntries,\n };\n }\n\n function findBundleEntry<T extends Resource>(reference: Reference<T>): T | undefined {\n for (const entry of responseBundle?.entry as BundleEntry[]) {\n if (entry.resource && reference.reference === getReferenceString(entry.resource)) {\n return entry.resource as T;\n }\n }\n return undefined;\n }\n}\n"],"names":[],"mappings":"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"}
@@ -1,6 +1,5 @@
1
1
  /// <reference types="react" />
2
2
  import { Reference, Resource } from '@medplum/fhirtypes';
3
- import './ResourceBadge.css';
4
3
  export interface ResourceBadgeProps {
5
4
  value?: Reference | Resource;
6
5
  link?: boolean;
@@ -1,9 +1,10 @@
1
+ import { Group } from '@mantine/core';
1
2
  import React from 'react';
2
3
  import { ResourceAvatar } from './ResourceAvatar.js';
3
4
  import { ResourceName } from './ResourceName.js';
4
5
 
5
6
  function ResourceBadge(props) {
6
- return (React.createElement("div", { className: "medplum-resource-badge" },
7
+ return (React.createElement(Group, { spacing: "xs" },
7
8
  React.createElement(ResourceAvatar, { size: 24, radius: 12, value: props.value, link: props.link }),
8
9
  React.createElement(ResourceName, { value: props.value, link: props.link })));
9
10
  }
@@ -1 +1 @@
1
- {"version":3,"file":"ResourceBadge.js","sources":["../../src/ResourceBadge.tsx"],"sourcesContent":["import { Reference, Resource } from '@medplum/fhirtypes';\nimport React from 'react';\nimport { ResourceAvatar } from './ResourceAvatar';\nimport { ResourceName } from './ResourceName';\n\nimport './ResourceBadge.css';\n\nexport interface ResourceBadgeProps {\n value?: Reference | Resource;\n link?: boolean;\n}\n\nexport function ResourceBadge(props: ResourceBadgeProps): JSX.Element {\n return (\n <div className=\"medplum-resource-badge\">\n <ResourceAvatar size={24} radius={12} value={props.value} link={props.link} />\n <ResourceName value={props.value} link={props.link} />\n </div>\n );\n}\n"],"names":[],"mappings":";;;;AAYM,SAAU,aAAa,CAAC,KAAyB,EAAA;AACrD,IAAA,QACE,KAAA,CAAA,aAAA,CAAA,KAAA,EAAA,EAAK,SAAS,EAAC,wBAAwB,EAAA;QACrC,KAAC,CAAA,aAAA,CAAA,cAAc,IAAC,IAAI,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAI,CAAA;AAC9E,QAAA,KAAA,CAAA,aAAA,CAAC,YAAY,EAAC,EAAA,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAI,CAAA,CAClD,EACN;AACJ;;;;"}
1
+ {"version":3,"file":"ResourceBadge.js","sources":["../../src/ResourceBadge.tsx"],"sourcesContent":["import { Group } from '@mantine/core';\nimport { Reference, Resource } from '@medplum/fhirtypes';\nimport React from 'react';\nimport { ResourceAvatar } from './ResourceAvatar';\nimport { ResourceName } from './ResourceName';\n\nexport interface ResourceBadgeProps {\n value?: Reference | Resource;\n link?: boolean;\n}\n\nexport function ResourceBadge(props: ResourceBadgeProps): JSX.Element {\n return (\n <Group spacing=\"xs\">\n <ResourceAvatar size={24} radius={12} value={props.value} link={props.link} />\n <ResourceName value={props.value} link={props.link} />\n </Group>\n );\n}\n"],"names":[],"mappings":";;;;;AAWM,SAAU,aAAa,CAAC,KAAyB,EAAA;AACrD,IAAA,QACE,KAAC,CAAA,aAAA,CAAA,KAAK,EAAC,EAAA,OAAO,EAAC,IAAI,EAAA;QACjB,KAAC,CAAA,aAAA,CAAA,cAAc,IAAC,IAAI,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAI,CAAA;AAC9E,QAAA,KAAA,CAAA,aAAA,CAAC,YAAY,EAAC,EAAA,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAI,CAAA,CAChD,EACR;AACJ;;;;"}
@@ -1,6 +1,5 @@
1
1
  /// <reference types="react" />
2
2
  import { Bundle, ResourceType } from '@medplum/fhirtypes';
3
- import './ResourceBlame.css';
4
3
  export interface ResourceBlameProps {
5
4
  history?: Bundle;
6
5
  resourceType?: ResourceType;
@@ -1,12 +1,60 @@
1
- import { Group } from '@mantine/core';
1
+ import { createStyles } from '@mantine/core';
2
2
  import React, { useState, useEffect } from 'react';
3
3
  import { MedplumLink } from './MedplumLink.js';
4
4
  import { useMedplum } from './MedplumProvider.js';
5
5
  import { ResourceBadge } from './ResourceBadge.js';
6
6
  import { blame } from './utils/blame.js';
7
7
 
8
+ const useStyles = createStyles((theme) => ({
9
+ container: {
10
+ overflowX: 'auto',
11
+ },
12
+ root: {
13
+ border: `0.1px solid ${theme.colors.gray[3]}`,
14
+ borderCollapse: 'collapse',
15
+ borderRadius: theme.radius.sm,
16
+ borderSpacing: 0,
17
+ fontSize: theme.fontSizes.xs,
18
+ width: '100%',
19
+ '& td': {
20
+ padding: '2px 4px 0 4px',
21
+ verticalAlign: 'top',
22
+ whiteSpace: 'nowrap',
23
+ },
24
+ },
25
+ startRow: {
26
+ borderTop: `0.1px solid ${theme.colors.gray[3]}`,
27
+ },
28
+ normalRow: {
29
+ borderTop: 0,
30
+ },
31
+ author: {
32
+ lineHeight: '10px',
33
+ },
34
+ dateTime: {
35
+ borderRight: `0.1px solid ${theme.colors.gray[3]}`,
36
+ lineHeight: '20px',
37
+ },
38
+ lineNumber: {
39
+ backgroundColor: theme.colors.gray[1],
40
+ border: 0,
41
+ color: theme.colors.gray[5],
42
+ fontFamily: theme.fontFamilyMonospace,
43
+ padding: `${theme.spacing.xs}px ${theme.spacing.sm}px`,
44
+ textAlign: 'right',
45
+ },
46
+ line: {
47
+ fontFamily: theme.fontFamilyMonospace,
48
+ fontSize: theme.fontSizes.sm,
49
+ padding: `${theme.spacing.xs}px ${theme.spacing.sm}px`,
50
+ },
51
+ pre: {
52
+ margin: 0,
53
+ },
54
+ }));
8
55
  function ResourceBlame(props) {
9
56
  var _a, _b;
57
+ const { classes } = useStyles();
10
58
  const medplum = useMedplum();
11
59
  const [value, setValue] = useState(props.history);
12
60
  useEffect(() => {
@@ -19,16 +67,17 @@ function ResourceBlame(props) {
19
67
  }
20
68
  const resource = (_b = (_a = value.entry) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.resource;
21
69
  const table = blame(value);
22
- return (React.createElement("div", { className: "medplum-blame-container" },
23
- React.createElement("table", { className: "medplum-blame" },
24
- React.createElement("tbody", null, table.map((row, index) => (React.createElement("tr", { key: 'row-' + index, className: row.span > 0 ? 'start-row' : 'normal-row' },
25
- row.span > 0 && (React.createElement("td", { className: "details", rowSpan: row.span },
26
- React.createElement(Group, { spacing: "xs", grow: true, noWrap: true },
27
- React.createElement(ResourceBadge, { value: row.meta.author, link: true }),
70
+ return (React.createElement("div", { className: classes.container },
71
+ React.createElement("table", { className: classes.root },
72
+ React.createElement("tbody", null, table.map((row, index) => (React.createElement("tr", { key: 'row-' + index, className: row.span > 0 ? classes.startRow : classes.normalRow },
73
+ row.span > 0 && (React.createElement(React.Fragment, null,
74
+ React.createElement("td", { className: classes.author, rowSpan: row.span },
75
+ React.createElement(ResourceBadge, { value: row.meta.author, link: true })),
76
+ React.createElement("td", { className: classes.dateTime, rowSpan: row.span },
28
77
  React.createElement(MedplumLink, { to: getVersionUrl(resource, row.meta.versionId) }, getTimeString(row.meta.lastUpdated))))),
29
- React.createElement("td", { className: "line-number" }, index + 1),
30
- React.createElement("td", { className: "line" },
31
- React.createElement("pre", { className: "line-pre" }, row.value)))))))));
78
+ React.createElement("td", { className: classes.lineNumber }, index + 1),
79
+ React.createElement("td", { className: classes.line },
80
+ React.createElement("pre", { className: classes.pre }, row.value)))))))));
32
81
  }
33
82
  function getVersionUrl(resource, versionId) {
34
83
  return `/${resource.resourceType}/${resource.id}/_history/${versionId}`;
@@ -1 +1 @@
1
- {"version":3,"file":"ResourceBlame.js","sources":["../../src/ResourceBlame.tsx"],"sourcesContent":["import { Group } from '@mantine/core';\nimport { Bundle, Resource, ResourceType } from '@medplum/fhirtypes';\nimport React, { useEffect, useState } from 'react';\nimport { MedplumLink } from './MedplumLink';\nimport { useMedplum } from './MedplumProvider';\nimport { ResourceBadge } from './ResourceBadge';\nimport { blame } from './utils/blame';\n\nimport './ResourceBlame.css';\n\nexport interface ResourceBlameProps {\n history?: Bundle;\n resourceType?: ResourceType;\n id?: string;\n}\n\nexport function ResourceBlame(props: ResourceBlameProps): JSX.Element {\n const medplum = useMedplum();\n const [value, setValue] = useState<Bundle | undefined>(props.history);\n\n useEffect(() => {\n if (!props.history && props.resourceType && props.id) {\n medplum.readHistory(props.resourceType, props.id).then(setValue).catch(console.log);\n }\n }, [medplum, props.history, props.resourceType, props.id]);\n\n if (!value) {\n return <div>Loading...</div>;\n }\n\n const resource = value.entry?.[0]?.resource as Resource;\n const table = blame(value);\n return (\n <div className=\"medplum-blame-container\">\n <table className=\"medplum-blame\">\n <tbody>\n {table.map((row, index) => (\n <tr key={'row-' + index} className={row.span > 0 ? 'start-row' : 'normal-row'}>\n {row.span > 0 && (\n <td className=\"details\" rowSpan={row.span}>\n <Group spacing=\"xs\" grow noWrap>\n <ResourceBadge value={row.meta.author} link={true} />\n <MedplumLink to={getVersionUrl(resource, row.meta.versionId as string)}>\n {getTimeString(row.meta.lastUpdated as string)}\n </MedplumLink>\n </Group>\n </td>\n )}\n <td className=\"line-number\">{index + 1}</td>\n <td className=\"line\">\n <pre className=\"line-pre\">{row.value}</pre>\n </td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n );\n}\n\nfunction getVersionUrl(resource: Resource, versionId: string): string {\n return `/${resource.resourceType}/${resource.id}/_history/${versionId}`;\n}\n\nexport function getTimeString(lastUpdated: string): string {\n const seconds = Math.floor((Date.now() - Date.parse(lastUpdated)) / 1000);\n\n const years = Math.floor(seconds / 31536000);\n if (years > 0) {\n return pluralizeTime(years, 'year');\n }\n\n const months = Math.floor(seconds / 2592000);\n if (months > 0) {\n return pluralizeTime(months, 'month');\n }\n\n const days = Math.floor(seconds / 86400);\n if (days > 0) {\n return pluralizeTime(days, 'day');\n }\n\n const hours = Math.floor(seconds / 3600);\n if (hours > 0) {\n return pluralizeTime(hours, 'hour');\n }\n\n const minutes = Math.floor(seconds / 60);\n if (minutes > 0) {\n return pluralizeTime(minutes, 'minute');\n }\n\n return pluralizeTime(seconds, 'second');\n}\n\nfunction pluralizeTime(count: number, noun: string): string {\n return `${count} ${count === 1 ? noun : noun + 's'} ago`;\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ResourceBlame.js","sources":["../../src/ResourceBlame.tsx"],"sourcesContent":["import { createStyles } from '@mantine/core';\nimport { Bundle, Resource, ResourceType } from '@medplum/fhirtypes';\nimport React, { useEffect, useState } from 'react';\nimport { MedplumLink } from './MedplumLink';\nimport { useMedplum } from './MedplumProvider';\nimport { ResourceBadge } from './ResourceBadge';\nimport { blame } from './utils/blame';\n\nconst useStyles = createStyles((theme) => ({\n container: {\n overflowX: 'auto',\n },\n\n root: {\n border: `0.1px solid ${theme.colors.gray[3]}`,\n borderCollapse: 'collapse',\n borderRadius: theme.radius.sm,\n borderSpacing: 0,\n fontSize: theme.fontSizes.xs,\n width: '100%',\n\n '& td': {\n padding: '2px 4px 0 4px',\n verticalAlign: 'top',\n whiteSpace: 'nowrap',\n },\n },\n\n startRow: {\n borderTop: `0.1px solid ${theme.colors.gray[3]}`,\n },\n\n normalRow: {\n borderTop: 0,\n },\n\n author: {\n lineHeight: '10px',\n },\n\n dateTime: {\n borderRight: `0.1px solid ${theme.colors.gray[3]}`,\n lineHeight: '20px',\n },\n\n lineNumber: {\n backgroundColor: theme.colors.gray[1],\n border: 0,\n color: theme.colors.gray[5],\n fontFamily: theme.fontFamilyMonospace,\n padding: `${theme.spacing.xs}px ${theme.spacing.sm}px`,\n textAlign: 'right',\n },\n\n line: {\n fontFamily: theme.fontFamilyMonospace,\n fontSize: theme.fontSizes.sm,\n padding: `${theme.spacing.xs}px ${theme.spacing.sm}px`,\n },\n\n pre: {\n margin: 0,\n },\n}));\n\nexport interface ResourceBlameProps {\n history?: Bundle;\n resourceType?: ResourceType;\n id?: string;\n}\n\nexport function ResourceBlame(props: ResourceBlameProps): JSX.Element {\n const { classes } = useStyles();\n const medplum = useMedplum();\n const [value, setValue] = useState<Bundle | undefined>(props.history);\n\n useEffect(() => {\n if (!props.history && props.resourceType && props.id) {\n medplum.readHistory(props.resourceType, props.id).then(setValue).catch(console.log);\n }\n }, [medplum, props.history, props.resourceType, props.id]);\n\n if (!value) {\n return <div>Loading...</div>;\n }\n\n const resource = value.entry?.[0]?.resource as Resource;\n const table = blame(value);\n return (\n <div className={classes.container}>\n <table className={classes.root}>\n <tbody>\n {table.map((row, index) => (\n <tr key={'row-' + index} className={row.span > 0 ? classes.startRow : classes.normalRow}>\n {row.span > 0 && (\n <>\n <td className={classes.author} rowSpan={row.span}>\n <ResourceBadge value={row.meta.author} link={true} />\n </td>\n <td className={classes.dateTime} rowSpan={row.span}>\n <MedplumLink to={getVersionUrl(resource, row.meta.versionId as string)}>\n {getTimeString(row.meta.lastUpdated as string)}\n </MedplumLink>\n </td>\n </>\n )}\n <td className={classes.lineNumber}>{index + 1}</td>\n <td className={classes.line}>\n <pre className={classes.pre}>{row.value}</pre>\n </td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n );\n}\n\nfunction getVersionUrl(resource: Resource, versionId: string): string {\n return `/${resource.resourceType}/${resource.id}/_history/${versionId}`;\n}\n\nexport function getTimeString(lastUpdated: string): string {\n const seconds = Math.floor((Date.now() - Date.parse(lastUpdated)) / 1000);\n\n const years = Math.floor(seconds / 31536000);\n if (years > 0) {\n return pluralizeTime(years, 'year');\n }\n\n const months = Math.floor(seconds / 2592000);\n if (months > 0) {\n return pluralizeTime(months, 'month');\n }\n\n const days = Math.floor(seconds / 86400);\n if (days > 0) {\n return pluralizeTime(days, 'day');\n }\n\n const hours = Math.floor(seconds / 3600);\n if (hours > 0) {\n return pluralizeTime(hours, 'hour');\n }\n\n const minutes = Math.floor(seconds / 60);\n if (minutes > 0) {\n return pluralizeTime(minutes, 'minute');\n }\n\n return pluralizeTime(seconds, 'second');\n}\n\nfunction pluralizeTime(count: number, noun: string): string {\n return `${count} ${count === 1 ? noun : noun + 's'} ago`;\n}\n"],"names":[],"mappings":"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"}
@@ -1,6 +1,5 @@
1
1
  /// <reference types="react" />
2
2
  import { Resource } from '@medplum/fhirtypes';
3
- import './ResourceDiff.css';
4
3
  export interface ResourceDiffProps {
5
4
  original: Resource;
6
5
  revised: Resource;
@@ -1,7 +1,17 @@
1
+ import { createStyles } from '@mantine/core';
1
2
  import { stringify } from '@medplum/core';
2
3
  import React from 'react';
3
4
  import { diff } from './utils/diff.js';
4
5
 
6
+ const useStyles = createStyles((theme) => ({
7
+ removed: {
8
+ color: theme.colors.red[7],
9
+ textDecoration: 'line-through',
10
+ },
11
+ added: {
12
+ color: theme.colors.green[7],
13
+ },
14
+ }));
5
15
  function ResourceDiff(props) {
6
16
  let originalResource = props.original;
7
17
  let revisedResource = props.revised;
@@ -15,11 +25,12 @@ function ResourceDiff(props) {
15
25
  return (React.createElement("pre", { style: { color: 'gray' } }, deltas.map((delta, index) => (React.createElement(ChangeDiff, { key: 'delta' + index, delta: delta })))));
16
26
  }
17
27
  function ChangeDiff(props) {
28
+ const { classes } = useStyles();
18
29
  return (React.createElement(React.Fragment, null,
19
30
  "...",
20
31
  React.createElement("br", null),
21
- props.delta.original.lines.length > 0 && (React.createElement("div", { className: "medplum-diff-removed" }, props.delta.original.lines.join('\n'))),
22
- props.delta.revised.lines.length > 0 && (React.createElement("div", { className: "medplum-diff-added" }, props.delta.revised.lines.join('\n'))),
32
+ props.delta.original.lines.length > 0 && (React.createElement("div", { className: classes.removed }, props.delta.original.lines.join('\n'))),
33
+ props.delta.revised.lines.length > 0 && (React.createElement("div", { className: classes.added }, props.delta.revised.lines.join('\n'))),
23
34
  "...",
24
35
  React.createElement("br", null)));
25
36
  }
@@ -1 +1 @@
1
- {"version":3,"file":"ResourceDiff.js","sources":["../../src/ResourceDiff.tsx"],"sourcesContent":["import { stringify } from '@medplum/core';\nimport { Resource } from '@medplum/fhirtypes';\nimport React from 'react';\nimport { Delta, diff } from './utils/diff';\nimport './ResourceDiff.css';\n\nexport interface ResourceDiffProps {\n original: Resource;\n revised: Resource;\n ignoreMeta?: boolean;\n}\n\nexport function ResourceDiff(props: ResourceDiffProps): JSX.Element {\n let originalResource = props.original;\n let revisedResource = props.revised;\n\n if (props.ignoreMeta) {\n originalResource = { ...originalResource, meta: undefined };\n revisedResource = { ...revisedResource, meta: undefined };\n }\n\n const original = stringify(originalResource, true).match(/[^\\r\\n]+/g) as string[];\n const revised = stringify(revisedResource, true).match(/[^\\r\\n]+/g) as string[];\n const deltas = diff(original, revised);\n return (\n <pre style={{ color: 'gray' }}>\n {deltas.map((delta, index) => (\n <ChangeDiff key={'delta' + index} delta={delta} />\n ))}\n </pre>\n );\n}\n\nfunction ChangeDiff(props: { delta: Delta }): JSX.Element {\n return (\n <>\n ...\n <br />\n {props.delta.original.lines.length > 0 && (\n <div className=\"medplum-diff-removed\">{props.delta.original.lines.join('\\n')}</div>\n )}\n {props.delta.revised.lines.length > 0 && (\n <div className=\"medplum-diff-added\">{props.delta.revised.lines.join('\\n')}</div>\n )}\n ...\n <br />\n </>\n );\n}\n"],"names":[],"mappings":";;;;AAYM,SAAU,YAAY,CAAC,KAAwB,EAAA;AACnD,IAAA,IAAI,gBAAgB,GAAG,KAAK,CAAC,QAAQ,CAAC;AACtC,IAAA,IAAI,eAAe,GAAG,KAAK,CAAC,OAAO,CAAC;IAEpC,IAAI,KAAK,CAAC,UAAU,EAAE;AACpB,QAAA,gBAAgB,mCAAQ,gBAAgB,CAAA,EAAA,EAAE,IAAI,EAAE,SAAS,GAAE,CAAC;AAC5D,QAAA,eAAe,mCAAQ,eAAe,CAAA,EAAA,EAAE,IAAI,EAAE,SAAS,GAAE,CAAC;AAC3D,KAAA;AAED,IAAA,MAAM,QAAQ,GAAG,SAAS,CAAC,gBAAgB,EAAE,IAAI,CAAC,CAAC,KAAK,CAAC,WAAW,CAAa,CAAC;AAClF,IAAA,MAAM,OAAO,GAAG,SAAS,CAAC,eAAe,EAAE,IAAI,CAAC,CAAC,KAAK,CAAC,WAAW,CAAa,CAAC;IAChF,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;AACvC,IAAA,QACE,KAAK,CAAA,aAAA,CAAA,KAAA,EAAA,EAAA,KAAK,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,EAAA,EAC1B,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,KAAK,MACvB,KAAC,CAAA,aAAA,CAAA,UAAU,IAAC,GAAG,EAAE,OAAO,GAAG,KAAK,EAAE,KAAK,EAAE,KAAK,EAAA,CAAI,CACnD,CAAC,CACE,EACN;AACJ,CAAC;AAED,SAAS,UAAU,CAAC,KAAuB,EAAA;AACzC,IAAA,QACE,KAAA,CAAA,aAAA,CAAA,KAAA,CAAA,QAAA,EAAA,IAAA;;QAEE,KAAM,CAAA,aAAA,CAAA,IAAA,EAAA,IAAA,CAAA;AACL,QAAA,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,KACpC,6BAAK,SAAS,EAAC,sBAAsB,EAAA,EAAE,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAO,CACpF;AACA,QAAA,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,KACnC,6BAAK,SAAS,EAAC,oBAAoB,EAAA,EAAE,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAO,CACjF;;QAED,KAAM,CAAA,aAAA,CAAA,IAAA,EAAA,IAAA,CAAA,CACL,EACH;AACJ;;;;"}
1
+ {"version":3,"file":"ResourceDiff.js","sources":["../../src/ResourceDiff.tsx"],"sourcesContent":["import { createStyles } from '@mantine/core';\nimport { stringify } from '@medplum/core';\nimport { Resource } from '@medplum/fhirtypes';\nimport React from 'react';\nimport { Delta, diff } from './utils/diff';\n\nconst useStyles = createStyles((theme) => ({\n removed: {\n color: theme.colors.red[7],\n textDecoration: 'line-through',\n },\n\n added: {\n color: theme.colors.green[7],\n },\n}));\n\nexport interface ResourceDiffProps {\n original: Resource;\n revised: Resource;\n ignoreMeta?: boolean;\n}\n\nexport function ResourceDiff(props: ResourceDiffProps): JSX.Element {\n let originalResource = props.original;\n let revisedResource = props.revised;\n\n if (props.ignoreMeta) {\n originalResource = { ...originalResource, meta: undefined };\n revisedResource = { ...revisedResource, meta: undefined };\n }\n\n const original = stringify(originalResource, true).match(/[^\\r\\n]+/g) as string[];\n const revised = stringify(revisedResource, true).match(/[^\\r\\n]+/g) as string[];\n const deltas = diff(original, revised);\n return (\n <pre style={{ color: 'gray' }}>\n {deltas.map((delta, index) => (\n <ChangeDiff key={'delta' + index} delta={delta} />\n ))}\n </pre>\n );\n}\n\nfunction ChangeDiff(props: { delta: Delta }): JSX.Element {\n const { classes } = useStyles();\n return (\n <>\n ...\n <br />\n {props.delta.original.lines.length > 0 && (\n <div className={classes.removed}>{props.delta.original.lines.join('\\n')}</div>\n )}\n {props.delta.revised.lines.length > 0 && (\n <div className={classes.added}>{props.delta.revised.lines.join('\\n')}</div>\n )}\n ...\n <br />\n </>\n );\n}\n"],"names":[],"mappings":";;;;;AAMA,MAAM,SAAS,GAAG,YAAY,CAAC,CAAC,KAAK,MAAM;AACzC,IAAA,OAAO,EAAE;QACP,KAAK,EAAE,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;AAC1B,QAAA,cAAc,EAAE,cAAc;AAC/B,KAAA;AAED,IAAA,KAAK,EAAE;QACL,KAAK,EAAE,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;AAC7B,KAAA;AACF,CAAA,CAAC,CAAC,CAAC;AAQE,SAAU,YAAY,CAAC,KAAwB,EAAA;AACnD,IAAA,IAAI,gBAAgB,GAAG,KAAK,CAAC,QAAQ,CAAC;AACtC,IAAA,IAAI,eAAe,GAAG,KAAK,CAAC,OAAO,CAAC;IAEpC,IAAI,KAAK,CAAC,UAAU,EAAE;AACpB,QAAA,gBAAgB,mCAAQ,gBAAgB,CAAA,EAAA,EAAE,IAAI,EAAE,SAAS,GAAE,CAAC;AAC5D,QAAA,eAAe,mCAAQ,eAAe,CAAA,EAAA,EAAE,IAAI,EAAE,SAAS,GAAE,CAAC;AAC3D,KAAA;AAED,IAAA,MAAM,QAAQ,GAAG,SAAS,CAAC,gBAAgB,EAAE,IAAI,CAAC,CAAC,KAAK,CAAC,WAAW,CAAa,CAAC;AAClF,IAAA,MAAM,OAAO,GAAG,SAAS,CAAC,eAAe,EAAE,IAAI,CAAC,CAAC,KAAK,CAAC,WAAW,CAAa,CAAC;IAChF,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;AACvC,IAAA,QACE,KAAK,CAAA,aAAA,CAAA,KAAA,EAAA,EAAA,KAAK,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,EAAA,EAC1B,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,KAAK,MACvB,KAAC,CAAA,aAAA,CAAA,UAAU,IAAC,GAAG,EAAE,OAAO,GAAG,KAAK,EAAE,KAAK,EAAE,KAAK,EAAA,CAAI,CACnD,CAAC,CACE,EACN;AACJ,CAAC;AAED,SAAS,UAAU,CAAC,KAAuB,EAAA;AACzC,IAAA,MAAM,EAAE,OAAO,EAAE,GAAG,SAAS,EAAE,CAAC;AAChC,IAAA,QACE,KAAA,CAAA,aAAA,CAAA,KAAA,CAAA,QAAA,EAAA,IAAA;;QAEE,KAAM,CAAA,aAAA,CAAA,IAAA,EAAA,IAAA,CAAA;AACL,QAAA,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,KACpC,KAAA,CAAA,aAAA,CAAA,KAAA,EAAA,EAAK,SAAS,EAAE,OAAO,CAAC,OAAO,EAAG,EAAA,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAO,CAC/E;AACA,QAAA,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,KACnC,KAAA,CAAA,aAAA,CAAA,KAAA,EAAA,EAAK,SAAS,EAAE,OAAO,CAAC,KAAK,EAAG,EAAA,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAO,CAC5E;;QAED,KAAM,CAAA,aAAA,CAAA,IAAA,EAAA,IAAA,CAAA,CACL,EACH;AACJ;;;;"}
@@ -1,7 +1,5 @@
1
1
  /// <reference types="react" />
2
2
  import { Resource } from '@medplum/fhirtypes';
3
- import './ResourceDiff.css';
4
- import './ResourceDiffTable.css';
5
3
  export interface ResourceDiffTableProps {
6
4
  original: Resource;
7
5
  revised: Resource;
@@ -1,9 +1,31 @@
1
+ import { createStyles } from '@mantine/core';
1
2
  import { toTypedValue, stringify, getPropertyDisplayName } from '@medplum/core';
2
3
  import React, { useState, useEffect } from 'react';
3
4
  import { useMedplum } from './MedplumProvider.js';
4
5
  import { getValueAndType, ResourcePropertyDisplay } from './ResourcePropertyDisplay.js';
5
6
 
7
+ const useStyles = createStyles((theme) => ({
8
+ root: {
9
+ borderCollapse: 'collapse',
10
+ width: '100%',
11
+ '& tr': {
12
+ borderTop: `0.1px solid ${theme.colors.gray[3]}`,
13
+ },
14
+ '& th, & td': {
15
+ padding: `${theme.spacing.sm}px ${theme.spacing.sm}px`,
16
+ verticalAlign: 'top',
17
+ },
18
+ },
19
+ removed: {
20
+ color: theme.colors.red[7],
21
+ textDecoration: 'line-through',
22
+ },
23
+ added: {
24
+ color: theme.colors.green[7],
25
+ },
26
+ }));
6
27
  function ResourceDiffTable(props) {
28
+ const { classes } = useStyles();
7
29
  const medplum = useMedplum();
8
30
  const [schema, setSchema] = useState();
9
31
  useEffect(() => {
@@ -16,7 +38,7 @@ function ResourceDiffTable(props) {
16
38
  if (!typeSchema) {
17
39
  return null;
18
40
  }
19
- return (React.createElement("table", { className: "medplum-diff-table" },
41
+ return (React.createElement("table", { className: classes.root },
20
42
  React.createElement("colgroup", null,
21
43
  React.createElement("col", { style: { width: '30%' } }),
22
44
  React.createElement("col", { style: { width: '35%' } }),
@@ -42,9 +64,9 @@ function ResourceDiffTable(props) {
42
64
  }
43
65
  return (React.createElement("tr", { key: key },
44
66
  React.createElement("td", null, getPropertyDisplayName(key)),
45
- React.createElement("td", { className: "medplum-diff-removed" },
67
+ React.createElement("td", { className: classes.removed },
46
68
  React.createElement(ResourcePropertyDisplay, { property: property, propertyType: originalPropertyType, value: originalPropertyValue, ignoreMissingValues: true })),
47
- React.createElement("td", { className: "medplum-diff-added" },
69
+ React.createElement("td", { className: classes.added },
48
70
  React.createElement(ResourcePropertyDisplay, { property: property, propertyType: revisedPropertyType, value: revisedPropertyValue, ignoreMissingValues: true }))));
49
71
  }))));
50
72
  }
@@ -1 +1 @@
1
- {"version":3,"file":"ResourceDiffTable.js","sources":["../../src/ResourceDiffTable.tsx"],"sourcesContent":["import { getPropertyDisplayName, IndexedStructureDefinition, stringify, toTypedValue } from '@medplum/core';\nimport { Resource } from '@medplum/fhirtypes';\nimport React, { useEffect, useState } from 'react';\nimport { useMedplum } from './MedplumProvider';\nimport { getValueAndType, ResourcePropertyDisplay } from './ResourcePropertyDisplay';\nimport './ResourceDiff.css';\nimport './ResourceDiffTable.css';\n\nexport interface ResourceDiffTableProps {\n original: Resource;\n revised: Resource;\n}\n\nexport function ResourceDiffTable(props: ResourceDiffTableProps): JSX.Element | null {\n const medplum = useMedplum();\n const [schema, setSchema] = useState<IndexedStructureDefinition | undefined>();\n\n useEffect(() => {\n medplum.requestSchema(props.original.resourceType).then(setSchema).catch(console.log);\n }, [medplum, props.original.resourceType]);\n\n if (!schema) {\n return null;\n }\n\n const typeSchema = schema.types[props.original.resourceType];\n if (!typeSchema) {\n return null;\n }\n\n return (\n <table className=\"medplum-diff-table\">\n <colgroup>\n <col style={{ width: '30%' }} />\n <col style={{ width: '35%' }} />\n <col style={{ width: '35%' }} />\n </colgroup>\n <thead>\n <tr>\n <th>Property</th>\n <th>Before</th>\n <th>After</th>\n </tr>\n </thead>\n <tbody>\n {Object.entries(typeSchema.properties).map((entry) => {\n const key = entry[0];\n if (key === 'id' || key === 'meta') {\n return null;\n }\n\n const property = entry[1];\n const [originalPropertyValue, originalPropertyType] = getValueAndType(toTypedValue(props.original), key);\n const [revisedPropertyValue, revisedPropertyType] = getValueAndType(toTypedValue(props.revised), key);\n if (isEmpty(originalPropertyValue) && isEmpty(revisedPropertyValue)) {\n return null;\n }\n\n if (stringify(originalPropertyValue) === stringify(revisedPropertyValue)) {\n return null;\n }\n\n return (\n <tr key={key}>\n <td>{getPropertyDisplayName(key)}</td>\n <td className=\"medplum-diff-removed\">\n <ResourcePropertyDisplay\n property={property}\n propertyType={originalPropertyType}\n value={originalPropertyValue}\n ignoreMissingValues={true}\n />\n </td>\n <td className=\"medplum-diff-added\">\n <ResourcePropertyDisplay\n property={property}\n propertyType={revisedPropertyType}\n value={revisedPropertyValue}\n ignoreMissingValues={true}\n />\n </td>\n </tr>\n );\n })}\n </tbody>\n </table>\n );\n}\n\nfunction isEmpty(value: unknown): boolean {\n return (\n !value ||\n (Array.isArray(value) && value.length === 0) ||\n (typeof value === 'object' && Object.keys(value).length === 0)\n );\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ResourceDiffTable.js","sources":["../../src/ResourceDiffTable.tsx"],"sourcesContent":["import { createStyles } from '@mantine/core';\nimport { getPropertyDisplayName, IndexedStructureDefinition, stringify, toTypedValue } from '@medplum/core';\nimport { Resource } from '@medplum/fhirtypes';\nimport React, { useEffect, useState } from 'react';\nimport { useMedplum } from './MedplumProvider';\nimport { getValueAndType, ResourcePropertyDisplay } from './ResourcePropertyDisplay';\n\nconst useStyles = createStyles((theme) => ({\n root: {\n borderCollapse: 'collapse',\n width: '100%',\n\n '& tr': {\n borderTop: `0.1px solid ${theme.colors.gray[3]}`,\n },\n\n '& th, & td': {\n padding: `${theme.spacing.sm}px ${theme.spacing.sm}px`,\n verticalAlign: 'top',\n },\n },\n\n removed: {\n color: theme.colors.red[7],\n textDecoration: 'line-through',\n },\n\n added: {\n color: theme.colors.green[7],\n },\n}));\n\nexport interface ResourceDiffTableProps {\n original: Resource;\n revised: Resource;\n}\n\nexport function ResourceDiffTable(props: ResourceDiffTableProps): JSX.Element | null {\n const { classes } = useStyles();\n const medplum = useMedplum();\n const [schema, setSchema] = useState<IndexedStructureDefinition | undefined>();\n\n useEffect(() => {\n medplum.requestSchema(props.original.resourceType).then(setSchema).catch(console.log);\n }, [medplum, props.original.resourceType]);\n\n if (!schema) {\n return null;\n }\n\n const typeSchema = schema.types[props.original.resourceType];\n if (!typeSchema) {\n return null;\n }\n\n return (\n <table className={classes.root}>\n <colgroup>\n <col style={{ width: '30%' }} />\n <col style={{ width: '35%' }} />\n <col style={{ width: '35%' }} />\n </colgroup>\n <thead>\n <tr>\n <th>Property</th>\n <th>Before</th>\n <th>After</th>\n </tr>\n </thead>\n <tbody>\n {Object.entries(typeSchema.properties).map((entry) => {\n const key = entry[0];\n if (key === 'id' || key === 'meta') {\n return null;\n }\n\n const property = entry[1];\n const [originalPropertyValue, originalPropertyType] = getValueAndType(toTypedValue(props.original), key);\n const [revisedPropertyValue, revisedPropertyType] = getValueAndType(toTypedValue(props.revised), key);\n if (isEmpty(originalPropertyValue) && isEmpty(revisedPropertyValue)) {\n return null;\n }\n\n if (stringify(originalPropertyValue) === stringify(revisedPropertyValue)) {\n return null;\n }\n\n return (\n <tr key={key}>\n <td>{getPropertyDisplayName(key)}</td>\n <td className={classes.removed}>\n <ResourcePropertyDisplay\n property={property}\n propertyType={originalPropertyType}\n value={originalPropertyValue}\n ignoreMissingValues={true}\n />\n </td>\n <td className={classes.added}>\n <ResourcePropertyDisplay\n property={property}\n propertyType={revisedPropertyType}\n value={revisedPropertyValue}\n ignoreMissingValues={true}\n />\n </td>\n </tr>\n );\n })}\n </tbody>\n </table>\n );\n}\n\nfunction isEmpty(value: unknown): boolean {\n return (\n !value ||\n (Array.isArray(value) && value.length === 0) ||\n (typeof value === 'object' && Object.keys(value).length === 0)\n );\n}\n"],"names":[],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { TextInput, Group, Button } from '@mantine/core';
1
+ import { Stack, TextInput, Group, Button } from '@mantine/core';
2
2
  import { capitalize } from '@medplum/core';
3
3
  import React, { useState, useEffect } from 'react';
4
4
  import { BackboneElementInput } from './BackboneElementInput.js';
@@ -26,10 +26,11 @@ function ResourceForm(props) {
26
26
  props.onSubmit(value);
27
27
  }
28
28
  } },
29
- React.createElement(FormSection, { title: "Resource Type", htmlFor: "resourceType", outcome: props.outcome },
30
- React.createElement(TextInput, { name: "resourceType", defaultValue: value.resourceType, disabled: true })),
31
- React.createElement(FormSection, { title: "ID", htmlFor: "id", outcome: props.outcome },
32
- React.createElement(TextInput, { name: "id", defaultValue: value.id, disabled: true })),
29
+ React.createElement(Stack, { mb: "xl" },
30
+ React.createElement(FormSection, { title: "Resource Type", htmlFor: "resourceType", outcome: props.outcome },
31
+ React.createElement(TextInput, { name: "resourceType", defaultValue: value.resourceType, disabled: true })),
32
+ React.createElement(FormSection, { title: "ID", htmlFor: "id", outcome: props.outcome },
33
+ React.createElement(TextInput, { name: "id", defaultValue: value.id, disabled: true }))),
33
34
  React.createElement(BackboneElementInput, { typeName: value.resourceType, defaultValue: value, outcome: props.outcome, onChange: setValue }),
34
35
  React.createElement(Group, null,
35
36
  React.createElement(Button, { type: "submit" }, "OK"),
@@ -1 +1 @@
1
- {"version":3,"file":"ResourceForm.js","sources":["../../src/ResourceForm.tsx"],"sourcesContent":["import { Button, Group, TextInput } from '@mantine/core';\nimport { capitalize, IndexedStructureDefinition } from '@medplum/core';\nimport { ElementDefinition, ElementDefinitionType, OperationOutcome, Reference, Resource } from '@medplum/fhirtypes';\nimport React, { useEffect, useState } from 'react';\nimport { BackboneElementInput } from './BackboneElementInput';\nimport { FormSection } from './FormSection';\nimport { useMedplum } from './MedplumProvider';\nimport { useResource } from './useResource';\n\nexport interface ResourceFormProps {\n defaultValue: Resource | Reference;\n outcome?: OperationOutcome;\n onSubmit: (resource: Resource) => void;\n onDelete?: (resource: Resource) => void;\n}\n\nexport function ResourceForm(props: ResourceFormProps): JSX.Element {\n const medplum = useMedplum();\n const defaultValue = useResource(props.defaultValue);\n const [schema, setSchema] = useState<IndexedStructureDefinition | undefined>();\n const [value, setValue] = useState<Resource | undefined>();\n\n useEffect(() => {\n if (defaultValue) {\n setValue(JSON.parse(JSON.stringify(defaultValue)));\n medplum.requestSchema(defaultValue.resourceType).then(setSchema).catch(console.log);\n }\n }, [medplum, defaultValue]);\n\n if (!schema || !value) {\n return <div>Loading...</div>;\n }\n\n return (\n <form\n noValidate\n autoComplete=\"off\"\n onSubmit={(e: React.FormEvent) => {\n e.preventDefault();\n if (props.onSubmit) {\n props.onSubmit(value);\n }\n }}\n >\n <FormSection title=\"Resource Type\" htmlFor=\"resourceType\" outcome={props.outcome}>\n <TextInput name=\"resourceType\" defaultValue={value.resourceType} disabled={true} />\n </FormSection>\n <FormSection title=\"ID\" htmlFor=\"id\" outcome={props.outcome}>\n <TextInput name=\"id\" defaultValue={value.id} disabled={true} />\n </FormSection>\n <BackboneElementInput\n typeName={value.resourceType}\n defaultValue={value}\n outcome={props.outcome}\n onChange={setValue}\n />\n <Group>\n <Button type=\"submit\">OK</Button>\n {props.onDelete && (\n <Button\n variant=\"outline\"\n color=\"red\"\n type=\"button\"\n onClick={() => {\n (props.onDelete as (resource: Resource) => void)(value);\n }}\n >\n Delete\n </Button>\n )}\n </Group>\n </form>\n );\n}\n\nexport function setPropertyValue(\n obj: any,\n key: string,\n propName: string,\n elementDefinition: ElementDefinition,\n value: any\n): any {\n const types = elementDefinition.type as ElementDefinitionType[];\n if (types.length > 1) {\n for (const type of types) {\n const compoundKey = key.replace('[x]', capitalize(type.code as string));\n if (compoundKey in obj) {\n delete obj[compoundKey];\n }\n }\n }\n obj[propName] = value;\n return obj;\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ResourceForm.js","sources":["../../src/ResourceForm.tsx"],"sourcesContent":["import { Button, Group, Stack, TextInput } from '@mantine/core';\nimport { capitalize, IndexedStructureDefinition } from '@medplum/core';\nimport { ElementDefinition, ElementDefinitionType, OperationOutcome, Reference, Resource } from '@medplum/fhirtypes';\nimport React, { useEffect, useState } from 'react';\nimport { BackboneElementInput } from './BackboneElementInput';\nimport { FormSection } from './FormSection';\nimport { useMedplum } from './MedplumProvider';\nimport { useResource } from './useResource';\n\nexport interface ResourceFormProps {\n defaultValue: Resource | Reference;\n outcome?: OperationOutcome;\n onSubmit: (resource: Resource) => void;\n onDelete?: (resource: Resource) => void;\n}\n\nexport function ResourceForm(props: ResourceFormProps): JSX.Element {\n const medplum = useMedplum();\n const defaultValue = useResource(props.defaultValue);\n const [schema, setSchema] = useState<IndexedStructureDefinition | undefined>();\n const [value, setValue] = useState<Resource | undefined>();\n\n useEffect(() => {\n if (defaultValue) {\n setValue(JSON.parse(JSON.stringify(defaultValue)));\n medplum.requestSchema(defaultValue.resourceType).then(setSchema).catch(console.log);\n }\n }, [medplum, defaultValue]);\n\n if (!schema || !value) {\n return <div>Loading...</div>;\n }\n\n return (\n <form\n noValidate\n autoComplete=\"off\"\n onSubmit={(e: React.FormEvent) => {\n e.preventDefault();\n if (props.onSubmit) {\n props.onSubmit(value);\n }\n }}\n >\n <Stack mb=\"xl\">\n <FormSection title=\"Resource Type\" htmlFor=\"resourceType\" outcome={props.outcome}>\n <TextInput name=\"resourceType\" defaultValue={value.resourceType} disabled={true} />\n </FormSection>\n <FormSection title=\"ID\" htmlFor=\"id\" outcome={props.outcome}>\n <TextInput name=\"id\" defaultValue={value.id} disabled={true} />\n </FormSection>\n </Stack>\n <BackboneElementInput\n typeName={value.resourceType}\n defaultValue={value}\n outcome={props.outcome}\n onChange={setValue}\n />\n <Group>\n <Button type=\"submit\">OK</Button>\n {props.onDelete && (\n <Button\n variant=\"outline\"\n color=\"red\"\n type=\"button\"\n onClick={() => {\n (props.onDelete as (resource: Resource) => void)(value);\n }}\n >\n Delete\n </Button>\n )}\n </Group>\n </form>\n );\n}\n\nexport function setPropertyValue(\n obj: any,\n key: string,\n propName: string,\n elementDefinition: ElementDefinition,\n value: any\n): any {\n const types = elementDefinition.type as ElementDefinitionType[];\n if (types.length > 1) {\n for (const type of types) {\n const compoundKey = key.replace('[x]', capitalize(type.code as string));\n if (compoundKey in obj) {\n delete obj[compoundKey];\n }\n }\n }\n obj[propName] = value;\n return obj;\n}\n"],"names":[],"mappings":"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"}
@@ -6,6 +6,22 @@ import { useMedplum } from './MedplumProvider.js';
6
6
  import { ResourceAvatar } from './ResourceAvatar.js';
7
7
  import { useResource } from './useResource.js';
8
8
 
9
+ /**
10
+ * Defines which search parameters will be used by the type ahead to search for each resourceType
11
+ */
12
+ const SEARCH_CODES = {
13
+ Schedule: '_id',
14
+ Task: '_id',
15
+ Patient: 'name',
16
+ Practitioner: 'name',
17
+ Questionnaire: 'name',
18
+ ServiceRequest: '_id',
19
+ DiagnosticReport: '_id',
20
+ Specimen: '_id',
21
+ Observation: 'code',
22
+ RequestGroup: '_id',
23
+ ActivityDefinition: 'name',
24
+ };
9
25
  function ResourceInput(props) {
10
26
  const medplum = useMedplum();
11
27
  const defaultValue = useResource(props.defaultValue);
@@ -20,7 +36,12 @@ function ResourceInput(props) {
20
36
  function loadValues(input) {
21
37
  return __awaiter(this, void 0, void 0, function* () {
22
38
  setLoading(true);
23
- const resources = yield medplum.searchResources(props.resourceType, 'name=' + encodeURIComponent(input) + '&_count=10');
39
+ const searchCode = SEARCH_CODES[props.resourceType] || 'name';
40
+ const searchParams = new URLSearchParams({
41
+ [searchCode]: encodeURIComponent(input),
42
+ _count: '10',
43
+ });
44
+ const resources = yield medplum.searchResources(props.resourceType, searchParams);
24
45
  setData(resources.map((resource) => ({ value: getDisplayString(resource), resource })));
25
46
  setLoading(false);
26
47
  });
@@ -1 +1 @@
1
- {"version":3,"file":"ResourceInput.js","sources":["../../src/ResourceInput.tsx"],"sourcesContent":["import { Autocomplete, AutocompleteItem, Group, Loader, Text } from '@mantine/core';\nimport { getDisplayString } from '@medplum/core';\nimport { Patient, Reference, Resource, ResourceType } from '@medplum/fhirtypes';\nimport React, { forwardRef, useEffect, useState } from 'react';\nimport { useMedplum } from './MedplumProvider';\nimport { ResourceAvatar } from './ResourceAvatar';\nimport { useResource } from './useResource';\n\nexport interface ResourceInputProps<T extends Resource = Resource> {\n readonly resourceType: ResourceType;\n readonly name: string;\n readonly defaultValue?: T | Reference<T>;\n readonly placeholder?: string;\n readonly loadOnFocus?: boolean;\n readonly onChange?: (value: T | undefined) => void;\n}\n\nexport function ResourceInput<T extends Resource = Resource>(props: ResourceInputProps<T>): JSX.Element {\n const medplum = useMedplum();\n const defaultValue = useResource(props.defaultValue);\n const [value, setValue] = useState<string>(defaultValue ? getDisplayString(defaultValue) : '');\n const [loading, setLoading] = useState(false);\n const [data, setData] = useState<AutocompleteItem[]>([]);\n\n useEffect(() => {\n if (defaultValue) {\n setValue(getDisplayString(defaultValue));\n }\n }, [defaultValue, setValue]);\n\n async function loadValues(input: string): Promise<void> {\n setLoading(true);\n const resources = await medplum.searchResources(\n props.resourceType,\n 'name=' + encodeURIComponent(input) + '&_count=10'\n );\n setData(resources.map((resource) => ({ value: getDisplayString(resource), resource })));\n setLoading(false);\n }\n\n async function handleChange(val: string): Promise<void> {\n setValue(val);\n return loadValues(val);\n }\n\n function handleSelect(item: AutocompleteItem): void {\n setValue(item.value);\n setData([]);\n if (props.onChange) {\n props.onChange(item.resource);\n }\n }\n\n return (\n <Autocomplete\n itemComponent={ItemComponent}\n value={value}\n data={data}\n placeholder={props.placeholder}\n onFocus={() => loadValues(value)}\n onChange={handleChange}\n onItemSubmit={handleSelect}\n rightSection={loading ? <Loader size={16} /> : null}\n />\n );\n}\n\nconst ItemComponent = forwardRef<HTMLDivElement, any>(({ value, resource, ...others }: any, ref) => {\n return (\n <div ref={ref} {...others}>\n <Group noWrap>\n <ResourceAvatar value={resource} />\n <div>\n <Text>{value}</Text>\n <Text size=\"xs\" color=\"dimmed\">\n {(resource as Patient).birthDate}\n </Text>\n </div>\n </Group>\n </div>\n );\n});\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ResourceInput.js","sources":["../../src/ResourceInput.tsx"],"sourcesContent":["import { Autocomplete, AutocompleteItem, Group, Loader, Text } from '@mantine/core';\nimport { getDisplayString } from '@medplum/core';\nimport { Patient, Reference, Resource, ResourceType } from '@medplum/fhirtypes';\nimport React, { forwardRef, useEffect, useState } from 'react';\nimport { useMedplum } from './MedplumProvider';\nimport { ResourceAvatar } from './ResourceAvatar';\nimport { useResource } from './useResource';\n\n/**\n * Defines which search parameters will be used by the type ahead to search for each resourceType\n */\nconst SEARCH_CODES: Record<string, string> = {\n Schedule: '_id',\n Task: '_id',\n Patient: 'name',\n Practitioner: 'name',\n Questionnaire: 'name',\n ServiceRequest: '_id',\n DiagnosticReport: '_id',\n Specimen: '_id',\n Observation: 'code',\n RequestGroup: '_id',\n ActivityDefinition: 'name',\n};\n\nexport interface ResourceInputProps<T extends Resource = Resource> {\n readonly resourceType: ResourceType;\n readonly name: string;\n readonly defaultValue?: T | Reference<T>;\n readonly placeholder?: string;\n readonly loadOnFocus?: boolean;\n readonly onChange?: (value: T | undefined) => void;\n}\n\nexport function ResourceInput<T extends Resource = Resource>(props: ResourceInputProps<T>): JSX.Element {\n const medplum = useMedplum();\n const defaultValue = useResource(props.defaultValue);\n const [value, setValue] = useState<string>(defaultValue ? getDisplayString(defaultValue) : '');\n const [loading, setLoading] = useState(false);\n const [data, setData] = useState<AutocompleteItem[]>([]);\n\n useEffect(() => {\n if (defaultValue) {\n setValue(getDisplayString(defaultValue));\n }\n }, [defaultValue, setValue]);\n\n async function loadValues(input: string): Promise<void> {\n setLoading(true);\n const searchCode = SEARCH_CODES[props.resourceType] || 'name';\n const searchParams = new URLSearchParams({\n [searchCode]: encodeURIComponent(input),\n _count: '10',\n });\n\n const resources = await medplum.searchResources(props.resourceType, searchParams);\n setData(resources.map((resource) => ({ value: getDisplayString(resource), resource })));\n setLoading(false);\n }\n\n async function handleChange(val: string): Promise<void> {\n setValue(val);\n return loadValues(val);\n }\n\n function handleSelect(item: AutocompleteItem): void {\n setValue(item.value);\n setData([]);\n if (props.onChange) {\n props.onChange(item.resource);\n }\n }\n\n return (\n <Autocomplete\n itemComponent={ItemComponent}\n value={value}\n data={data}\n placeholder={props.placeholder}\n onFocus={() => loadValues(value)}\n onChange={handleChange}\n onItemSubmit={handleSelect}\n rightSection={loading ? <Loader size={16} /> : null}\n />\n );\n}\n\nconst ItemComponent = forwardRef<HTMLDivElement, any>(({ value, resource, ...others }: any, ref) => {\n return (\n <div ref={ref} {...others}>\n <Group noWrap>\n <ResourceAvatar value={resource} />\n <div>\n <Text>{value}</Text>\n <Text size=\"xs\" color=\"dimmed\">\n {(resource as Patient).birthDate}\n </Text>\n </div>\n </Group>\n </div>\n );\n});\n"],"names":[],"mappings":"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"}
@@ -1,6 +1,7 @@
1
1
  /// <reference types="react" />
2
+ import { TextProps } from '@mantine/core';
2
3
  import { Reference, Resource } from '@medplum/fhirtypes';
3
- export interface ResourceNameProps {
4
+ export interface ResourceNameProps extends TextProps {
4
5
  value?: Reference | Resource;
5
6
  link?: boolean;
6
7
  }
@@ -1,15 +1,18 @@
1
+ import { __rest } from './node_modules/tslib/tslib.es6.js';
2
+ import { Text } from '@mantine/core';
1
3
  import { getDisplayString } from '@medplum/core';
2
4
  import React from 'react';
3
5
  import { MedplumLink } from './MedplumLink.js';
4
6
  import { useResource } from './useResource.js';
5
7
 
6
8
  function ResourceName(props) {
7
- const resource = useResource(props.value);
9
+ const { value, link } = props, rest = __rest(props, ["value", "link"]);
10
+ const resource = useResource(value);
8
11
  if (!resource) {
9
12
  return null;
10
13
  }
11
14
  const text = getDisplayString(resource);
12
- return props.link ? React.createElement(MedplumLink, { to: resource }, text) : React.createElement("span", null, text);
15
+ return link ? (React.createElement(MedplumLink, Object.assign({ to: resource }, rest), text)) : (React.createElement(Text, Object.assign({ component: "span" }, rest), text));
13
16
  }
14
17
 
15
18
  export { ResourceName };
@@ -1 +1 @@
1
- {"version":3,"file":"ResourceName.js","sources":["../../src/ResourceName.tsx"],"sourcesContent":["import { getDisplayString } from '@medplum/core';\nimport { Reference, Resource } from '@medplum/fhirtypes';\nimport React from 'react';\nimport { MedplumLink } from './MedplumLink';\nimport { useResource } from './useResource';\n\nexport interface ResourceNameProps {\n value?: Reference | Resource;\n link?: boolean;\n}\n\nexport function ResourceName(props: ResourceNameProps): JSX.Element | null {\n const resource = useResource(props.value);\n if (!resource) {\n return null;\n }\n\n const text = getDisplayString(resource);\n\n return props.link ? <MedplumLink to={resource}>{text}</MedplumLink> : <span>{text}</span>;\n}\n"],"names":[],"mappings":";;;;;AAWM,SAAU,YAAY,CAAC,KAAwB,EAAA;IACnD,MAAM,QAAQ,GAAG,WAAW,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IAC1C,IAAI,CAAC,QAAQ,EAAE;AACb,QAAA,OAAO,IAAI,CAAC;AACb,KAAA;AAED,IAAA,MAAM,IAAI,GAAG,gBAAgB,CAAC,QAAQ,CAAC,CAAC;IAExC,OAAO,KAAK,CAAC,IAAI,GAAG,KAAA,CAAA,aAAA,CAAC,WAAW,EAAC,EAAA,EAAE,EAAE,QAAQ,EAAA,EAAG,IAAI,CAAe,GAAG,KAAA,CAAA,aAAA,CAAA,MAAA,EAAA,IAAA,EAAO,IAAI,CAAQ,CAAC;AAC5F;;;;"}
1
+ {"version":3,"file":"ResourceName.js","sources":["../../src/ResourceName.tsx"],"sourcesContent":["import { Text, TextProps } from '@mantine/core';\nimport { getDisplayString } from '@medplum/core';\nimport { Reference, Resource } from '@medplum/fhirtypes';\nimport React from 'react';\nimport { MedplumLink } from './MedplumLink';\nimport { useResource } from './useResource';\n\nexport interface ResourceNameProps extends TextProps {\n value?: Reference | Resource;\n link?: boolean;\n}\n\nexport function ResourceName(props: ResourceNameProps): JSX.Element | null {\n const { value, link, ...rest } = props;\n const resource = useResource(value);\n if (!resource) {\n return null;\n }\n\n const text = getDisplayString(resource);\n\n return link ? (\n <MedplumLink to={resource} {...rest}>\n {text}\n </MedplumLink>\n ) : (\n <Text component=\"span\" {...rest}>\n {text}\n </Text>\n );\n}\n"],"names":[],"mappings":";;;;;;;AAYM,SAAU,YAAY,CAAC,KAAwB,EAAA;AACnD,IAAA,MAAM,EAAE,KAAK,EAAE,IAAI,EAAc,GAAA,KAAK,EAAd,IAAI,GAAK,MAAA,CAAA,KAAK,EAAhC,CAAA,OAAA,EAAA,MAAA,CAAwB,CAAQ,CAAC;AACvC,IAAA,MAAM,QAAQ,GAAG,WAAW,CAAC,KAAK,CAAC,CAAC;IACpC,IAAI,CAAC,QAAQ,EAAE;AACb,QAAA,OAAO,IAAI,CAAC;AACb,KAAA;AAED,IAAA,MAAM,IAAI,GAAG,gBAAgB,CAAC,QAAQ,CAAC,CAAC;AAExC,IAAA,OAAO,IAAI,IACT,KAAC,CAAA,aAAA,CAAA,WAAW,EAAC,MAAA,CAAA,MAAA,CAAA,EAAA,EAAE,EAAE,QAAQ,EAAM,EAAA,IAAI,GAChC,IAAI,CACO,KAEd,KAAA,CAAA,aAAA,CAAC,IAAI,EAAC,MAAA,CAAA,MAAA,CAAA,EAAA,SAAS,EAAC,MAAM,IAAK,IAAI,CAAA,EAC5B,IAAI,CACA,CACR,CAAC;AACJ;;;;"}
@@ -27,7 +27,7 @@ function ResourcePropertyDisplay(props) {
27
27
  }
28
28
  switch (propertyType) {
29
29
  case PropertyType.boolean:
30
- return React.createElement("div", null, value === undefined ? '' : Boolean(value).toString());
30
+ return React.createElement(React.Fragment, null, value === undefined ? '' : Boolean(value).toString());
31
31
  case PropertyType.SystemString:
32
32
  case PropertyType.code:
33
33
  case PropertyType.date:
@@ -37,18 +37,18 @@ function ResourcePropertyDisplay(props) {
37
37
  case PropertyType.unsignedInt:
38
38
  case PropertyType.uri:
39
39
  case PropertyType.url:
40
- return React.createElement("div", null, value);
40
+ return React.createElement(React.Fragment, null, value);
41
41
  case PropertyType.canonical:
42
42
  return React.createElement(ReferenceDisplay, { value: { reference: value }, link: props.link });
43
43
  case PropertyType.dateTime:
44
44
  case PropertyType.instant:
45
- return React.createElement("div", null, formatDateTime(value));
45
+ return React.createElement(React.Fragment, null, formatDateTime(value));
46
46
  case PropertyType.markdown:
47
47
  return React.createElement("pre", null, value);
48
48
  case PropertyType.Address:
49
49
  return React.createElement(AddressDisplay, { value: value });
50
50
  case PropertyType.Annotation:
51
- return React.createElement("div", null, value === null || value === void 0 ? void 0 : value.text);
51
+ return React.createElement(React.Fragment, null, value === null || value === void 0 ? void 0 : value.text);
52
52
  case PropertyType.Attachment:
53
53
  return React.createElement(AttachmentDisplay, { value: value, maxWidth: props.maxWidth });
54
54
  case PropertyType.CodeableConcept:
@@ -64,7 +64,7 @@ function ResourcePropertyDisplay(props) {
64
64
  case PropertyType.Identifier:
65
65
  return React.createElement(IdentifierDisplay, { value: value });
66
66
  case PropertyType.Period:
67
- return React.createElement("div", null, formatPeriod(value));
67
+ return React.createElement(React.Fragment, null, formatPeriod(value));
68
68
  case PropertyType.Quantity:
69
69
  return React.createElement(QuantityDisplay, { value: value });
70
70
  case PropertyType.Range:
@@ -74,7 +74,7 @@ function ResourcePropertyDisplay(props) {
74
74
  case PropertyType.Reference:
75
75
  return React.createElement(ReferenceDisplay, { value: value, link: props.link });
76
76
  case PropertyType.Timing:
77
- return React.createElement("div", null, formatTiming(value));
77
+ return React.createElement(React.Fragment, null, formatTiming(value));
78
78
  default:
79
79
  if (!(property === null || property === void 0 ? void 0 : property.path)) {
80
80
  throw Error(`Displaying property of type ${props.propertyType} requires element definition path`);