@medplum/react 2.0.22 → 2.0.24

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 (58) hide show
  1. package/dist/cjs/index.cjs +71 -70
  2. package/dist/cjs/index.cjs.map +1 -1
  3. package/dist/cjs/index.min.cjs +1 -1
  4. package/dist/esm/AddressInput/AddressInput.mjs +3 -3
  5. package/dist/esm/AddressInput/AddressInput.mjs.map +1 -1
  6. package/dist/esm/AppShell/Header.mjs +4 -4
  7. package/dist/esm/AppShell/Header.mjs.map +1 -1
  8. package/dist/esm/AsyncAutocomplete/AsyncAutocomplete.mjs +9 -3
  9. package/dist/esm/AsyncAutocomplete/AsyncAutocomplete.mjs.map +1 -1
  10. package/dist/esm/AttachmentArrayDisplay/AttachmentArrayDisplay.mjs +2 -3
  11. package/dist/esm/AttachmentArrayDisplay/AttachmentArrayDisplay.mjs.map +1 -1
  12. package/dist/esm/AttachmentButton/AttachmentButton.mjs +1 -1
  13. package/dist/esm/AttachmentButton/AttachmentButton.mjs.map +1 -1
  14. package/dist/esm/BackboneElementDisplay/BackboneElementDisplay.mjs +1 -1
  15. package/dist/esm/BackboneElementDisplay/BackboneElementDisplay.mjs.map +1 -1
  16. package/dist/esm/BackboneElementInput/BackboneElementInput.mjs +1 -1
  17. package/dist/esm/BackboneElementInput/BackboneElementInput.mjs.map +1 -1
  18. package/dist/esm/BookmarkDialog/BookmarkDialog.mjs +2 -2
  19. package/dist/esm/BookmarkDialog/BookmarkDialog.mjs.map +1 -1
  20. package/dist/esm/DiagnosticReportDisplay/DiagnosticReportDisplay.mjs +10 -12
  21. package/dist/esm/DiagnosticReportDisplay/DiagnosticReportDisplay.mjs.map +1 -1
  22. package/dist/esm/FhirPathTable/FhirPathTable.mjs +7 -7
  23. package/dist/esm/FhirPathTable/FhirPathTable.mjs.map +1 -1
  24. package/dist/esm/GoogleButton/GoogleButton.mjs +2 -2
  25. package/dist/esm/GoogleButton/GoogleButton.mjs.map +1 -1
  26. package/dist/esm/PlanDefinitionBuilder/PlanDefinitionBuilder.mjs +1 -1
  27. package/dist/esm/PlanDefinitionBuilder/PlanDefinitionBuilder.mjs.map +1 -1
  28. package/dist/esm/QuestionnaireBuilder/QuestionnaireBuilder.mjs +6 -7
  29. package/dist/esm/QuestionnaireBuilder/QuestionnaireBuilder.mjs.map +1 -1
  30. package/dist/esm/QuestionnaireForm/QuestionnaireForm.mjs +2 -1
  31. package/dist/esm/QuestionnaireForm/QuestionnaireForm.mjs.map +1 -1
  32. package/dist/esm/ReferenceRangeEditor/ReferenceRangeEditor.mjs +6 -6
  33. package/dist/esm/ReferenceRangeEditor/ReferenceRangeEditor.mjs.map +1 -1
  34. package/dist/esm/ResourcePropertyDisplay/ResourcePropertyDisplay.mjs +2 -2
  35. package/dist/esm/ResourcePropertyDisplay/ResourcePropertyDisplay.mjs.map +1 -1
  36. package/dist/esm/ResourcePropertyInput/ResourcePropertyInput.mjs +3 -3
  37. package/dist/esm/ResourcePropertyInput/ResourcePropertyInput.mjs.map +1 -1
  38. package/dist/esm/ResourceTimeline/ResourceTimeline.mjs.map +1 -1
  39. package/dist/esm/SearchControl/SearchControl.mjs +2 -2
  40. package/dist/esm/SearchControl/SearchControl.mjs.map +1 -1
  41. package/dist/esm/SearchControl/SearchUtils.mjs +1 -1
  42. package/dist/esm/SearchControl/SearchUtils.mjs.map +1 -1
  43. package/dist/esm/SearchFieldEditor/SearchFieldEditor.mjs +1 -1
  44. package/dist/esm/SearchFieldEditor/SearchFieldEditor.mjs.map +1 -1
  45. package/dist/esm/SearchFilterValueDisplay/SearchFilterValueDisplay.mjs +1 -1
  46. package/dist/esm/SearchFilterValueDisplay/SearchFilterValueDisplay.mjs.map +1 -1
  47. package/dist/esm/SearchFilterValueInput/SearchFilterValueInput.mjs +1 -1
  48. package/dist/esm/SearchFilterValueInput/SearchFilterValueInput.mjs.map +1 -1
  49. package/dist/esm/TimingInput/TimingInput.mjs +3 -3
  50. package/dist/esm/TimingInput/TimingInput.mjs.map +1 -1
  51. package/dist/esm/ValueSetAutocomplete/ValueSetAutocomplete.mjs +1 -1
  52. package/dist/esm/ValueSetAutocomplete/ValueSetAutocomplete.mjs.map +1 -1
  53. package/dist/esm/auth/SignInForm.mjs +4 -2
  54. package/dist/esm/auth/SignInForm.mjs.map +1 -1
  55. package/dist/esm/index.min.mjs +1 -1
  56. package/dist/esm/utils/diff.mjs +1 -1
  57. package/dist/esm/utils/diff.mjs.map +1 -1
  58. package/package.json +16 -16
@@ -2,7 +2,7 @@ import { Group, NativeSelect, TextInput } from '@mantine/core';
2
2
  import React, { useState, useRef } from 'react';
3
3
 
4
4
  function getLine(address, index) {
5
- return address && address.line && address.line.length > index ? address.line[index] : '';
5
+ return address.line && address.line.length > index ? address.line[index] : '';
6
6
  }
