@medplum/react 1.0.2 → 1.0.4

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 (61) hide show
  1. package/dist/cjs/CodeableConceptDisplay/CodeableConceptDisplay.d.ts +1 -1
  2. package/dist/cjs/Container/Container.d.ts +3 -0
  3. package/dist/cjs/Document/Document.d.ts +3 -6
  4. package/dist/cjs/Panel/Panel.d.ts +11 -0
  5. package/dist/cjs/Timeline/Timeline.d.ts +2 -4
  6. package/dist/cjs/index.d.ts +13 -0
  7. package/dist/cjs/index.js +492 -447
  8. package/dist/cjs/index.js.map +1 -1
  9. package/dist/cjs/index.min.js +1 -1
  10. package/dist/cjs/index.min.js.map +1 -1
  11. package/dist/esm/AttachmentDisplay/AttachmentDisplay.js +2 -1
  12. package/dist/esm/AttachmentDisplay/AttachmentDisplay.js.map +1 -1
  13. package/dist/esm/BackboneElementDisplay/BackboneElementDisplay.js +3 -0
  14. package/dist/esm/BackboneElementDisplay/BackboneElementDisplay.js.map +1 -1
  15. package/dist/esm/CodeableConceptDisplay/CodeableConceptDisplay.d.ts +1 -1
  16. package/dist/esm/CodeableConceptDisplay/CodeableConceptDisplay.js +2 -14
  17. package/dist/esm/CodeableConceptDisplay/CodeableConceptDisplay.js.map +1 -1
  18. package/dist/esm/CodingDisplay/CodingDisplay.js +2 -2
  19. package/dist/esm/CodingDisplay/CodingDisplay.js.map +1 -1
  20. package/dist/esm/Container/Container.d.ts +3 -0
  21. package/dist/esm/Container/Container.js +20 -0
  22. package/dist/esm/Container/Container.js.map +1 -0
  23. package/dist/esm/DiagnosticReportDisplay/DiagnosticReportDisplay.js +2 -15
  24. package/dist/esm/DiagnosticReportDisplay/DiagnosticReportDisplay.js.map +1 -1
  25. package/dist/esm/Document/Document.d.ts +3 -6
  26. package/dist/esm/Document/Document.js +5 -6
  27. package/dist/esm/Document/Document.js.map +1 -1
  28. package/dist/esm/Panel/Panel.d.ts +11 -0
  29. package/dist/esm/Panel/Panel.js +35 -0
  30. package/dist/esm/Panel/Panel.js.map +1 -0
  31. package/dist/esm/PlanDefinitionBuilder/PlanDefinitionBuilder.js +3 -3
  32. package/dist/esm/PlanDefinitionBuilder/PlanDefinitionBuilder.js.map +1 -1
  33. package/dist/esm/QuestionnaireBuilder/QuestionnaireBuilder.js +6 -6
  34. package/dist/esm/QuestionnaireBuilder/QuestionnaireBuilder.js.map +1 -1
  35. package/dist/esm/ReferenceRangeEditor/ReferenceRangeEditor.js +4 -3
  36. package/dist/esm/ReferenceRangeEditor/ReferenceRangeEditor.js.map +1 -1
  37. package/dist/esm/ResourceInput/ResourceInput.js +1 -0
  38. package/dist/esm/ResourceInput/ResourceInput.js.map +1 -1
  39. package/dist/esm/ResourcePropertyDisplay/ResourcePropertyDisplay.js +4 -0
  40. package/dist/esm/ResourcePropertyDisplay/ResourcePropertyDisplay.js.map +1 -1
  41. package/dist/esm/ResourcePropertyInput/ResourcePropertyInput.js +4 -0
  42. package/dist/esm/ResourcePropertyInput/ResourcePropertyInput.js.map +1 -1
  43. package/dist/esm/ResourceTimeline/ResourceTimeline.js +3 -2
  44. package/dist/esm/ResourceTimeline/ResourceTimeline.js.map +1 -1
  45. package/dist/esm/SearchControl/SearchControl.js +2 -1
  46. package/dist/esm/SearchControl/SearchControl.js.map +1 -1
  47. package/dist/esm/Timeline/Timeline.d.ts +2 -4
  48. package/dist/esm/Timeline/Timeline.js +14 -10
  49. package/dist/esm/Timeline/Timeline.js.map +1 -1
  50. package/dist/esm/auth/AuthenticationForm.js +2 -2
  51. package/dist/esm/auth/AuthenticationForm.js.map +1 -1
  52. package/dist/esm/auth/NewProjectForm.js +5 -4
  53. package/dist/esm/auth/NewProjectForm.js.map +1 -1
  54. package/dist/esm/auth/NewUserForm.js +7 -6
  55. package/dist/esm/auth/NewUserForm.js.map +1 -1
  56. package/dist/esm/index.d.ts +13 -0
  57. package/dist/esm/index.js +13 -0
  58. package/dist/esm/index.js.map +1 -1
  59. package/dist/esm/index.min.js +1 -1
  60. package/dist/esm/index.min.js.map +1 -1
  61. package/package.json +5 -5
package/dist/cjs/index.js CHANGED
@@ -64,28 +64,6 @@
64
64
  React.createElement(core$1.TextInput, { placeholder: "Postal Code", defaultValue: value.postalCode, onChange: (e) => setPostalCode(e.currentTarget.value) })));
65
65
  }
66
66
 
67
- function AttachmentDisplay(props) {
68
- const value = props.value;
69
- const { contentType, url, title } = value !== null && value !== void 0 ? value : {};
70
- if (!url) {
71
- return null;
72
- }
73
- return (React.createElement("div", { "data-testid": "attachment-display" },
74
- (contentType === null || contentType === void 0 ? void 0 : contentType.startsWith('image/')) && (React.createElement("img", { "data-testid": "attachment-image", style: { maxWidth: props.maxWidth }, src: url, alt: value === null || value === void 0 ? void 0 : value.title })),
75
- (contentType === null || contentType === void 0 ? void 0 : contentType.startsWith('video/')) && (React.createElement("video", { "data-testid": "attachment-video", style: { maxWidth: props.maxWidth }, controls: true },
76
- React.createElement("source", { type: contentType, src: url }))),
77
- contentType === 'application/pdf' && !(title === null || title === void 0 ? void 0 : title.endsWith('.pdf')) && (React.createElement("div", { "data-testid": "attachment-pdf", style: { maxWidth: props.maxWidth, minHeight: 400 } },
78
- React.createElement("iframe", { width: "100%", height: "400", src: url + '#navpanes=0', allowFullScreen: true, frameBorder: 0, seamless: true }))),
79
- React.createElement("div", { "data-testid": "download-link", style: { padding: '2px 16px 16px 16px' } },
80
- React.createElement("a", { href: value === null || value === void 0 ? void 0 : value.url, "data-testid": "attachment-details", target: "_blank", rel: "noopener noreferrer" }, (value === null || value === void 0 ? void 0 : value.title) || 'Download'))));
81
- }
82
-
83
- function AttachmentArrayDisplay(props) {
84
- return (React.createElement("div", null, props.values &&
85
- props.values.map((v, index) => (React.createElement("div", { key: 'attatchment-' + index },
86
- React.createElement(AttachmentDisplay, { value: v, maxWidth: props.maxWidth }))))));
87
- }
88
-
89
67
  const reactContext = React.createContext(undefined);