7
7
  function setLine(address, index, str) {
8
8
  const line = address.line || [];
@@ -44,8 +44,8 @@ function AddressInput(props) {
44
44
  setValueWrapper({ ...valueRef.current, postalCode });
45
45
  }
46
46
  return (React.createElement(Group, { spacing: "xs", grow: true, noWrap: true },
47
- React.createElement(NativeSelect, { "data-testid": "address-use", defaultValue: value?.use, onChange: (e) => setUse(e.currentTarget.value), data: ['', 'home', 'work', 'temp', 'old', 'billing'] }),
48
- React.createElement(NativeSelect, { "data-testid": "address-type", defaultValue: value?.type, onChange: (e) => setType(e.currentTarget.value), data: ['', 'postal', 'physical', 'both'] }),
47
+ React.createElement(NativeSelect, { "data-testid": "address-use", defaultValue: value.use, onChange: (e) => setUse(e.currentTarget.value), data: ['', 'home', 'work', 'temp', 'old', 'billing'] }),
48
+ React.createElement(NativeSelect, { "data-testid": "address-type", defaultValue: value.type, onChange: (e) => setType(e.currentTarget.value), data: ['', 'postal', 'physical', 'both'] }),
49
49
  React.createElement(TextInput, { placeholder: "Line 1", defaultValue: getLine(value, 0), onChange: (e) => setLine1(e.currentTarget.value) }),
50
50
  React.createElement(TextInput, { placeholder: "Line 2", defaultValue: getLine(value, 1), onChange: (e) => setLine2(e.currentTarget.value) }),
51
51
  React.createElement(TextInput, { placeholder: "City", defaultValue: value.city, onChange: (e) => setCity(e.currentTarget.value) }),
@@ -1 +1 @@
1
- {"version":3,"file":"AddressInput.mjs","sources":["../../../src/AddressInput/AddressInput.tsx"],"sourcesContent":["import { Group, NativeSelect, TextInput } from '@mantine/core';\nimport { Address } from '@medplum/fhirtypes';\nimport React, { useRef, useState } from 'react';\n\nfunction getLine(address: Address, index: number): string {\n return address && address.line && address.line.length > index ? address.line[index] : '';\n}\n\nfunction setLine(address: Address, index: number, str: string): Address {\n const line: string[] = address.line || [];\n while (line.length <= index) {\n line.push('');\n }\n line[index] = str;\n return { ...address, line };\n}\n\nexport interface AddressInputProps {\n name: string;\n defaultValue?: Address;\n onChange?: (value: Address) => void;\n}\n\nexport function AddressInput(props: AddressInputProps): JSX.Element {\n const [value, setValue] = useState<Address>(props.defaultValue || {});\n\n const valueRef = useRef<Address>();\n valueRef.current = value;\n\n function setValueWrapper(newValue: Address): void {\n setValue(newValue);\n if (props.onChange) {\n props.onChange(newValue);\n }\n }\n\n function setUse(use: 'home' | 'work' | 'temp' | 'old' | 'billing'): void {\n setValueWrapper({ ...valueRef.current, use });\n }\n\n function setType(type: 'postal' | 'physical' | 'both'): void {\n setValueWrapper({ ...valueRef.current, type });\n }\n\n function setLine1(line1: string): void {\n setValueWrapper(setLine(valueRef.current || {}, 0, line1));\n }\n\n function setLine2(line2: string): void {\n setValueWrapper(setLine(valueRef.current || {}, 1, line2));\n }\n\n function setCity(city: string): void {\n setValueWrapper({ ...valueRef.current, city });\n }\n\n function setState(state: string): void {\n setValueWrapper({ ...valueRef.current, state });\n }\n\n function setPostalCode(postalCode: string): void {\n setValueWrapper({ ...valueRef.current, postalCode });\n }\n\n return (\n <Group spacing=\"xs\" grow noWrap>\n <NativeSelect\n data-testid=\"address-use\"\n defaultValue={value?.use}\n onChange={(e) => setUse(e.currentTarget.value as 'home' | 'work' | 'temp' | 'old' | 'billing')}\n data={['', 'home', 'work', 'temp', 'old', 'billing']}\n />\n <NativeSelect\n data-testid=\"address-type\"\n defaultValue={value?.type}\n onChange={(e) => setType(e.currentTarget.value as 'postal' | 'physical' | 'both')}\n data={['', 'postal', 'physical', 'both']}\n />\n <TextInput\n placeholder=\"Line 1\"\n defaultValue={getLine(value, 0)}\n onChange={(e) => setLine1(e.currentTarget.value)}\n />\n <TextInput\n placeholder=\"Line 2\"\n defaultValue={getLine(value, 1)}\n onChange={(e) => setLine2(e.currentTarget.value)}\n />\n <TextInput placeholder=\"City\" defaultValue={value.city} onChange={(e) => setCity(e.currentTarget.value)} />\n <TextInput placeholder=\"State\" defaultValue={value.state} onChange={(e) => setState(e.currentTarget.value)} />\n <TextInput\n placeholder=\"Postal Code\"\n defaultValue={value.postalCode}\n onChange={(e) => setPostalCode(e.currentTarget.value)}\n />\n </Group>\n );\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"AddressInput.mjs","sources":["../../../src/AddressInput/AddressInput.tsx"],"sourcesContent":["import { Group, NativeSelect, TextInput } from '@mantine/core';\nimport { Address } from '@medplum/fhirtypes';\nimport React, { useRef, useState } from 'react';\n\nfunction getLine(address: Address, index: number): string {\n return address.line && address.line.length > index ? address.line[index] : '';\n}\n\nfunction setLine(address: Address, index: number, str: string): Address {\n const line: string[] = address.line || [];\n while (line.length <= index) {\n line.push('');\n }\n line[index] = str;\n return { ...address, line };\n}\n\nexport interface AddressInputProps {\n name: string;\n defaultValue?: Address;\n onChange?: (value: Address) => void;\n}\n\nexport function AddressInput(props: AddressInputProps): JSX.Element {\n const [value, setValue] = useState<Address>(props.defaultValue || {});\n\n const valueRef = useRef<Address>();\n valueRef.current = value;\n\n function setValueWrapper(newValue: Address): void {\n setValue(newValue);\n if (props.onChange) {\n props.onChange(newValue);\n }\n }\n\n function setUse(use: 'home' | 'work' | 'temp' | 'old' | 'billing'): void {\n setValueWrapper({ ...valueRef.current, use });\n }\n\n function setType(type: 'postal' | 'physical' | 'both'): void {\n setValueWrapper({ ...valueRef.current, type });\n }\n\n function setLine1(line1: string): void {\n setValueWrapper(setLine(valueRef.current || {}, 0, line1));\n }\n\n function setLine2(line2: string): void {\n setValueWrapper(setLine(valueRef.current || {}, 1, line2));\n }\n\n function setCity(city: string): void {\n setValueWrapper({ ...valueRef.current, city });\n }\n\n function setState(state: string): void {\n setValueWrapper({ ...valueRef.current, state });\n }\n\n function setPostalCode(postalCode: string): void {\n setValueWrapper({ ...valueRef.current, postalCode });\n }\n\n return (\n <Group spacing=\"xs\" grow noWrap>\n <NativeSelect\n data-testid=\"address-use\"\n defaultValue={value.use}\n onChange={(e) => setUse(e.currentTarget.value as 'home' | 'work' | 'temp' | 'old' | 'billing')}\n data={['', 'home', 'work', 'temp', 'old', 'billing']}\n />\n <NativeSelect\n data-testid=\"address-type\"\n defaultValue={value.type}\n onChange={(e) => setType(e.currentTarget.value as 'postal' | 'physical' | 'both')}\n data={['', 'postal', 'physical', 'both']}\n />\n <TextInput\n placeholder=\"Line 1\"\n defaultValue={getLine(value, 0)}\n onChange={(e) => setLine1(e.currentTarget.value)}\n />\n <TextInput\n placeholder=\"Line 2\"\n defaultValue={getLine(value, 1)}\n onChange={(e) => setLine2(e.currentTarget.value)}\n />\n <TextInput placeholder=\"City\" defaultValue={value.city} onChange={(e) => setCity(e.currentTarget.value)} />\n <TextInput placeholder=\"State\" defaultValue={value.state} onChange={(e) => setState(e.currentTarget.value)} />\n <TextInput\n placeholder=\"Postal Code\"\n defaultValue={value.postalCode}\n onChange={(e) => setPostalCode(e.currentTarget.value)}\n />\n </Group>\n );\n}\n"],"names":[],"mappings":"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"}
@@ -61,9 +61,9 @@ function Header(props) {
61
61
  React.createElement(Stack, { align: "center", p: "xl" },
62
62
  React.createElement(ResourceAvatar, { size: "xl", radius: 100, value: context.profile }),
63
63
  React.createElement(HumanNameDisplay, { value: context.profile?.name?.[0] }),
64
- React.createElement(Text, { color: "dimmed", size: "xs" }, medplum.getActiveLogin()?.project?.display)),
64
+ React.createElement(Text, { color: "dimmed", size: "xs" }, medplum.getActiveLogin()?.project.display)),
65
65
  logins.length > 1 && React.createElement(Menu.Divider, null),
66
- logins.map((login) => login.profile?.reference !== getReferenceString(context.profile) && (React.createElement(Menu.Item, { key: login.profile?.reference, onClick: () => {
66
+ logins.map((login) => login.profile.reference !== getReferenceString(context.profile) && (React.createElement(Menu.Item, { key: login.profile.reference, onClick: () => {
67
67
  medplum
68
68
  .setActiveLogin(login)
69
69
  .then(() => window.location.reload())
@@ -72,8 +72,8 @@ function Header(props) {
72
72
  React.createElement(Group, null,
73
73
  React.createElement(Avatar, { radius: "xl" }),
74
74
  React.createElement("div", { style: { flex: 1 } },
75
- React.createElement(Text, { size: "sm", weight: 500 }, login.profile?.display),
76
- React.createElement(Text, { color: "dimmed", size: "xs" }, login.project?.display)))))),
75
+ React.createElement(Text, { size: "sm", weight: 500 }, login.profile.display),
76
+ React.createElement(Text, { color: "dimmed", size: "xs" }, login.project.display)))))),
77
77
  React.createElement(Menu.Divider, null),
78
78
  React.createElement(Menu.Item, { icon: React.createElement(IconSwitchHorizontal, { size: 14, stroke: 1.5 }), onClick: () => navigate('/signin') }, "Add another account"),
79
79
  React.createElement(Menu.Item, { icon: React.createElement(IconSettings, { size: 14, stroke: 1.5 }), onClick: () => navigate(`/${getReferenceString(profile)}`) }, "Account settings"),
@@ -1 +1 @@
1
- {"version":3,"file":"Header.mjs","sources":["../../../src/AppShell/Header.tsx"],"sourcesContent":["import { Avatar, createStyles, Group, Header as MantineHeader, Menu, Stack, Text, UnstyledButton } from '@mantine/core';\nimport { formatHumanName, getReferenceString, ProfileResource } from '@medplum/core';\nimport { HumanName } from '@medplum/fhirtypes';\nimport { IconChevronDown, IconLogout, IconSettings, IconSwitchHorizontal } from '@tabler/icons-react';\nimport React, { useState } from 'react';\nimport { HumanNameDisplay } from '../HumanNameDisplay/HumanNameDisplay';\nimport { useMedplumContext } from '../MedplumProvider/MedplumProvider';\nimport { ResourceAvatar } from '../ResourceAvatar/ResourceAvatar';\nimport { HeaderSearchInput } from './HeaderSearchInput';\n\nconst useStyles = createStyles((theme) => ({\n logoButton: {\n padding: `${theme.spacing.xs} ${theme.spacing.sm}`,\n borderRadius: theme.radius.sm,\n transition: 'background-color 100ms ease',\n\n '&:hover': {\n backgroundColor: theme.fn.lighten(\n theme.fn.variant({ variant: 'filled', color: theme.primaryColor }).background as string,\n 0.8\n ),\n },\n },\n\n user: {\n padding: `${theme.spacing.xs} ${theme.spacing.sm}`,\n borderRadius: theme.radius.sm,\n transition: 'background-color 100ms ease',\n\n '&:hover': {\n backgroundColor: theme.fn.lighten(\n theme.fn.variant({ variant: 'filled', color: theme.primaryColor }).background as string,\n 0.8\n ),\n },\n },\n\n userName: {\n fontWeight: 500,\n lineHeight: 1,\n marginRight: 3,\n\n [theme.fn.smallerThan('xs')]: {\n display: 'none',\n },\n },\n\n userActive: {\n backgroundColor: theme.fn.lighten(\n theme.fn.variant({ variant: 'filled', color: theme.primaryColor }).background as string,\n 0.8\n ),\n },\n}));\n\ninterface HeaderProps {\n pathname?: string;\n searchParams?: URLSearchParams;\n logo: React.ReactNode;\n version?: string;\n navbarToggle: () => void;\n}\n\nexport function Header(props: HeaderProps): JSX.Element {\n const context = useMedplumContext();\n const { medplum, profile, navigate } = context;\n const logins = medplum.getLogins();\n const { classes, cx } = useStyles();\n const [userMenuOpened, setUserMenuOpened] = useState(false);\n\n return (\n <MantineHeader height={60} p={8} style={{ zIndex: 101 }}>\n <Group position=\"apart\">\n <Group spacing=\"xs\">\n <UnstyledButton className={classes.logoButton} onClick={props.navbarToggle}>\n {props.logo}\n </UnstyledButton>\n <HeaderSearchInput pathname={props.pathname} searchParams={props.searchParams} />\n </Group>\n\n <Menu\n width={260}\n shadow=\"xl\"\n position=\"bottom-end\"\n transitionProps={{ transition: 'pop-top-right' }}\n opened={userMenuOpened}\n onClose={() => setUserMenuOpened(false)}\n >\n <Menu.Target>\n <UnstyledButton\n className={cx(classes.user, { [classes.userActive]: userMenuOpened })}\n onClick={() => setUserMenuOpened((o) => !o)}\n >\n <Group spacing={7}>\n <ResourceAvatar value={profile} radius=\"xl\" size={24} />\n <Text size=\"sm\" className={classes.userName}>\n {formatHumanName(profile?.name?.[0] as HumanName)}\n </Text>\n <IconChevronDown size={12} stroke={1.5} />\n </Group>\n </UnstyledButton>\n </Menu.Target>\n <Menu.Dropdown>\n <Stack align=\"center\" p=\"xl\">\n <ResourceAvatar size=\"xl\" radius={100} value={context.profile} />\n <HumanNameDisplay value={context.profile?.name?.[0] as HumanName} />\n <Text color=\"dimmed\" size=\"xs\">\n {medplum.getActiveLogin()?.project?.display}\n </Text>\n </Stack>\n {logins.length > 1 && <Menu.Divider />}\n {logins.map(\n (login) =>\n login.profile?.reference !== getReferenceString(context.profile as ProfileResource) && (\n <Menu.Item\n key={login.profile?.reference}\n onClick={() => {\n medplum\n .setActiveLogin(login)\n .then(() => window.location.reload())\n .catch(console.log);\n }}\n >\n <Group>\n <Avatar radius=\"xl\" />\n <div style={{ flex: 1 }}>\n <Text size=\"sm\" weight={500}>\n {login.profile?.display}\n </Text>\n <Text color=\"dimmed\" size=\"xs\">\n {login.project?.display}\n </Text>\n </div>\n </Group>\n </Menu.Item>\n )\n )}\n <Menu.Divider />\n <Menu.Item icon={<IconSwitchHorizontal size={14} stroke={1.5} />} onClick={() => navigate('/signin')}>\n Add another account\n </Menu.Item>\n <Menu.Item\n icon={<IconSettings size={14} stroke={1.5} />}\n onClick={() => navigate(`/${getReferenceString(profile as ProfileResource)}`)}\n >\n Account settings\n </Menu.Item>\n <Menu.Item\n icon={<IconLogout size={14} stroke={1.5} />}\n onClick={async () => {\n await medplum.signOut();\n navigate('/signin');\n }}\n >\n Sign out\n </Menu.Item>\n <Text size=\"xs\" color=\"dimmed\" align=\"center\">\n {props.version}\n </Text>\n </Menu.Dropdown>\n </Menu>\n </Group>\n </MantineHeader>\n );\n}\n"],"names":["MantineHeader"],"mappings":";;;;;;;;;;;;AAUA,MAAM,SAAS,GAAG,YAAY,CAAC,CAAC,KAAK,MAAM;AACzC,IAAA,UAAU,EAAE;AACV,QAAA,OAAO,EAAE,CAAA,EAAG,KAAK,CAAC,OAAO,CAAC,EAAE,CAAA,CAAA,EAAI,KAAK,CAAC,OAAO,CAAC,EAAE,CAAE,CAAA;AAClD,QAAA,YAAY,EAAE,KAAK,CAAC,MAAM,CAAC,EAAE;AAC7B,QAAA,UAAU,EAAE,6BAA6B;AAEzC,QAAA,SAAS,EAAE;AACT,YAAA,eAAe,EAAE,KAAK,CAAC,EAAE,CAAC,OAAO,CAC/B,KAAK,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,KAAK,CAAC,YAAY,EAAE,CAAC,CAAC,UAAoB,EACvF,GAAG,CACJ;AACF,SAAA;AACF,KAAA;AAED,IAAA,IAAI,EAAE;AACJ,QAAA,OAAO,EAAE,CAAA,EAAG,KAAK,CAAC,OAAO,CAAC,EAAE,CAAA,CAAA,EAAI,KAAK,CAAC,OAAO,CAAC,EAAE,CAAE,CAAA;AAClD,QAAA,YAAY,EAAE,KAAK,CAAC,MAAM,CAAC,EAAE;AAC7B,QAAA,UAAU,EAAE,6BAA6B;AAEzC,QAAA,SAAS,EAAE;AACT,YAAA,eAAe,EAAE,KAAK,CAAC,EAAE,CAAC,OAAO,CAC/B,KAAK,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,KAAK,CAAC,YAAY,EAAE,CAAC,CAAC,UAAoB,EACvF,GAAG,CACJ;AACF,SAAA;AACF,KAAA;AAED,IAAA,QAAQ,EAAE;AACR,QAAA,UAAU,EAAE,GAAG;AACf,QAAA,UAAU,EAAE,CAAC;AACb,QAAA,WAAW,EAAE,CAAC;QAEd,CAAC,KAAK,CAAC,EAAE,CAAC,WAAW,CAAC,IAAI,CAAC,GAAG;AAC5B,YAAA,OAAO,EAAE,MAAM;AAChB,SAAA;AACF,KAAA;AAED,IAAA,UAAU,EAAE;AACV,QAAA,eAAe,EAAE,KAAK,CAAC,EAAE,CAAC,OAAO,CAC/B,KAAK,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,KAAK,CAAC,YAAY,EAAE,CAAC,CAAC,UAAoB,EACvF,GAAG,CACJ;AACF,KAAA;AACF,CAAA,CAAC,CAAC,CAAC;AAUE,SAAU,MAAM,CAAC,KAAkB,EAAA;AACvC,IAAA,MAAM,OAAO,GAAG,iBAAiB,EAAE,CAAC;IACpC,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC;AAC/C,IAAA,MAAM,MAAM,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;IACnC,MAAM,EAAE,OAAO,EAAE,EAAE,EAAE,GAAG,SAAS,EAAE,CAAC;IACpC,MAAM,CAAC,cAAc,EAAE,iBAAiB,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;AAE5D,IAAA,QACE,KAAC,CAAA,aAAA,CAAAA,QAAa,IAAC,MAAM,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,EAAA;AACrD,QAAA,KAAA,CAAA,aAAA,CAAC,KAAK,EAAA,EAAC,QAAQ,EAAC,OAAO,EAAA;AACrB,YAAA,KAAA,CAAA,aAAA,CAAC,KAAK,EAAA,EAAC,OAAO,EAAC,IAAI,EAAA;AACjB,gBAAA,KAAA,CAAA,aAAA,CAAC,cAAc,EAAC,EAAA,SAAS,EAAE,OAAO,CAAC,UAAU,EAAE,OAAO,EAAE,KAAK,CAAC,YAAY,IACvE,KAAK,CAAC,IAAI,CACI;AACjB,gBAAA,KAAA,CAAA,aAAA,CAAC,iBAAiB,EAAA,EAAC,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,YAAY,EAAE,KAAK,CAAC,YAAY,GAAI,CAC3E;AAER,YAAA,KAAA,CAAA,aAAA,CAAC,IAAI,EAAA,EACH,KAAK,EAAE,GAAG,EACV,MAAM,EAAC,IAAI,EACX,QAAQ,EAAC,YAAY,EACrB,eAAe,EAAE,EAAE,UAAU,EAAE,eAAe,EAAE,EAChD,MAAM,EAAE,cAAc,EACtB,OAAO,EAAE,MAAM,iBAAiB,CAAC,KAAK,CAAC,EAAA;gBAEvC,KAAC,CAAA,aAAA,CAAA,IAAI,CAAC,MAAM,EAAA,IAAA;AACV,oBAAA,KAAA,CAAA,aAAA,CAAC,cAAc,EAAA,EACb,SAAS,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,UAAU,GAAG,cAAc,EAAE,CAAC,EACrE,OAAO,EAAE,MAAM,iBAAiB,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAA;AAE3C,wBAAA,KAAA,CAAA,aAAA,CAAC,KAAK,EAAA,EAAC,OAAO,EAAE,CAAC,EAAA;AACf,4BAAA,KAAA,CAAA,aAAA,CAAC,cAAc,EAAA,EAAC,KAAK,EAAE,OAAO,EAAE,MAAM,EAAC,IAAI,EAAC,IAAI,EAAE,EAAE,EAAI,CAAA;4BACxD,KAAC,CAAA,aAAA,CAAA,IAAI,IAAC,IAAI,EAAC,IAAI,EAAC,SAAS,EAAE,OAAO,CAAC,QAAQ,IACxC,eAAe,CAAC,OAAO,EAAE,IAAI,GAAG,CAAC,CAAc,CAAC,CAC5C;AACP,4BAAA,KAAA,CAAA,aAAA,CAAC,eAAe,EAAA,EAAC,IAAI,EAAE,EAAE,EAAE,MAAM,EAAE,GAAG,EAAA,CAAI,CACpC,CACO,CACL;gBACd,KAAC,CAAA,aAAA,CAAA,IAAI,CAAC,QAAQ,EAAA,IAAA;oBACZ,KAAC,CAAA,aAAA,CAAA,KAAK,IAAC,KAAK,EAAC,QAAQ,EAAC,CAAC,EAAC,IAAI,EAAA;AAC1B,wBAAA,KAAA,CAAA,aAAA,CAAC,cAAc,EAAA,EAAC,IAAI,EAAC,IAAI,EAAC,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,OAAO,CAAC,OAAO,EAAI,CAAA;AACjE,wBAAA,KAAA,CAAA,aAAA,CAAC,gBAAgB,EAAA,EAAC,KAAK,EAAE,OAAO,CAAC,OAAO,EAAE,IAAI,GAAG,CAAC,CAAc,EAAI,CAAA;AACpE,wBAAA,KAAA,CAAA,aAAA,CAAC,IAAI,EAAC,EAAA,KAAK,EAAC,QAAQ,EAAC,IAAI,EAAC,IAAI,IAC3B,OAAO,CAAC,cAAc,EAAE,EAAE,OAAO,EAAE,OAAO,CACtC,CACD;oBACP,MAAM,CAAC,MAAM,GAAG,CAAC,IAAI,KAAC,CAAA,aAAA,CAAA,IAAI,CAAC,OAAO,EAAG,IAAA,CAAA;AACrC,oBAAA,MAAM,CAAC,GAAG,CACT,CAAC,KAAK,KACJ,KAAK,CAAC,OAAO,EAAE,SAAS,KAAK,kBAAkB,CAAC,OAAO,CAAC,OAA0B,CAAC,KACjF,KAAC,CAAA,aAAA,CAAA,IAAI,CAAC,IAAI,IACR,GAAG,EAAE,KAAK,CAAC,OAAO,EAAE,SAAS,EAC7B,OAAO,EAAE,MAAK;4BACZ,OAAO;iCACJ,cAAc,CAAC,KAAK,CAAC;iCACrB,IAAI,CAAC,MAAM,MAAM,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC;AACpC,iCAAA,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;yBACvB,EAAA;AAED,wBAAA,KAAA,CAAA,aAAA,CAAC,KAAK,EAAA,IAAA;AACJ,4BAAA,KAAA,CAAA,aAAA,CAAC,MAAM,EAAA,EAAC,MAAM,EAAC,IAAI,EAAG,CAAA;AACtB,4BAAA,KAAA,CAAA,aAAA,CAAA,KAAA,EAAA,EAAK,KAAK,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE,EAAA;AACrB,gCAAA,KAAA,CAAA,aAAA,CAAC,IAAI,EAAA,EAAC,IAAI,EAAC,IAAI,EAAC,MAAM,EAAE,GAAG,IACxB,KAAK,CAAC,OAAO,EAAE,OAAO,CAClB;gCACP,KAAC,CAAA,aAAA,CAAA,IAAI,IAAC,KAAK,EAAC,QAAQ,EAAC,IAAI,EAAC,IAAI,EAAA,EAC3B,KAAK,CAAC,OAAO,EAAE,OAAO,CAClB,CACH,CACA,CACE,CACb,CACJ;oBACD,KAAC,CAAA,aAAA,CAAA,IAAI,CAAC,OAAO,EAAG,IAAA,CAAA;oBAChB,KAAC,CAAA,aAAA,CAAA,IAAI,CAAC,IAAI,EAAC,EAAA,IAAI,EAAE,KAAA,CAAA,aAAA,CAAC,oBAAoB,EAAA,EAAC,IAAI,EAAE,EAAE,EAAE,MAAM,EAAE,GAAG,EAAA,CAAI,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC,SAAS,CAAC,EAExF,EAAA,qBAAA,CAAA;AACZ,oBAAA,KAAA,CAAA,aAAA,CAAC,IAAI,CAAC,IAAI,EAAA,EACR,IAAI,EAAE,KAAA,CAAA,aAAA,CAAC,YAAY,EAAA,EAAC,IAAI,EAAE,EAAE,EAAE,MAAM,EAAE,GAAG,EAAI,CAAA,EAC7C,OAAO,EAAE,MAAM,QAAQ,CAAC,CAAI,CAAA,EAAA,kBAAkB,CAAC,OAA0B,CAAC,CAAA,CAAE,CAAC,EAGnE,EAAA,kBAAA,CAAA;oBACZ,KAAC,CAAA,aAAA,CAAA,IAAI,CAAC,IAAI,EAAA,EACR,IAAI,EAAE,KAAA,CAAA,aAAA,CAAC,UAAU,EAAA,EAAC,IAAI,EAAE,EAAE,EAAE,MAAM,EAAE,GAAG,EAAA,CAAI,EAC3C,OAAO,EAAE,YAAW;AAClB,4BAAA,MAAM,OAAO,CAAC,OAAO,EAAE,CAAC;4BACxB,QAAQ,CAAC,SAAS,CAAC,CAAC;AACtB,yBAAC,EAGS,EAAA,UAAA,CAAA;oBACZ,KAAC,CAAA,aAAA,CAAA,IAAI,IAAC,IAAI,EAAC,IAAI,EAAC,KAAK,EAAC,QAAQ,EAAC,KAAK,EAAC,QAAQ,EAAA,EAC1C,KAAK,CAAC,OAAO,CACT,CACO,CACX,CACD,CACM,EAChB;AACJ;;;;"}
1
+ {"version":3,"file":"Header.mjs","sources":["../../../src/AppShell/Header.tsx"],"sourcesContent":["import { Avatar, createStyles, Group, Header as MantineHeader, Menu, Stack, Text, UnstyledButton } from '@mantine/core';\nimport { formatHumanName, getReferenceString, ProfileResource } from '@medplum/core';\nimport { HumanName } from '@medplum/fhirtypes';\nimport { IconChevronDown, IconLogout, IconSettings, IconSwitchHorizontal } from '@tabler/icons-react';\nimport React, { useState } from 'react';\nimport { HumanNameDisplay } from '../HumanNameDisplay/HumanNameDisplay';\nimport { useMedplumContext } from '../MedplumProvider/MedplumProvider';\nimport { ResourceAvatar } from '../ResourceAvatar/ResourceAvatar';\nimport { HeaderSearchInput } from './HeaderSearchInput';\n\nconst useStyles = createStyles((theme) => ({\n logoButton: {\n padding: `${theme.spacing.xs} ${theme.spacing.sm}`,\n borderRadius: theme.radius.sm,\n transition: 'background-color 100ms ease',\n\n '&:hover': {\n backgroundColor: theme.fn.lighten(\n theme.fn.variant({ variant: 'filled', color: theme.primaryColor }).background as string,\n 0.8\n ),\n },\n },\n\n user: {\n padding: `${theme.spacing.xs} ${theme.spacing.sm}`,\n borderRadius: theme.radius.sm,\n transition: 'background-color 100ms ease',\n\n '&:hover': {\n backgroundColor: theme.fn.lighten(\n theme.fn.variant({ variant: 'filled', color: theme.primaryColor }).background as string,\n 0.8\n ),\n },\n },\n\n userName: {\n fontWeight: 500,\n lineHeight: 1,\n marginRight: 3,\n\n [theme.fn.smallerThan('xs')]: {\n display: 'none',\n },\n },\n\n userActive: {\n backgroundColor: theme.fn.lighten(\n theme.fn.variant({ variant: 'filled', color: theme.primaryColor }).background as string,\n 0.8\n ),\n },\n}));\n\ninterface HeaderProps {\n pathname?: string;\n searchParams?: URLSearchParams;\n logo: React.ReactNode;\n version?: string;\n navbarToggle: () => void;\n}\n\nexport function Header(props: HeaderProps): JSX.Element {\n const context = useMedplumContext();\n const { medplum, profile, navigate } = context;\n const logins = medplum.getLogins();\n const { classes, cx } = useStyles();\n const [userMenuOpened, setUserMenuOpened] = useState(false);\n\n return (\n <MantineHeader height={60} p={8} style={{ zIndex: 101 }}>\n <Group position=\"apart\">\n <Group spacing=\"xs\">\n <UnstyledButton className={classes.logoButton} onClick={props.navbarToggle}>\n {props.logo}\n </UnstyledButton>\n <HeaderSearchInput pathname={props.pathname} searchParams={props.searchParams} />\n </Group>\n\n <Menu\n width={260}\n shadow=\"xl\"\n position=\"bottom-end\"\n transitionProps={{ transition: 'pop-top-right' }}\n opened={userMenuOpened}\n onClose={() => setUserMenuOpened(false)}\n >\n <Menu.Target>\n <UnstyledButton\n className={cx(classes.user, { [classes.userActive]: userMenuOpened })}\n onClick={() => setUserMenuOpened((o) => !o)}\n >\n <Group spacing={7}>\n <ResourceAvatar value={profile} radius=\"xl\" size={24} />\n <Text size=\"sm\" className={classes.userName}>\n {formatHumanName(profile?.name?.[0] as HumanName)}\n </Text>\n <IconChevronDown size={12} stroke={1.5} />\n </Group>\n </UnstyledButton>\n </Menu.Target>\n <Menu.Dropdown>\n <Stack align=\"center\" p=\"xl\">\n <ResourceAvatar size=\"xl\" radius={100} value={context.profile} />\n <HumanNameDisplay value={context.profile?.name?.[0] as HumanName} />\n <Text color=\"dimmed\" size=\"xs\">\n {medplum.getActiveLogin()?.project.display}\n </Text>\n </Stack>\n {logins.length > 1 && <Menu.Divider />}\n {logins.map(\n (login) =>\n login.profile.reference !== getReferenceString(context.profile as ProfileResource) && (\n <Menu.Item\n key={login.profile.reference}\n onClick={() => {\n medplum\n .setActiveLogin(login)\n .then(() => window.location.reload())\n .catch(console.log);\n }}\n >\n <Group>\n <Avatar radius=\"xl\" />\n <div style={{ flex: 1 }}>\n <Text size=\"sm\" weight={500}>\n {login.profile.display}\n </Text>\n <Text color=\"dimmed\" size=\"xs\">\n {login.project.display}\n </Text>\n </div>\n </Group>\n </Menu.Item>\n )\n )}\n <Menu.Divider />\n <Menu.Item icon={<IconSwitchHorizontal size={14} stroke={1.5} />} onClick={() => navigate('/signin')}>\n Add another account\n </Menu.Item>\n <Menu.Item\n icon={<IconSettings size={14} stroke={1.5} />}\n onClick={() => navigate(`/${getReferenceString(profile as ProfileResource)}`)}\n >\n Account settings\n </Menu.Item>\n <Menu.Item\n icon={<IconLogout size={14} stroke={1.5} />}\n onClick={async () => {\n await medplum.signOut();\n navigate('/signin');\n }}\n >\n Sign out\n </Menu.Item>\n <Text size=\"xs\" color=\"dimmed\" align=\"center\">\n {props.version}\n </Text>\n </Menu.Dropdown>\n </Menu>\n </Group>\n </MantineHeader>\n );\n}\n"],"names":["MantineHeader"],"mappings":"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"}
@@ -1,5 +1,7 @@
1
1
  import { MultiSelect, Loader } from '@mantine/core';
2
2
  import React, { useRef, useState, useCallback, useEffect } from 'react';
3
+ import { showNotification } from '@mantine/notifications';
4
+ import { normalizeErrorString } from '@medplum/core';
3
5
  import { killEvent } from '../utils/dom.mjs';
4
6
 
5
7
  function AsyncAutocomplete(props) {
@@ -10,7 +12,7 @@ function AsyncAutocomplete(props) {
10
12
  const [timer, setTimer] = useState();
11
13
  const [abortController, setAbortController] = useState();
12
14
  const [autoSubmit, setAutoSubmit] = useState();
13
- const [options, setOptions] = useState(defaultItems?.map(toOption));
15
+ const [options, setOptions] = useState(defaultItems.map(toOption));
14
16
  const lastValueRef = useRef();
15
17
  lastValueRef.current = lastValue;
16
18
  const timerRef = useRef();
@@ -23,7 +25,7 @@ function AsyncAutocomplete(props) {
23
25
  optionsRef.current = options;
24
26
  const handleTimer = useCallback(() => {
25
27
  setTimer(undefined);
26
- const value = inputRef.current?.value?.trim() || '';
28
+ const value = inputRef.current?.value.trim() || '';
27
29
  if (value === lastValueRef.current) {
28
30
  // Nothing has changed, move on
29
31
  return;
@@ -44,7 +46,11 @@ function AsyncAutocomplete(props) {
44
46
  }
45
47
  }
46
48
  })
47
- .catch(console.log);
49
+ .catch((err) => {
50
+ if (!(newAbortController.signal.aborted || err.message.includes('aborted'))) {
51
+ showNotification({ color: 'red', message: normalizeErrorString(err) });
52
+ }
53
+ });
48
54
  }, [loadOptions, onChange, toOption]);
49
55
  const handleSearchChange = useCallback(() => {
50
56
  if (abortControllerRef.current) {
@@ -1 +1 @@
1
- {"version":3,"file":"AsyncAutocomplete.mjs","sources":["../../../src/AsyncAutocomplete/AsyncAutocomplete.tsx"],"sourcesContent":["import { Loader, MultiSelect, MultiSelectProps, SelectItem } from '@mantine/core';\nimport React, { useCallback, useEffect, useRef, useState } from 'react';\nimport { killEvent } from '../utils/dom';\n\nexport interface AsyncAutocompleteOption<T> extends SelectItem {\n resource: T;\n}\n\nexport interface AsyncAutocompleteProps<T>\n extends Omit<MultiSelectProps, 'data' | 'defaultValue' | 'loadOptions' | 'onChange' | 'onCreate' | 'searchable'> {\n defaultValue?: T | T[];\n toKey: (item: T) => string;\n toOption: (item: T) => AsyncAutocompleteOption<T>;\n loadOptions: (input: string, signal: AbortSignal) => Promise<T[]>;\n onChange: (item: T[]) => void;\n onCreate?: (input: string) => T;\n creatable?: boolean;\n}\n\nexport function AsyncAutocomplete<T>(props: AsyncAutocompleteProps<T>): JSX.Element {\n const { defaultValue, toKey, toOption, loadOptions, onChange, onCreate, creatable, ...rest } = props;\n const defaultItems = toDefaultItems(defaultValue);\n const inputRef = useRef<HTMLInputElement>(null);\n const [lastValue, setLastValue] = useState<string | undefined>(undefined);\n const [timer, setTimer] = useState<number>();\n const [abortController, setAbortController] = useState<AbortController>();\n const [autoSubmit, setAutoSubmit] = useState<boolean>();\n const [options, setOptions] = useState<AsyncAutocompleteOption<T>[]>(defaultItems?.map(toOption));\n\n const lastValueRef = useRef<string>();\n lastValueRef.current = lastValue;\n\n const timerRef = useRef<number>();\n timerRef.current = timer;\n\n const abortControllerRef = useRef<AbortController>();\n abortControllerRef.current = abortController;\n\n const autoSubmitRef = useRef<boolean>();\n autoSubmitRef.current = autoSubmit;\n\n const optionsRef = useRef<AsyncAutocompleteOption<T>[]>();\n optionsRef.current = options;\n\n const handleTimer = useCallback((): void => {\n setTimer(undefined);\n\n const value = inputRef.current?.value?.trim() || '';\n if (value === lastValueRef.current) {\n // Nothing has changed, move on\n return;\n }\n\n setLastValue(value);\n\n const newAbortController = new AbortController();\n setAbortController(newAbortController);\n\n loadOptions(value, newAbortController.signal)\n .then((newValues: T[]) => {\n if (!newAbortController.signal.aborted) {\n setOptions(newValues.map(toOption));\n setAbortController(undefined);\n if (autoSubmitRef.current) {\n if (newValues.length > 0) {\n onChange(newValues.slice(0, 1));\n }\n setAutoSubmit(false);\n }\n }\n })\n .catch(console.log);\n }, [loadOptions, onChange, toOption]);\n\n const handleSearchChange = useCallback((): void => {\n if (abortControllerRef.current) {\n abortControllerRef.current.abort();\n setAbortController(undefined);\n }\n\n if (timerRef.current !== undefined) {\n window.clearTimeout(timerRef.current);\n }\n\n const newTimer = window.setTimeout(() => handleTimer(), 100);\n setTimer(newTimer);\n }, [handleTimer]);\n\n const handleChange = useCallback(\n (values: string[]): void => {\n const result: T[] = [];\n for (const value of values) {\n let item = optionsRef.current?.find((option) => option.value === value)?.resource;\n if (!item && creatable !== false) {\n item = (onCreate as (input: string) => T)(value);\n }\n\n if (item) {\n result.push(item);\n }\n }\n onChange(result);\n },\n [creatable, onChange, onCreate]\n );\n\n const handleKeyDown = useCallback(\n (e: React.KeyboardEvent): void => {\n if (e.key === 'Enter') {\n if (!timerRef.current && !abortControllerRef.current) {\n killEvent(e);\n if (optionsRef.current && optionsRef.current.length > 0) {\n setOptions(optionsRef.current.slice(0, 1));\n handleChange([optionsRef.current[0].value]);\n }\n } else {\n // The user pressed enter, but we don't have results yet.\n // We need to wait for the results to come in.\n setAutoSubmit(true);\n }\n }\n },\n [handleChange]\n );\n\n const handleCreate = useCallback(\n (input: string): AsyncAutocompleteOption<T> => {\n const option = toOption((onCreate as (input: string) => T)(input));\n setOptions([...(optionsRef.current as AsyncAutocompleteOption<T>[]), option]);\n return option;\n },\n [onCreate, setOptions, toOption]\n );\n\n const handleFilter = useCallback((_value: string, selected: boolean) => !selected, []);\n\n useEffect(() => {\n return () => {\n if (abortControllerRef.current) {\n abortControllerRef.current.abort();\n }\n };\n }, []);\n\n return (\n <MultiSelect\n {...rest}\n ref={inputRef}\n defaultValue={defaultItems.map(toKey)}\n searchable\n onKeyDown={handleKeyDown}\n onSearchChange={handleSearchChange}\n data={options}\n onFocus={handleTimer}\n onChange={handleChange}\n onCreate={handleCreate}\n rightSectionWidth={40}\n rightSection={abortController ? <Loader size={16} /> : null}\n filter={handleFilter}\n creatable\n />\n );\n}\n\nfunction toDefaultItems<T>(defaultValue: T | T[] | undefined): T[] {\n if (!defaultValue) {\n return [];\n }\n if (Array.isArray(defaultValue)) {\n return defaultValue;\n }\n return [defaultValue];\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"AsyncAutocomplete.mjs","sources":["../../../src/AsyncAutocomplete/AsyncAutocomplete.tsx"],"sourcesContent":["import { Loader, MultiSelect, MultiSelectProps, SelectItem } from '@mantine/core';\nimport React, { useCallback, useEffect, useRef, useState } from 'react';\nimport { showNotification } from '@mantine/notifications';\nimport { normalizeErrorString } from '@medplum/core';\nimport { killEvent } from '../utils/dom';\n\nexport interface AsyncAutocompleteOption<T> extends SelectItem {\n resource: T;\n}\n\nexport interface AsyncAutocompleteProps<T>\n extends Omit<MultiSelectProps, 'data' | 'defaultValue' | 'loadOptions' | 'onChange' | 'onCreate' | 'searchable'> {\n defaultValue?: T | T[];\n toKey: (item: T) => string;\n toOption: (item: T) => AsyncAutocompleteOption<T>;\n loadOptions: (input: string, signal: AbortSignal) => Promise<T[]>;\n onChange: (item: T[]) => void;\n onCreate?: (input: string) => T;\n creatable?: boolean;\n}\n\nexport function AsyncAutocomplete<T>(props: AsyncAutocompleteProps<T>): JSX.Element {\n const { defaultValue, toKey, toOption, loadOptions, onChange, onCreate, creatable, ...rest } = props;\n const defaultItems = toDefaultItems(defaultValue);\n const inputRef = useRef<HTMLInputElement>(null);\n const [lastValue, setLastValue] = useState<string | undefined>(undefined);\n const [timer, setTimer] = useState<number>();\n const [abortController, setAbortController] = useState<AbortController>();\n const [autoSubmit, setAutoSubmit] = useState<boolean>();\n const [options, setOptions] = useState<AsyncAutocompleteOption<T>[]>(defaultItems.map(toOption));\n\n const lastValueRef = useRef<string>();\n lastValueRef.current = lastValue;\n\n const timerRef = useRef<number>();\n timerRef.current = timer;\n\n const abortControllerRef = useRef<AbortController>();\n abortControllerRef.current = abortController;\n\n const autoSubmitRef = useRef<boolean>();\n autoSubmitRef.current = autoSubmit;\n\n const optionsRef = useRef<AsyncAutocompleteOption<T>[]>();\n optionsRef.current = options;\n\n const handleTimer = useCallback((): void => {\n setTimer(undefined);\n\n const value = inputRef.current?.value.trim() || '';\n if (value === lastValueRef.current) {\n // Nothing has changed, move on\n return;\n }\n\n setLastValue(value);\n\n const newAbortController = new AbortController();\n setAbortController(newAbortController);\n\n loadOptions(value, newAbortController.signal)\n .then((newValues: T[]) => {\n if (!newAbortController.signal.aborted) {\n setOptions(newValues.map(toOption));\n setAbortController(undefined);\n if (autoSubmitRef.current) {\n if (newValues.length > 0) {\n onChange(newValues.slice(0, 1));\n }\n setAutoSubmit(false);\n }\n }\n })\n .catch((err) => {\n if (!(newAbortController.signal.aborted || err.message.includes('aborted'))) {\n showNotification({ color: 'red', message: normalizeErrorString(err) });\n }\n });\n }, [loadOptions, onChange, toOption]);\n\n const handleSearchChange = useCallback((): void => {\n if (abortControllerRef.current) {\n abortControllerRef.current.abort();\n setAbortController(undefined);\n }\n\n if (timerRef.current !== undefined) {\n window.clearTimeout(timerRef.current);\n }\n\n const newTimer = window.setTimeout(() => handleTimer(), 100);\n setTimer(newTimer);\n }, [handleTimer]);\n\n const handleChange = useCallback(\n (values: string[]): void => {\n const result: T[] = [];\n for (const value of values) {\n let item = optionsRef.current?.find((option) => option.value === value)?.resource;\n if (!item && creatable !== false) {\n item = (onCreate as (input: string) => T)(value);\n }\n\n if (item) {\n result.push(item);\n }\n }\n onChange(result);\n },\n [creatable, onChange, onCreate]\n );\n\n const handleKeyDown = useCallback(\n (e: React.KeyboardEvent): void => {\n if (e.key === 'Enter') {\n if (!timerRef.current && !abortControllerRef.current) {\n killEvent(e);\n if (optionsRef.current && optionsRef.current.length > 0) {\n setOptions(optionsRef.current.slice(0, 1));\n handleChange([optionsRef.current[0].value]);\n }\n } else {\n // The user pressed enter, but we don't have results yet.\n // We need to wait for the results to come in.\n setAutoSubmit(true);\n }\n }\n },\n [handleChange]\n );\n\n const handleCreate = useCallback(\n (input: string): AsyncAutocompleteOption<T> => {\n const option = toOption((onCreate as (input: string) => T)(input));\n setOptions([...(optionsRef.current as AsyncAutocompleteOption<T>[]), option]);\n return option;\n },\n [onCreate, setOptions, toOption]\n );\n\n const handleFilter = useCallback((_value: string, selected: boolean) => !selected, []);\n\n useEffect(() => {\n return () => {\n if (abortControllerRef.current) {\n abortControllerRef.current.abort();\n }\n };\n }, []);\n\n return (\n <MultiSelect\n {...rest}\n ref={inputRef}\n defaultValue={defaultItems.map(toKey)}\n searchable\n onKeyDown={handleKeyDown}\n onSearchChange={handleSearchChange}\n data={options}\n onFocus={handleTimer}\n onChange={handleChange}\n onCreate={handleCreate}\n rightSectionWidth={40}\n rightSection={abortController ? <Loader size={16} /> : null}\n filter={handleFilter}\n creatable\n />\n );\n}\n\nfunction toDefaultItems<T>(defaultValue: T | T[] | undefined): T[] {\n if (!defaultValue) {\n return [];\n }\n if (Array.isArray(defaultValue)) {\n return defaultValue;\n }\n return [defaultValue];\n}\n"],"names":[],"mappings":"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"}
@@ -2,9 +2,8 @@ import React from 'react';
2
2
  import { AttachmentDisplay } from '../AttachmentDisplay/AttachmentDisplay.mjs';
3
3
 
4
4
  function AttachmentArrayDisplay(props) {
5
- return (React.createElement("div", null, props.values &&
6
- props.values.map((v, index) => (React.createElement("div", { key: 'attatchment-' + index },
7
- React.createElement(AttachmentDisplay, { value: v, maxWidth: props.maxWidth }))))));
5
+ return (React.createElement("div", null, props.values?.map((v, index) => (React.createElement("div", { key: 'attatchment-' + index },
6
+ React.createElement(AttachmentDisplay, { value: v, maxWidth: props.maxWidth }))))));
8
7
  }
9
8
 
10
9
  export { AttachmentArrayDisplay };
@@ -1 +1 @@
1
- {"version":3,"file":"AttachmentArrayDisplay.mjs","sources":["../../../src/AttachmentArrayDisplay/AttachmentArrayDisplay.tsx"],"sourcesContent":["import { Attachment } from '@medplum/fhirtypes';\nimport React from 'react';\nimport { AttachmentDisplay } from '../AttachmentDisplay/AttachmentDisplay';\n\nexport interface AttachmentArrayDisplayProps {\n values?: Attachment[];\n maxWidth?: number;\n}\n\nexport function AttachmentArrayDisplay(props: AttachmentArrayDisplayProps): JSX.Element {\n return (\n <div>\n {props.values &&\n props.values.map((v, index) => (\n <div key={'attatchment-' + index}>\n <AttachmentDisplay value={v} maxWidth={props.maxWidth} />\n </div>\n ))}\n </div>\n );\n}\n"],"names":[],"mappings":";;;AASM,SAAU,sBAAsB,CAAC,KAAkC,EAAA;AACvE,IAAA,QACE,KAAA,CAAA,aAAA,CAAA,KAAA,EAAA,IAAA,EACG,KAAK,CAAC,MAAM;AACX,QAAA,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,KAAK,MACxB,KAAA,CAAA,aAAA,CAAA,KAAA,EAAA,EAAK,GAAG,EAAE,cAAc,GAAG,KAAK,EAAA;AAC9B,YAAA,KAAA,CAAA,aAAA,CAAC,iBAAiB,EAAC,EAAA,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAI,CAAA,CACrD,CACP,CAAC,CACA,EACN;AACJ;;;;"}
1
+ {"version":3,"file":"AttachmentArrayDisplay.mjs","sources":["../../../src/AttachmentArrayDisplay/AttachmentArrayDisplay.tsx"],"sourcesContent":["import { Attachment } from '@medplum/fhirtypes';\nimport React from 'react';\nimport { AttachmentDisplay } from '../AttachmentDisplay/AttachmentDisplay';\n\nexport interface AttachmentArrayDisplayProps {\n values?: Attachment[];\n maxWidth?: number;\n}\n\nexport function AttachmentArrayDisplay(props: AttachmentArrayDisplayProps): JSX.Element {\n return (\n <div>\n {props.values?.map((v, index) => (\n <div key={'attatchment-' + index}>\n <AttachmentDisplay value={v} maxWidth={props.maxWidth} />\n </div>\n ))}\n </div>\n );\n}\n"],"names":[],"mappings":";;;AASM,SAAU,sBAAsB,CAAC,KAAkC,EAAA;IACvE,QACE,iCACG,KAAK,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC,EAAE,KAAK,MAC1B,6BAAK,GAAG,EAAE,cAAc,GAAG,KAAK,EAAA;AAC9B,QAAA,KAAA,CAAA,aAAA,CAAC,iBAAiB,EAAC,EAAA,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAI,CAAA,CACrD,CACP,CAAC,CACE,EACN;AACJ;;;;"}
@@ -43,7 +43,7 @@ function AttachmentButton(props) {
43
43
  });
44
44
  })
45
45
  .catch((outcome) => {
46
- alert(outcome?.issue?.[0]?.details?.text);
46
+ alert(outcome.issue?.[0]?.details?.text);
47
47
  });
48
48
  }
49
49
  return (React.createElement(React.Fragment, null,
@@ -1 +1 @@
1
- {"version":3,"file":"AttachmentButton.mjs","sources":["../../../src/AttachmentButton/AttachmentButton.tsx"],"sourcesContent":["import { Attachment, Binary, OperationOutcome } from '@medplum/fhirtypes';\nimport React, { useRef } from 'react';\nimport { useMedplum } from '../MedplumProvider/MedplumProvider';\nimport { killEvent } from '../utils/dom';\n\nexport interface AttachmentButtonProps {\n onUpload: (attachment: Attachment) => void;\n onUploadStart?: () => void;\n onUploadProgress?: (e: ProgressEvent) => void;\n children(props: { onClick(e: React.MouseEvent): void }): React.ReactNode;\n}\n\nexport function AttachmentButton(props: AttachmentButtonProps): JSX.Element {\n const medplum = useMedplum();\n const fileInputRef = useRef<HTMLInputElement>(null);\n\n function onClick(e: React.MouseEvent): void {\n killEvent(e);\n fileInputRef.current?.click();\n }\n\n function onFileChange(e: React.ChangeEvent): void {\n killEvent(e);\n const files = (e.target as HTMLInputElement).files;\n if (files) {\n Array.from(files).forEach(processFile);\n }\n }\n\n /**\n * Processes a single file.\n * @param file The file descriptor.\n */\n function processFile(file: File): void {\n if (!file) {\n return;\n }\n\n const fileName = file.name;\n if (!fileName) {\n return;\n }\n\n if (props.onUploadStart) {\n props.onUploadStart();\n }\n\n const filename = file.name;\n const contentType = file.type || 'application/octet-stream';\n medplum\n .createBinary(file, filename, contentType, props.onUploadProgress)\n .then((binary: Binary) => {\n props.onUpload({\n contentType: binary.contentType,\n url: binary.url,\n title: filename,\n });\n })\n .catch((outcome: OperationOutcome) => {\n alert(outcome?.issue?.[0]?.details?.text);\n });\n }\n\n return (\n <>\n <input\n type=\"file\"\n data-testid=\"upload-file-input\"\n style={{ display: 'none' }}\n ref={fileInputRef}\n onChange={(e) => onFileChange(e)}\n />\n {props.children({ onClick })}\n </>\n );\n}\n"],"names":[],"mappings":";;;;AAYM,SAAU,gBAAgB,CAAC,KAA4B,EAAA;AAC3D,IAAA,MAAM,OAAO,GAAG,UAAU,EAAE,CAAC;AAC7B,IAAA,MAAM,YAAY,GAAG,MAAM,CAAmB,IAAI,CAAC,CAAC;IAEpD,SAAS,OAAO,CAAC,CAAmB,EAAA;QAClC,SAAS,CAAC,CAAC,CAAC,CAAC;AACb,QAAA,YAAY,CAAC,OAAO,EAAE,KAAK,EAAE,CAAC;KAC/B;IAED,SAAS,YAAY,CAAC,CAAoB,EAAA;QACxC,SAAS,CAAC,CAAC,CAAC,CAAC;AACb,QAAA,MAAM,KAAK,GAAI,CAAC,CAAC,MAA2B,CAAC,KAAK,CAAC;AACnD,QAAA,IAAI,KAAK,EAAE;YACT,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;AACxC,SAAA;KACF;AAED;;;AAGG;IACH,SAAS,WAAW,CAAC,IAAU,EAAA;QAC7B,IAAI,CAAC,IAAI,EAAE;YACT,OAAO;AACR,SAAA;AAED,QAAA,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC;QAC3B,IAAI,CAAC,QAAQ,EAAE;YACb,OAAO;AACR,SAAA;QAED,IAAI,KAAK,CAAC,aAAa,EAAE;YACvB,KAAK,CAAC,aAAa,EAAE,CAAC;AACvB,SAAA;AAED,QAAA,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC;AAC3B,QAAA,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,IAAI,0BAA0B,CAAC;QAC5D,OAAO;aACJ,YAAY,CAAC,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,KAAK,CAAC,gBAAgB,CAAC;AACjE,aAAA,IAAI,CAAC,CAAC,MAAc,KAAI;YACvB,KAAK,CAAC,QAAQ,CAAC;gBACb,WAAW,EAAE,MAAM,CAAC,WAAW;gBAC/B,GAAG,EAAE,MAAM,CAAC,GAAG;AACf,gBAAA,KAAK,EAAE,QAAQ;AAChB,aAAA,CAAC,CAAC;AACL,SAAC,CAAC;AACD,aAAA,KAAK,CAAC,CAAC,OAAyB,KAAI;AACnC,YAAA,KAAK,CAAC,OAAO,EAAE,KAAK,GAAG,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC;AAC5C,SAAC,CAAC,CAAC;KACN;AAED,IAAA,QACE,KAAA,CAAA,aAAA,CAAA,KAAA,CAAA,QAAA,EAAA,IAAA;AACE,QAAA,KAAA,CAAA,aAAA,CAAA,OAAA,EAAA,EACE,IAAI,EAAC,MAAM,EAAA,aAAA,EACC,mBAAmB,EAC/B,KAAK,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,EAC1B,GAAG,EAAE,YAAY,EACjB,QAAQ,EAAE,CAAC,CAAC,KAAK,YAAY,CAAC,CAAC,CAAC,EAChC,CAAA;QACD,KAAK,CAAC,QAAQ,CAAC,EAAE,OAAO,EAAE,CAAC,CAC3B,EACH;AACJ;;;;"}
1
+ {"version":3,"file":"AttachmentButton.mjs","sources":["../../../src/AttachmentButton/AttachmentButton.tsx"],"sourcesContent":["import { Attachment, Binary, OperationOutcome } from '@medplum/fhirtypes';\nimport React, { useRef } from 'react';\nimport { useMedplum } from '../MedplumProvider/MedplumProvider';\nimport { killEvent } from '../utils/dom';\n\nexport interface AttachmentButtonProps {\n onUpload: (attachment: Attachment) => void;\n onUploadStart?: () => void;\n onUploadProgress?: (e: ProgressEvent) => void;\n children(props: { onClick(e: React.MouseEvent): void }): React.ReactNode;\n}\n\nexport function AttachmentButton(props: AttachmentButtonProps): JSX.Element {\n const medplum = useMedplum();\n const fileInputRef = useRef<HTMLInputElement>(null);\n\n function onClick(e: React.MouseEvent): void {\n killEvent(e);\n fileInputRef.current?.click();\n }\n\n function onFileChange(e: React.ChangeEvent): void {\n killEvent(e);\n const files = (e.target as HTMLInputElement).files;\n if (files) {\n Array.from(files).forEach(processFile);\n }\n }\n\n /**\n * Processes a single file.\n * @param file The file descriptor.\n */\n function processFile(file: File): void {\n if (!file) {\n return;\n }\n\n const fileName = file.name;\n if (!fileName) {\n return;\n }\n\n if (props.onUploadStart) {\n props.onUploadStart();\n }\n\n const filename = file.name;\n const contentType = file.type || 'application/octet-stream';\n medplum\n .createBinary(file, filename, contentType, props.onUploadProgress)\n .then((binary: Binary) => {\n props.onUpload({\n contentType: binary.contentType,\n url: binary.url,\n title: filename,\n });\n })\n .catch((outcome: OperationOutcome) => {\n alert(outcome.issue?.[0]?.details?.text);\n });\n }\n\n return (\n <>\n <input\n type=\"file\"\n data-testid=\"upload-file-input\"\n style={{ display: 'none' }}\n ref={fileInputRef}\n onChange={(e) => onFileChange(e)}\n />\n {props.children({ onClick })}\n </>\n );\n}\n"],"names":[],"mappings":";;;;AAYM,SAAU,gBAAgB,CAAC,KAA4B,EAAA;AAC3D,IAAA,MAAM,OAAO,GAAG,UAAU,EAAE,CAAC;AAC7B,IAAA,MAAM,YAAY,GAAG,MAAM,CAAmB,IAAI,CAAC,CAAC;IAEpD,SAAS,OAAO,CAAC,CAAmB,EAAA;QAClC,SAAS,CAAC,CAAC,CAAC,CAAC;AACb,QAAA,YAAY,CAAC,OAAO,EAAE,KAAK,EAAE,CAAC;KAC/B;IAED,SAAS,YAAY,CAAC,CAAoB,EAAA;QACxC,SAAS,CAAC,CAAC,CAAC,CAAC;AACb,QAAA,MAAM,KAAK,GAAI,CAAC,CAAC,MAA2B,CAAC,KAAK,CAAC;AACnD,QAAA,IAAI,KAAK,EAAE;YACT,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;AACxC,SAAA;KACF;AAED;;;AAGG;IACH,SAAS,WAAW,CAAC,IAAU,EAAA;QAC7B,IAAI,CAAC,IAAI,EAAE;YACT,OAAO;AACR,SAAA;AAED,QAAA,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC;QAC3B,IAAI,CAAC,QAAQ,EAAE;YACb,OAAO;AACR,SAAA;QAED,IAAI,KAAK,CAAC,aAAa,EAAE;YACvB,KAAK,CAAC,aAAa,EAAE,CAAC;AACvB,SAAA;AAED,QAAA,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC;AAC3B,QAAA,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,IAAI,0BAA0B,CAAC;QAC5D,OAAO;aACJ,YAAY,CAAC,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,KAAK,CAAC,gBAAgB,CAAC;AACjE,aAAA,IAAI,CAAC,CAAC,MAAc,KAAI;YACvB,KAAK,CAAC,QAAQ,CAAC;gBACb,WAAW,EAAE,MAAM,CAAC,WAAW;gBAC/B,GAAG,EAAE,MAAM,CAAC,GAAG;AACf,gBAAA,KAAK,EAAE,QAAQ;AAChB,aAAA,CAAC,CAAC;AACL,SAAC,CAAC;AACD,aAAA,KAAK,CAAC,CAAC,OAAyB,KAAI;AACnC,YAAA,KAAK,CAAC,OAAO,CAAC,KAAK,GAAG,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC;AAC3C,SAAC,CAAC,CAAC;KACN;AAED,IAAA,QACE,KAAA,CAAA,aAAA,CAAA,KAAA,CAAA,QAAA,EAAA,IAAA;AACE,QAAA,KAAA,CAAA,aAAA,CAAA,OAAA,EAAA,EACE,IAAI,EAAC,MAAM,EAAA,aAAA,EACC,mBAAmB,EAC/B,KAAK,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,EAC1B,GAAG,EAAE,YAAY,EACjB,QAAQ,EAAE,CAAC,CAAC,KAAK,YAAY,CAAC,CAAC,CAAC,EAChC,CAAA;QACD,KAAK,CAAC,QAAQ,CAAC,EAAE,OAAO,EAAE,CAAC,CAC3B,EACH;AACJ;;;;"}
@@ -28,7 +28,7 @@ function BackboneElementDisplay(props) {
28
28
  }
29
29
  return (React.createElement(DescriptionList, { compact: props.compact }, Object.entries(typeSchema.properties).map((entry) => {
30
30
  const key = entry[0];
31
- if (DEFAULT_IGNORED_PROPERTIES.indexOf(key) >= 0) {
31
+ if (DEFAULT_IGNORED_PROPERTIES.includes(key)) {
32
32
  return null;
33
33
  }
34
34
  const property = entry[1];
@@ -1 +1 @@
1
- {"version":3,"file":"BackboneElementDisplay.mjs","sources":["../../../src/BackboneElementDisplay/BackboneElementDisplay.tsx"],"sourcesContent":["import { getPropertyDisplayName, globalSchema, TypedValue } from '@medplum/core';\nimport React from 'react';\nimport { DEFAULT_IGNORED_PROPERTIES } from '../constants';\nimport { DescriptionList, DescriptionListEntry } from '../DescriptionList/DescriptionList';\nimport { getValueAndType, ResourcePropertyDisplay } from '../ResourcePropertyDisplay/ResourcePropertyDisplay';\n\nexport interface BackboneElementDisplayProps {\n value: TypedValue;\n compact?: boolean;\n ignoreMissingValues?: boolean;\n link?: boolean;\n}\n\nexport function BackboneElementDisplay(props: BackboneElementDisplayProps): JSX.Element | null {\n const typedValue = props.value;\n const value = typedValue.value;\n if (!value) {\n return null;\n }\n\n const typeName = typedValue.type;\n const typeSchema = globalSchema.types[typeName];\n if (!typeSchema) {\n return <div>{typeName}&nbsp;not implemented</div>;\n }\n\n if (\n typeof value === 'object' &&\n 'name' in value &&\n Object.keys(value).length === 1 &&\n typeof value.name === 'string'\n ) {\n // Special case for common BackboneElement pattern\n // Where there is an object with a single property 'name'\n // Just display the name value.\n return <div>{value.name}</div>;\n }\n\n return (\n <DescriptionList compact={props.compact}>\n {Object.entries(typeSchema.properties).map((entry) => {\n const key = entry[0];\n if (DEFAULT_IGNORED_PROPERTIES.indexOf(key) >= 0) {\n return null;\n }\n const property = entry[1];\n if (!property.path) {\n property.path = typeName + '.' + key;\n }\n const [propertyValue, propertyType] = getValueAndType(typedValue, key);\n if (\n props.ignoreMissingValues &&\n (!propertyValue || (Array.isArray(propertyValue) && propertyValue.length === 0))\n ) {\n return null;\n }\n return (\n <DescriptionListEntry key={key} term={getPropertyDisplayName(key)}>\n <ResourcePropertyDisplay\n property={property}\n propertyType={propertyType}\n value={propertyValue}\n ignoreMissingValues={props.ignoreMissingValues}\n link={props.link}\n />\n </DescriptionListEntry>\n );\n })}\n </DescriptionList>\n );\n}\n"],"names":[],"mappings":";;;;;;AAaM,SAAU,sBAAsB,CAAC,KAAkC,EAAA;AACvE,IAAA,MAAM,UAAU,GAAG,KAAK,CAAC,KAAK,CAAC;AAC/B,IAAA,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC;IAC/B,IAAI,CAAC,KAAK,EAAE;AACV,QAAA,OAAO,IAAI,CAAC;AACb,KAAA;AAED,IAAA,MAAM,QAAQ,GAAG,UAAU,CAAC,IAAI,CAAC;IACjC,MAAM,UAAU,GAAG,YAAY,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IAChD,IAAI,CAAC,UAAU,EAAE;QACf,OAAO,KAAA,CAAA,aAAA,CAAA,KAAA,EAAA,IAAA;YAAM,QAAQ;oCAA4B,CAAC;AACnD,KAAA;IAED,IACE,OAAO,KAAK,KAAK,QAAQ;AACzB,QAAA,MAAM,IAAI,KAAK;QACf,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,KAAK,CAAC;AAC/B,QAAA,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ,EAC9B;;;;AAIA,QAAA,OAAO,KAAM,CAAA,aAAA,CAAA,KAAA,EAAA,IAAA,EAAA,KAAK,CAAC,IAAI,CAAO,CAAC;AAChC,KAAA;IAED,QACE,KAAC,CAAA,aAAA,CAAA,eAAe,EAAC,EAAA,OAAO,EAAE,KAAK,CAAC,OAAO,EAAA,EACpC,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,KAAI;AACnD,QAAA,MAAM,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QACrB,IAAI,0BAA0B,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE;AAChD,YAAA,OAAO,IAAI,CAAC;AACb,SAAA;AACD,QAAA,MAAM,QAAQ,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;AAC1B,QAAA,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE;YAClB,QAAQ,CAAC,IAAI,GAAG,QAAQ,GAAG,GAAG,GAAG,GAAG,CAAC;AACtC,SAAA;AACD,QAAA,MAAM,CAAC,aAAa,EAAE,YAAY,CAAC,GAAG,eAAe,CAAC,UAAU,EAAE,GAAG,CAAC,CAAC;QACvE,IACE,KAAK,CAAC,mBAAmB;AACzB,aAAC,CAAC,aAAa,KAAK,KAAK,CAAC,OAAO,CAAC,aAAa,CAAC,IAAI,aAAa,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,EAChF;AACA,YAAA,OAAO,IAAI,CAAC;AACb,SAAA;AACD,QAAA,QACE,KAAA,CAAA,aAAA,CAAC,oBAAoB,EAAA,EAAC,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,sBAAsB,CAAC,GAAG,CAAC,EAAA;AAC/D,YAAA,KAAA,CAAA,aAAA,CAAC,uBAAuB,EAAA,EACtB,QAAQ,EAAE,QAAQ,EAClB,YAAY,EAAE,YAAY,EAC1B,KAAK,EAAE,aAAa,EACpB,mBAAmB,EAAE,KAAK,CAAC,mBAAmB,EAC9C,IAAI,EAAE,KAAK,CAAC,IAAI,EAAA,CAChB,CACmB,EACvB;KACH,CAAC,CACc,EAClB;AACJ;;;;"}
1
+ {"version":3,"file":"BackboneElementDisplay.mjs","sources":["../../../src/BackboneElementDisplay/BackboneElementDisplay.tsx"],"sourcesContent":["import { getPropertyDisplayName, globalSchema, TypedValue } from '@medplum/core';\nimport React from 'react';\nimport { DEFAULT_IGNORED_PROPERTIES } from '../constants';\nimport { DescriptionList, DescriptionListEntry } from '../DescriptionList/DescriptionList';\nimport { getValueAndType, ResourcePropertyDisplay } from '../ResourcePropertyDisplay/ResourcePropertyDisplay';\n\nexport interface BackboneElementDisplayProps {\n value: TypedValue;\n compact?: boolean;\n ignoreMissingValues?: boolean;\n link?: boolean;\n}\n\nexport function BackboneElementDisplay(props: BackboneElementDisplayProps): JSX.Element | null {\n const typedValue = props.value;\n const value = typedValue.value;\n if (!value) {\n return null;\n }\n\n const typeName = typedValue.type;\n const typeSchema = globalSchema.types[typeName];\n if (!typeSchema) {\n return <div>{typeName}&nbsp;not implemented</div>;\n }\n\n if (\n typeof value === 'object' &&\n 'name' in value &&\n Object.keys(value).length === 1 &&\n typeof value.name === 'string'\n ) {\n // Special case for common BackboneElement pattern\n // Where there is an object with a single property 'name'\n // Just display the name value.\n return <div>{value.name}</div>;\n }\n\n return (\n <DescriptionList compact={props.compact}>\n {Object.entries(typeSchema.properties).map((entry) => {\n const key = entry[0];\n if (DEFAULT_IGNORED_PROPERTIES.includes(key)) {\n return null;\n }\n const property = entry[1];\n if (!property.path) {\n property.path = typeName + '.' + key;\n }\n const [propertyValue, propertyType] = getValueAndType(typedValue, key);\n if (\n props.ignoreMissingValues &&\n (!propertyValue || (Array.isArray(propertyValue) && propertyValue.length === 0))\n ) {\n return null;\n }\n return (\n <DescriptionListEntry key={key} term={getPropertyDisplayName(key)}>\n <ResourcePropertyDisplay\n property={property}\n propertyType={propertyType}\n value={propertyValue}\n ignoreMissingValues={props.ignoreMissingValues}\n link={props.link}\n />\n </DescriptionListEntry>\n );\n })}\n </DescriptionList>\n );\n}\n"],"names":[],"mappings":";;;;;;AAaM,SAAU,sBAAsB,CAAC,KAAkC,EAAA;AACvE,IAAA,MAAM,UAAU,GAAG,KAAK,CAAC,KAAK,CAAC;AAC/B,IAAA,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC;IAC/B,IAAI,CAAC,KAAK,EAAE;AACV,QAAA,OAAO,IAAI,CAAC;AACb,KAAA;AAED,IAAA,MAAM,QAAQ,GAAG,UAAU,CAAC,IAAI,CAAC;IACjC,MAAM,UAAU,GAAG,YAAY,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IAChD,IAAI,CAAC,UAAU,EAAE;QACf,OAAO,KAAA,CAAA,aAAA,CAAA,KAAA,EAAA,IAAA;YAAM,QAAQ;oCAA4B,CAAC;AACnD,KAAA;IAED,IACE,OAAO,KAAK,KAAK,QAAQ;AACzB,QAAA,MAAM,IAAI,KAAK;QACf,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,KAAK,CAAC;AAC/B,QAAA,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ,EAC9B;;;;AAIA,QAAA,OAAO,KAAM,CAAA,aAAA,CAAA,KAAA,EAAA,IAAA,EAAA,KAAK,CAAC,IAAI,CAAO,CAAC;AAChC,KAAA;IAED,QACE,KAAC,CAAA,aAAA,CAAA,eAAe,EAAC,EAAA,OAAO,EAAE,KAAK,CAAC,OAAO,EAAA,EACpC,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,KAAI;AACnD,QAAA,MAAM,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;AACrB,QAAA,IAAI,0BAA0B,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE;AAC5C,YAAA,OAAO,IAAI,CAAC;AACb,SAAA;AACD,QAAA,MAAM,QAAQ,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;AAC1B,QAAA,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE;YAClB,QAAQ,CAAC,IAAI,GAAG,QAAQ,GAAG,GAAG,GAAG,GAAG,CAAC;AACtC,SAAA;AACD,QAAA,MAAM,CAAC,aAAa,EAAE,YAAY,CAAC,GAAG,eAAe,CAAC,UAAU,EAAE,GAAG,CAAC,CAAC;QACvE,IACE,KAAK,CAAC,mBAAmB;AACzB,aAAC,CAAC,aAAa,KAAK,KAAK,CAAC,OAAO,CAAC,aAAa,CAAC,IAAI,aAAa,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,EAChF;AACA,YAAA,OAAO,IAAI,CAAC;AACb,SAAA;AACD,QAAA,QACE,KAAA,CAAA,aAAA,CAAC,oBAAoB,EAAA,EAAC,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,sBAAsB,CAAC,GAAG,CAAC,EAAA;AAC/D,YAAA,KAAA,CAAA,aAAA,CAAC,uBAAuB,EAAA,EACtB,QAAQ,EAAE,QAAQ,EAClB,YAAY,EAAE,YAAY,EAC1B,KAAK,EAAE,aAAa,EACpB,mBAAmB,EAAE,KAAK,CAAC,mBAAmB,EAC9C,IAAI,EAAE,KAAK,CAAC,IAAI,EAAA,CAChB,CACmB,EACvB;KACH,CAAC,CACc,EAClB;AACJ;;;;"}
@@ -26,7 +26,7 @@ function BackboneElementInput(props) {
26
26
  const typedValue = { type: typeName, value };
27
27
  return (React.createElement(Stack, null, Object.entries(typeSchema.properties).map((entry) => {
28
28
  const key = entry[0];
29
- if (key === 'id' || DEFAULT_IGNORED_PROPERTIES.indexOf(key) >= 0) {
29
+ if (key === 'id' || DEFAULT_IGNORED_PROPERTIES.includes(key)) {
30
30
  return null;
31
31
  }
32
32
  const property = entry[1];
@@ -1 +1 @@
1
- {"version":3,"file":"BackboneElementInput.mjs","sources":["../../../src/BackboneElementInput/BackboneElementInput.tsx"],"sourcesContent":["import { Stack } from '@mantine/core';\nimport { getPropertyDisplayName, globalSchema } from '@medplum/core';\nimport { OperationOutcome } from '@medplum/fhirtypes';\nimport React, { useState } from 'react';\nimport { CheckboxFormSection } from '../CheckboxFormSection/CheckboxFormSection';\nimport { DEFAULT_IGNORED_PROPERTIES } from '../constants';\nimport { FormSection } from '../FormSection/FormSection';\nimport { setPropertyValue } from '../ResourceForm/ResourceForm';\nimport { getValueAndType } from '../ResourcePropertyDisplay/ResourcePropertyDisplay';\nimport { ResourcePropertyInput } from '../ResourcePropertyInput/ResourcePropertyInput';\n\nexport interface BackboneElementInputProps {\n typeName: string;\n defaultValue?: any;\n outcome?: OperationOutcome;\n onChange?: (value: any) => void;\n}\n\nexport function BackboneElementInput(props: BackboneElementInputProps): JSX.Element {\n const [value, setValue] = useState<any>(props.defaultValue ?? {});\n\n function setValueWrapper(newValue: any): void {\n setValue(newValue);\n if (props.onChange) {\n props.onChange(newValue);\n }\n }\n\n const typeName = props.typeName;\n const typeSchema = globalSchema.types[typeName];\n if (!typeSchema) {\n return <div>{typeName}&nbsp;not implemented</div>;\n }\n\n const typedValue = { type: typeName, value };\n\n return (\n <Stack>\n {Object.entries(typeSchema.properties).map((entry) => {\n const key = entry[0];\n if (key === 'id' || DEFAULT_IGNORED_PROPERTIES.indexOf(key) >= 0) {\n return null;\n }\n const property = entry[1];\n if (!property.type) {\n return null;\n }\n\n const [propertyValue, propertyType] = getValueAndType(typedValue, key);\n const required = property.min !== undefined && property.min > 0;\n\n if (property.type.length === 1 && property.type[0].code === 'boolean') {\n return (\n <CheckboxFormSection\n key={key}\n title={getPropertyDisplayName(key)}\n description={property.definition}\n htmlFor={key}\n >\n <ResourcePropertyInput\n property={property}\n name={key}\n defaultValue={propertyValue}\n defaultPropertyType={propertyType}\n outcome={props.outcome}\n onChange={(newValue: any, propName?: string) => {\n setValueWrapper(setPropertyValue(value, key, propName ?? key, entry[1], newValue));\n }}\n />\n </CheckboxFormSection>\n );\n }\n\n return (\n <FormSection\n key={key}\n title={getPropertyDisplayName(key)}\n description={property.definition}\n withAsterisk={required}\n htmlFor={key}\n outcome={props.outcome}\n >\n <ResourcePropertyInput\n property={property}\n name={key}\n defaultValue={propertyValue}\n defaultPropertyType={propertyType}\n onChange={(newValue: any, propName?: string) => {\n setValueWrapper(setPropertyValue(value, key, propName ?? key, entry[1], newValue));\n }}\n />\n </FormSection>\n );\n })}\n </Stack>\n );\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"BackboneElementInput.mjs","sources":["../../../src/BackboneElementInput/BackboneElementInput.tsx"],"sourcesContent":["import { Stack } from '@mantine/core';\nimport { getPropertyDisplayName, globalSchema } from '@medplum/core';\nimport { OperationOutcome } from '@medplum/fhirtypes';\nimport React, { useState } from 'react';\nimport { CheckboxFormSection } from '../CheckboxFormSection/CheckboxFormSection';\nimport { DEFAULT_IGNORED_PROPERTIES } from '../constants';\nimport { FormSection } from '../FormSection/FormSection';\nimport { setPropertyValue } from '../ResourceForm/ResourceForm';\nimport { getValueAndType } from '../ResourcePropertyDisplay/ResourcePropertyDisplay';\nimport { ResourcePropertyInput } from '../ResourcePropertyInput/ResourcePropertyInput';\n\nexport interface BackboneElementInputProps {\n typeName: string;\n defaultValue?: any;\n outcome?: OperationOutcome;\n onChange?: (value: any) => void;\n}\n\nexport function BackboneElementInput(props: BackboneElementInputProps): JSX.Element {\n const [value, setValue] = useState<any>(props.defaultValue ?? {});\n\n function setValueWrapper(newValue: any): void {\n setValue(newValue);\n if (props.onChange) {\n props.onChange(newValue);\n }\n }\n\n const typeName = props.typeName;\n const typeSchema = globalSchema.types[typeName];\n if (!typeSchema) {\n return <div>{typeName}&nbsp;not implemented</div>;\n }\n\n const typedValue = { type: typeName, value };\n\n return (\n <Stack>\n {Object.entries(typeSchema.properties).map((entry) => {\n const key = entry[0];\n if (key === 'id' || DEFAULT_IGNORED_PROPERTIES.includes(key)) {\n return null;\n }\n const property = entry[1];\n if (!property.type) {\n return null;\n }\n\n const [propertyValue, propertyType] = getValueAndType(typedValue, key);\n const required = property.min !== undefined && property.min > 0;\n\n if (property.type.length === 1 && property.type[0].code === 'boolean') {\n return (\n <CheckboxFormSection\n key={key}\n title={getPropertyDisplayName(key)}\n description={property.definition}\n htmlFor={key}\n >\n <ResourcePropertyInput\n property={property}\n name={key}\n defaultValue={propertyValue}\n defaultPropertyType={propertyType}\n outcome={props.outcome}\n onChange={(newValue: any, propName?: string) => {\n setValueWrapper(setPropertyValue(value, key, propName ?? key, entry[1], newValue));\n }}\n />\n </CheckboxFormSection>\n );\n }\n\n return (\n <FormSection\n key={key}\n title={getPropertyDisplayName(key)}\n description={property.definition}\n withAsterisk={required}\n htmlFor={key}\n outcome={props.outcome}\n >\n <ResourcePropertyInput\n property={property}\n name={key}\n defaultValue={propertyValue}\n defaultPropertyType={propertyType}\n onChange={(newValue: any, propName?: string) => {\n setValueWrapper(setPropertyValue(value, key, propName ?? key, entry[1], newValue));\n }}\n />\n </FormSection>\n );\n })}\n </Stack>\n );\n}\n"],"names":[],"mappings":"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"}
@@ -12,7 +12,7 @@ function BookmarkDialog(props) {
12
12
  const { menuname, bookmarkname: name } = formData;
13
13
  const target = `${props.pathname}?${props.searchParams.toString()}`;
14
14
  const newConfig = deepClone(config);
15
- const menu = newConfig?.menu?.find(({ title }) => title === menuname);
15
+ const menu = newConfig.menu?.find(({ title }) => title === menuname);
16
16
  menu?.link?.push({ name, target });
17
17
  medplum
18
18
  .updateResource(newConfig)
@@ -40,7 +40,7 @@ function SelectMenu(props) {
40
40
  return config?.menu?.map((menu) => menu.title);
41
41
  }
42
42
  const menus = userConfigToMenu(props.config);
43
- return (React.createElement(NativeSelect, { name: "menuname", defaultValue: menus?.[0], label: "Select Menu Option", placeholder: "Menu", data: menus, withAsterisk: true }));
43
+ return (React.createElement(NativeSelect, { name: "menuname", defaultValue: menus[0], label: "Select Menu Option", placeholder: "Menu", data: menus, withAsterisk: true }));
44
44
  }
45
45
 
46
46
  export { BookmarkDialog };
@@ -1 +1 @@
1
- {"version":3,"file":"BookmarkDialog.mjs","sources":["../../../src/BookmarkDialog/BookmarkDialog.tsx"],"sourcesContent":["import { Button, Group, Modal, NativeSelect, Stack, TextInput } from '@mantine/core';\nimport { showNotification } from '@mantine/notifications';\nimport { deepClone, normalizeErrorString } from '@medplum/core';\nimport { UserConfiguration } from '@medplum/fhirtypes';\nimport React from 'react';\nimport { Form } from '../Form/Form';\nimport { useMedplum } from '../MedplumProvider/MedplumProvider';\n\ninterface BookmarkDialogProps {\n pathname: string;\n searchParams: URLSearchParams;\n visible: boolean;\n onOk: () => void;\n onCancel: () => void;\n defaultValue?: string;\n}\nexport function BookmarkDialog(props: BookmarkDialogProps): JSX.Element | null {\n const medplum = useMedplum();\n const config = medplum.getUserConfiguration() as UserConfiguration;\n\n function submitHandler(formData: Record<string, string>): void {\n const { menuname, bookmarkname: name } = formData;\n const target = `${props.pathname}?${props.searchParams.toString()}`;\n const newConfig = deepClone(config) as UserConfiguration;\n const menu = newConfig?.menu?.find(({ title }) => title === menuname);\n\n menu?.link?.push({ name, target });\n medplum\n .updateResource(newConfig)\n .then((res) => {\n // refresh current config menu\n config.menu = res.menu;\n medplum.dispatchEvent({ type: 'change' });\n showNotification({ color: 'green', message: 'Success' });\n props.onOk();\n })\n .catch((err: any) => {\n showNotification({ color: 'red', message: normalizeErrorString(err) });\n });\n }\n\n return (\n <Modal\n title=\"Add Bookmark\"\n closeButtonProps={{ 'aria-label': 'Close' }}\n opened={props.visible}\n onClose={props.onCancel}\n >\n <Form onSubmit={submitHandler}>\n <Stack>\n <SelectMenu config={config}></SelectMenu>\n <TextInput label=\"Bookmark Name\" type=\"text\" name=\"bookmarkname\" placeholder=\"bookmark name\" withAsterisk />\n <Group position=\"right\">\n <Button mt=\"sm\" type=\"submit\">\n OK\n </Button>\n </Group>\n </Stack>\n </Form>\n </Modal>\n );\n}\n\ninterface SelectMenuProps {\n config: UserConfiguration | undefined;\n}\n\nfunction SelectMenu(props: SelectMenuProps): JSX.Element {\n function userConfigToMenu(config: UserConfiguration | undefined): string[] {\n return config?.menu?.map((menu) => menu.title) as [];\n }\n const menus = userConfigToMenu(props.config);\n\n return (\n <NativeSelect\n name=\"menuname\"\n defaultValue={menus?.[0]}\n label=\"Select Menu Option\"\n placeholder=\"Menu\"\n data={menus}\n withAsterisk\n />\n );\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"BookmarkDialog.mjs","sources":["../../../src/BookmarkDialog/BookmarkDialog.tsx"],"sourcesContent":["import { Button, Group, Modal, NativeSelect, Stack, TextInput } from '@mantine/core';\nimport { showNotification } from '@mantine/notifications';\nimport { deepClone, normalizeErrorString } from '@medplum/core';\nimport { UserConfiguration } from '@medplum/fhirtypes';\nimport React from 'react';\nimport { Form } from '../Form/Form';\nimport { useMedplum } from '../MedplumProvider/MedplumProvider';\n\ninterface BookmarkDialogProps {\n pathname: string;\n searchParams: URLSearchParams;\n visible: boolean;\n onOk: () => void;\n onCancel: () => void;\n defaultValue?: string;\n}\nexport function BookmarkDialog(props: BookmarkDialogProps): JSX.Element | null {\n const medplum = useMedplum();\n const config = medplum.getUserConfiguration() as UserConfiguration;\n\n function submitHandler(formData: Record<string, string>): void {\n const { menuname, bookmarkname: name } = formData;\n const target = `${props.pathname}?${props.searchParams.toString()}`;\n const newConfig = deepClone(config) as UserConfiguration;\n const menu = newConfig.menu?.find(({ title }) => title === menuname);\n\n menu?.link?.push({ name, target });\n medplum\n .updateResource(newConfig)\n .then((res) => {\n // refresh current config menu\n config.menu = res.menu;\n medplum.dispatchEvent({ type: 'change' });\n showNotification({ color: 'green', message: 'Success' });\n props.onOk();\n })\n .catch((err: any) => {\n showNotification({ color: 'red', message: normalizeErrorString(err) });\n });\n }\n\n return (\n <Modal\n title=\"Add Bookmark\"\n closeButtonProps={{ 'aria-label': 'Close' }}\n opened={props.visible}\n onClose={props.onCancel}\n >\n <Form onSubmit={submitHandler}>\n <Stack>\n <SelectMenu config={config}></SelectMenu>\n <TextInput label=\"Bookmark Name\" type=\"text\" name=\"bookmarkname\" placeholder=\"bookmark name\" withAsterisk />\n <Group position=\"right\">\n <Button mt=\"sm\" type=\"submit\">\n OK\n </Button>\n </Group>\n </Stack>\n </Form>\n </Modal>\n );\n}\n\ninterface SelectMenuProps {\n config: UserConfiguration | undefined;\n}\n\nfunction SelectMenu(props: SelectMenuProps): JSX.Element {\n function userConfigToMenu(config: UserConfiguration | undefined): string[] {\n return config?.menu?.map((menu) => menu.title) as [];\n }\n const menus = userConfigToMenu(props.config);\n\n return (\n <NativeSelect\n name=\"menuname\"\n defaultValue={menus[0]}\n label=\"Select Menu Option\"\n placeholder=\"Menu\"\n data={menus}\n withAsterisk\n />\n );\n}\n"],"names":[],"mappings":"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"}
@@ -74,16 +74,14 @@ function DiagnosticReportHeader({ value }) {
74
74
  React.createElement(Text, { size: "xs", transform: "uppercase", color: "dimmed" }, "Subject"),
75
75
  React.createElement(Text, null,
76
76
  React.createElement(ResourceBadge, { value: value.subject, link: true })))),
77
- value.resultsInterpreter &&
78
- value.resultsInterpreter.map((interpreter) => (React.createElement("div", { key: interpreter.reference },
79
- React.createElement(Text, { size: "xs", transform: "uppercase", color: "dimmed" }, "Interpreter"),
80
- React.createElement(Text, null,
81
- React.createElement(ResourceBadge, { value: interpreter, link: true }))))),
82
- value.performer &&
83
- value.performer.map((performer) => (React.createElement("div", { key: performer.reference },
84
- React.createElement(Text, { size: "xs", transform: "uppercase", color: "dimmed" }, "Performer"),
85
- React.createElement(Text, null,
86
- React.createElement(ResourceBadge, { value: performer, link: true }))))),
77
+ value.resultsInterpreter?.map((interpreter) => (React.createElement("div", { key: interpreter.reference },
78
+ React.createElement(Text, { size: "xs", transform: "uppercase", color: "dimmed" }, "Interpreter"),
79
+ React.createElement(Text, null,
80
+ React.createElement(ResourceBadge, { value: interpreter, link: true }))))),
81
+ value.performer?.map((performer) => (React.createElement("div", { key: performer.reference },
82
+ React.createElement(Text, { size: "xs", transform: "uppercase", color: "dimmed" }, "Performer"),
83
+ React.createElement(Text, null,
84
+ React.createElement(ResourceBadge, { value: performer, link: true }))))),
87
85
  value.issued && (React.createElement("div", null,
88
86
  React.createElement(Text, { size: "xs", transform: "uppercase", color: "dimmed" }, "Issued"),
89
87
  React.createElement(Text, null, formatDateTime(value.issued)))),
@@ -125,7 +123,7 @@ function ObservationRow(props) {
125
123
  if (!observation) {
126
124
  return null;
127
125
  }
128
- const displayNotes = !props.hideObservationNotes && observation?.note;
126
+ const displayNotes = !props.hideObservationNotes && observation.note;
129
127
  const critical = isCritical(observation);
130
128
  return (React.createElement(React.Fragment, null,
131
129
  React.createElement("tr", { className: cx({ [classes.criticalRow]: critical }) },
@@ -139,7 +137,7 @@ function ObservationRow(props) {
139
137
  React.createElement("td", null, observation.interpretation && observation.interpretation.length > 0 && (React.createElement(CodeableConceptDisplay, { value: observation.interpretation[0] }))),
140
138
  React.createElement("td", null, observation.category && observation.category.length > 0 && (React.createElement("ul", null, observation.category.map((concept, index) => (React.createElement("li", { key: `category-${index}` },
141
139
  React.createElement(CodeableConceptDisplay, { value: concept }))))))),
142
- React.createElement("td", null, observation.performer?.map((performer) => (React.createElement(ReferenceDisplay, { key: performer?.reference, value: performer })))),
140
+ React.createElement("td", null, observation.performer?.map((performer) => (React.createElement(ReferenceDisplay, { key: performer.reference, value: performer })))),
143
141
  React.createElement("td", null, observation.status && React.createElement(StatusBadge, { status: observation.status }))),
144
142
  displayNotes && (React.createElement("tr", null,
145
143
  React.createElement("td", { colSpan: 6 },
@@ -1 +1 @@
1
- {"version":3,"file":"DiagnosticReportDisplay.mjs","sources":["../../../src/DiagnosticReportDisplay/DiagnosticReportDisplay.tsx"],"sourcesContent":["import { createStyles, Group, List, Stack, Text, Title } from '@mantine/core';\nimport { capitalize, formatDateTime, formatObservationValue } from '@medplum/core';\nimport {\n Annotation,\n DiagnosticReport,\n Observation,\n ObservationComponent,\n ObservationReferenceRange,\n Reference,\n Specimen,\n} from '@medplum/fhirtypes';\nimport React, { useEffect, useState } from 'react';\nimport { CodeableConceptDisplay } from '../CodeableConceptDisplay/CodeableConceptDisplay';\nimport { MedplumLink } from '../MedplumLink/MedplumLink';\nimport { useMedplum } from '../MedplumProvider/MedplumProvider';\nimport { NoteDisplay } from '../NoteDisplay/NoteDisplay';\nimport { RangeDisplay } from '../RangeDisplay/RangeDisplay';\nimport { ReferenceDisplay } from '../ReferenceDisplay/ReferenceDisplay';\nimport { ResourceBadge } from '../ResourceBadge/ResourceBadge';\nimport { StatusBadge } from '../StatusBadge/StatusBadge';\nimport { useResource } from '../useResource/useResource';\n\nconst useStyles = createStyles((theme) => ({\n table: {\n border: `0.1px solid ${theme.colors.gray[5]}`,\n borderCollapse: 'collapse',\n\n '& td, & th': {\n border: `0.1px solid ${theme.colors.gray[5]}`,\n padding: 4,\n },\n },\n\n criticalRow: {\n background: theme.colorScheme === 'dark' ? theme.colors.red[7] : theme.colors.red[1],\n border: `0.1px solid ${theme.colors.red[5]}`,\n color: theme.colors.red[5],\n fontWeight: 500,\n\n '& td': {\n border: `0.1px solid ${theme.colors.red[5]}`,\n },\n },\n\n noteBody: { fontSize: theme.fontSizes.sm },\n noteCite: { fontSize: theme.fontSizes.xs, marginBlockStart: 3 },\n noteRoot: { padding: 5 },\n}));\n\nexport interface DiagnosticReportDisplayProps {\n value?: DiagnosticReport | Reference<DiagnosticReport>;\n hideObservationNotes?: boolean;\n hideSpecimenInfo?: boolean;\n}\n\nDiagnosticReportDisplay.defaultProps = {\n hideObservationNotes: false,\n hideSpecimenInfo: false,\n} as DiagnosticReportDisplayProps;\n\nexport function DiagnosticReportDisplay(props: DiagnosticReportDisplayProps): JSX.Element | null {\n const medplum = useMedplum();\n const diagnosticReport = useResource(props.value);\n const [specimens, setSpecimens] = useState<Specimen[]>();\n\n useEffect(() => {\n if (diagnosticReport?.specimen) {\n Promise.allSettled(diagnosticReport.specimen.map((ref) => medplum.readReference(ref)))\n .then((outcomes) =>\n outcomes\n .filter((outcome) => outcome.status === 'fulfilled')\n .map((outcome) => (outcome as PromiseFulfilledResult<Specimen>).value)\n )\n .then(setSpecimens)\n .catch(console.error);\n }\n }, [medplum, diagnosticReport]);\n\n if (!diagnosticReport) {\n return null;\n }\n\n const specimenNotes: Annotation[] = specimens?.flatMap((spec) => spec.note || []) || [];\n\n if (diagnosticReport.presentedForm && diagnosticReport.presentedForm.length > 0) {\n const pf = diagnosticReport.presentedForm[0];\n if (pf.contentType?.startsWith('text/plain') && pf.data) {\n specimenNotes.push({ text: window.atob(pf.data) });\n }\n }\n\n return (\n <Stack>\n <Title>Diagnostic Report</Title>\n <DiagnosticReportHeader value={diagnosticReport} />\n {!props.hideSpecimenInfo && SpecimenInfo(specimens)}\n {diagnosticReport.result && (\n <ObservationTable hideObservationNotes={props.hideObservationNotes} value={diagnosticReport.result} />\n )}\n {specimenNotes.length > 0 && <NoteDisplay value={specimenNotes} />}\n </Stack>\n );\n}\n\ninterface DiagnosticReportHeaderProps {\n value: DiagnosticReport;\n}\n\nfunction DiagnosticReportHeader({ value }: DiagnosticReportHeaderProps): JSX.Element {\n return (\n <Group mt=\"md\" spacing={30}>\n {value.subject && (\n <div>\n <Text size=\"xs\" transform=\"uppercase\" color=\"dimmed\">\n Subject\n </Text>\n <Text>\n <ResourceBadge value={value.subject} link={true} />\n </Text>\n </div>\n )}\n {value.resultsInterpreter &&\n value.resultsInterpreter.map((interpreter) => (\n <div key={interpreter.reference}>\n <Text size=\"xs\" transform=\"uppercase\" color=\"dimmed\">\n Interpreter\n </Text>\n <Text>\n <ResourceBadge value={interpreter} link={true} />\n </Text>\n </div>\n ))}\n {value.performer &&\n value.performer.map((performer) => (\n <div key={performer.reference}>\n <Text size=\"xs\" transform=\"uppercase\" color=\"dimmed\">\n Performer\n </Text>\n <Text>\n <ResourceBadge value={performer} link={true} />\n </Text>\n </div>\n ))}\n {value.issued && (\n <div>\n <Text size=\"xs\" transform=\"uppercase\" color=\"dimmed\">\n Issued\n </Text>\n <Text>{formatDateTime(value.issued)}</Text>\n </div>\n )}\n {value.status && (\n <div>\n <Text size=\"xs\" transform=\"uppercase\" color=\"dimmed\">\n Status\n </Text>\n <Text>{capitalize(value.status)}</Text>\n </div>\n )}\n </Group>\n );\n}\n\nfunction SpecimenInfo(specimens: Specimen[] | undefined): JSX.Element {\n return (\n <Stack spacing={'xs'}>\n <Title order={2} size=\"h6\">\n Specimens\n </Title>\n\n <List type=\"ordered\">\n {specimens?.map((specimen, index) => (\n <List.Item ml={'sm'} key={`specimen-${specimen.id}-${index}`}>\n <Group spacing={20}>\n <Group spacing={5}>\n <Text fw={500}>Collected:</Text> {formatDateTime(specimen.collection?.collectedDateTime)}\n </Group>\n <Group spacing={5}>\n <Text fw={500}>Received:</Text> {formatDateTime(specimen.receivedTime)}\n </Group>\n </Group>\n </List.Item>\n ))}\n </List>\n </Stack>\n );\n}\n\nexport interface ObservationTableProps {\n value?: Observation[] | Reference<Observation>[];\n hideObservationNotes?: boolean;\n}\n\nexport function ObservationTable(props: ObservationTableProps): JSX.Element {\n const { classes } = useStyles();\n return (\n <table className={classes.table}>\n <thead>\n <tr>\n <th>Test</th>\n <th>Value</th>\n <th>Reference Range</th>\n <th>Interpretation</th>\n <th>Category</th>\n <th>Performer</th>\n <th>Status</th>\n </tr>\n </thead>\n <tbody>\n {props.value?.map((observation, index) => (\n <ObservationRow\n key={`obs-${observation.id}-${index}`}\n hideObservationNotes={props.hideObservationNotes}\n value={observation}\n />\n ))}\n </tbody>\n </table>\n );\n}\n\ninterface ObservationRowProps {\n value: Observation | Reference<Observation>;\n hideObservationNotes?: boolean;\n}\n\nfunction ObservationRow(props: ObservationRowProps): JSX.Element | null {\n const { classes, cx } = useStyles();\n const observation = useResource(props.value);\n\n if (!observation) {\n return null;\n }\n const displayNotes = !props.hideObservationNotes && observation?.note;\n\n const critical = isCritical(observation);\n\n return (\n <>\n <tr className={cx({ [classes.criticalRow]: critical })}>\n <td rowSpan={displayNotes ? 2 : 1}>\n <MedplumLink to={observation}>\n <CodeableConceptDisplay value={observation.code} />\n </MedplumLink>\n </td>\n <td>\n <ObservationValueDisplay value={observation} />\n </td>\n <td>\n <ReferenceRangeDisplay value={observation.referenceRange} />\n </td>\n <td>\n {observation.interpretation && observation.interpretation.length > 0 && (\n <CodeableConceptDisplay value={observation.interpretation[0]} />\n )}\n </td>\n <td>\n {observation.category && observation.category.length > 0 && (\n <ul>\n {observation.category.map((concept, index) => (\n <li key={`category-${index}`}>\n <CodeableConceptDisplay value={concept} />\n </li>\n ))}\n </ul>\n )}\n </td>\n <td>\n {observation.performer?.map((performer) => (\n <ReferenceDisplay key={performer?.reference} value={performer} />\n ))}\n </td>\n <td>{observation.status && <StatusBadge status={observation.status} />}</td>\n </tr>\n {displayNotes && (\n <tr>\n <td colSpan={6}>\n <NoteDisplay value={observation.note} />\n </td>\n </tr>\n )}\n </>\n );\n}\n\ninterface ObservationValueDisplayProps {\n value?: Observation | ObservationComponent;\n}\n\nfunction ObservationValueDisplay(props: ObservationValueDisplayProps): JSX.Element | null {\n const obs = props.value;\n return <>{formatObservationValue(obs)}</>;\n}\n\ninterface ReferenceRangeProps {\n value?: ObservationReferenceRange[];\n}\n\nfunction ReferenceRangeDisplay(props: ReferenceRangeProps): JSX.Element | null {\n const range = props.value && props.value.length > 0 && props.value[0];\n if (!range) {\n return null;\n }\n if (range.text) {\n return <>{range.text}</>;\n }\n return <RangeDisplay value={range} />;\n}\n\n/**\n * Returns true if the observation is critical.\n * See: https://www.hl7.org/fhir/valueset-observation-interpretation.html\n * @param observation The FHIR observation.\n * @returns True if the FHIR observation is a critical value.\n */\nfunction isCritical(observation: Observation): boolean {\n const code = observation.interpretation?.[0]?.coding?.[0]?.code;\n return code === 'AA' || code === 'LL' || code === 'HH' || code === 'A';\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"DiagnosticReportDisplay.mjs","sources":["../../../src/DiagnosticReportDisplay/DiagnosticReportDisplay.tsx"],"sourcesContent":["import { createStyles, Group, List, Stack, Text, Title } from '@mantine/core';\nimport { capitalize, formatDateTime, formatObservationValue } from '@medplum/core';\nimport {\n Annotation,\n DiagnosticReport,\n Observation,\n ObservationComponent,\n ObservationReferenceRange,\n Reference,\n Specimen,\n} from '@medplum/fhirtypes';\nimport React, { useEffect, useState } from 'react';\nimport { CodeableConceptDisplay } from '../CodeableConceptDisplay/CodeableConceptDisplay';\nimport { MedplumLink } from '../MedplumLink/MedplumLink';\nimport { useMedplum } from '../MedplumProvider/MedplumProvider';\nimport { NoteDisplay } from '../NoteDisplay/NoteDisplay';\nimport { RangeDisplay } from '../RangeDisplay/RangeDisplay';\nimport { ReferenceDisplay } from '../ReferenceDisplay/ReferenceDisplay';\nimport { ResourceBadge } from '../ResourceBadge/ResourceBadge';\nimport { StatusBadge } from '../StatusBadge/StatusBadge';\nimport { useResource } from '../useResource/useResource';\n\nconst useStyles = createStyles((theme) => ({\n table: {\n border: `0.1px solid ${theme.colors.gray[5]}`,\n borderCollapse: 'collapse',\n\n '& td, & th': {\n border: `0.1px solid ${theme.colors.gray[5]}`,\n padding: 4,\n },\n },\n\n criticalRow: {\n background: theme.colorScheme === 'dark' ? theme.colors.red[7] : theme.colors.red[1],\n border: `0.1px solid ${theme.colors.red[5]}`,\n color: theme.colors.red[5],\n fontWeight: 500,\n\n '& td': {\n border: `0.1px solid ${theme.colors.red[5]}`,\n },\n },\n\n noteBody: { fontSize: theme.fontSizes.sm },\n noteCite: { fontSize: theme.fontSizes.xs, marginBlockStart: 3 },\n noteRoot: { padding: 5 },\n}));\n\nexport interface DiagnosticReportDisplayProps {\n value?: DiagnosticReport | Reference<DiagnosticReport>;\n hideObservationNotes?: boolean;\n hideSpecimenInfo?: boolean;\n}\n\nDiagnosticReportDisplay.defaultProps = {\n hideObservationNotes: false,\n hideSpecimenInfo: false,\n} as DiagnosticReportDisplayProps;\n\nexport function DiagnosticReportDisplay(props: DiagnosticReportDisplayProps): JSX.Element | null {\n const medplum = useMedplum();\n const diagnosticReport = useResource(props.value);\n const [specimens, setSpecimens] = useState<Specimen[]>();\n\n useEffect(() => {\n if (diagnosticReport?.specimen) {\n Promise.allSettled(diagnosticReport.specimen.map((ref) => medplum.readReference(ref)))\n .then((outcomes) =>\n outcomes\n .filter((outcome) => outcome.status === 'fulfilled')\n .map((outcome) => (outcome as PromiseFulfilledResult<Specimen>).value)\n )\n .then(setSpecimens)\n .catch(console.error);\n }\n }, [medplum, diagnosticReport]);\n\n if (!diagnosticReport) {\n return null;\n }\n\n const specimenNotes: Annotation[] = specimens?.flatMap((spec) => spec.note || []) || [];\n\n if (diagnosticReport.presentedForm && diagnosticReport.presentedForm.length > 0) {\n const pf = diagnosticReport.presentedForm[0];\n if (pf.contentType?.startsWith('text/plain') && pf.data) {\n specimenNotes.push({ text: window.atob(pf.data) });\n }\n }\n\n return (\n <Stack>\n <Title>Diagnostic Report</Title>\n <DiagnosticReportHeader value={diagnosticReport} />\n {!props.hideSpecimenInfo && SpecimenInfo(specimens)}\n {diagnosticReport.result && (\n <ObservationTable hideObservationNotes={props.hideObservationNotes} value={diagnosticReport.result} />\n )}\n {specimenNotes.length > 0 && <NoteDisplay value={specimenNotes} />}\n </Stack>\n );\n}\n\ninterface DiagnosticReportHeaderProps {\n value: DiagnosticReport;\n}\n\nfunction DiagnosticReportHeader({ value }: DiagnosticReportHeaderProps): JSX.Element {\n return (\n <Group mt=\"md\" spacing={30}>\n {value.subject && (\n <div>\n <Text size=\"xs\" transform=\"uppercase\" color=\"dimmed\">\n Subject\n </Text>\n <Text>\n <ResourceBadge value={value.subject} link={true} />\n </Text>\n </div>\n )}\n {value.resultsInterpreter?.map((interpreter) => (\n <div key={interpreter.reference}>\n <Text size=\"xs\" transform=\"uppercase\" color=\"dimmed\">\n Interpreter\n </Text>\n <Text>\n <ResourceBadge value={interpreter} link={true} />\n </Text>\n </div>\n ))}\n {value.performer?.map((performer) => (\n <div key={performer.reference}>\n <Text size=\"xs\" transform=\"uppercase\" color=\"dimmed\">\n Performer\n </Text>\n <Text>\n <ResourceBadge value={performer} link={true} />\n </Text>\n </div>\n ))}\n {value.issued && (\n <div>\n <Text size=\"xs\" transform=\"uppercase\" color=\"dimmed\">\n Issued\n </Text>\n <Text>{formatDateTime(value.issued)}</Text>\n </div>\n )}\n {value.status && (\n <div>\n <Text size=\"xs\" transform=\"uppercase\" color=\"dimmed\">\n Status\n </Text>\n <Text>{capitalize(value.status)}</Text>\n </div>\n )}\n </Group>\n );\n}\n\nfunction SpecimenInfo(specimens: Specimen[] | undefined): JSX.Element {\n return (\n <Stack spacing={'xs'}>\n <Title order={2} size=\"h6\">\n Specimens\n </Title>\n\n <List type=\"ordered\">\n {specimens?.map((specimen, index) => (\n <List.Item ml={'sm'} key={`specimen-${specimen.id}-${index}`}>\n <Group spacing={20}>\n <Group spacing={5}>\n <Text fw={500}>Collected:</Text> {formatDateTime(specimen.collection?.collectedDateTime)}\n </Group>\n <Group spacing={5}>\n <Text fw={500}>Received:</Text> {formatDateTime(specimen.receivedTime)}\n </Group>\n </Group>\n </List.Item>\n ))}\n </List>\n </Stack>\n );\n}\n\nexport interface ObservationTableProps {\n value?: Observation[] | Reference<Observation>[];\n hideObservationNotes?: boolean;\n}\n\nexport function ObservationTable(props: ObservationTableProps): JSX.Element {\n const { classes } = useStyles();\n return (\n <table className={classes.table}>\n <thead>\n <tr>\n <th>Test</th>\n <th>Value</th>\n <th>Reference Range</th>\n <th>Interpretation</th>\n <th>Category</th>\n <th>Performer</th>\n <th>Status</th>\n </tr>\n </thead>\n <tbody>\n {props.value?.map((observation, index) => (\n <ObservationRow\n key={`obs-${observation.id}-${index}`}\n hideObservationNotes={props.hideObservationNotes}\n value={observation}\n />\n ))}\n </tbody>\n </table>\n );\n}\n\ninterface ObservationRowProps {\n value: Observation | Reference<Observation>;\n hideObservationNotes?: boolean;\n}\n\nfunction ObservationRow(props: ObservationRowProps): JSX.Element | null {\n const { classes, cx } = useStyles();\n const observation = useResource(props.value);\n\n if (!observation) {\n return null;\n }\n const displayNotes = !props.hideObservationNotes && observation.note;\n\n const critical = isCritical(observation);\n\n return (\n <>\n <tr className={cx({ [classes.criticalRow]: critical })}>\n <td rowSpan={displayNotes ? 2 : 1}>\n <MedplumLink to={observation}>\n <CodeableConceptDisplay value={observation.code} />\n </MedplumLink>\n </td>\n <td>\n <ObservationValueDisplay value={observation} />\n </td>\n <td>\n <ReferenceRangeDisplay value={observation.referenceRange} />\n </td>\n <td>\n {observation.interpretation && observation.interpretation.length > 0 && (\n <CodeableConceptDisplay value={observation.interpretation[0]} />\n )}\n </td>\n <td>\n {observation.category && observation.category.length > 0 && (\n <ul>\n {observation.category.map((concept, index) => (\n <li key={`category-${index}`}>\n <CodeableConceptDisplay value={concept} />\n </li>\n ))}\n </ul>\n )}\n </td>\n <td>\n {observation.performer?.map((performer) => (\n <ReferenceDisplay key={performer.reference} value={performer} />\n ))}\n </td>\n <td>{observation.status && <StatusBadge status={observation.status} />}</td>\n </tr>\n {displayNotes && (\n <tr>\n <td colSpan={6}>\n <NoteDisplay value={observation.note} />\n </td>\n </tr>\n )}\n </>\n );\n}\n\ninterface ObservationValueDisplayProps {\n value?: Observation | ObservationComponent;\n}\n\nfunction ObservationValueDisplay(props: ObservationValueDisplayProps): JSX.Element | null {\n const obs = props.value;\n return <>{formatObservationValue(obs)}</>;\n}\n\ninterface ReferenceRangeProps {\n value?: ObservationReferenceRange[];\n}\n\nfunction ReferenceRangeDisplay(props: ReferenceRangeProps): JSX.Element | null {\n const range = props.value && props.value.length > 0 && props.value[0];\n if (!range) {\n return null;\n }\n if (range.text) {\n return <>{range.text}</>;\n }\n return <RangeDisplay value={range} />;\n}\n\n/**\n * Returns true if the observation is critical.\n * See: https://www.hl7.org/fhir/valueset-observation-interpretation.html\n * @param observation The FHIR observation.\n * @returns True if the FHIR observation is a critical value.\n */\nfunction isCritical(observation: Observation): boolean {\n const code = observation.interpretation?.[0]?.coding?.[0]?.code;\n return code === 'AA' || code === 'LL' || code === 'HH' || code === 'A';\n}\n"],"names":[],"mappings":"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"}