90
68
  /**
91
69
  * The MedplumProvider component provides Medplum context state.
@@ -132,6 +110,49 @@
132
110
  return useMedplumContext().profile;
133
111
  }
134
112
 
113
+ function AnnotationInput(props) {
114
+ const author = useMedplumProfile();
115
+ const [value, setValue] = React.useState(props.defaultValue || {});
116
+ const valueRef = React.useRef();
117
+ valueRef.current = value;
118
+ function setText(text) {
119
+ const newValue = text
120
+ ? {
121
+ text,
122
+ authorReference: author && core.createReference(author),
123
+ time: new Date().toISOString(),
124
+ }
125
+ : {};
126
+ setValue(newValue);
127
+ if (props.onChange) {
128
+ props.onChange(newValue);
129
+ }
130
+ }
131
+ return (React.createElement(core$1.TextInput, { name: props.name, placeholder: "Annotation text", defaultValue: value.text, onChange: (e) => setText(e.currentTarget.value) }));
132
+ }
133
+
134
+ function AttachmentDisplay(props) {
135
+ const value = props.value;
136
+ const { contentType, url, title } = value !== null && value !== void 0 ? value : {};
137
+ if (!url) {
138
+ return null;
139
+ }
140
+ return (React.createElement("div", { "data-testid": "attachment-display" },
141
+ (contentType === null || contentType === void 0 ? void 0 : contentType.startsWith('image/')) && (React.createElement("img", { "data-testid": "attachment-image", style: { maxWidth: props.maxWidth }, src: url, alt: value === null || value === void 0 ? void 0 : value.title })),
142
+ (contentType === null || contentType === void 0 ? void 0 : contentType.startsWith('video/')) && (React.createElement("video", { "data-testid": "attachment-video", style: { maxWidth: props.maxWidth }, controls: true },
143
+ React.createElement("source", { type: contentType, src: url }))),
144
+ contentType === 'application/pdf' && !(title === null || title === void 0 ? void 0 : title.endsWith('.pdf')) && (React.createElement("div", { "data-testid": "attachment-pdf", style: { maxWidth: props.maxWidth, minHeight: 400 } },
145
+ React.createElement("iframe", { width: "100%", height: "400", src: url + '#navpanes=0', allowFullScreen: true, frameBorder: 0, seamless: true }))),
146
+ React.createElement("div", { "data-testid": "download-link", style: { padding: '2px 16px 16px 16px' } },
147
+ React.createElement(core$1.Anchor, { href: value === null || value === void 0 ? void 0 : value.url, "data-testid": "attachment-details", target: "_blank", rel: "noopener noreferrer" }, (value === null || value === void 0 ? void 0 : value.title) || 'Download'))));
148
+ }
149
+
150
+ function AttachmentArrayDisplay(props) {
151
+ return (React.createElement("div", null, props.values &&
152
+ props.values.map((v, index) => (React.createElement("div", { key: 'attatchment-' + index },
153
+ React.createElement(AttachmentDisplay, { value: v, maxWidth: props.maxWidth }))))));
154
+ }
155
+
135
156
  /**
136
157
  * Kills a browser event.
137
158
  * Prevents default behavior.
@@ -271,15 +292,6 @@
271
292
  return (React.createElement(AttachmentButton, { onUpload: setValueWrapper }, (props) => React.createElement(core$1.Button, Object.assign({}, props), "Upload...")));
272
293
  }
273
294
 
274
- function Document(props) {
275
- let style = undefined;
276
- if (props.width) {
277
- style = { maxWidth: props.width };
278
- }
279
- return (React.createElement(core$1.Container, null,
280
- React.createElement(core$1.Paper, { style: style, mx: "auto", my: "lg", p: "lg", shadow: "xs", radius: "sm", withBorder: true }, props.children)));
281
- }
282
-
283
295
  /******************************************************************************
284
296
  Copyright (c) Microsoft Corporation.
285
297
 
@@ -317,6 +329,55 @@
317
329
  });
318
330
  }
319
331
 
332
+ const useStyles$d = core$1.createStyles(() => ({
333
+ root: {
334
+ '@media (max-width: 800px)': {
335
+ paddingLeft: 4,
336
+ paddingRight: 4,
337
+ },
338
+ },
339
+ }));
340
+ function Container(props) {
341
+ const { children } = props, others = __rest(props, ["children"]);
342
+ const { classes } = useStyles$d();
343
+ return (React.createElement(core$1.Container, Object.assign({ className: classes.root }, others), children));
344
+ }
345
+
346
+ const useStyles$c = core$1.createStyles((theme, { width, fill }) => ({
347
+ paper: {
348
+ maxWidth: width,
349
+ margin: `${theme.spacing.xl}px auto`,
350
+ padding: fill ? 0 : theme.spacing.md,
351
+ '@media (max-width: 800px)': {
352
+ padding: fill ? 0 : 8,
353
+ },
354
+ '& img': {
355
+ width: '100%',
356
+ maxWidth: '100%',
357
+ },
358
+ '& video': {
359
+ width: '100%',
360
+ maxWidth: '100%',
361
+ },
362
+ },
363
+ }));
364
+ const defaultProps$1 = {
365
+ shadow: 'xs',
366
+ radius: 'md',
367
+ withBorder: true,
368
+ };
369
+ function Panel(props) {
370
+ const _a = core$1.useComponentDefaultProps('Panel', defaultProps$1, props), { className, children, width, fill, unstyled } = _a, others = __rest(_a, ["className", "children", "width", "fill", "unstyled"]);
371
+ const { classes, cx } = useStyles$c({ width, fill }, { name: 'Panel', unstyled });
372
+ return (React.createElement(core$1.Paper, Object.assign({ className: cx(classes.paper, className) }, others), children));
373
+ }
374
+
375
+ function Document(props) {
376
+ const { children } = props, others = __rest(props, ["children"]);
377
+ return (React.createElement(Container, null,
378
+ React.createElement(Panel, Object.assign({}, others), children)));
379
+ }
380
+
320
381
  /**
321
382
  * Parses an HTML form and returns the result as a JavaScript object.
322
383
  * @param form The HTML form element.
@@ -431,10 +492,11 @@
431
492
  React.createElement(core$1.Stack, { spacing: "xl" },
432
493
  React.createElement(core$1.TextInput, { name: "projectName", label: "Project Name", placeholder: "My Project", required: true, autoFocus: true, error: getErrorsForInput(outcome, 'firstName') }),
433
494
  React.createElement(core$1.Text, { color: "dimmed", size: "xs" },
434
- "By clicking submit you agree to the Medplum ",
435
- React.createElement("a", { href: "https://www.medplum.com/privacy" }, "Privacy\u00A0Policy"),
495
+ "By clicking submit you agree to the Medplum",
496
+ ' ',
497
+ React.createElement(core$1.Anchor, { href: "https://www.medplum.com/privacy" }, "Privacy\u00A0Policy"),
436
498
  ' and ',
437
- React.createElement("a", { href: "https://www.medplum.com/terms" }, "Terms\u00A0of\u00A0Service"),
499
+ React.createElement(core$1.Anchor, { href: "https://www.medplum.com/terms" }, "Terms\u00A0of\u00A0Service"),
438
500
  ".")),
439
501
  React.createElement(core$1.Group, { position: "right", mt: "xl", noWrap: true },
440
502
  React.createElement(core$1.Button, { type: "submit" }, "Create project"))));
@@ -575,17 +637,18 @@
575
637
  React.createElement(core$1.TextInput, { name: "email", type: "email", label: "Email", placeholder: "name@domain.com", required: true, error: getErrorsForInput(outcome, 'email') }),
576
638
  React.createElement(core$1.PasswordInput, { name: "password", label: "Password", autoComplete: "off", required: true, error: getErrorsForInput(outcome, 'password') }),
577
639
  React.createElement(core$1.Text, { color: "dimmed", size: "xs" },
578
- "By clicking submit you agree to the Medplum ",
579
- React.createElement("a", { href: "https://www.medplum.com/privacy" }, "Privacy\u00A0Policy"),
640
+ "By clicking submit you agree to the Medplum",
641
+ ' ',
642
+ React.createElement(core$1.Anchor, { href: "https://www.medplum.com/privacy" }, "Privacy\u00A0Policy"),
580
643
  ' and ',
581
- React.createElement("a", { href: "https://www.medplum.com/terms" }, "Terms\u00A0of\u00A0Service"),
644
+ React.createElement(core$1.Anchor, { href: "https://www.medplum.com/terms" }, "Terms\u00A0of\u00A0Service"),
582
645
  "."),
583
646
  React.createElement(core$1.Text, { color: "dimmed", size: "xs" },
584
647
  "This site is protected by reCAPTCHA and the Google",
585
648
  ' ',
586
- React.createElement("a", { href: "https://policies.google.com/privacy" }, "Privacy\u00A0Policy"),
649
+ React.createElement(core$1.Anchor, { href: "https://policies.google.com/privacy" }, "Privacy\u00A0Policy"),
587
650
  ' and ',
588
- React.createElement("a", { href: "https://policies.google.com/terms" }, "Terms\u00A0of\u00A0Service"),
651
+ React.createElement(core$1.Anchor, { href: "https://policies.google.com/terms" }, "Terms\u00A0of\u00A0Service"),
589
652
  " apply.")),
590
653
  React.createElement(core$1.Group, { position: "apart", mt: "xl", noWrap: true },
591
654
  React.createElement(core$1.Checkbox, { name: "remember", label: "Remember me", size: "xs" }),
@@ -659,10 +722,10 @@
659
722
  React.createElement(core$1.Stack, { spacing: "xl" },
660
723
  React.createElement(core$1.TextInput, { name: "email", type: "email", label: "Email", placeholder: "name@domain.com", required: true, autoFocus: true, error: getErrorsForInput(outcome, 'email') }),
661
724
  React.createElement(core$1.PasswordInput, { name: "password", type: "password", label: "Password", autoComplete: "off", required: true, error: getErrorsForInput(outcome, 'password') })),
662
- React.createElement(core$1.Group, { position: "apart", mt: "xl", noWrap: true },
725
+ React.createElement(core$1.Group, { position: "apart", mt: "xl", spacing: 0, noWrap: true },
663
726
  onForgotPassword && (React.createElement(core$1.Anchor, { component: "button", type: "button", color: "dimmed", onClick: onForgotPassword, size: "xs" }, "Forgot password")),
664
727
  onRegister && (React.createElement(core$1.Anchor, { component: "button", type: "button", color: "dimmed", onClick: onRegister, size: "xs" }, "Register")),
665
- React.createElement(core$1.Checkbox, { id: "remember", name: "remember", label: "Remember me", size: "xs" }),
728
+ React.createElement(core$1.Checkbox, { id: "remember", name: "remember", label: "Remember me", size: "xs", sx: { lineHeight: 1 } }),
666
729
  React.createElement(core$1.Button, { type: "submit" }, "Sign in"))));
667
730
  }
668
731
 
@@ -769,13 +832,6 @@
769
832
  })()));
770
833
  }
771
834
 
772
- function CheckboxFormSection(props) {
773
- return (React.createElement(core$1.Group, { noWrap: true },
774
- React.createElement("div", null, props.children),
775
- React.createElement("div", null,
776
- React.createElement(core$1.Input.Wrapper, { id: props.htmlFor, label: props.title, description: props.description }, (() => null)()))));
777
- }
778
-
779
835
  const DEFAULT_IGNORED_PROPERTIES = [
780
836
  'meta',
781
837
  'implicitRules',
@@ -786,116 +842,6 @@
786
842
  'modifierExtension',
787
843
  ];
788
844
 
789
- function FormSection(props) {
790
- return (React.createElement(core$1.Input.Wrapper, { id: props.htmlFor, label: props.title, description: props.description, error: getErrorsForInput(props.outcome, props.htmlFor) }, props.children));
791
- }
792
-
793
- const system = {
794
- resourceType: 'Device',
795
- id: 'system',
796
- deviceName: [
797
- {
798
- name: 'System',
799
- },
800
- ],
801
- };
802
- /**
803
- * React Hook to use a FHIR reference.
804
- * Handles the complexity of resolving references and caching resources.
805
- * @param value The resource or reference to resource.
806
- * @returns The resolved resource.
807
- */
808
- function useResource(value) {
809
- const medplum = useMedplum();
810
- const [resource, setResource] = React.useState(getInitialResource(medplum, value));
811
- React.useEffect(() => {
812
- let subscribed = true;
813
- if (!resource && value && 'reference' in value && value.reference) {
814
- medplum
815
- .readReference(value)
816
- .then((r) => {
817
- if (subscribed) {
818
- setResource(r);
819
- }
820
- })
821
- .catch(() => setResource(undefined));
822
- }
823
- return (() => (subscribed = false));
824
- }, [medplum, resource, value]);
825
- return resource;
826
- }
827
- /**
828
- * Returns the initial resource value based on the input value.
829
- * If the input value is a resource, returns the resource.
830
- * If the input value is a reference to system, returns the system resource.
831
- * If the input value is a reference to a resource available in the cache, returns the resource.
832
- * Otherwise, returns undefined.
833
- * @param medplum The medplum client.
834
- * @param value The resource or reference to resource.
835
- * @returns An initial resource if available; undefined otherwise.
836
- */
837
- function getInitialResource(medplum, value) {
838
- if (!value) {
839
- return undefined;
840
- }
841
- if ('resourceType' in value) {
842
- return value;
843
- }
844
- if ('reference' in value) {
845
- if (value.reference === 'system') {
846
- return system;
847
- }
848
- return medplum.getCachedReference(value);
849
- }
850
- return undefined;
851
- }
852
-
853
- function ResourceForm(props) {
854
- const medplum = useMedplum();
855
- const defaultValue = useResource(props.defaultValue);
856
- const [schema, setSchema] = React.useState();
857
- const [value, setValue] = React.useState();
858
- React.useEffect(() => {
859
- if (defaultValue) {
860
- setValue(JSON.parse(JSON.stringify(defaultValue)));
861
- medplum.requestSchema(defaultValue.resourceType).then(setSchema).catch(console.log);
862
- }
863
- }, [medplum, defaultValue]);
864
- if (!schema || !value) {
865
- return React.createElement("div", null, "Loading...");
866
- }
867
- return (React.createElement("form", { noValidate: true, autoComplete: "off", onSubmit: (e) => {
868
- e.preventDefault();
869
- if (props.onSubmit) {
870
- props.onSubmit(value);
871
- }
872
- } },
873
- React.createElement(core$1.Stack, { mb: "xl" },
874
- React.createElement(FormSection, { title: "Resource Type", htmlFor: "resourceType", outcome: props.outcome },
875
- React.createElement(core$1.TextInput, { name: "resourceType", defaultValue: value.resourceType, disabled: true })),
876
- React.createElement(FormSection, { title: "ID", htmlFor: "id", outcome: props.outcome },
877
- React.createElement(core$1.TextInput, { name: "id", defaultValue: value.id, disabled: true }))),
878
- React.createElement(BackboneElementInput, { typeName: value.resourceType, defaultValue: value, outcome: props.outcome, onChange: setValue }),
879
- React.createElement(core$1.Group, { position: "right", mt: "xl" },
880
- React.createElement(core$1.Button, { type: "submit" }, "OK"),
881
- props.onDelete && (React.createElement(core$1.Button, { variant: "outline", color: "red", type: "button", onClick: () => {
882
- props.onDelete(value);
883
- } }, "Delete")))));
884
- }
885
- function setPropertyValue(obj, key, propName, elementDefinition, value) {
886
- const types = elementDefinition.type;
887
- if (types.length > 1) {
888
- for (const type of types) {
889
- const compoundKey = key.replace('[x]', core.capitalize(type.code));
890
- if (compoundKey in obj) {
891
- delete obj[compoundKey];
892
- }
893
- }
894
- }
895
- obj[propName] = value;
896
- return obj;
897
- }
898
-
899
845
  const useStyles$b = core$1.createStyles((theme) => ({
900
846
  root: {
901
847
  display: 'grid',
@@ -926,63 +872,12 @@
926
872
  React.createElement("dd", null, props.children)));
927
873
  }
928
874
 
929
- function BackboneElementDisplay(props) {
930
- const typedValue = props.value;
931
- const value = typedValue.value;
932
- if (!value) {
933
- return null;
934
- }
935
- const typeName = typedValue.type;
936
- const typeSchema = core.globalSchema.types[typeName];
937
- if (!typeSchema) {
938
- return React.createElement("div", null,
939
- typeName,
940
- "\u00A0not implemented");
941
- }
942
- if (typeof value === 'object' &&
943
- 'name' in value &&
944
- Object.keys(value).length === 1 &&
945
- typeof value.name === 'string') {
946
- // Special case for common BackboneElement pattern
947
- // Where there is an object with a single property 'name'
948
- // Just display the name value.
949
- return React.createElement("div", null, value.name);
950
- }
951
- return (React.createElement(DescriptionList, { compact: props.compact }, Object.entries(typeSchema.properties).map((entry) => {
952
- const key = entry[0];
953
- if (DEFAULT_IGNORED_PROPERTIES.indexOf(key) >= 0) {
954
- return null;
955
- }
956
- const property = entry[1];
957
- const [propertyValue, propertyType] = getValueAndType(typedValue, key);
958
- if (props.ignoreMissingValues &&
959
- (!propertyValue || (Array.isArray(propertyValue) && propertyValue.length === 0))) {
960
- return null;
961
- }
962
- return (React.createElement(DescriptionListEntry, { key: key, term: core.getPropertyDisplayName(key) },
963
- React.createElement(ResourcePropertyDisplay, { property: property, propertyType: propertyType, value: propertyValue, ignoreMissingValues: props.ignoreMissingValues, link: props.link })));
964
- })));
875
+ function CodeableConceptDisplay(props) {
876
+ return React.createElement(React.Fragment, null, core.formatCodeableConcept(props.value));
965
877
  }
966
878
 
967
879
  function CodingDisplay(props) {
968
- var _a, _b;
969
- return React.createElement(React.Fragment, null, ((_a = props.value) === null || _a === void 0 ? void 0 : _a.display) || ((_b = props.value) === null || _b === void 0 ? void 0 : _b.code));
970
- }
971
-
972
- function CodeableConceptDisplay(props) {
973
- const value = props.value;
974
- if (!value) {
975
- return null;
976
- }
977
- if (value.text) {
978
- return React.createElement(React.Fragment, null, value.text);
979
- }
980
- if (value.coding) {
981
- return (React.createElement(React.Fragment, null, value.coding.map((coding, index) => (React.createElement(React.Fragment, { key: 'coding-' + index },
982
- index > 0 && React.createElement(React.Fragment, null, ', '),
983
- React.createElement(CodingDisplay, { value: coding }))))));
984
- }
985
- return null;
880
+ return React.createElement(React.Fragment, null, core.formatCoding(props.value));
986
881
  }
987
882
 
988
883
  function ContactPointDisplay(props) {
@@ -1175,6 +1070,7 @@
1175
1070
  case core.PropertyType.Period:
1176
1071
  return React.createElement(React.Fragment, null, core.formatPeriod(value));
1177
1072
  case core.PropertyType.Quantity:
1073
+ case core.PropertyType.Duration:
1178
1074
  return React.createElement(QuantityDisplay, { value: value });
1179
1075
  case core.PropertyType.Range:
1180
1076
  return React.createElement(RangeDisplay, { value: value });
@@ -1184,6 +1080,9 @@
1184
1080
  return React.createElement(ReferenceDisplay, { value: value, link: props.link });
1185
1081
  case core.PropertyType.Timing:
1186
1082
  return React.createElement(React.Fragment, null, core.formatTiming(value));
1083
+ case core.PropertyType.Dosage:
1084
+ case core.PropertyType.UsageContext:
1085
+ return (React.createElement(BackboneElementDisplay, { value: { type: propertyType, value }, compact: true, ignoreMissingValues: props.ignoreMissingValues }));
1187
1086
  default:
1188
1087
  if (!(property === null || property === void 0 ? void 0 : property.path)) {
1189
1088
  throw Error(`Displaying property of type ${props.propertyType} requires element definition path`);
@@ -1212,25 +1111,162 @@
1212
1111
  return [typedResult.value, typedResult.type];
1213
1112
  }
1214
1113
 
1215
- function AnnotationInput(props) {
1216
- const author = useMedplumProfile();
1217
- const [value, setValue] = React.useState(props.defaultValue || {});
1218
- const valueRef = React.useRef();
1219
- valueRef.current = value;
1220
- function setText(text) {
1221
- const newValue = text
1222
- ? {
1223
- text,
1224
- authorReference: author && core.createReference(author),
1225
- time: new Date().toISOString(),
1114
+ function BackboneElementDisplay(props) {
1115
+ const typedValue = props.value;
1116
+ const value = typedValue.value;
1117
+ if (!value) {
1118
+ return null;
1119
+ }
1120
+ const typeName = typedValue.type;
1121
+ const typeSchema = core.globalSchema.types[typeName];
1122
+ if (!typeSchema) {
1123
+ return React.createElement("div", null,
1124
+ typeName,
1125
+ "\u00A0not implemented");
1126
+ }
1127
+ if (typeof value === 'object' &&
1128
+ 'name' in value &&
1129
+ Object.keys(value).length === 1 &&
1130
+ typeof value.name === 'string') {
1131
+ // Special case for common BackboneElement pattern
1132
+ // Where there is an object with a single property 'name'
1133
+ // Just display the name value.
1134
+ return React.createElement("div", null, value.name);
1135
+ }
1136
+ return (React.createElement(DescriptionList, { compact: props.compact }, Object.entries(typeSchema.properties).map((entry) => {
1137
+ const key = entry[0];
1138
+ if (DEFAULT_IGNORED_PROPERTIES.indexOf(key) >= 0) {
1139
+ return null;
1140
+ }
1141
+ const property = entry[1];
1142
+ if (!property.path) {
1143
+ property.path = typeName + '.' + key;
1144
+ }
1145
+ const [propertyValue, propertyType] = getValueAndType(typedValue, key);
1146
+ if (props.ignoreMissingValues &&
1147
+ (!propertyValue || (Array.isArray(propertyValue) && propertyValue.length === 0))) {
1148
+ return null;
1149
+ }
1150
+ return (React.createElement(DescriptionListEntry, { key: key, term: core.getPropertyDisplayName(key) },
1151
+ React.createElement(ResourcePropertyDisplay, { property: property, propertyType: propertyType, value: propertyValue, ignoreMissingValues: props.ignoreMissingValues, link: props.link })));
1152
+ })));
1153
+ }
1154
+
1155
+ function CheckboxFormSection(props) {
1156
+ return (React.createElement(core$1.Group, { noWrap: true },
1157
+ React.createElement("div", null, props.children),
1158
+ React.createElement("div", null,
1159
+ React.createElement(core$1.Input.Wrapper, { id: props.htmlFor, label: props.title, description: props.description }, (() => null)()))));
1160
+ }
1161
+
1162
+ function FormSection(props) {
1163
+ return (React.createElement(core$1.Input.Wrapper, { id: props.htmlFor, label: props.title, description: props.description, error: getErrorsForInput(props.outcome, props.htmlFor) }, props.children));
1164
+ }
1165
+
1166
+ const system = {
1167
+ resourceType: 'Device',
1168
+ id: 'system',
1169
+ deviceName: [
1170
+ {
1171
+ name: 'System',
1172
+ },
1173
+ ],
1174
+ };
1175
+ /**
1176
+ * React Hook to use a FHIR reference.
1177
+ * Handles the complexity of resolving references and caching resources.
1178
+ * @param value The resource or reference to resource.
1179
+ * @returns The resolved resource.
1180
+ */
1181
+ function useResource(value) {
1182
+ const medplum = useMedplum();
1183
+ const [resource, setResource] = React.useState(getInitialResource(medplum, value));
1184
+ React.useEffect(() => {
1185
+ let subscribed = true;
1186
+ if (!resource && value && 'reference' in value && value.reference) {
1187
+ medplum
1188
+ .readReference(value)
1189
+ .then((r) => {
1190
+ if (subscribed) {
1191
+ setResource(r);
1192
+ }
1193
+ })
1194
+ .catch(() => setResource(undefined));
1195
+ }
1196
+ return (() => (subscribed = false));
1197
+ }, [medplum, resource, value]);
1198
+ return resource;
1199
+ }
1200
+ /**
1201
+ * Returns the initial resource value based on the input value.
1202
+ * If the input value is a resource, returns the resource.
1203
+ * If the input value is a reference to system, returns the system resource.
1204
+ * If the input value is a reference to a resource available in the cache, returns the resource.
1205
+ * Otherwise, returns undefined.
1206
+ * @param medplum The medplum client.
1207
+ * @param value The resource or reference to resource.
1208
+ * @returns An initial resource if available; undefined otherwise.
1209
+ */
1210
+ function getInitialResource(medplum, value) {
1211
+ if (!value) {
1212
+ return undefined;
1213
+ }
1214
+ if ('resourceType' in value) {
1215
+ return value;
1216
+ }
1217
+ if ('reference' in value) {
1218
+ if (value.reference === 'system') {
1219
+ return system;
1220
+ }
1221
+ return medplum.getCachedReference(value);
1222
+ }
1223
+ return undefined;
1224
+ }
1225
+
1226
+ function ResourceForm(props) {
1227
+ const medplum = useMedplum();
1228
+ const defaultValue = useResource(props.defaultValue);
1229
+ const [schema, setSchema] = React.useState();
1230
+ const [value, setValue] = React.useState();
1231
+ React.useEffect(() => {
1232
+ if (defaultValue) {
1233
+ setValue(JSON.parse(JSON.stringify(defaultValue)));
1234
+ medplum.requestSchema(defaultValue.resourceType).then(setSchema).catch(console.log);
1235
+ }
1236
+ }, [medplum, defaultValue]);
1237
+ if (!schema || !value) {
1238
+ return React.createElement("div", null, "Loading...");
1239
+ }
1240
+ return (React.createElement("form", { noValidate: true, autoComplete: "off", onSubmit: (e) => {
1241
+ e.preventDefault();
1242
+ if (props.onSubmit) {
1243
+ props.onSubmit(value);
1244
+ }
1245
+ } },
1246
+ React.createElement(core$1.Stack, { mb: "xl" },
1247
+ React.createElement(FormSection, { title: "Resource Type", htmlFor: "resourceType", outcome: props.outcome },
1248
+ React.createElement(core$1.TextInput, { name: "resourceType", defaultValue: value.resourceType, disabled: true })),
1249
+ React.createElement(FormSection, { title: "ID", htmlFor: "id", outcome: props.outcome },
1250
+ React.createElement(core$1.TextInput, { name: "id", defaultValue: value.id, disabled: true }))),
1251
+ React.createElement(BackboneElementInput, { typeName: value.resourceType, defaultValue: value, outcome: props.outcome, onChange: setValue }),
1252
+ React.createElement(core$1.Group, { position: "right", mt: "xl" },
1253
+ React.createElement(core$1.Button, { type: "submit" }, "OK"),
1254
+ props.onDelete && (React.createElement(core$1.Button, { variant: "outline", color: "red", type: "button", onClick: () => {
1255
+ props.onDelete(value);
1256
+ } }, "Delete")))));
1257
+ }
1258
+ function setPropertyValue(obj, key, propName, elementDefinition, value) {
1259
+ const types = elementDefinition.type;
1260
+ if (types.length > 1) {
1261
+ for (const type of types) {
1262
+ const compoundKey = key.replace('[x]', core.capitalize(type.code));
1263
+ if (compoundKey in obj) {
1264
+ delete obj[compoundKey];
1226
1265
  }
1227
- : {};
1228
- setValue(newValue);
1229
- if (props.onChange) {
1230
- props.onChange(newValue);
1231
1266
  }
1232
1267
  }
1233
- return (React.createElement(core$1.TextInput, { name: props.name, placeholder: "Annotation text", defaultValue: value.text, onChange: (e) => setText(e.currentTarget.value) }));
1268
+ obj[propName] = value;
1269
+ return obj;
1234
1270
  }
1235
1271
 
1236
1272
  function valueSetElementToAutocompleteItem(element) {
@@ -1658,6 +1694,7 @@
1658
1694
  Observation: 'code',
1659
1695
  RequestGroup: '_id',
1660
1696
  ActivityDefinition: 'name',
1697
+ User: 'email',
1661
1698
  };
1662
1699
  function ResourceInput(props) {
1663
1700
  const medplum = useMedplum();
@@ -1981,6 +2018,7 @@
1981
2018
  return React.createElement(IdentifierInput, { name: name, defaultValue: value, onChange: props.onChange });
1982
2019
  case core.PropertyType.Period:
1983
2020
  return React.createElement(PeriodInput, { name: name, defaultValue: value, onChange: props.onChange });
2021
+ case core.PropertyType.Duration:
1984
2022
  case core.PropertyType.Quantity:
1985
2023
  return React.createElement(QuantityInput, { name: name, defaultValue: value, onChange: props.onChange });
1986
2024
  case core.PropertyType.Range:
@@ -1991,53 +2029,184 @@
1991
2029
  return (React.createElement(ReferenceInput, { name: name, defaultValue: value, targetTypes: getTargetTypes(property), onChange: props.onChange }));
1992
2030
  case core.PropertyType.Timing:
1993
2031
  return React.createElement(TimingInput, { name: name, defaultValue: value, onChange: props.onChange });
2032
+ case core.PropertyType.Dosage:
2033
+ case core.PropertyType.UsageContext:
2034
+ return (React.createElement(BackboneElementInput, { typeName: propertyType, defaultValue: value, onChange: props.onChange, outcome: props.outcome }));
1994
2035
  default:
1995
2036
  return (React.createElement(BackboneElementInput, { typeName: core.buildTypeName((_a = property.path) === null || _a === void 0 ? void 0 : _a.split('.')), defaultValue: value, onChange: props.onChange, outcome: props.outcome }));
1996
2037
  }
1997
2038
  }
1998
- function getTargetTypes(property) {
1999
- var _a, _b, _c;
2000
- return (_c = (_b = (_a = property === null || property === void 0 ? void 0 : property.type) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.targetProfile) === null || _c === void 0 ? void 0 : _c.map((p) => p.split('/').pop());
2039
+ function getTargetTypes(property) {
2040
+ var _a, _b, _c;
2041
+ return (_c = (_b = (_a = property === null || property === void 0 ? void 0 : property.type) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.targetProfile) === null || _c === void 0 ? void 0 : _c.map((p) => p.split('/').pop());
2042
+ }
2043
+
2044
+ function BackboneElementInput(props) {
2045
+ var _a;
2046
+ const [value, setValue] = React.useState((_a = props.defaultValue) !== null && _a !== void 0 ? _a : {});
2047
+ function setValueWrapper(newValue) {
2048
+ setValue(newValue);
2049
+ if (props.onChange) {
2050
+ props.onChange(newValue);
2051
+ }
2052
+ }
2053
+ const typeName = props.typeName;
2054
+ const typeSchema = core.globalSchema.types[typeName];
2055
+ if (!typeSchema) {
2056
+ return React.createElement("div", null,
2057
+ typeName,
2058
+ "\u00A0not implemented");
2059
+ }
2060
+ const typedValue = { type: typeName, value };
2061
+ return (React.createElement(core$1.Stack, null, Object.entries(typeSchema.properties).map((entry) => {
2062
+ const key = entry[0];
2063
+ if (key === 'id' || DEFAULT_IGNORED_PROPERTIES.indexOf(key) >= 0) {
2064
+ return null;
2065
+ }
2066
+ const property = entry[1];
2067
+ if (!property.type) {
2068
+ return null;
2069
+ }
2070
+ const [propertyValue, propertyType] = getValueAndType(typedValue, key);
2071
+ if (property.type.length === 1 && property.type[0].code === 'boolean') {
2072
+ return (React.createElement(CheckboxFormSection, { key: key, title: core.getPropertyDisplayName(key), description: property.definition, htmlFor: key },
2073
+ React.createElement(ResourcePropertyInput, { property: property, name: key, defaultValue: propertyValue, defaultPropertyType: propertyType, outcome: props.outcome, onChange: (newValue, propName) => {
2074
+ setValueWrapper(setPropertyValue(value, key, propName !== null && propName !== void 0 ? propName : key, entry[1], newValue));
2075
+ } })));
2076
+ }
2077
+ return (React.createElement(FormSection, { key: key, title: core.getPropertyDisplayName(key), description: property.definition, htmlFor: key, outcome: props.outcome },
2078
+ React.createElement(ResourcePropertyInput, { property: property, name: key, defaultValue: propertyValue, defaultPropertyType: propertyType, outcome: props.outcome, onChange: (newValue, propName) => {
2079
+ setValueWrapper(setPropertyValue(value, key, propName !== null && propName !== void 0 ? propName : key, entry[1], newValue));
2080
+ } })));
2081
+ })));
2082
+ }
2083
+
2084
+ const useStyles$a = core$1.createStyles((theme) => ({
2085
+ table: {
2086
+ width: 350,
2087
+ '& th': {
2088
+ fontWeight: 'normal',
2089
+ fontSize: 11,
2090
+ padding: 8,
2091
+ textAlign: 'center',
2092
+ },
2093
+ '& td': {
2094
+ padding: '2px 4px',
2095
+ },
2096
+ '& td button': {
2097
+ width: 44,
2098
+ height: 44,
2099
+ color: theme.colors[theme.primaryColor][5],
2100
+ fontSize: 16,
2101
+ fontWeight: 500,
2102
+ textAlign: 'center',
2103
+ padding: 0,
2104
+ backgroundColor: theme.colors[theme.primaryColor][0],
2105
+ border: 0,
2106
+ borderRadius: '50%',
2107
+ cursor: 'pointer',
2108
+ },
2109
+ '& td button:hover': {
2110
+ backgroundColor: theme.colors[theme.primaryColor][1],
2111
+ },
2112
+ '& td button:disabled': {
2113
+ backgroundColor: 'transparent',
2114
+ cursor: 'default',
2115
+ color: theme.colors.gray[4],
2116
+ fontWeight: 'normal',
2117
+ },
2118
+ },
2119
+ }));
2120
+ /**
2121
+ * Returns a month display string (e.g. "January 2020").
2122
+ * @param date Any date within the month.
2123
+ * @returns The month display string (e.g. "January 2020")
2124
+ */
2125
+ function getMonthString(date) {
2126
+ return date.toLocaleString('default', { month: 'long' }) + ' ' + date.getFullYear();
2127
+ }
2128
+ function CalendarInput(props) {
2129
+ const { classes } = useStyles$a();
2130
+ const { onChangeMonth, onClick } = props;
2131
+ const [month, setMonth] = React.useState(getStartMonth);
2132
+ function moveMonth(delta) {
2133
+ setMonth((currMonth) => {
2134
+ const newMonth = new Date(currMonth.getTime());
2135
+ newMonth.setMonth(currMonth.getMonth() + delta);
2136
+ onChangeMonth(newMonth);
2137
+ return newMonth;
2138
+ });
2139
+ }
2140
+ const grid = React.useMemo(() => buildGrid(month, props.slots), [month, props.slots]);
2141
+ return (React.createElement("div", null,
2142
+ React.createElement(core$1.Group, { position: "apart", spacing: "xs", grow: true, noWrap: true },
2143
+ React.createElement("p", { style: { flex: 1 } }, getMonthString(month)),
2144
+ React.createElement(core$1.Group, { position: "right", spacing: "xs" },
2145
+ React.createElement(core$1.Button, { variant: "outline", "aria-label": "Previous month", onClick: () => moveMonth(-1) }, "<"),
2146
+ React.createElement(core$1.Button, { variant: "outline", "aria-label": "Next month", onClick: () => moveMonth(1) }, ">"))),
2147
+ React.createElement("table", { className: classes.table },
2148
+ React.createElement("thead", null,
2149
+ React.createElement("tr", null,
2150
+ React.createElement("th", null, "SUN"),
2151
+ React.createElement("th", null, "MON"),
2152
+ React.createElement("th", null, "TUE"),
2153
+ React.createElement("th", null, "WED"),
2154
+ React.createElement("th", null, "THU"),
2155
+ React.createElement("th", null, "FRI"),
2156
+ React.createElement("th", null, "SAT"))),
2157
+ React.createElement("tbody", null, grid.map((week, weekIndex) => (React.createElement("tr", { key: 'week-' + weekIndex }, week.map((day, dayIndex) => (React.createElement("td", { key: 'day-' + dayIndex }, day && (React.createElement(core$1.Button, { disabled: !day.available, onClick: () => onClick(day.date) }, day.date.getDate()))))))))))));
2158
+ }
2159
+ function getStartMonth() {
2160
+ const result = new Date();
2161
+ result.setDate(1);
2162
+ result.setHours(0, 0, 0, 0);
2163
+ return result;
2001
2164
  }
2002
-
2003
- function BackboneElementInput(props) {
2004
- var _a;
2005
- const [value, setValue] = React.useState((_a = props.defaultValue) !== null && _a !== void 0 ? _a : {});
2006
- function setValueWrapper(newValue) {
2007
- setValue(newValue);
2008
- if (props.onChange) {
2009
- props.onChange(newValue);
2010
- }
2011
- }
2012
- const typeName = props.typeName;
2013
- const typeSchema = core.globalSchema.types[typeName];
2014
- if (!typeSchema) {
2015
- return React.createElement("div", null,
2016
- typeName,
2017
- "\u00A0not implemented");
2165
+ function buildGrid(startDate, slots) {
2166
+ const d = new Date(startDate.getFullYear(), startDate.getMonth());
2167
+ const grid = [];
2168
+ let row = [];
2169
+ // Fill leading empty days
2170
+ for (let i = 0; i < d.getDay(); i++) {
2171
+ row.push(undefined);
2018
2172
  }
2019
- const typedValue = { type: typeName, value };
2020
- return (React.createElement(core$1.Stack, null, Object.entries(typeSchema.properties).map((entry) => {
2021
- const key = entry[0];
2022
- if (key === 'id' || DEFAULT_IGNORED_PROPERTIES.indexOf(key) >= 0) {
2023
- return null;
2173
+ while (d.getMonth() === startDate.getMonth()) {
2174
+ row.push({
2175
+ date: new Date(d.getTime()),
2176
+ available: isDayAvailable(d, slots),
2177
+ });
2178
+ if (d.getDay() === 6) {
2179
+ grid.push(row);
2180
+ row = [];
2024
2181
  }
2025
- const property = entry[1];
2026
- if (!property.type) {
2027
- return null;
2182
+ d.setDate(d.getDate() + 1);
2183
+ }
2184
+ // Fill trailing empty days
2185
+ if (d.getDay() !== 0) {
2186
+ for (let i = d.getDay(); i < 7; i++) {
2187
+ row.push(undefined);
2028
2188
  }
2029
- const [propertyValue, propertyType] = getValueAndType(typedValue, key);
2030
- if (property.type.length === 1 && property.type[0].code === 'boolean') {
2031
- return (React.createElement(CheckboxFormSection, { key: key, title: core.getPropertyDisplayName(key), description: property.definition, htmlFor: key },
2032
- React.createElement(ResourcePropertyInput, { property: property, name: key, defaultValue: propertyValue, defaultPropertyType: propertyType, outcome: props.outcome, onChange: (newValue, propName) => {
2033
- setValueWrapper(setPropertyValue(value, key, propName !== null && propName !== void 0 ? propName : key, entry[1], newValue));
2034
- } })));
2189
+ grid.push(row);
2190
+ }
2191
+ return grid;
2192
+ }
2193
+ /**
2194
+ * Returns true if the given date is available for booking.
2195
+ * @param day The day to check.
2196
+ * @param slots The list of available slots.
2197
+ * @returns True if there are any available slots for the day.
2198
+ */
2199
+ function isDayAvailable(day, slots) {
2200
+ // Note that slot start and end time may or may not be in UTC.
2201
+ for (const slot of slots) {
2202
+ const slotStart = new Date(slot.start);
2203
+ if (slotStart.getFullYear() === day.getFullYear() &&
2204
+ slotStart.getMonth() === day.getMonth() &&
2205
+ slotStart.getDate() === day.getDate()) {
2206
+ return true;
2035
2207
  }
2036
- return (React.createElement(FormSection, { key: key, title: core.getPropertyDisplayName(key), description: property.definition, htmlFor: key, outcome: props.outcome },
2037
- React.createElement(ResourcePropertyInput, { property: property, name: key, defaultValue: propertyValue, defaultPropertyType: propertyType, outcome: props.outcome, onChange: (newValue, propName) => {
2038
- setValueWrapper(setPropertyValue(value, key, propName !== null && propName !== void 0 ? propName : key, entry[1], newValue));
2039
- } })));
2040
- })));
2208
+ }
2209
+ return false;
2041
2210
  }
2042
2211
 
2043
2212
  function ResourceName(props) {
@@ -2056,7 +2225,7 @@
2056
2225
  React.createElement(ResourceName, { value: props.value, link: props.link })));
2057
2226
  }
2058
2227
 
2059
- const useStyles$a = core$1.createStyles((theme) => ({
2228
+ const useStyles$9 = core$1.createStyles((theme) => ({
2060
2229
  table: {
2061
2230
  border: `0.1px solid ${theme.colors.gray[5]}`,
2062
2231
  borderCollapse: 'collapse',
@@ -2117,7 +2286,7 @@
2117
2286
  }
2118
2287
  function ObservationTable(props) {
2119
2288
  var _a;
2120
- const { classes } = useStyles$a();
2289
+ const { classes } = useStyles$9();
2121
2290
  return (React.createElement("table", { className: classes.table },
2122
2291
  React.createElement("thead", null,
2123
2292
  React.createElement("tr", null,
@@ -2128,7 +2297,7 @@
2128
2297
  React.createElement("tbody", null, (_a = props.value) === null || _a === void 0 ? void 0 : _a.map((observation, index) => (React.createElement(ObservationRow, { key: 'obs-' + index, value: observation }))))));
2129
2298
  }
2130
2299
  function ObservationRow(props) {
2131
- const { classes, cx } = useStyles$a();
2300
+ const { classes, cx } = useStyles$9();
2132
2301
  const observation = useResource(props.value);
2133
2302
  if (!observation) {
2134
2303
  return null;
@@ -2145,20 +2314,8 @@
2145
2314
  React.createElement("td", null, observation.interpretation && observation.interpretation.length > 0 && (React.createElement(CodeableConceptDisplay, { value: observation.interpretation[0] })))));
2146
2315
  }
2147
2316
  function ObservationValueDisplay(props) {
2148
- var _a;
2149
2317
  const obs = props.value;
2150
- if (obs === null || obs === void 0 ? void 0 : obs.valueQuantity) {
2151
- return React.createElement(QuantityDisplay, { value: (_a = props.value) === null || _a === void 0 ? void 0 : _a.valueQuantity });
2152
- }
2153
- if (obs === null || obs === void 0 ? void 0 : obs.valueString) {
2154
- return React.createElement(React.Fragment, null, obs.valueString);
2155
- }
2156
- if (obs && 'component' in obs && (obs === null || obs === void 0 ? void 0 : obs.component)) {
2157
- return (React.createElement(React.Fragment, null, obs.component
2158
- .map((component, index) => (React.createElement(ObservationValueDisplay, { key: `obs-${index}`, value: component })))
2159
- .reduce((prev, curr) => [prev, ' / ', curr])));
2160
- }
2161
- return null;
2318
+ return React.createElement(React.Fragment, null, core.formatObservationValue(obs));
2162
2319
  }
2163
2320
  function ReferenceRangeDisplay(props) {
2164
2321
  const range = props.value && props.value.length > 0 && props.value[0];
@@ -2182,7 +2339,7 @@
2182
2339
  return code === 'AA' || code === 'LL' || code === 'HH' || code === 'A';
2183
2340
  }
2184
2341
 
2185
- const useStyles$9 = core$1.createStyles((theme) => ({
2342
+ const useStyles$8 = core$1.createStyles((theme) => ({
2186
2343
  root: {
2187
2344
  borderCollapse: 'collapse',
2188
2345
  width: '100%',
@@ -2203,7 +2360,7 @@
2203
2360
  },
2204
2361
  }));
2205
2362
  function ResourceDiffTable(props) {
2206
- const { classes } = useStyles$9();
2363
+ const { classes } = useStyles$8();
2207
2364
  const medplum = useMedplum();
2208
2365
  const [schema, setSchema] = React.useState();
2209
2366
  React.useEffect(() => {
@@ -2293,29 +2450,30 @@
2293
2450
  }
2294
2451
 
2295
2452
  function Timeline(props) {
2296
- return React.createElement(core$1.Container, null, props.children);
2453
+ return React.createElement(Container, null, props.children);
2297
2454
  }
2298
2455
  function TimelineItem(props) {
2299
- var _a, _b, _c;
2300
- const author = (_a = props.profile) !== null && _a !== void 0 ? _a : (_b = props.resource.meta) === null || _b === void 0 ? void 0 : _b.author;
2301
- return (React.createElement(core$1.Paper, { "data-testid": "timeline-item", m: "lg", p: "sm", shadow: "xs", radius: "sm", withBorder: true, className: props.className },
2302
- React.createElement(core$1.Group, { position: "apart", spacing: 8 },
2456
+ var _a, _b;
2457
+ const { resource, profile, padding, popupMenuItems } = props, others = __rest(props, ["resource", "profile", "padding", "popupMenuItems"]);
2458
+ const author = profile !== null && profile !== void 0 ? profile : (_a = resource.meta) === null || _a === void 0 ? void 0 : _a.author;
2459
+ return (React.createElement(Panel, Object.assign({ "data-testid": "timeline-item", fill: true }, others),
2460
+ React.createElement(core$1.Group, { position: "apart", spacing: 8, mx: "xs", my: "sm" },
2303
2461
  React.createElement(ResourceAvatar, { value: author, link: true, size: "md" }),
2304
2462
  React.createElement("div", { style: { flex: 1 } },
2305
2463
  React.createElement(core$1.Text, { size: "sm" },
2306
2464
  React.createElement(ResourceName, { color: "dark", weight: 500, value: author, link: true })),
2307
2465
  React.createElement(core$1.Text, { size: "xs" },
2308
- React.createElement(MedplumLink, { color: "dimmed", to: props.resource }, core.formatDateTime((_c = props.resource.meta) === null || _c === void 0 ? void 0 : _c.lastUpdated)),
2466
+ React.createElement(MedplumLink, { color: "dimmed", to: props.resource }, core.formatDateTime((_b = props.resource.meta) === null || _b === void 0 ? void 0 : _b.lastUpdated)),
2309
2467
  React.createElement(core$1.Text, { component: "span", color: "dimmed", mx: 8 }, "\u00B7"),
2310
2468
  React.createElement(MedplumLink, { color: "dimmed", to: props.resource }, props.resource.resourceType))),
2311
- props.popupMenuItems && (React.createElement(core$1.Menu, { position: "bottom-end", shadow: "md", width: 200 },
2469
+ popupMenuItems && (React.createElement(core$1.Menu, { position: "bottom-end", shadow: "md", width: 200 },
2312
2470
  React.createElement(core$1.Menu.Target, null,
2313
2471
  React.createElement(core$1.ActionIcon, { radius: "xl", "aria-label": `Actions for ${core.getReferenceString(props.resource)}` },
2314
2472
  React.createElement(icons.IconDots, null))),
2315
- props.popupMenuItems))),
2473
+ popupMenuItems))),
2316
2474
  React.createElement(ErrorBoundary, null,
2317
- props.padding && React.createElement("div", { style: { padding: '2px 16px 16px 16px' } }, props.children),
2318
- !props.padding && React.createElement(React.Fragment, null, props.children))));
2475
+ padding && React.createElement("div", { style: { padding: '0 16px 16px 16px' } }, props.children),
2476
+ !padding && React.createElement(React.Fragment, null, props.children))));
2319
2477
  }
2320
2478
 
2321
2479
  /**
@@ -2364,7 +2522,7 @@
2364
2522
  return new Date(dateTime).getTime();
2365
2523
  }
2366
2524
 
2367
- const useStyles$8 = core$1.createStyles((theme) => ({
2525
+ const useStyles$7 = core$1.createStyles((theme) => ({
2368
2526
  pinnedComment: {
2369
2527
  backgroundColor: theme.colors.blue[0],
2370
2528
  },
@@ -2522,7 +2680,7 @@
2522
2680
  React.createElement(core$1.Loader, null)));
2523
2681
  }
2524
2682
  return (React.createElement(Timeline, null,
2525
- props.createCommunication && (React.createElement(core$1.Paper, { m: "lg", p: "sm", shadow: "xs", radius: "sm", withBorder: true },
2683
+ props.createCommunication && (React.createElement(Panel, null,
2526
2684
  React.createElement(Form, { testid: "timeline-form", onSubmit: (formData) => {
2527
2685
  createComment(formData.text);
2528
2686
  const input = inputRef.current;
@@ -2593,7 +2751,7 @@
2593
2751
  }
2594
2752
  function CommunicationTimelineItem(props) {
2595
2753
  var _a, _b;
2596
- const { classes } = useStyles$8();
2754
+ const { classes } = useStyles$7();
2597
2755
  const routine = !props.resource.priority || props.resource.priority === 'routine';
2598
2756
  const className = routine ? undefined : classes.pinnedComment;
2599
2757
  return (React.createElement(TimelineItem, { resource: props.resource, profile: props.resource.sender, padding: true, className: className, popupMenuItems: React.createElement(TimelineItemPopupMenu, Object.assign({}, props)) },
@@ -3742,7 +3900,7 @@
3742
3900
  this.browserEvent = browserEvent;
3743
3901
  }
3744
3902
  }
3745
- const useStyles$7 = core$1.createStyles((theme) => ({
3903
+ const useStyles$6 = core$1.createStyles((theme) => ({
3746
3904
  root: {
3747
3905
  maxWidth: '100%',
3748
3906
  overflow: 'auto',
@@ -3780,7 +3938,7 @@
3780
3938
  */
3781
3939
  function SearchControl(props) {
3782
3940
  var _a, _b, _c;
3783
- const { classes } = useStyles$7();
3941
+ const { classes } = useStyles$6();
3784
3942
  const medplum = useMedplum();
3785
3943
  const [schemaLoaded, setSchemaLoaded] = React.useState(false);
3786
3944
  const [outcome, setOutcome] = React.useState();
@@ -3946,7 +4104,7 @@
3946
4104
  checkboxColumn && (React.createElement("td", null,
3947
4105
  React.createElement("input", { type: "checkbox", value: "checked", "data-testid": "row-checkbox", "aria-label": `Checkbox for ${resource.id}`, checked: !!state.selected[resource.id], onChange: (e) => handleSingleCheckboxClick(e, resource.id) }))),
3948
4106
  fields.map((field) => (React.createElement("td", { key: field.name }, renderValue(resource, field))))))))),
3949
- (resources === null || resources === void 0 ? void 0 : resources.length) === 0 && (React.createElement(core$1.Container, null,
4107
+ (resources === null || resources === void 0 ? void 0 : resources.length) === 0 && (React.createElement(Container, null,
3950
4108
  React.createElement(core$1.Center, null,
3951
4109
  React.createElement(core$1.Text, { size: "xl", color: "dimmed" }, "No results")))),
3952
4110
  (lastResult === null || lastResult === void 0 ? void 0 : lastResult.total) !== undefined && lastResult.total > 0 && (React.createElement(core$1.Center, { m: "md", p: "md" },
@@ -4155,7 +4313,7 @@
4155
4313
  }) }));
4156
4314
  }
4157
4315
 
4158
- const useStyles$6 = core$1.createStyles((theme) => ({
4316
+ const useStyles$5 = core$1.createStyles((theme) => ({
4159
4317
  section: {
4160
4318
  position: 'relative',
4161
4319
  margin: '4px 4px 8px 0',
@@ -4221,7 +4379,7 @@
4221
4379
  React.createElement(core$1.Button, { type: "submit" }, "Save"))));
4222
4380
  }
4223
4381
  function ActionArrayBuilder(props) {
4224
- const { classes } = useStyles$6();
4382
+ const { classes } = useStyles$5();
4225
4383
  const actionsRef = React.useRef();
4226
4384
  actionsRef.current = props.actions;
4227
4385
  function changeAction(changedAction) {
@@ -4238,13 +4396,13 @@
4238
4396
  props.actions.map((action) => (React.createElement("div", { key: action.id },
4239
4397
  React.createElement(ActionBuilder, { action: action, selectedKey: props.selectedKey, setSelectedKey: props.setSelectedKey, hoverKey: props.hoverKey, setHoverKey: props.setHoverKey, onChange: changeAction, onRemove: () => removeAction(action) })))),
4240
4398
  React.createElement("div", { className: classes.bottomActions },
4241
- React.createElement("a", { href: "#", onClick: (e) => {
4399
+ React.createElement(core$1.Anchor, { href: "#", onClick: (e) => {
4242
4400
  killEvent(e);
4243
4401
  addAction({ id: generateId$1() });
4244
4402
  } }, "Add action"))));
4245
4403
  }
4246
4404
  function ActionBuilder(props) {
4247
- const { classes, cx } = useStyles$6();
4405
+ const { classes, cx } = useStyles$5();
4248
4406
  const { action } = props;
4249
4407
  const actionType = getInitialActionType(action);
4250
4408
  const editing = props.selectedKey === props.action.id;
@@ -4264,7 +4422,7 @@
4264
4422
  return (React.createElement("div", { "data-testid": action.id, className: className, onClick: onClick, onMouseOver: onHover },
4265
4423
  editing ? (React.createElement(ActionEditor, { action: action, actionType: actionType, onChange: props.onChange, selectedKey: props.selectedKey, setSelectedKey: props.setSelectedKey, hoverKey: props.hoverKey, setHoverKey: props.setHoverKey, onRemove: props.onRemove })) : (React.createElement(ActionDisplay, { action: action, actionType: actionType })),
4266
4424
  React.createElement("div", { className: classes.bottomActions },
4267
- React.createElement("a", { href: "#", onClick: (e) => {
4425
+ React.createElement(core$1.Anchor, { href: "#", onClick: (e) => {
4268
4426
  e.preventDefault();
4269
4427
  props.onRemove();
4270
4428
  } }, "Remove"))));
@@ -4665,7 +4823,7 @@
4665
4823
  }
4666
4824
  }
4667
4825
 
4668
- const useStyles$5 = core$1.createStyles((theme) => ({
4826
+ const useStyles$4 = core$1.createStyles((theme) => ({
4669
4827
  section: {
4670
4828
  position: 'relative',
4671
4829
  margin: '4px 4px 8px 0',
@@ -4744,7 +4902,7 @@
4744
4902
  }
4745
4903
  function ItemBuilder(props) {
4746
4904
  var _a;
4747
- const { classes, cx } = useStyles$5();
4905
+ const { classes, cx } = useStyles$4();
4748
4906
  const resource = props.item;
4749
4907
  const item = props.item;
4750
4908
  const isResource = 'resourceType' in props.item;
@@ -4814,7 +4972,7 @@
4814
4972
  ] })))) : (React.createElement("div", null, linkId)))),
4815
4973
  React.createElement("div", { className: classes.bottomActions },
4816
4974
  isContainer && (React.createElement(React.Fragment, null,
4817
- React.createElement("a", { href: "#", onClick: (e) => {
4975
+ React.createElement(core$1.Anchor, { href: "#", onClick: (e) => {
4818
4976
  e.preventDefault();
4819
4977
  addItem({
4820
4978
  id: generateId(),
@@ -4823,7 +4981,7 @@
4823
4981
  text: 'Question',
4824
4982
  });
4825
4983
  } }, "Add item"),
4826
- React.createElement("a", { href: "#", onClick: (e) => {
4984
+ React.createElement(core$1.Anchor, { href: "#", onClick: (e) => {
4827
4985
  e.preventDefault();
4828
4986
  addItem({
4829
4987
  id: generateId(),
@@ -4832,7 +4990,7 @@
4832
4990
  text: 'Group',
4833
4991
  });
4834
4992
  } }, "Add group"))),
4835
- editing && !isResource && (React.createElement("a", { href: "#", onClick: (e) => {
4993
+ editing && !isResource && (React.createElement(core$1.Anchor, { href: "#", onClick: (e) => {
4836
4994
  e.preventDefault();
4837
4995
  if (props.onRemove) {
4838
4996
  props.onRemove();
@@ -4861,12 +5019,12 @@
4861
5019
  props.onChange(newOptions);
4862
5020
  } })),
4863
5021
  React.createElement("div", null,
4864
- React.createElement("a", { href: "#", onClick: (e) => {
5022
+ React.createElement(core$1.Anchor, { href: "#", onClick: (e) => {
4865
5023
  killEvent(e);
4866
5024
  props.onChange(options.filter((o) => o.id !== option.id));
4867
5025
  } }, "Remove"))));
4868
5026
  }),
4869
- React.createElement("a", { href: "#", onClick: (e) => {
5027
+ React.createElement(core$1.Anchor, { href: "#", onClick: (e) => {
4870
5028
  killEvent(e);
4871
5029
  props.onChange([
4872
5030
  ...options,
@@ -4921,7 +5079,7 @@
4921
5079
  return options.map((option) => (Object.assign(Object.assign({}, option), { id: option.id || generateId() })));
4922
5080
  }
4923
5081
 
4924
- const useStyles$4 = core$1.createStyles((theme) => ({
5082
+ const useStyles$3 = core$1.createStyles((theme) => ({
4925
5083
  section: {
4926
5084
  position: 'relative',
4927
5085
  margin: '4px 4px 8px 0',
@@ -5025,8 +5183,8 @@
5025
5183
  }
5026
5184
  function ReferenceRangeGroupEditor(props) {
5027
5185
  const { intervalGroup, unit } = props;
5028
- const { classes } = useStyles$4();
5029
- return (React.createElement(core$1.Container, { "data-testid": intervalGroup.id, className: classes.section },
5186
+ const { classes } = useStyles$3();
5187
+ return (React.createElement(Container, { "data-testid": intervalGroup.id, className: classes.section },
5030
5188
  React.createElement(core$1.Stack, { spacing: 'lg' },
5031
5189
  React.createElement(core$1.Group, { position: "right" },
5032
5190
  React.createElement(core$1.ActionIcon, { title: "Remove Group", "data-testid": `remove-group-button-${intervalGroup.id}`, key: `remove-group-button-${intervalGroup.id}`, size: "sm", onClick: (e) => {
@@ -5487,7 +5645,7 @@
5487
5645
  }
5488
5646
  }
5489
5647
 
5490
- const useStyles$3 = core$1.createStyles((theme) => ({
5648
+ const useStyles$2 = core$1.createStyles((theme) => ({
5491
5649
  container: {
5492
5650
  overflowX: 'auto',
5493
5651
  },
@@ -5536,7 +5694,7 @@
5536
5694
  }));
5537
5695
  function ResourceBlame(props) {
5538
5696
  var _a, _b;
5539
- const { classes } = useStyles$3();
5697
+ const { classes } = useStyles$2();
5540
5698
  const medplum = useMedplum();
5541
5699
  const [value, setValue] = React.useState(props.history);
5542
5700
  React.useEffect(() => {
@@ -5592,7 +5750,7 @@
5592
5750
  return `${count} ${count === 1 ? noun : noun + 's'} ago`;
5593
5751
  }
5594
5752
 
5595
- const useStyles$2 = core$1.createStyles((theme) => ({
5753
+ const useStyles$1 = core$1.createStyles((theme) => ({
5596
5754
  removed: {
5597
5755
  color: theme.colors.red[7],
5598
5756
  textDecoration: 'line-through',
@@ -5614,7 +5772,7 @@
5614
5772
  return (React.createElement("pre", { style: { color: 'gray' } }, deltas.map((delta, index) => (React.createElement(ChangeDiff, { key: 'delta' + index, delta: delta })))));
5615
5773
  }
5616
5774
  function ChangeDiff(props) {
5617
- const { classes } = useStyles$2();
5775
+ const { classes } = useStyles$1();
5618
5776
  return (React.createElement(React.Fragment, null,
5619
5777
  "...",
5620
5778
  React.createElement("br", null),
@@ -5668,134 +5826,6 @@
5668
5826
  return `/${resource.resourceType}/${resource.id}/_history/${(_a = resource.meta) === null || _a === void 0 ? void 0 : _a.versionId}`;
5669
5827
  }
5670
5828
 
5671
- const useStyles$1 = core$1.createStyles((theme) => ({
5672
- table: {
5673
- width: 350,
5674
- '& th': {
5675
- fontWeight: 'normal',
5676
- fontSize: 11,
5677
- padding: 8,
5678
- textAlign: 'center',
5679
- },
5680
- '& td': {
5681
- padding: '2px 4px',
5682
- },
5683
- '& td button': {
5684
- width: 44,
5685
- height: 44,
5686
- color: theme.colors[theme.primaryColor][5],
5687
- fontSize: 16,
5688
- fontWeight: 500,
5689
- textAlign: 'center',
5690
- padding: 0,
5691
- backgroundColor: theme.colors[theme.primaryColor][0],
5692
- border: 0,
5693
- borderRadius: '50%',
5694
- cursor: 'pointer',
5695
- },
5696
- '& td button:hover': {
5697
- backgroundColor: theme.colors[theme.primaryColor][1],
5698
- },
5699
- '& td button:disabled': {
5700
- backgroundColor: 'transparent',
5701
- cursor: 'default',
5702
- color: theme.colors.gray[4],
5703
- fontWeight: 'normal',
5704
- },
5705
- },
5706
- }));
5707
- /**
5708
- * Returns a month display string (e.g. "January 2020").
5709
- * @param date Any date within the month.
5710
- * @returns The month display string (e.g. "January 2020")
5711
- */
5712
- function getMonthString(date) {
5713
- return date.toLocaleString('default', { month: 'long' }) + ' ' + date.getFullYear();
5714
- }
5715
- function CalendarInput(props) {
5716
- const { classes } = useStyles$1();
5717
- const { onChangeMonth, onClick } = props;
5718
- const [month, setMonth] = React.useState(getStartMonth);
5719
- function moveMonth(delta) {
5720
- setMonth((currMonth) => {
5721
- const newMonth = new Date(currMonth.getTime());
5722
- newMonth.setMonth(currMonth.getMonth() + delta);
5723
- onChangeMonth(newMonth);
5724
- return newMonth;
5725
- });
5726
- }
5727
- const grid = React.useMemo(() => buildGrid(month, props.slots), [month, props.slots]);
5728
- return (React.createElement("div", null,
5729
- React.createElement(core$1.Group, { position: "apart", spacing: "xs", grow: true, noWrap: true },
5730
- React.createElement("p", { style: { flex: 1 } }, getMonthString(month)),
5731
- React.createElement(core$1.Group, { position: "right", spacing: "xs" },
5732
- React.createElement(core$1.Button, { variant: "outline", "aria-label": "Previous month", onClick: () => moveMonth(-1) }, "<"),
5733
- React.createElement(core$1.Button, { variant: "outline", "aria-label": "Next month", onClick: () => moveMonth(1) }, ">"))),
5734
- React.createElement("table", { className: classes.table },
5735
- React.createElement("thead", null,
5736
- React.createElement("tr", null,
5737
- React.createElement("th", null, "SUN"),
5738
- React.createElement("th", null, "MON"),
5739
- React.createElement("th", null, "TUE"),
5740
- React.createElement("th", null, "WED"),
5741
- React.createElement("th", null, "THU"),
5742
- React.createElement("th", null, "FRI"),
5743
- React.createElement("th", null, "SAT"))),
5744
- React.createElement("tbody", null, grid.map((week, weekIndex) => (React.createElement("tr", { key: 'week-' + weekIndex }, week.map((day, dayIndex) => (React.createElement("td", { key: 'day-' + dayIndex }, day && (React.createElement(core$1.Button, { disabled: !day.available, onClick: () => onClick(day.date) }, day.date.getDate()))))))))))));
5745
- }
5746
- function getStartMonth() {
5747
- const result = new Date();
5748
- result.setDate(1);
5749
- result.setHours(0, 0, 0, 0);
5750
- return result;
5751
- }
5752
- function buildGrid(startDate, slots) {
5753
- const d = new Date(startDate.getFullYear(), startDate.getMonth());
5754
- const grid = [];
5755
- let row = [];
5756
- // Fill leading empty days
5757
- for (let i = 0; i < d.getDay(); i++) {
5758
- row.push(undefined);
5759
- }
5760
- while (d.getMonth() === startDate.getMonth()) {
5761
- row.push({
5762
- date: new Date(d.getTime()),
5763
- available: isDayAvailable(d, slots),
5764
- });
5765
- if (d.getDay() === 6) {
5766
- grid.push(row);
5767
- row = [];
5768
- }
5769
- d.setDate(d.getDate() + 1);
5770
- }
5771
- // Fill trailing empty days
5772
- if (d.getDay() !== 0) {
5773
- for (let i = d.getDay(); i < 7; i++) {
5774
- row.push(undefined);
5775
- }
5776
- grid.push(row);
5777
- }
5778
- return grid;
5779
- }
5780
- /**
5781
- * Returns true if the given date is available for booking.
5782
- * @param day The day to check.
5783
- * @param slots The list of available slots.
5784
- * @returns True if there are any available slots for the day.
5785
- */
5786
- function isDayAvailable(day, slots) {
5787
- // Note that slot start and end time may or may not be in UTC.
5788
- for (const slot of slots) {
5789
- const slotStart = new Date(slot.start);
5790
- if (slotStart.getFullYear() === day.getFullYear() &&
5791
- slotStart.getMonth() === day.getMonth() &&
5792
- slotStart.getDate() === day.getDate()) {
5793
- return true;
5794
- }
5795
- }
5796
- return false;
5797
- }
5798
-
5799
5829
  const useStyles = core$1.createStyles((theme) => ({
5800
5830
  container: {
5801
5831
  display: 'flex',
@@ -5934,19 +5964,26 @@
5934
5964
 
5935
5965
  exports.AddressDisplay = AddressDisplay;
5936
5966
  exports.AddressInput = AddressInput;
5967
+ exports.AnnotationInput = AnnotationInput;
5937
5968
  exports.AttachmentArrayDisplay = AttachmentArrayDisplay;
5938
5969
  exports.AttachmentArrayInput = AttachmentArrayInput;
5939
5970
  exports.AttachmentButton = AttachmentButton;
5971
+ exports.AttachmentDisplay = AttachmentDisplay;
5940
5972
  exports.AttachmentInput = AttachmentInput;
5973
+ exports.BackboneElementDisplay = BackboneElementDisplay;
5941
5974
  exports.BackboneElementInput = BackboneElementInput;
5975
+ exports.CalendarInput = CalendarInput;
5942
5976
  exports.CheckboxFormSection = CheckboxFormSection;
5943
5977
  exports.CodeInput = CodeInput;
5944
5978
  exports.CodeableConceptDisplay = CodeableConceptDisplay;
5945
5979
  exports.CodeableConceptInput = CodeableConceptInput;
5980
+ exports.CodingDisplay = CodingDisplay;
5981
+ exports.CodingInput = CodingInput;
5946
5982
  exports.ContactDetailDisplay = ContactDetailDisplay;
5947
5983
  exports.ContactDetailInput = ContactDetailInput;
5948
5984
  exports.ContactPointDisplay = ContactPointDisplay;
5949
5985
  exports.ContactPointInput = ContactPointInput;
5986
+ exports.Container = Container;
5950
5987
  exports.DateTimeInput = DateTimeInput;
5951
5988
  exports.DefaultResourceTimeline = DefaultResourceTimeline;
5952
5989
  exports.DescriptionList = DescriptionList;
@@ -5962,6 +5999,7 @@
5962
5999
  exports.FormSection = FormSection;
5963
6000
  exports.HumanNameDisplay = HumanNameDisplay;
5964
6001
  exports.HumanNameInput = HumanNameInput;
6002
+ exports.IdentifierDisplay = IdentifierDisplay;
5965
6003
  exports.IdentifierInput = IdentifierInput;
5966
6004
  exports.Logo = Logo;
5967
6005
  exports.MedplumLink = MedplumLink;
@@ -5969,13 +6007,17 @@
5969
6007
  exports.MemoizedFhirPathTable = MemoizedFhirPathTable;
5970
6008
  exports.MemoizedSearchControl = MemoizedSearchControl;
5971
6009
  exports.ObservationTable = ObservationTable;
6010
+ exports.Panel = Panel;
5972
6011
  exports.PatientTimeline = PatientTimeline;
5973
6012
  exports.PlanDefinitionBuilder = PlanDefinitionBuilder;
6013
+ exports.QuantityDisplay = QuantityDisplay;
6014
+ exports.QuantityInput = QuantityInput;
5974
6015
  exports.QuestionnaireBuilder = QuestionnaireBuilder;
5975
6016
  exports.QuestionnaireForm = QuestionnaireForm;
5976
6017
  exports.QuestionnaireFormItem = QuestionnaireFormItem;
5977
6018
  exports.RangeDisplay = RangeDisplay;
5978
6019
  exports.RangeInput = RangeInput;
6020
+ exports.ReferenceDisplay = ReferenceDisplay;
5979
6021
  exports.ReferenceInput = ReferenceInput;
5980
6022
  exports.ReferenceRangeEditor = ReferenceRangeEditor;
5981
6023
  exports.ReferenceRangeGroupEditor = ReferenceRangeGroupEditor;
@@ -6007,6 +6049,7 @@
6007
6049
  exports.StatusBadge = StatusBadge;
6008
6050
  exports.Timeline = Timeline;
6009
6051
  exports.TimelineItem = TimelineItem;
6052
+ exports.TimingInput = TimingInput;
6010
6053
  exports.addDateFilterBetween = addDateFilterBetween;
6011
6054
  exports.addField = addField;
6012
6055
  exports.addFilter = addFilter;
@@ -6027,10 +6070,12 @@
6027
6070
  exports.deleteFilter = deleteFilter;
6028
6071
  exports.getErrorsForInput = getErrorsForInput;
6029
6072
  exports.getIssuesForExpression = getIssuesForExpression;
6073
+ exports.getMonthString = getMonthString;
6030
6074
  exports.getOpString = getOpString;
6031
6075
  exports.getRecaptcha = getRecaptcha;
6032
6076
  exports.getSearchOperators = getSearchOperators;
6033
6077
  exports.getSortField = getSortField;
6078
+ exports.getStartMonth = getStartMonth;
6034
6079
  exports.getTimeString = getTimeString;
6035
6080
  exports.getValueAndType = getValueAndType;
6036
6081
  exports.initRecaptcha = initRecaptcha;