@medplum/react 2.0.17 → 2.0.18
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.
- package/dist/cjs/index.cjs +149 -84
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs/index.min.cjs +1 -1
- package/dist/esm/AppShell/AppShell.mjs +1 -1
- package/dist/esm/AppShell/AppShell.mjs.map +1 -1
- package/dist/esm/AppShell/Navbar.mjs +21 -14
- package/dist/esm/AppShell/Navbar.mjs.map +1 -1
- package/dist/esm/BookmarkDialog/BookmarkDialog.mjs +49 -0
- package/dist/esm/BookmarkDialog/BookmarkDialog.mjs.map +1 -0
- package/dist/esm/DefaultResourceTimeline/DefaultResourceTimeline.mjs +6 -1
- package/dist/esm/DefaultResourceTimeline/DefaultResourceTimeline.mjs.map +1 -1
- package/dist/esm/PatientTimeline/PatientTimeline.mjs +10 -7
- package/dist/esm/PatientTimeline/PatientTimeline.mjs.map +1 -1
- package/dist/esm/SearchControl/SearchUtils.mjs +1 -0
- package/dist/esm/SearchControl/SearchUtils.mjs.map +1 -1
- package/dist/esm/SearchFilterEditor/SearchFilterEditor.mjs +1 -1
- package/dist/esm/SearchFilterEditor/SearchFilterEditor.mjs.map +1 -1
- package/dist/esm/ServiceRequestTimeline/ServiceRequestTimeline.mjs +7 -4
- package/dist/esm/ServiceRequestTimeline/ServiceRequestTimeline.mjs.map +1 -1
- package/dist/esm/auth/AuthenticationForm.mjs +1 -1
- package/dist/esm/auth/AuthenticationForm.mjs.map +1 -1
- package/dist/esm/index.min.mjs +1 -1
- package/dist/esm/node_modules/@tabler/icons-react/dist/esm/icons/IconPlus.mjs +13 -0
- package/dist/esm/node_modules/@tabler/icons-react/dist/esm/icons/IconPlus.mjs.map +1 -0
- package/dist/types/AppShell/AppShell.d.ts +1 -0
- package/dist/types/AppShell/Navbar.d.ts +1 -0
- package/dist/types/BookmarkDialog/BookmarkDialog.d.ts +8 -0
- package/package.json +1 -1
|
@@ -28,7 +28,7 @@ function AppShell(props) {
|
|
|
28
28
|
main: {
|
|
29
29
|
background: theme.colorScheme === 'dark' ? theme.colors.dark[8] : theme.colors.gray[0],
|
|
30
30
|
},
|
|
31
|
-
}, padding: 0, fixed: true, header: profile && React.createElement(Header, { logo: props.logo, version: props.version, navbarToggle: toggleNavbar }), navbar: profile && navbarOpen ? React.createElement(Navbar, { menus: props.menus, closeNavbar: closeNavbar }) : undefined },
|
|
31
|
+
}, padding: 0, fixed: true, header: profile && React.createElement(Header, { logo: props.logo, version: props.version, navbarToggle: toggleNavbar }), navbar: profile && navbarOpen ? (React.createElement(Navbar, { menus: props.menus, closeNavbar: closeNavbar, displayAddBookmark: props.displayAddBookmark })) : undefined },
|
|
32
32
|
React.createElement(ErrorBoundary, null,
|
|
33
33
|
React.createElement(Suspense, { fallback: React.createElement(Loading, null) }, props.children))));
|
|
34
34
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AppShell.mjs","sources":["../../../src/AppShell/AppShell.tsx"],"sourcesContent":["import { AppShell as MantineAppShell, useMantineTheme } from '@mantine/core';\nimport React, { Suspense, useState } from 'react';\nimport { ErrorBoundary } from '../ErrorBoundary/ErrorBoundary';\nimport { Loading } from '../Loading/Loading';\nimport { useMedplum, useMedplumProfile } from '../MedplumProvider/MedplumProvider';\nimport { Header } from './Header';\nimport { Navbar, NavbarMenu } from './Navbar';\n\nexport interface AppShellProps {\n logo: React.ReactNode;\n version?: string;\n menus?: NavbarMenu[];\n children: React.ReactNode;\n}\n\nexport function AppShell(props: AppShellProps): JSX.Element {\n const theme = useMantineTheme();\n const [navbarOpen, setNavbarOpen] = useState(localStorage['navbarOpen'] === 'true');\n const medplum = useMedplum();\n const profile = useMedplumProfile();\n\n function setNavbarOpenWrapper(open: boolean): void {\n localStorage['navbarOpen'] = open.toString();\n setNavbarOpen(open);\n }\n\n function closeNavbar(): void {\n setNavbarOpenWrapper(false);\n }\n\n function toggleNavbar(): void {\n setNavbarOpenWrapper(!navbarOpen);\n }\n\n if (medplum.isLoading()) {\n return <Loading />;\n }\n\n return (\n <MantineAppShell\n styles={{\n main: {\n background: theme.colorScheme === 'dark' ? theme.colors.dark[8] : theme.colors.gray[0],\n },\n }}\n padding={0}\n fixed={true}\n header={profile && <Header logo={props.logo} version={props.version} navbarToggle={toggleNavbar} />}\n navbar={profile && navbarOpen ? <Navbar menus={props.menus} closeNavbar={closeNavbar}
|
|
1
|
+
{"version":3,"file":"AppShell.mjs","sources":["../../../src/AppShell/AppShell.tsx"],"sourcesContent":["import { AppShell as MantineAppShell, useMantineTheme } from '@mantine/core';\nimport React, { Suspense, useState } from 'react';\nimport { ErrorBoundary } from '../ErrorBoundary/ErrorBoundary';\nimport { Loading } from '../Loading/Loading';\nimport { useMedplum, useMedplumProfile } from '../MedplumProvider/MedplumProvider';\nimport { Header } from './Header';\nimport { Navbar, NavbarMenu } from './Navbar';\n\nexport interface AppShellProps {\n logo: React.ReactNode;\n version?: string;\n menus?: NavbarMenu[];\n children: React.ReactNode;\n displayAddBookmark?: boolean;\n}\n\nexport function AppShell(props: AppShellProps): JSX.Element {\n const theme = useMantineTheme();\n const [navbarOpen, setNavbarOpen] = useState(localStorage['navbarOpen'] === 'true');\n const medplum = useMedplum();\n const profile = useMedplumProfile();\n\n function setNavbarOpenWrapper(open: boolean): void {\n localStorage['navbarOpen'] = open.toString();\n setNavbarOpen(open);\n }\n\n function closeNavbar(): void {\n setNavbarOpenWrapper(false);\n }\n\n function toggleNavbar(): void {\n setNavbarOpenWrapper(!navbarOpen);\n }\n\n if (medplum.isLoading()) {\n return <Loading />;\n }\n\n return (\n <MantineAppShell\n styles={{\n main: {\n background: theme.colorScheme === 'dark' ? theme.colors.dark[8] : theme.colors.gray[0],\n },\n }}\n padding={0}\n fixed={true}\n header={profile && <Header logo={props.logo} version={props.version} navbarToggle={toggleNavbar} />}\n navbar={\n profile && navbarOpen ? (\n <Navbar menus={props.menus} closeNavbar={closeNavbar} displayAddBookmark={props.displayAddBookmark} />\n ) : undefined\n }\n >\n <ErrorBoundary>\n <Suspense fallback={<Loading />}>{props.children}</Suspense>\n </ErrorBoundary>\n </MantineAppShell>\n );\n}\n"],"names":["MantineAppShell"],"mappings":";;;;;;;;AAgBM,SAAU,QAAQ,CAAC,KAAoB,EAAA;AAC3C,IAAA,MAAM,KAAK,GAAG,eAAe,EAAE,CAAC;AAChC,IAAA,MAAM,CAAC,UAAU,EAAE,aAAa,CAAC,GAAG,QAAQ,CAAC,YAAY,CAAC,YAAY,CAAC,KAAK,MAAM,CAAC,CAAC;AACpF,IAAA,MAAM,OAAO,GAAG,UAAU,EAAE,CAAC;AAC7B,IAAA,MAAM,OAAO,GAAG,iBAAiB,EAAE,CAAC;IAEpC,SAAS,oBAAoB,CAAC,IAAa,EAAA;QACzC,YAAY,CAAC,YAAY,CAAC,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;QAC7C,aAAa,CAAC,IAAI,CAAC,CAAC;KACrB;AAED,IAAA,SAAS,WAAW,GAAA;QAClB,oBAAoB,CAAC,KAAK,CAAC,CAAC;KAC7B;AAED,IAAA,SAAS,YAAY,GAAA;AACnB,QAAA,oBAAoB,CAAC,CAAC,UAAU,CAAC,CAAC;KACnC;AAED,IAAA,IAAI,OAAO,CAAC,SAAS,EAAE,EAAE;QACvB,OAAO,KAAA,CAAA,aAAA,CAAC,OAAO,EAAA,IAAA,CAAG,CAAC;AACpB,KAAA;AAED,IAAA,QACE,KAAA,CAAA,aAAA,CAACA,UAAe,EAAA,EACd,MAAM,EAAE;AACN,YAAA,IAAI,EAAE;gBACJ,UAAU,EAAE,KAAK,CAAC,WAAW,KAAK,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;AACvF,aAAA;AACF,SAAA,EACD,OAAO,EAAE,CAAC,EACV,KAAK,EAAE,IAAI,EACX,MAAM,EAAE,OAAO,IAAI,oBAAC,MAAM,EAAA,EAAC,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,YAAY,EAAE,YAAY,EAAI,CAAA,EACnG,MAAM,EACJ,OAAO,IAAI,UAAU,IACnB,KAAA,CAAA,aAAA,CAAC,MAAM,EAAA,EAAC,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,kBAAkB,EAAE,KAAK,CAAC,kBAAkB,EAAI,CAAA,IACpG,SAAS,EAAA;AAGf,QAAA,KAAA,CAAA,aAAA,CAAC,aAAa,EAAA,IAAA;AACZ,YAAA,KAAA,CAAA,aAAA,CAAC,QAAQ,EAAA,EAAC,QAAQ,EAAE,oBAAC,OAAO,EAAA,IAAA,CAAG,EAAG,EAAA,KAAK,CAAC,QAAQ,CAAY,CAC9C,CACA,EAClB;AACJ;;;;"}
|
|
@@ -1,9 +1,11 @@
|
|
|
1
|
-
import { createStyles, Navbar as Navbar$1, Text, Space } from '@mantine/core';
|
|
2
|
-
import React from 'react';
|
|
1
|
+
import { createStyles, Navbar as Navbar$1, Text, Button, Space } from '@mantine/core';
|
|
2
|
+
import React, { useState } from 'react';
|
|
3
3
|
import { useLocation, useSearchParams } from 'react-router-dom';
|
|
4
|
+
import { BookmarkDialog } from '../BookmarkDialog/BookmarkDialog.mjs';
|
|
4
5
|
import { CodeInput } from '../CodeInput/CodeInput.mjs';
|
|
5
6
|
import { MedplumLink } from '../MedplumLink/MedplumLink.mjs';
|
|
6
7
|
import { useMedplumNavigate } from '../MedplumProvider/MedplumProvider.mjs';
|
|
8
|
+
import IconPlus from '../node_modules/@tabler/icons-react/dist/esm/icons/IconPlus.mjs';
|
|
7
9
|
|
|
8
10
|
const useStyles = createStyles((theme) => {
|
|
9
11
|
return {
|
|
@@ -54,6 +56,7 @@ const useStyles = createStyles((theme) => {
|
|
|
54
56
|
function Navbar(props) {
|
|
55
57
|
const { classes } = useStyles();
|
|
56
58
|
const navigate = useMedplumNavigate();
|
|
59
|
+
const [bookmarkDialogVisible, setBookmarkDialogVisible] = useState(false);
|
|
57
60
|
function onLinkClick(e, to) {
|
|
58
61
|
e.stopPropagation();
|
|
59
62
|
e.preventDefault();
|
|
@@ -67,18 +70,22 @@ function Navbar(props) {
|
|
|
67
70
|
navigate(`/${resourceType}`);
|
|
68
71
|
}
|
|
69
72
|
}
|
|
70
|
-
return (React.createElement(
|
|
71
|
-
React.createElement(Navbar$1
|
|
72
|
-
React.createElement(
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
React.createElement(
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
73
|
+
return (React.createElement(React.Fragment, null,
|
|
74
|
+
React.createElement(Navbar$1, { width: { sm: 250 }, p: "xs" },
|
|
75
|
+
React.createElement(Navbar$1.Section, { mb: "sm" },
|
|
76
|
+
React.createElement(CodeInput, { key: window.location.pathname, name: "resourceType", placeholder: "Resource Type", property: {
|
|
77
|
+
binding: {
|
|
78
|
+
valueSet: 'http://hl7.org/fhir/ValueSet/resource-types',
|
|
79
|
+
},
|
|
80
|
+
}, onChange: (newValue) => navigateResourceType(newValue), creatable: false, maxSelectedValues: 0, clearSearchOnChange: true, clearable: false })),
|
|
81
|
+
React.createElement(Navbar$1.Section, { grow: true },
|
|
82
|
+
props.menus?.map((menu) => (React.createElement(React.Fragment, { key: `menu-${menu.title}` },
|
|
83
|
+
React.createElement(Text, { className: classes.menuTitle }, menu.title),
|
|
84
|
+
menu.links?.map((link) => (React.createElement(NavbarLink, { key: link.href, to: link.href, onClick: (e) => onLinkClick(e, link.href) },
|
|
85
|
+
React.createElement(NavLinkIcon, { to: link.href, icon: link.icon }),
|
|
86
|
+
React.createElement("span", null, link.label))))))),
|
|
87
|
+
props.displayAddBookmark && (React.createElement(Button, { variant: "subtle", size: "xs", mt: "xl", leftIcon: React.createElement(IconPlus, { size: "0.75rem" }), onClick: () => setBookmarkDialogVisible(true) }, "Add Bookmark")))),
|
|
88
|
+
React.createElement(BookmarkDialog, { visible: bookmarkDialogVisible, onOk: () => setBookmarkDialogVisible(false), onCancel: () => setBookmarkDialogVisible(false) })));
|
|
82
89
|
}
|
|
83
90
|
function NavbarLink(props) {
|
|
84
91
|
const { classes, cx } = useStyles();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Navbar.mjs","sources":["../../../src/AppShell/Navbar.tsx"],"sourcesContent":["import { createStyles, Navbar as MantineNavbar, Space, Text } from '@mantine/core';\nimport React from 'react';\nimport { useLocation, useSearchParams } from 'react-router-dom';\nimport { CodeInput } from '../CodeInput/CodeInput';\nimport { MedplumLink } from '../MedplumLink/MedplumLink';\nimport { useMedplumNavigate } from '../MedplumProvider/MedplumProvider';\n\nconst useStyles = createStyles((theme) => {\n return {\n menuTitle: {\n margin: '20px 0 4px 6px',\n fontSize: '9px',\n fontWeight: 'normal',\n textTransform: 'uppercase',\n letterSpacing: '2px',\n },\n\n link: {\n ...theme.fn.focusStyles(),\n display: 'flex',\n alignItems: 'center',\n textDecoration: 'none',\n fontSize: theme.fontSizes.sm,\n color: theme.colorScheme === 'dark' ? theme.colors.dark[1] : theme.colors.gray[7],\n padding: `8px 12px`,\n borderRadius: theme.radius.sm,\n fontWeight: 500,\n\n '&:hover': {\n backgroundColor: theme.colorScheme === 'dark' ? theme.colors.dark[6] : theme.colors.gray[0],\n color: theme.colorScheme === 'dark' ? theme.white : theme.black,\n textDecoration: 'none',\n\n [`& svg`]: {\n color: theme.colorScheme === 'dark' ? theme.white : theme.black,\n },\n },\n\n '& svg': {\n color: theme.colorScheme === 'dark' ? theme.colors.dark[2] : theme.colors.gray[6],\n marginRight: theme.spacing.sm,\n strokeWidth: 1.5,\n width: 18,\n height: 18,\n },\n },\n\n linkActive: {\n '&, &:hover': {\n backgroundColor: theme.fn.variant({ variant: 'light', color: theme.primaryColor }).background,\n color: theme.fn.variant({ variant: 'light', color: theme.primaryColor }).color,\n [`& svg`]: {\n color: theme.fn.variant({ variant: 'light', color: theme.primaryColor }).color,\n },\n },\n },\n };\n});\n\nexport interface NavbarLink {\n icon?: JSX.Element;\n label?: string;\n href: string;\n}\n\nexport interface NavbarMenu {\n title?: string;\n links?: NavbarLink[];\n}\n\nexport interface NavbarProps {\n menus?: NavbarMenu[];\n closeNavbar: () => void;\n}\n\nexport function Navbar(props: NavbarProps): JSX.Element {\n const { classes } = useStyles();\n const navigate = useMedplumNavigate();\n\n function onLinkClick(e: React.SyntheticEvent, to: string): void {\n e.stopPropagation();\n e.preventDefault();\n navigate(to);\n if (window.innerWidth < 768) {\n props.closeNavbar();\n }\n }\n\n function navigateResourceType(resourceType: string | undefined): void {\n if (resourceType) {\n navigate(`/${resourceType}`);\n }\n }\n\n return (\n <MantineNavbar width={{ sm: 250 }} p=\"xs\">\n <MantineNavbar.Section>\n <CodeInput\n key={window.location.pathname}\n name=\"resourceType\"\n placeholder=\"Resource Type\"\n property={{\n binding: {\n valueSet: 'http://hl7.org/fhir/ValueSet/resource-types',\n },\n }}\n onChange={(newValue) => navigateResourceType(newValue)}\n creatable={false}\n maxSelectedValues={0}\n clearSearchOnChange={true}\n clearable={false}\n />\n </MantineNavbar.Section>\n {props.menus && (\n <MantineNavbar.Section grow>\n {props.menus.map((menu) => (\n <React.Fragment key={`menu-${menu.title}`}>\n <Text className={classes.menuTitle}>{menu.title}</Text>\n {menu.links?.map((link) => (\n <NavbarLink key={link.href} to={link.href} onClick={(e) => onLinkClick(e, link.href)}>\n <NavLinkIcon to={link.href} icon={link.icon} />\n <span>{link.label}</span>\n </NavbarLink>\n ))}\n </React.Fragment>\n ))}\n </MantineNavbar.Section>\n )}\n </MantineNavbar>\n );\n}\n\ninterface NavbarLinkProps {\n to: string;\n onClick: React.MouseEventHandler;\n children: React.ReactNode;\n}\n\nfunction NavbarLink(props: NavbarLinkProps): JSX.Element {\n const { classes, cx } = useStyles();\n const location = useLocation();\n const [searchParams] = useSearchParams();\n const toUrl = new URL(props.to, window.location.protocol + '//' + window.location.host);\n const isActive = location.pathname === toUrl.pathname && matchesParams(searchParams, toUrl);\n\n return (\n <MedplumLink onClick={props.onClick} to={props.to} className={cx(classes.link, { [classes.linkActive]: isActive })}>\n {props.children}\n </MedplumLink>\n );\n}\n\n/**\n * Returns true if the search params match.\n * @param searchParams The current search params.\n * @param toUrl The destination URL of the link.\n * @returns True if the search params match.\n */\nfunction matchesParams(searchParams: URLSearchParams, toUrl: URL): boolean {\n for (const [key, value] of toUrl.searchParams.entries()) {\n if (searchParams.get(key) !== value) {\n return false;\n }\n }\n return true;\n}\n\ninterface NavLinkIconProps {\n to: string;\n icon?: JSX.Element;\n}\n\nfunction NavLinkIcon(props: NavLinkIconProps): JSX.Element {\n if (props.icon) {\n return props.icon;\n }\n return <Space w={30} />;\n}\n"],"names":["MantineNavbar"],"mappings":";;;;;;;AAOA,MAAM,SAAS,GAAG,YAAY,CAAC,CAAC,KAAK,KAAI;IACvC,OAAO;AACL,QAAA,SAAS,EAAE;AACT,YAAA,MAAM,EAAE,gBAAgB;AACxB,YAAA,QAAQ,EAAE,KAAK;AACf,YAAA,UAAU,EAAE,QAAQ;AACpB,YAAA,aAAa,EAAE,WAAW;AAC1B,YAAA,aAAa,EAAE,KAAK;AACrB,SAAA;AAED,QAAA,IAAI,EAAE;AACJ,YAAA,GAAG,KAAK,CAAC,EAAE,CAAC,WAAW,EAAE;AACzB,YAAA,OAAO,EAAE,MAAM;AACf,YAAA,UAAU,EAAE,QAAQ;AACpB,YAAA,cAAc,EAAE,MAAM;AACtB,YAAA,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC,EAAE;YAC5B,KAAK,EAAE,KAAK,CAAC,WAAW,KAAK,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;AACjF,YAAA,OAAO,EAAE,CAAU,QAAA,CAAA;AACnB,YAAA,YAAY,EAAE,KAAK,CAAC,MAAM,CAAC,EAAE;AAC7B,YAAA,UAAU,EAAE,GAAG;AAEf,YAAA,SAAS,EAAE;gBACT,eAAe,EAAE,KAAK,CAAC,WAAW,KAAK,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;AAC3F,gBAAA,KAAK,EAAE,KAAK,CAAC,WAAW,KAAK,MAAM,GAAG,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC,KAAK;AAC/D,gBAAA,cAAc,EAAE,MAAM;gBAEtB,CAAC,CAAA,KAAA,CAAO,GAAG;AACT,oBAAA,KAAK,EAAE,KAAK,CAAC,WAAW,KAAK,MAAM,GAAG,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC,KAAK;AAChE,iBAAA;AACF,aAAA;AAED,YAAA,OAAO,EAAE;gBACP,KAAK,EAAE,KAAK,CAAC,WAAW,KAAK,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;AACjF,gBAAA,WAAW,EAAE,KAAK,CAAC,OAAO,CAAC,EAAE;AAC7B,gBAAA,WAAW,EAAE,GAAG;AAChB,gBAAA,KAAK,EAAE,EAAE;AACT,gBAAA,MAAM,EAAE,EAAE;AACX,aAAA;AACF,SAAA;AAED,QAAA,UAAU,EAAE;AACV,YAAA,YAAY,EAAE;gBACZ,eAAe,EAAE,KAAK,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,CAAC,YAAY,EAAE,CAAC,CAAC,UAAU;gBAC7F,KAAK,EAAE,KAAK,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,CAAC,YAAY,EAAE,CAAC,CAAC,KAAK;gBAC9E,CAAC,CAAA,KAAA,CAAO,GAAG;oBACT,KAAK,EAAE,KAAK,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,CAAC,YAAY,EAAE,CAAC,CAAC,KAAK;AAC/E,iBAAA;AACF,aAAA;AACF,SAAA;KACF,CAAC;AACJ,CAAC,CAAC,CAAC;AAkBG,SAAU,MAAM,CAAC,KAAkB,EAAA;AACvC,IAAA,MAAM,EAAE,OAAO,EAAE,GAAG,SAAS,EAAE,CAAC;AAChC,IAAA,MAAM,QAAQ,GAAG,kBAAkB,EAAE,CAAC;AAEtC,IAAA,SAAS,WAAW,CAAC,CAAuB,EAAE,EAAU,EAAA;QACtD,CAAC,CAAC,eAAe,EAAE,CAAC;QACpB,CAAC,CAAC,cAAc,EAAE,CAAC;QACnB,QAAQ,CAAC,EAAE,CAAC,CAAC;AACb,QAAA,IAAI,MAAM,CAAC,UAAU,GAAG,GAAG,EAAE;YAC3B,KAAK,CAAC,WAAW,EAAE,CAAC;AACrB,SAAA;KACF;IAED,SAAS,oBAAoB,CAAC,YAAgC,EAAA;AAC5D,QAAA,IAAI,YAAY,EAAE;AAChB,YAAA,QAAQ,CAAC,CAAA,CAAA,EAAI,YAAY,CAAA,CAAE,CAAC,CAAC;AAC9B,SAAA;KACF;AAED,IAAA,QACE,KAAA,CAAA,aAAA,CAACA,QAAa,EAAA,EAAC,KAAK,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,CAAC,EAAC,IAAI,EAAA;QACvC,KAAC,CAAA,aAAA,CAAAA,QAAa,CAAC,OAAO,EAAA,IAAA;AACpB,YAAA,KAAA,CAAA,aAAA,CAAC,SAAS,EACR,EAAA,GAAG,EAAE,MAAM,CAAC,QAAQ,CAAC,QAAQ,EAC7B,IAAI,EAAC,cAAc,EACnB,WAAW,EAAC,eAAe,EAC3B,QAAQ,EAAE;AACR,oBAAA,OAAO,EAAE;AACP,wBAAA,QAAQ,EAAE,6CAA6C;AACxD,qBAAA;AACF,iBAAA,EACD,QAAQ,EAAE,CAAC,QAAQ,KAAK,oBAAoB,CAAC,QAAQ,CAAC,EACtD,SAAS,EAAE,KAAK,EAChB,iBAAiB,EAAE,CAAC,EACpB,mBAAmB,EAAE,IAAI,EACzB,SAAS,EAAE,KAAK,EAAA,CAChB,CACoB;AACvB,QAAA,KAAK,CAAC,KAAK,KACV,oBAACA,QAAa,CAAC,OAAO,EAAA,EAAC,IAAI,EACxB,IAAA,EAAA,EAAA,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,MACpB,oBAAC,KAAK,CAAC,QAAQ,EAAA,EAAC,GAAG,EAAE,CAAA,KAAA,EAAQ,IAAI,CAAC,KAAK,CAAE,CAAA,EAAA;YACvC,KAAC,CAAA,aAAA,CAAA,IAAI,EAAC,EAAA,SAAS,EAAE,OAAO,CAAC,SAAS,EAAG,EAAA,IAAI,CAAC,KAAK,CAAQ;AACtD,YAAA,IAAI,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,IAAI,MACpB,oBAAC,UAAU,EAAA,EAAC,GAAG,EAAE,IAAI,CAAC,IAAI,EAAE,EAAE,EAAE,IAAI,CAAC,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC,KAAK,WAAW,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,EAAA;AAClF,gBAAA,KAAA,CAAA,aAAA,CAAC,WAAW,EAAA,EAAC,EAAE,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAI,CAAA;AAC/C,gBAAA,KAAA,CAAA,aAAA,CAAA,MAAA,EAAA,IAAA,EAAO,IAAI,CAAC,KAAK,CAAQ,CACd,CACd,CAAC,CACa,CAClB,CAAC,CACoB,CACzB,CACa,EAChB;AACJ,CAAC;AAQD,SAAS,UAAU,CAAC,KAAsB,EAAA;IACxC,MAAM,EAAE,OAAO,EAAE,EAAE,EAAE,GAAG,SAAS,EAAE,CAAC;AACpC,IAAA,MAAM,QAAQ,GAAG,WAAW,EAAE,CAAC;AAC/B,IAAA,MAAM,CAAC,YAAY,CAAC,GAAG,eAAe,EAAE,CAAC;IACzC,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,EAAE,EAAE,MAAM,CAAC,QAAQ,CAAC,QAAQ,GAAG,IAAI,GAAG,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;AACxF,IAAA,MAAM,QAAQ,GAAG,QAAQ,CAAC,QAAQ,KAAK,KAAK,CAAC,QAAQ,IAAI,aAAa,CAAC,YAAY,EAAE,KAAK,CAAC,CAAC;AAE5F,IAAA,QACE,KAAC,CAAA,aAAA,CAAA,WAAW,IAAC,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,EAAE,EAAE,KAAK,CAAC,EAAE,EAAE,SAAS,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,UAAU,GAAG,QAAQ,EAAE,CAAC,EAC/G,EAAA,KAAK,CAAC,QAAQ,CACH,EACd;AACJ,CAAC;AAED;;;;;AAKG;AACH,SAAS,aAAa,CAAC,YAA6B,EAAE,KAAU,EAAA;AAC9D,IAAA,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,KAAK,CAAC,YAAY,CAAC,OAAO,EAAE,EAAE;QACvD,IAAI,YAAY,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,KAAK,EAAE;AACnC,YAAA,OAAO,KAAK,CAAC;AACd,SAAA;AACF,KAAA;AACD,IAAA,OAAO,IAAI,CAAC;AACd,CAAC;AAOD,SAAS,WAAW,CAAC,KAAuB,EAAA;IAC1C,IAAI,KAAK,CAAC,IAAI,EAAE;QACd,OAAO,KAAK,CAAC,IAAI,CAAC;AACnB,KAAA;AACD,IAAA,OAAO,oBAAC,KAAK,EAAA,EAAC,CAAC,EAAE,EAAE,GAAI,CAAC;AAC1B;;;;"}
|
|
1
|
+
{"version":3,"file":"Navbar.mjs","sources":["../../../src/AppShell/Navbar.tsx"],"sourcesContent":["import { Button, createStyles, Navbar as MantineNavbar, Space, Text } from '@mantine/core';\nimport { IconPlus } from '@tabler/icons-react';\nimport React, { useState } from 'react';\nimport { useLocation, useSearchParams } from 'react-router-dom';\nimport { BookmarkDialog } from '../BookmarkDialog/BookmarkDialog';\nimport { CodeInput } from '../CodeInput/CodeInput';\nimport { MedplumLink } from '../MedplumLink/MedplumLink';\nimport { useMedplumNavigate } from '../MedplumProvider/MedplumProvider';\n\nconst useStyles = createStyles((theme) => {\n return {\n menuTitle: {\n margin: '20px 0 4px 6px',\n fontSize: '9px',\n fontWeight: 'normal',\n textTransform: 'uppercase',\n letterSpacing: '2px',\n },\n\n link: {\n ...theme.fn.focusStyles(),\n display: 'flex',\n alignItems: 'center',\n textDecoration: 'none',\n fontSize: theme.fontSizes.sm,\n color: theme.colorScheme === 'dark' ? theme.colors.dark[1] : theme.colors.gray[7],\n padding: `8px 12px`,\n borderRadius: theme.radius.sm,\n fontWeight: 500,\n\n '&:hover': {\n backgroundColor: theme.colorScheme === 'dark' ? theme.colors.dark[6] : theme.colors.gray[0],\n color: theme.colorScheme === 'dark' ? theme.white : theme.black,\n textDecoration: 'none',\n\n [`& svg`]: {\n color: theme.colorScheme === 'dark' ? theme.white : theme.black,\n },\n },\n\n '& svg': {\n color: theme.colorScheme === 'dark' ? theme.colors.dark[2] : theme.colors.gray[6],\n marginRight: theme.spacing.sm,\n strokeWidth: 1.5,\n width: 18,\n height: 18,\n },\n },\n\n linkActive: {\n '&, &:hover': {\n backgroundColor: theme.fn.variant({ variant: 'light', color: theme.primaryColor }).background,\n color: theme.fn.variant({ variant: 'light', color: theme.primaryColor }).color,\n [`& svg`]: {\n color: theme.fn.variant({ variant: 'light', color: theme.primaryColor }).color,\n },\n },\n },\n };\n});\n\nexport interface NavbarLink {\n icon?: JSX.Element;\n label?: string;\n href: string;\n}\n\nexport interface NavbarMenu {\n title?: string;\n links?: NavbarLink[];\n}\n\nexport interface NavbarProps {\n menus?: NavbarMenu[];\n closeNavbar: () => void;\n displayAddBookmark?: boolean;\n}\n\nexport function Navbar(props: NavbarProps): JSX.Element {\n const { classes } = useStyles();\n const navigate = useMedplumNavigate();\n const [bookmarkDialogVisible, setBookmarkDialogVisible] = useState(false);\n\n function onLinkClick(e: React.SyntheticEvent, to: string): void {\n e.stopPropagation();\n e.preventDefault();\n navigate(to);\n if (window.innerWidth < 768) {\n props.closeNavbar();\n }\n }\n\n function navigateResourceType(resourceType: string | undefined): void {\n if (resourceType) {\n navigate(`/${resourceType}`);\n }\n }\n\n return (\n <>\n <MantineNavbar width={{ sm: 250 }} p=\"xs\">\n <MantineNavbar.Section mb=\"sm\">\n <CodeInput\n key={window.location.pathname}\n name=\"resourceType\"\n placeholder=\"Resource Type\"\n property={{\n binding: {\n valueSet: 'http://hl7.org/fhir/ValueSet/resource-types',\n },\n }}\n onChange={(newValue) => navigateResourceType(newValue)}\n creatable={false}\n maxSelectedValues={0}\n clearSearchOnChange={true}\n clearable={false}\n />\n </MantineNavbar.Section>\n <MantineNavbar.Section grow>\n {props.menus?.map((menu) => (\n <React.Fragment key={`menu-${menu.title}`}>\n <Text className={classes.menuTitle}>{menu.title}</Text>\n {menu.links?.map((link) => (\n <NavbarLink key={link.href} to={link.href} onClick={(e) => onLinkClick(e, link.href)}>\n <NavLinkIcon to={link.href} icon={link.icon} />\n <span>{link.label}</span>\n </NavbarLink>\n ))}\n </React.Fragment>\n ))}\n {props.displayAddBookmark && (\n <Button\n variant=\"subtle\"\n size=\"xs\"\n mt=\"xl\"\n leftIcon={<IconPlus size=\"0.75rem\" />}\n onClick={() => setBookmarkDialogVisible(true)}\n >\n Add Bookmark\n </Button>\n )}\n </MantineNavbar.Section>\n </MantineNavbar>\n <BookmarkDialog\n visible={bookmarkDialogVisible}\n onOk={() => setBookmarkDialogVisible(false)}\n onCancel={() => setBookmarkDialogVisible(false)}\n />\n </>\n );\n}\ninterface NavbarLinkProps {\n to: string;\n onClick: React.MouseEventHandler;\n children: React.ReactNode;\n}\n\nfunction NavbarLink(props: NavbarLinkProps): JSX.Element {\n const { classes, cx } = useStyles();\n const location = useLocation();\n const [searchParams] = useSearchParams();\n const toUrl = new URL(props.to, window.location.protocol + '//' + window.location.host);\n const isActive = location.pathname === toUrl.pathname && matchesParams(searchParams, toUrl);\n\n return (\n <MedplumLink onClick={props.onClick} to={props.to} className={cx(classes.link, { [classes.linkActive]: isActive })}>\n {props.children}\n </MedplumLink>\n );\n}\n\n/**\n * Returns true if the search params match.\n * @param searchParams The current search params.\n * @param toUrl The destination URL of the link.\n * @returns True if the search params match.\n */\nfunction matchesParams(searchParams: URLSearchParams, toUrl: URL): boolean {\n for (const [key, value] of toUrl.searchParams.entries()) {\n if (searchParams.get(key) !== value) {\n return false;\n }\n }\n return true;\n}\n\ninterface NavLinkIconProps {\n to: string;\n icon?: JSX.Element;\n}\n\nfunction NavLinkIcon(props: NavLinkIconProps): JSX.Element {\n if (props.icon) {\n return props.icon;\n }\n return <Space w={30} />;\n}\n"],"names":["MantineNavbar"],"mappings":"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"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { Modal, Stack, TextInput, Group, Button, NativeSelect } from '@mantine/core';
|
|
2
|
+
import { showNotification } from '@mantine/notifications';
|
|
3
|
+
import { deepClone, normalizeErrorString } from '@medplum/core';
|
|
4
|
+
import React from 'react';
|
|
5
|
+
import { useLocation } from 'react-router-dom';
|
|
6
|
+
import { Form } from '../Form/Form.mjs';
|
|
7
|
+
import { useMedplum } from '../MedplumProvider/MedplumProvider.mjs';
|
|
8
|
+
|
|
9
|
+
function BookmarkDialog(props) {
|
|
10
|
+
const medplum = useMedplum();
|
|
11
|
+
const config = medplum.getUserConfiguration();
|
|
12
|
+
const location = useLocation();
|
|
13
|
+
function submitHandler(formData) {
|
|
14
|
+
const { menuname, bookmarkname: name } = formData;
|
|
15
|
+
const target = location.pathname + location.search;
|
|
16
|
+
const newConfig = deepClone(config);
|
|
17
|
+
const menu = newConfig?.menu?.find(({ title }) => title === menuname);
|
|
18
|
+
menu?.link?.push({ name, target });
|
|
19
|
+
medplum
|
|
20
|
+
.updateResource(newConfig)
|
|
21
|
+
.then((res) => {
|
|
22
|
+
// refresh current config menu
|
|
23
|
+
config.menu = res.menu;
|
|
24
|
+
medplum.dispatchEvent({ type: 'change' });
|
|
25
|
+
showNotification({ color: 'green', message: 'Success' });
|
|
26
|
+
props.onOk();
|
|
27
|
+
})
|
|
28
|
+
.catch((err) => {
|
|
29
|
+
showNotification({ color: 'red', message: normalizeErrorString(err) });
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
return (React.createElement(Modal, { title: "Add Bookmark", closeButtonProps: { 'aria-label': 'Close' }, opened: props.visible, onClose: props.onCancel },
|
|
33
|
+
React.createElement(Form, { onSubmit: submitHandler },
|
|
34
|
+
React.createElement(Stack, null,
|
|
35
|
+
React.createElement(SelectMenu, { config: config }),
|
|
36
|
+
React.createElement(TextInput, { label: "Bookmark Name", type: "text", name: "bookmarkname", placeholder: "bookmark name", withAsterisk: true }),
|
|
37
|
+
React.createElement(Group, { position: "right" },
|
|
38
|
+
React.createElement(Button, { mt: "sm", type: "submit" }, "OK"))))));
|
|
39
|
+
}
|
|
40
|
+
function SelectMenu(props) {
|
|
41
|
+
function userConfigToMenu(config) {
|
|
42
|
+
return config?.menu?.map((menu) => menu.title);
|
|
43
|
+
}
|
|
44
|
+
const menus = userConfigToMenu(props.config);
|
|
45
|
+
return (React.createElement(NativeSelect, { name: "menuname", defaultValue: menus?.[0], label: "Select Menu Option", placeholder: "Menu", data: menus, withAsterisk: true }));
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export { BookmarkDialog };
|
|
49
|
+
//# sourceMappingURL=BookmarkDialog.mjs.map
|
|
@@ -0,0 +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 { useLocation } from 'react-router-dom';\nimport { Form } from '../Form/Form';\nimport { useMedplum } from '../MedplumProvider/MedplumProvider';\n\ninterface BookmarkDialogProps {\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 const location = useLocation();\n function submitHandler(formData: Record<string, string>): void {\n const { menuname, bookmarkname: name } = formData;\n const target = location.pathname + location.search;\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":";;;;;;;;AAeM,SAAU,cAAc,CAAC,KAA0B,EAAA;AACvD,IAAA,MAAM,OAAO,GAAG,UAAU,EAAE,CAAC;AAC7B,IAAA,MAAM,MAAM,GAAG,OAAO,CAAC,oBAAoB,EAAuB,CAAC;AACnE,IAAA,MAAM,QAAQ,GAAG,WAAW,EAAE,CAAC;IAC/B,SAAS,aAAa,CAAC,QAAgC,EAAA;QACrD,MAAM,EAAE,QAAQ,EAAE,YAAY,EAAE,IAAI,EAAE,GAAG,QAAQ,CAAC;QAClD,MAAM,MAAM,GAAG,QAAQ,CAAC,QAAQ,GAAG,QAAQ,CAAC,MAAM,CAAC;AACnD,QAAA,MAAM,SAAS,GAAG,SAAS,CAAC,MAAM,CAAsB,CAAC;AACzD,QAAA,MAAM,IAAI,GAAG,SAAS,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,KAAK,KAAK,QAAQ,CAAC,CAAC;QAEtE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;QACnC,OAAO;aACJ,cAAc,CAAC,SAAS,CAAC;AACzB,aAAA,IAAI,CAAC,CAAC,GAAG,KAAI;;AAEZ,YAAA,MAAM,CAAC,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC;YACvB,OAAO,CAAC,aAAa,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC;YAC1C,gBAAgB,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,CAAC,CAAC;YACzD,KAAK,CAAC,IAAI,EAAE,CAAC;AACf,SAAC,CAAC;AACD,aAAA,KAAK,CAAC,CAAC,GAAQ,KAAI;AAClB,YAAA,gBAAgB,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,oBAAoB,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;AACzE,SAAC,CAAC,CAAC;KACN;IAED,QACE,KAAC,CAAA,aAAA,CAAA,KAAK,EACJ,EAAA,KAAK,EAAC,cAAc,EACpB,gBAAgB,EAAE,EAAE,YAAY,EAAE,OAAO,EAAE,EAC3C,MAAM,EAAE,KAAK,CAAC,OAAO,EACrB,OAAO,EAAE,KAAK,CAAC,QAAQ,EAAA;AAEvB,QAAA,KAAA,CAAA,aAAA,CAAC,IAAI,EAAA,EAAC,QAAQ,EAAE,aAAa,EAAA;AAC3B,YAAA,KAAA,CAAA,aAAA,CAAC,KAAK,EAAA,IAAA;AACJ,gBAAA,KAAA,CAAA,aAAA,CAAC,UAAU,EAAA,EAAC,MAAM,EAAE,MAAM,EAAe,CAAA;AACzC,gBAAA,KAAA,CAAA,aAAA,CAAC,SAAS,EAAC,EAAA,KAAK,EAAC,eAAe,EAAC,IAAI,EAAC,MAAM,EAAC,IAAI,EAAC,cAAc,EAAC,WAAW,EAAC,eAAe,EAAC,YAAY,EAAG,IAAA,EAAA,CAAA;AAC5G,gBAAA,KAAA,CAAA,aAAA,CAAC,KAAK,EAAA,EAAC,QAAQ,EAAC,OAAO,EAAA;AACrB,oBAAA,KAAA,CAAA,aAAA,CAAC,MAAM,EAAA,EAAC,EAAE,EAAC,IAAI,EAAC,IAAI,EAAC,QAAQ,SAEpB,CACH,CACF,CACH,CACD,EACR;AACJ,CAAC;AAMD,SAAS,UAAU,CAAC,KAAsB,EAAA;IACxC,SAAS,gBAAgB,CAAC,MAAqC,EAAA;AAC7D,QAAA,OAAO,MAAM,EAAE,IAAI,EAAE,GAAG,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,KAAK,CAAO,CAAC;KACtD;IACD,MAAM,KAAK,GAAG,gBAAgB,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;AAE7C,IAAA,QACE,KAAA,CAAA,aAAA,CAAC,YAAY,EAAA,EACX,IAAI,EAAC,UAAU,EACf,YAAY,EAAE,KAAK,GAAG,CAAC,CAAC,EACxB,KAAK,EAAC,oBAAoB,EAC1B,WAAW,EAAC,MAAM,EAClB,IAAI,EAAE,KAAK,EACX,YAAY,EAAA,IAAA,EAAA,CACZ,EACF;AACJ;;;;"}
|
|
@@ -3,7 +3,12 @@ import { ResourceTimeline } from '../ResourceTimeline/ResourceTimeline.mjs';
|
|
|
3
3
|
|
|
4
4
|
function DefaultResourceTimeline(props) {
|
|
5
5
|
return (React.createElement(ResourceTimeline, { value: props.resource, loadTimelineResources: async (medplum, resourceType, id) => {
|
|
6
|
-
|
|
6
|
+
const ref = `${resourceType}/${id}`;
|
|
7
|
+
const _count = 100;
|
|
8
|
+
return Promise.allSettled([
|
|
9
|
+
medplum.readHistory(resourceType, id),
|
|
10
|
+
medplum.search('Task', { _filter: `based-on eq ${ref} or focus eq ${ref} or subject eq ${ref}`, _count }),
|
|
11
|
+
]);
|
|
7
12
|
} }));
|
|
8
13
|
}
|
|
9
14
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DefaultResourceTimeline.mjs","sources":["../../../src/DefaultResourceTimeline/DefaultResourceTimeline.tsx"],"sourcesContent":["import { MedplumClient } from '@medplum/core';\nimport { Reference, Resource, ResourceType } from '@medplum/fhirtypes';\nimport React from 'react';\nimport { ResourceTimeline } from '../ResourceTimeline/ResourceTimeline';\n\nexport interface DefaultResourceTimelineProps {\n resource: Resource | Reference;\n}\n\nexport function DefaultResourceTimeline(props: DefaultResourceTimelineProps): JSX.Element {\n return (\n <ResourceTimeline\n value={props.resource}\n loadTimelineResources={async (medplum: MedplumClient, resourceType: ResourceType, id: string) => {\n return Promise.allSettled([medplum.readHistory(resourceType, id)]);\n }}\n />\n );\n}\n"],"names":[],"mappings":";;;AASM,SAAU,uBAAuB,CAAC,KAAmC,EAAA;IACzE,QACE,oBAAC,gBAAgB,EAAA,EACf,KAAK,EAAE,KAAK,CAAC,QAAQ,EACrB,qBAAqB,EAAE,OAAO,OAAsB,EAAE,YAA0B,EAAE,EAAU,KAAI;AAC9F,YAAA,OAAO,OAAO,CAAC,UAAU,CAAC,
|
|
1
|
+
{"version":3,"file":"DefaultResourceTimeline.mjs","sources":["../../../src/DefaultResourceTimeline/DefaultResourceTimeline.tsx"],"sourcesContent":["import { MedplumClient } from '@medplum/core';\nimport { Reference, Resource, ResourceType } from '@medplum/fhirtypes';\nimport React from 'react';\nimport { ResourceTimeline } from '../ResourceTimeline/ResourceTimeline';\n\nexport interface DefaultResourceTimelineProps {\n resource: Resource | Reference;\n}\n\nexport function DefaultResourceTimeline(props: DefaultResourceTimelineProps): JSX.Element {\n return (\n <ResourceTimeline\n value={props.resource}\n loadTimelineResources={async (medplum: MedplumClient, resourceType: ResourceType, id: string) => {\n const ref = `${resourceType}/${id}`;\n const _count = 100;\n return Promise.allSettled([\n medplum.readHistory(resourceType, id),\n medplum.search('Task', { _filter: `based-on eq ${ref} or focus eq ${ref} or subject eq ${ref}`, _count }),\n ]);\n }}\n />\n );\n}\n"],"names":[],"mappings":";;;AASM,SAAU,uBAAuB,CAAC,KAAmC,EAAA;IACzE,QACE,oBAAC,gBAAgB,EAAA,EACf,KAAK,EAAE,KAAK,CAAC,QAAQ,EACrB,qBAAqB,EAAE,OAAO,OAAsB,EAAE,YAA0B,EAAE,EAAU,KAAI;AAC9F,YAAA,MAAM,GAAG,GAAG,CAAA,EAAG,YAAY,CAAI,CAAA,EAAA,EAAE,EAAE,CAAC;YACpC,MAAM,MAAM,GAAG,GAAG,CAAC;YACnB,OAAO,OAAO,CAAC,UAAU,CAAC;AACxB,gBAAA,OAAO,CAAC,WAAW,CAAC,YAAY,EAAE,EAAE,CAAC;AACrC,gBAAA,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,EAAE,OAAO,EAAE,CAAA,YAAA,EAAe,GAAG,CAAA,aAAA,EAAgB,GAAG,CAAkB,eAAA,EAAA,GAAG,EAAE,EAAE,MAAM,EAAE,CAAC;AAC1G,aAAA,CAAC,CAAC;SACJ,EAAA,CACD,EACF;AACJ;;;;"}
|
|
@@ -3,15 +3,18 @@ import React, { useCallback } from 'react';
|
|
|
3
3
|
import { ResourceTimeline } from '../ResourceTimeline/ResourceTimeline.mjs';
|
|
4
4
|
|
|
5
5
|
function PatientTimeline(props) {
|
|
6
|
-
const loadTimelineResources = useCallback((medplum,
|
|
6
|
+
const loadTimelineResources = useCallback((medplum, resourceType, id) => {
|
|
7
|
+
const ref = `${resourceType}/${id}`;
|
|
8
|
+
const _count = 100;
|
|
7
9
|
return Promise.allSettled([
|
|
8
10
|
medplum.readHistory('Patient', id),
|
|
9
|
-
medplum.search('Communication',
|
|
10
|
-
medplum.search('Device',
|
|
11
|
-
medplum.search('DeviceRequest',
|
|
12
|
-
medplum.search('DiagnosticReport',
|
|
13
|
-
medplum.search('Media',
|
|
14
|
-
medplum.search('ServiceRequest',
|
|
11
|
+
medplum.search('Communication', { subject: ref, _count }),
|
|
12
|
+
medplum.search('Device', { patient: ref, _count }),
|
|
13
|
+
medplum.search('DeviceRequest', { patient: ref, _count }),
|
|
14
|
+
medplum.search('DiagnosticReport', { subject: ref, _count }),
|
|
15
|
+
medplum.search('Media', { subject: ref, _count }),
|
|
16
|
+
medplum.search('ServiceRequest', { subject: ref, _count }),
|
|
17
|
+
medplum.search('Task', { subject: ref, _count }),
|
|
15
18
|
]);
|
|
16
19
|
}, []);
|
|
17
20
|
return (React.createElement(ResourceTimeline, { value: props.patient, loadTimelineResources: loadTimelineResources, createCommunication: (resource, sender, text) => ({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PatientTimeline.mjs","sources":["../../../src/PatientTimeline/PatientTimeline.tsx"],"sourcesContent":["import { createReference, MedplumClient, ProfileResource } from '@medplum/core';\nimport { Attachment, Patient, Reference, ResourceType } from '@medplum/fhirtypes';\nimport React, { useCallback } from 'react';\nimport { ResourceTimeline } from '../ResourceTimeline/ResourceTimeline';\n\nexport interface PatientTimelineProps {\n patient: Patient | Reference<Patient>;\n}\n\nexport function PatientTimeline(props: PatientTimelineProps): JSX.Element {\n const loadTimelineResources = useCallback((medplum: MedplumClient,
|
|
1
|
+
{"version":3,"file":"PatientTimeline.mjs","sources":["../../../src/PatientTimeline/PatientTimeline.tsx"],"sourcesContent":["import { createReference, MedplumClient, ProfileResource } from '@medplum/core';\nimport { Attachment, Patient, Reference, ResourceType } from '@medplum/fhirtypes';\nimport React, { useCallback } from 'react';\nimport { ResourceTimeline } from '../ResourceTimeline/ResourceTimeline';\n\nexport interface PatientTimelineProps {\n patient: Patient | Reference<Patient>;\n}\n\nexport function PatientTimeline(props: PatientTimelineProps): JSX.Element {\n const loadTimelineResources = useCallback((medplum: MedplumClient, resourceType: ResourceType, id: string) => {\n const ref = `${resourceType}/${id}`;\n const _count = 100;\n return Promise.allSettled([\n medplum.readHistory('Patient', id),\n medplum.search('Communication', { subject: ref, _count }),\n medplum.search('Device', { patient: ref, _count }),\n medplum.search('DeviceRequest', { patient: ref, _count }),\n medplum.search('DiagnosticReport', { subject: ref, _count }),\n medplum.search('Media', { subject: ref, _count }),\n medplum.search('ServiceRequest', { subject: ref, _count }),\n medplum.search('Task', { subject: ref, _count }),\n ]);\n }, []);\n\n return (\n <ResourceTimeline\n value={props.patient}\n loadTimelineResources={loadTimelineResources}\n createCommunication={(resource: Patient, sender: ProfileResource, text: string) => ({\n resourceType: 'Communication',\n status: 'completed',\n subject: createReference(resource),\n sender: createReference(sender),\n sent: new Date().toISOString(),\n payload: [{ contentString: text }],\n })}\n createMedia={(resource: Patient, operator: ProfileResource, content: Attachment) => ({\n resourceType: 'Media',\n status: 'completed',\n subject: createReference(resource),\n operator: createReference(operator),\n issued: new Date().toISOString(),\n content,\n })}\n />\n );\n}\n"],"names":[],"mappings":";;;;AASM,SAAU,eAAe,CAAC,KAA2B,EAAA;IACzD,MAAM,qBAAqB,GAAG,WAAW,CAAC,CAAC,OAAsB,EAAE,YAA0B,EAAE,EAAU,KAAI;AAC3G,QAAA,MAAM,GAAG,GAAG,CAAA,EAAG,YAAY,CAAI,CAAA,EAAA,EAAE,EAAE,CAAC;QACpC,MAAM,MAAM,GAAG,GAAG,CAAC;QACnB,OAAO,OAAO,CAAC,UAAU,CAAC;AACxB,YAAA,OAAO,CAAC,WAAW,CAAC,SAAS,EAAE,EAAE,CAAC;AAClC,YAAA,OAAO,CAAC,MAAM,CAAC,eAAe,EAAE,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC;AACzD,YAAA,OAAO,CAAC,MAAM,CAAC,QAAQ,EAAE,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC;AAClD,YAAA,OAAO,CAAC,MAAM,CAAC,eAAe,EAAE,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC;AACzD,YAAA,OAAO,CAAC,MAAM,CAAC,kBAAkB,EAAE,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC;AAC5D,YAAA,OAAO,CAAC,MAAM,CAAC,OAAO,EAAE,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC;AACjD,YAAA,OAAO,CAAC,MAAM,CAAC,gBAAgB,EAAE,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC;AAC1D,YAAA,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC;AACjD,SAAA,CAAC,CAAC;KACJ,EAAE,EAAE,CAAC,CAAC;IAEP,QACE,KAAC,CAAA,aAAA,CAAA,gBAAgB,EACf,EAAA,KAAK,EAAE,KAAK,CAAC,OAAO,EACpB,qBAAqB,EAAE,qBAAqB,EAC5C,mBAAmB,EAAE,CAAC,QAAiB,EAAE,MAAuB,EAAE,IAAY,MAAM;AAClF,YAAA,YAAY,EAAE,eAAe;AAC7B,YAAA,MAAM,EAAE,WAAW;AACnB,YAAA,OAAO,EAAE,eAAe,CAAC,QAAQ,CAAC;AAClC,YAAA,MAAM,EAAE,eAAe,CAAC,MAAM,CAAC;AAC/B,YAAA,IAAI,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;AAC9B,YAAA,OAAO,EAAE,CAAC,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC;AACnC,SAAA,CAAC,EACF,WAAW,EAAE,CAAC,QAAiB,EAAE,QAAyB,EAAE,OAAmB,MAAM;AACnF,YAAA,YAAY,EAAE,OAAO;AACrB,YAAA,MAAM,EAAE,WAAW;AACnB,YAAA,OAAO,EAAE,eAAe,CAAC,QAAQ,CAAC;AAClC,YAAA,QAAQ,EAAE,eAAe,CAAC,QAAQ,CAAC;AACnC,YAAA,MAAM,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YAChC,OAAO;SACR,CAAC,EAAA,CACF,EACF;AACJ;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SearchUtils.mjs","sources":["../../../src/SearchControl/SearchUtils.tsx"],"sourcesContent":["import {\n capitalize,\n DEFAULT_SEARCH_COUNT,\n evalFhirPathTyped,\n Filter,\n formatDateTime,\n Operator,\n PropertyType,\n SearchRequest,\n} from '@medplum/core';\nimport { ElementDefinition, Resource, SearchParameter } from '@medplum/fhirtypes';\nimport React from 'react';\nimport { getValueAndType, ResourcePropertyDisplay } from '../ResourcePropertyDisplay/ResourcePropertyDisplay';\nimport { SearchControlField } from './SearchControlField';\n\nconst searchParamToOperators: Record<string, Operator[]> = {\n string: [Operator.EQUALS, Operator.NOT, Operator.CONTAINS, Operator.EXACT],\n fulltext: [Operator.EQUALS, Operator.NOT, Operator.CONTAINS, Operator.EXACT],\n token: [Operator.EQUALS, Operator.NOT],\n reference: [Operator.EQUALS, Operator.NOT],\n numeric: [\n Operator.EQUALS,\n Operator.NOT_EQUALS,\n Operator.GREATER_THAN,\n Operator.LESS_THAN,\n Operator.GREATER_THAN_OR_EQUALS,\n Operator.LESS_THAN_OR_EQUALS,\n ],\n quantity: [\n Operator.EQUALS,\n Operator.NOT_EQUALS,\n Operator.GREATER_THAN,\n Operator.LESS_THAN,\n Operator.GREATER_THAN_OR_EQUALS,\n Operator.LESS_THAN_OR_EQUALS,\n ],\n date: [\n Operator.EQUALS,\n Operator.NOT_EQUALS,\n Operator.GREATER_THAN,\n Operator.LESS_THAN,\n Operator.GREATER_THAN_OR_EQUALS,\n Operator.LESS_THAN_OR_EQUALS,\n Operator.STARTS_AFTER,\n Operator.ENDS_BEFORE,\n Operator.APPROXIMATELY,\n ],\n datetime: [\n Operator.EQUALS,\n Operator.NOT_EQUALS,\n Operator.GREATER_THAN,\n Operator.LESS_THAN,\n Operator.GREATER_THAN_OR_EQUALS,\n Operator.LESS_THAN_OR_EQUALS,\n Operator.STARTS_AFTER,\n Operator.ENDS_BEFORE,\n Operator.APPROXIMATELY,\n ],\n};\n\nconst operatorNames: Record<Operator, string> = {\n eq: 'equals',\n ne: 'not equals',\n gt: 'greater than',\n lt: 'less than',\n ge: 'greater than or equals',\n le: 'less than or equals',\n sa: 'starts after',\n eb: 'ends before',\n ap: 'approximately',\n contains: 'contains',\n exact: 'exact',\n text: 'text',\n not: 'not',\n above: 'above',\n below: 'below',\n in: 'in',\n 'not-in': 'not in',\n 'of-type': 'of type',\n missing: 'missing',\n identifier: 'identifier',\n};\n\n/**\n * Sets the array of filters.\n *\n * @param {Array} filters The new filters.\n */\nexport function setFilters(definition: SearchRequest, filters: Filter[]): SearchRequest {\n return {\n ...definition,\n filters: filters,\n offset: 0,\n name: undefined,\n };\n}\n\n/**\n * Clears all of the filters.\n */\nexport function clearFilters(definition: SearchRequest): SearchRequest {\n return setFilters(definition, []);\n}\n\n/**\n * Clears all of the filters on a certain field.\n *\n * @param {string} code The field key name to clear filters.\n */\nexport function clearFiltersOnField(definition: SearchRequest, code: string): SearchRequest {\n return setFilters(\n definition,\n (definition.filters || []).filter((f) => f.code !== code)\n );\n}\n\n/**\n * Adds a filter.\n *\n * @param {string} field The field key name.\n * @param {Operator} op The operation key name.\n * @param {?string} value The filter value.\n * @param {boolean=} opt_clear Optional flag to clear filters on the field.\n */\nexport function addFilter(\n definition: SearchRequest,\n field: string,\n op: Operator,\n value?: string,\n opt_clear?: boolean\n): SearchRequest {\n if (opt_clear) {\n definition = clearFiltersOnField(definition, field);\n }\n\n const nextFilters: Filter[] = [];\n if (definition.filters) {\n nextFilters.push(...definition.filters);\n }\n nextFilters.push({ code: field, operator: op, value: value || '' });\n\n return setFilters(definition, nextFilters);\n}\n\n/**\n * Adds a field.\n *\n * @param {string} field The field key name.\n */\nexport function addField(definition: SearchRequest, field: string): SearchRequest {\n if (definition.fields && definition.fields.includes(field)) {\n return definition;\n }\n const newFields = [];\n if (definition.fields) {\n newFields.push(...definition.fields);\n }\n newFields.push(field);\n return {\n ...definition,\n fields: newFields,\n name: undefined,\n };\n}\n\n/**\n * Deletes a filter at the specified index.\n *\n * @param {number} index The filter index.\n */\nexport function deleteFilter(definition: SearchRequest, index: number): SearchRequest {\n if (!definition.filters) {\n return definition;\n }\n const newFilters = [...definition.filters];\n newFilters.splice(index, 1);\n return {\n ...definition,\n filters: newFilters,\n name: undefined,\n };\n}\n\n/**\n * Adds a filter that constrains the specified field to \"yesterday\".\n *\n * @param {string} field The field key name.\n */\nexport function addYesterdayFilter(definition: SearchRequest, field: string): SearchRequest {\n return addDayFilter(definition, field, -1);\n}\n\n/**\n * Adds a filter that constrains the specified field to \"today\".\n *\n * @param {string} field The field key name.\n */\nexport function addTodayFilter(definition: SearchRequest, field: string): SearchRequest {\n return addDayFilter(definition, field, 0);\n}\n\n/**\n * Adds a filter that constrains the specified field to \"tomorrow\".\n *\n * @param {string} field The field key name.\n */\nexport function addTomorrowFilter(definition: SearchRequest, field: string): SearchRequest {\n return addDayFilter(definition, field, 1);\n}\n\n/**\n * Adds a filter that constrains the specified field to a day.\n * The day is specified as a delta from the current day.\n * \"Today\" would be 0.\n * \"Yesterday\" would be -1.\n * \"Tomorrow\" would be 1.\n *\n * @param {string} field The field key name.\n * @param {number} delta The number of days from this day.\n */\nfunction addDayFilter(definition: SearchRequest, field: string, delta: number): SearchRequest {\n const startTime = new Date();\n startTime.setDate(startTime.getDate() + delta);\n startTime.setHours(0, 0, 0, 0);\n\n const endTime = new Date(startTime.getTime());\n endTime.setDate(endTime.getDate() + 1);\n endTime.setTime(endTime.getTime() - 1);\n\n return addDateFilterBetween(definition, field, startTime, endTime);\n}\n\n/**\n * Adds a filter that constrains the specified field to \"last month\".\n *\n * @param {string} field The field key name.\n */\nexport function addLastMonthFilter(definition: SearchRequest, field: string): SearchRequest {\n return addMonthFilter(definition, field, -1);\n}\n\n/**\n * Adds a filter that constrains the specified field to \"this month\".\n *\n * @param {string} field The field key name.\n */\nexport function addThisMonthFilter(definition: SearchRequest, field: string): SearchRequest {\n return addMonthFilter(definition, field, 0);\n}\n\n/**\n * Adds a filter that constrains the specified field to \"next month\".\n *\n * @param {string} field The field key name.\n */\nexport function addNextMonthFilter(definition: SearchRequest, field: string): SearchRequest {\n return addMonthFilter(definition, field, 1);\n}\n\n/**\n * Adds a filter that constrains the specified field to a month.\n * The month is specified as a delta from the current month.\n * \"This month\" would be 0.\n * \"Last month\" would be -1.\n * \"Next month\" would be 1.\n *\n * @param {string} field The field key name.\n * @param {number} delta The number of months from this month.\n */\nfunction addMonthFilter(definition: SearchRequest, field: string, delta: number): SearchRequest {\n const startTime = new Date();\n startTime.setMonth(startTime.getMonth() + delta);\n startTime.setDate(1);\n startTime.setHours(0, 0, 0, 0);\n\n const endTime = new Date(startTime.getTime());\n endTime.setMonth(endTime.getMonth() + 1);\n endTime.setDate(1);\n endTime.setHours(0, 0, 0, 0);\n endTime.setTime(endTime.getTime() - 1);\n\n return addDateFilterBetween(definition, field, startTime, endTime);\n}\n\n/**\n * Adds a filter that constrains the specified field to the year to date.\n *\n * @param {string} field The field key name.\n */\nexport function addYearToDateFilter(definition: SearchRequest, field: string): SearchRequest {\n const startTime = new Date();\n startTime.setMonth(0);\n startTime.setDate(1);\n startTime.setHours(0, 0, 0, 0);\n\n const endTime = new Date();\n\n return addDateFilterBetween(definition, field, startTime, endTime);\n}\n\n/**\n * Adds a filter for a date between two dates (inclusive of both dates).\n *\n * @param {string} field The field key name.\n * @param {Date} d1 The start date.\n * @param {Date} d2 The end date.\n */\nexport function addDateFilterBetween(definition: SearchRequest, field: string, d1: Date, d2: Date): SearchRequest {\n definition = clearFiltersOnField(definition, field);\n definition = addDateFilterImpl(definition, field, Operator.GREATER_THAN_OR_EQUALS, d1);\n definition = addDateFilterImpl(definition, field, Operator.LESS_THAN_OR_EQUALS, d2);\n return definition;\n}\n\n/**\n * Adds a filter for a date before a certain date/time.\n *\n * @param {string} field The field key name.\n * @param {Operator} op The date/time operation.\n * @param {Date} value The date.\n */\nfunction addDateFilterImpl(definition: SearchRequest, field: string, op: Operator, value: Date): SearchRequest {\n return addFilter(definition, field, op, value.toISOString());\n}\n\n/**\n * Adds a filter that constrains the specified field to \"missing\".\n *\n * @param {string} field The field key name.\n */\nexport function addMissingFilter(definition: SearchRequest, field: string, value = true): SearchRequest {\n return addFilter(definition, field, Operator.MISSING, value.toString());\n}\n\n/**\n * Sets the offset (starting at zero).\n *\n * @param {number} offset The offset number.\n */\nexport function setOffset(definition: SearchRequest, offset: number): SearchRequest {\n if (definition.offset === offset) {\n return definition;\n }\n return {\n ...definition,\n offset,\n name: undefined,\n };\n}\n\n/**\n * Creates a new search request with the search offset at the specified page.\n * @param definition The search definition.\n * @param page The new page number\n * @return The new search definition.\n */\nexport function setPage(definition: SearchRequest, page: number): SearchRequest {\n const count = definition.count ?? DEFAULT_SEARCH_COUNT;\n const newOffset = (page - 1) * count;\n return setOffset(definition, newOffset);\n}\n\n/**\n * Sorts the search by the specified key, and optional direction.\n * Direction defaults to ascending ('asc') if not specified.\n *\n * @param {string} sortField The sort key.\n */\nexport function setSort(definition: SearchRequest, sort: string, desc?: boolean): SearchRequest {\n if (sort === getSortField(definition) && desc !== undefined && desc === isSortDescending(definition)) {\n return definition;\n }\n return {\n ...definition,\n sortRules: [\n {\n code: sort,\n descending: !!desc,\n },\n ],\n name: undefined,\n };\n}\n\n/**\n * Toggles the sort of the search by key.\n * If the search is already sorted by the key, reverses the direction.\n * If the search is not sorted by the key, sort in ascending order.\n *\n * @param {string} key The field key name.\n */\nexport function toggleSort(definition: SearchRequest, key: string): SearchRequest {\n let desc = false;\n if (getSortField(definition) === key) {\n desc = !isSortDescending(definition);\n }\n return setSort(definition, key, desc);\n}\n\nexport function getSortField(definition: SearchRequest): string | undefined {\n const sortRules = definition.sortRules;\n if (!sortRules || sortRules.length === 0) {\n return undefined;\n }\n const field = sortRules[0].code;\n return field.startsWith('-') ? field.substr(1) : field;\n}\n\nexport function isSortDescending(definition: SearchRequest): boolean {\n const sortRules = definition.sortRules;\n if (!sortRules || sortRules.length === 0) {\n return false;\n }\n return !!sortRules[0].descending;\n}\n\n/**\n * Returns a list of operators for a search parameter.\n * @param searchParam The search parameter.\n * @returns The list of operators that can be used for the search parameter.\n */\nexport function getSearchOperators(searchParam: SearchParameter): Operator[] | undefined {\n return searchParamToOperators[searchParam.type as string];\n}\n\n/**\n * Returns a string representing the operation.\n *\n * @param {string} op The operation code.\n * @return {string} A display string for the operation.\n */\nexport function getOpString(op: Operator): string {\n return operatorNames[op] ?? '';\n}\n\n/**\n * Returns a field display name.\n * @param key The field key.\n * @returns The field display name.\n */\nexport function buildFieldNameString(key: string): string {\n let tmp = key;\n\n // If dot separated, only the last part\n if (tmp.includes('.')) {\n tmp = tmp.split('.').pop() as string;\n }\n\n // Special case for ID\n if (tmp === 'id') {\n return 'ID';\n }\n\n // Special case for Version ID\n if (tmp === 'versionId') {\n return 'Version ID';\n }\n\n // Remove choice of type\n tmp = tmp.replace('[x]', '');\n\n // Convert camel case to space separated\n tmp = tmp.replace(/([A-Z])/g, ' $1');\n\n // Convert dashes and underscores to spaces\n tmp = tmp.replace(/[-_]/g, ' ');\n\n // Normalize whitespace to single space character\n tmp = tmp.replace(/\\s+/g, ' ');\n\n // Trim\n tmp = tmp.trim();\n\n // Capitalize the first letter of each word\n return tmp.split(/\\s/).map(capitalize).join(' ');\n}\n\n/**\n * Returns a fragment to be displayed in the search table for the value.\n * @param resource The parent resource.\n * @param key The search code or FHIRPath expression.\n * @returns The fragment to display.\n */\nexport function renderValue(resource: Resource, field: SearchControlField): string | JSX.Element | null | undefined {\n const key = field.name;\n if (key === 'id') {\n return resource.id;\n }\n\n if (key === 'meta.versionId') {\n return resource.meta?.versionId;\n }\n\n if (key === '_lastUpdated') {\n return formatDateTime(resource.meta?.lastUpdated);\n }\n\n // Priority 1: ElementDefinition by exact match\n if (field.elementDefinition && `${resource.resourceType}.${field.name}` === field.elementDefinition.path) {\n return renderPropertyValue(resource, field.elementDefinition);\n }\n\n // Priority 2: SearchParameter by exact match\n if (field.searchParams && field.searchParams.length === 1 && field.name === field.searchParams[0].code) {\n return renderSearchParameterValue(resource, field.searchParams[0], field.elementDefinition);\n }\n\n // We don't know how to render this field definition\n return null;\n}\n\n/**\n * Returns a fragment to be displayed in the search table for a resource property.\n * @param resource The parent resource.\n * @param elementDefinition The property element definition.\n * @returns A React element or null.\n */\nfunction renderPropertyValue(resource: Resource, elementDefinition: ElementDefinition): JSX.Element | null {\n const path = elementDefinition.path?.split('.')?.pop()?.replaceAll('[x]', '') || '';\n const [value, propertyType] = getValueAndType({ type: resource.resourceType, value: resource }, path);\n if (!value) {\n return null;\n }\n\n return (\n <ResourcePropertyDisplay\n property={elementDefinition}\n propertyType={propertyType}\n value={value}\n maxWidth={200}\n ignoreMissingValues={true}\n link={false}\n />\n );\n}\n\n/**\n * Returns a fragment to be displayed in the search table for a search parameter.\n * @param resource The parent resource.\n * @param searchParam The search parameter.\n * @param elementDefinition Optional element definition.\n * @returns A React element or null.\n */\nfunction renderSearchParameterValue(\n resource: Resource,\n searchParam: SearchParameter,\n elementDefinition: ElementDefinition | undefined\n): JSX.Element | null {\n const value = evalFhirPathTyped(searchParam.expression as string, [{ type: resource.resourceType, value: resource }]);\n if (!value || value.length === 0) {\n return null;\n }\n\n if (elementDefinition) {\n return (\n <ResourcePropertyDisplay\n propertyType={value[0].type as PropertyType}\n value={value[0].value}\n maxWidth={200}\n ignoreMissingValues={true}\n link={false}\n />\n );\n }\n\n return (\n <>\n {value.map((v, index) => (\n <span key={`${index}-${value.length}`}>\n {typeof v === 'object' ? JSON.stringify(v) : (v as string | number)}\n </span>\n ))}\n </>\n );\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"SearchUtils.mjs","sources":["../../../src/SearchControl/SearchUtils.tsx"],"sourcesContent":["import {\n capitalize,\n DEFAULT_SEARCH_COUNT,\n evalFhirPathTyped,\n Filter,\n formatDateTime,\n Operator,\n PropertyType,\n SearchRequest,\n} from '@medplum/core';\nimport { ElementDefinition, Resource, SearchParameter } from '@medplum/fhirtypes';\nimport React from 'react';\nimport { getValueAndType, ResourcePropertyDisplay } from '../ResourcePropertyDisplay/ResourcePropertyDisplay';\nimport { SearchControlField } from './SearchControlField';\n\nconst searchParamToOperators: Record<string, Operator[]> = {\n string: [Operator.EQUALS, Operator.NOT, Operator.CONTAINS, Operator.EXACT],\n fulltext: [Operator.EQUALS, Operator.NOT, Operator.CONTAINS, Operator.EXACT],\n token: [Operator.EQUALS, Operator.NOT],\n reference: [Operator.EQUALS, Operator.NOT],\n numeric: [\n Operator.EQUALS,\n Operator.NOT_EQUALS,\n Operator.GREATER_THAN,\n Operator.LESS_THAN,\n Operator.GREATER_THAN_OR_EQUALS,\n Operator.LESS_THAN_OR_EQUALS,\n ],\n quantity: [\n Operator.EQUALS,\n Operator.NOT_EQUALS,\n Operator.GREATER_THAN,\n Operator.LESS_THAN,\n Operator.GREATER_THAN_OR_EQUALS,\n Operator.LESS_THAN_OR_EQUALS,\n ],\n date: [\n Operator.EQUALS,\n Operator.NOT_EQUALS,\n Operator.GREATER_THAN,\n Operator.LESS_THAN,\n Operator.GREATER_THAN_OR_EQUALS,\n Operator.LESS_THAN_OR_EQUALS,\n Operator.STARTS_AFTER,\n Operator.ENDS_BEFORE,\n Operator.APPROXIMATELY,\n ],\n datetime: [\n Operator.EQUALS,\n Operator.NOT_EQUALS,\n Operator.GREATER_THAN,\n Operator.LESS_THAN,\n Operator.GREATER_THAN_OR_EQUALS,\n Operator.LESS_THAN_OR_EQUALS,\n Operator.STARTS_AFTER,\n Operator.ENDS_BEFORE,\n Operator.APPROXIMATELY,\n ],\n};\n\nconst operatorNames: Record<Operator, string> = {\n eq: 'equals',\n ne: 'not equals',\n gt: 'greater than',\n lt: 'less than',\n ge: 'greater than or equals',\n le: 'less than or equals',\n sa: 'starts after',\n eb: 'ends before',\n ap: 'approximately',\n contains: 'contains',\n exact: 'exact',\n text: 'text',\n not: 'not',\n above: 'above',\n below: 'below',\n in: 'in',\n 'not-in': 'not in',\n 'of-type': 'of type',\n missing: 'missing',\n identifier: 'identifier',\n iterate: 'iterate',\n};\n\n/**\n * Sets the array of filters.\n *\n * @param {Array} filters The new filters.\n */\nexport function setFilters(definition: SearchRequest, filters: Filter[]): SearchRequest {\n return {\n ...definition,\n filters: filters,\n offset: 0,\n name: undefined,\n };\n}\n\n/**\n * Clears all of the filters.\n */\nexport function clearFilters(definition: SearchRequest): SearchRequest {\n return setFilters(definition, []);\n}\n\n/**\n * Clears all of the filters on a certain field.\n *\n * @param {string} code The field key name to clear filters.\n */\nexport function clearFiltersOnField(definition: SearchRequest, code: string): SearchRequest {\n return setFilters(\n definition,\n (definition.filters || []).filter((f) => f.code !== code)\n );\n}\n\n/**\n * Adds a filter.\n *\n * @param {string} field The field key name.\n * @param {Operator} op The operation key name.\n * @param {?string} value The filter value.\n * @param {boolean=} opt_clear Optional flag to clear filters on the field.\n */\nexport function addFilter(\n definition: SearchRequest,\n field: string,\n op: Operator,\n value?: string,\n opt_clear?: boolean\n): SearchRequest {\n if (opt_clear) {\n definition = clearFiltersOnField(definition, field);\n }\n\n const nextFilters: Filter[] = [];\n if (definition.filters) {\n nextFilters.push(...definition.filters);\n }\n nextFilters.push({ code: field, operator: op, value: value || '' });\n\n return setFilters(definition, nextFilters);\n}\n\n/**\n * Adds a field.\n *\n * @param {string} field The field key name.\n */\nexport function addField(definition: SearchRequest, field: string): SearchRequest {\n if (definition.fields && definition.fields.includes(field)) {\n return definition;\n }\n const newFields = [];\n if (definition.fields) {\n newFields.push(...definition.fields);\n }\n newFields.push(field);\n return {\n ...definition,\n fields: newFields,\n name: undefined,\n };\n}\n\n/**\n * Deletes a filter at the specified index.\n *\n * @param {number} index The filter index.\n */\nexport function deleteFilter(definition: SearchRequest, index: number): SearchRequest {\n if (!definition.filters) {\n return definition;\n }\n const newFilters = [...definition.filters];\n newFilters.splice(index, 1);\n return {\n ...definition,\n filters: newFilters,\n name: undefined,\n };\n}\n\n/**\n * Adds a filter that constrains the specified field to \"yesterday\".\n *\n * @param {string} field The field key name.\n */\nexport function addYesterdayFilter(definition: SearchRequest, field: string): SearchRequest {\n return addDayFilter(definition, field, -1);\n}\n\n/**\n * Adds a filter that constrains the specified field to \"today\".\n *\n * @param {string} field The field key name.\n */\nexport function addTodayFilter(definition: SearchRequest, field: string): SearchRequest {\n return addDayFilter(definition, field, 0);\n}\n\n/**\n * Adds a filter that constrains the specified field to \"tomorrow\".\n *\n * @param {string} field The field key name.\n */\nexport function addTomorrowFilter(definition: SearchRequest, field: string): SearchRequest {\n return addDayFilter(definition, field, 1);\n}\n\n/**\n * Adds a filter that constrains the specified field to a day.\n * The day is specified as a delta from the current day.\n * \"Today\" would be 0.\n * \"Yesterday\" would be -1.\n * \"Tomorrow\" would be 1.\n *\n * @param {string} field The field key name.\n * @param {number} delta The number of days from this day.\n */\nfunction addDayFilter(definition: SearchRequest, field: string, delta: number): SearchRequest {\n const startTime = new Date();\n startTime.setDate(startTime.getDate() + delta);\n startTime.setHours(0, 0, 0, 0);\n\n const endTime = new Date(startTime.getTime());\n endTime.setDate(endTime.getDate() + 1);\n endTime.setTime(endTime.getTime() - 1);\n\n return addDateFilterBetween(definition, field, startTime, endTime);\n}\n\n/**\n * Adds a filter that constrains the specified field to \"last month\".\n *\n * @param {string} field The field key name.\n */\nexport function addLastMonthFilter(definition: SearchRequest, field: string): SearchRequest {\n return addMonthFilter(definition, field, -1);\n}\n\n/**\n * Adds a filter that constrains the specified field to \"this month\".\n *\n * @param {string} field The field key name.\n */\nexport function addThisMonthFilter(definition: SearchRequest, field: string): SearchRequest {\n return addMonthFilter(definition, field, 0);\n}\n\n/**\n * Adds a filter that constrains the specified field to \"next month\".\n *\n * @param {string} field The field key name.\n */\nexport function addNextMonthFilter(definition: SearchRequest, field: string): SearchRequest {\n return addMonthFilter(definition, field, 1);\n}\n\n/**\n * Adds a filter that constrains the specified field to a month.\n * The month is specified as a delta from the current month.\n * \"This month\" would be 0.\n * \"Last month\" would be -1.\n * \"Next month\" would be 1.\n *\n * @param {string} field The field key name.\n * @param {number} delta The number of months from this month.\n */\nfunction addMonthFilter(definition: SearchRequest, field: string, delta: number): SearchRequest {\n const startTime = new Date();\n startTime.setMonth(startTime.getMonth() + delta);\n startTime.setDate(1);\n startTime.setHours(0, 0, 0, 0);\n\n const endTime = new Date(startTime.getTime());\n endTime.setMonth(endTime.getMonth() + 1);\n endTime.setDate(1);\n endTime.setHours(0, 0, 0, 0);\n endTime.setTime(endTime.getTime() - 1);\n\n return addDateFilterBetween(definition, field, startTime, endTime);\n}\n\n/**\n * Adds a filter that constrains the specified field to the year to date.\n *\n * @param {string} field The field key name.\n */\nexport function addYearToDateFilter(definition: SearchRequest, field: string): SearchRequest {\n const startTime = new Date();\n startTime.setMonth(0);\n startTime.setDate(1);\n startTime.setHours(0, 0, 0, 0);\n\n const endTime = new Date();\n\n return addDateFilterBetween(definition, field, startTime, endTime);\n}\n\n/**\n * Adds a filter for a date between two dates (inclusive of both dates).\n *\n * @param {string} field The field key name.\n * @param {Date} d1 The start date.\n * @param {Date} d2 The end date.\n */\nexport function addDateFilterBetween(definition: SearchRequest, field: string, d1: Date, d2: Date): SearchRequest {\n definition = clearFiltersOnField(definition, field);\n definition = addDateFilterImpl(definition, field, Operator.GREATER_THAN_OR_EQUALS, d1);\n definition = addDateFilterImpl(definition, field, Operator.LESS_THAN_OR_EQUALS, d2);\n return definition;\n}\n\n/**\n * Adds a filter for a date before a certain date/time.\n *\n * @param {string} field The field key name.\n * @param {Operator} op The date/time operation.\n * @param {Date} value The date.\n */\nfunction addDateFilterImpl(definition: SearchRequest, field: string, op: Operator, value: Date): SearchRequest {\n return addFilter(definition, field, op, value.toISOString());\n}\n\n/**\n * Adds a filter that constrains the specified field to \"missing\".\n *\n * @param {string} field The field key name.\n */\nexport function addMissingFilter(definition: SearchRequest, field: string, value = true): SearchRequest {\n return addFilter(definition, field, Operator.MISSING, value.toString());\n}\n\n/**\n * Sets the offset (starting at zero).\n *\n * @param {number} offset The offset number.\n */\nexport function setOffset(definition: SearchRequest, offset: number): SearchRequest {\n if (definition.offset === offset) {\n return definition;\n }\n return {\n ...definition,\n offset,\n name: undefined,\n };\n}\n\n/**\n * Creates a new search request with the search offset at the specified page.\n * @param definition The search definition.\n * @param page The new page number\n * @return The new search definition.\n */\nexport function setPage(definition: SearchRequest, page: number): SearchRequest {\n const count = definition.count ?? DEFAULT_SEARCH_COUNT;\n const newOffset = (page - 1) * count;\n return setOffset(definition, newOffset);\n}\n\n/**\n * Sorts the search by the specified key, and optional direction.\n * Direction defaults to ascending ('asc') if not specified.\n *\n * @param {string} sortField The sort key.\n */\nexport function setSort(definition: SearchRequest, sort: string, desc?: boolean): SearchRequest {\n if (sort === getSortField(definition) && desc !== undefined && desc === isSortDescending(definition)) {\n return definition;\n }\n return {\n ...definition,\n sortRules: [\n {\n code: sort,\n descending: !!desc,\n },\n ],\n name: undefined,\n };\n}\n\n/**\n * Toggles the sort of the search by key.\n * If the search is already sorted by the key, reverses the direction.\n * If the search is not sorted by the key, sort in ascending order.\n *\n * @param {string} key The field key name.\n */\nexport function toggleSort(definition: SearchRequest, key: string): SearchRequest {\n let desc = false;\n if (getSortField(definition) === key) {\n desc = !isSortDescending(definition);\n }\n return setSort(definition, key, desc);\n}\n\nexport function getSortField(definition: SearchRequest): string | undefined {\n const sortRules = definition.sortRules;\n if (!sortRules || sortRules.length === 0) {\n return undefined;\n }\n const field = sortRules[0].code;\n return field.startsWith('-') ? field.substr(1) : field;\n}\n\nexport function isSortDescending(definition: SearchRequest): boolean {\n const sortRules = definition.sortRules;\n if (!sortRules || sortRules.length === 0) {\n return false;\n }\n return !!sortRules[0].descending;\n}\n\n/**\n * Returns a list of operators for a search parameter.\n * @param searchParam The search parameter.\n * @returns The list of operators that can be used for the search parameter.\n */\nexport function getSearchOperators(searchParam: SearchParameter): Operator[] | undefined {\n return searchParamToOperators[searchParam.type as string];\n}\n\n/**\n * Returns a string representing the operation.\n *\n * @param {string} op The operation code.\n * @return {string} A display string for the operation.\n */\nexport function getOpString(op: Operator): string {\n return operatorNames[op] ?? '';\n}\n\n/**\n * Returns a field display name.\n * @param key The field key.\n * @returns The field display name.\n */\nexport function buildFieldNameString(key: string): string {\n let tmp = key;\n\n // If dot separated, only the last part\n if (tmp.includes('.')) {\n tmp = tmp.split('.').pop() as string;\n }\n\n // Special case for ID\n if (tmp === 'id') {\n return 'ID';\n }\n\n // Special case for Version ID\n if (tmp === 'versionId') {\n return 'Version ID';\n }\n\n // Remove choice of type\n tmp = tmp.replace('[x]', '');\n\n // Convert camel case to space separated\n tmp = tmp.replace(/([A-Z])/g, ' $1');\n\n // Convert dashes and underscores to spaces\n tmp = tmp.replace(/[-_]/g, ' ');\n\n // Normalize whitespace to single space character\n tmp = tmp.replace(/\\s+/g, ' ');\n\n // Trim\n tmp = tmp.trim();\n\n // Capitalize the first letter of each word\n return tmp.split(/\\s/).map(capitalize).join(' ');\n}\n\n/**\n * Returns a fragment to be displayed in the search table for the value.\n * @param resource The parent resource.\n * @param key The search code or FHIRPath expression.\n * @returns The fragment to display.\n */\nexport function renderValue(resource: Resource, field: SearchControlField): string | JSX.Element | null | undefined {\n const key = field.name;\n if (key === 'id') {\n return resource.id;\n }\n\n if (key === 'meta.versionId') {\n return resource.meta?.versionId;\n }\n\n if (key === '_lastUpdated') {\n return formatDateTime(resource.meta?.lastUpdated);\n }\n\n // Priority 1: ElementDefinition by exact match\n if (field.elementDefinition && `${resource.resourceType}.${field.name}` === field.elementDefinition.path) {\n return renderPropertyValue(resource, field.elementDefinition);\n }\n\n // Priority 2: SearchParameter by exact match\n if (field.searchParams && field.searchParams.length === 1 && field.name === field.searchParams[0].code) {\n return renderSearchParameterValue(resource, field.searchParams[0], field.elementDefinition);\n }\n\n // We don't know how to render this field definition\n return null;\n}\n\n/**\n * Returns a fragment to be displayed in the search table for a resource property.\n * @param resource The parent resource.\n * @param elementDefinition The property element definition.\n * @returns A React element or null.\n */\nfunction renderPropertyValue(resource: Resource, elementDefinition: ElementDefinition): JSX.Element | null {\n const path = elementDefinition.path?.split('.')?.pop()?.replaceAll('[x]', '') || '';\n const [value, propertyType] = getValueAndType({ type: resource.resourceType, value: resource }, path);\n if (!value) {\n return null;\n }\n\n return (\n <ResourcePropertyDisplay\n property={elementDefinition}\n propertyType={propertyType}\n value={value}\n maxWidth={200}\n ignoreMissingValues={true}\n link={false}\n />\n );\n}\n\n/**\n * Returns a fragment to be displayed in the search table for a search parameter.\n * @param resource The parent resource.\n * @param searchParam The search parameter.\n * @param elementDefinition Optional element definition.\n * @returns A React element or null.\n */\nfunction renderSearchParameterValue(\n resource: Resource,\n searchParam: SearchParameter,\n elementDefinition: ElementDefinition | undefined\n): JSX.Element | null {\n const value = evalFhirPathTyped(searchParam.expression as string, [{ type: resource.resourceType, value: resource }]);\n if (!value || value.length === 0) {\n return null;\n }\n\n if (elementDefinition) {\n return (\n <ResourcePropertyDisplay\n propertyType={value[0].type as PropertyType}\n value={value[0].value}\n maxWidth={200}\n ignoreMissingValues={true}\n link={false}\n />\n );\n }\n\n return (\n <>\n {value.map((v, index) => (\n <span key={`${index}-${value.length}`}>\n {typeof v === 'object' ? JSON.stringify(v) : (v as string | number)}\n </span>\n ))}\n </>\n );\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -20,7 +20,7 @@ function SearchFilterEditor(props) {
|
|
|
20
20
|
return null;
|
|
21
21
|
}
|
|
22
22
|
const resourceType = props.search.resourceType;
|
|
23
|
-
const searchParams = globalSchema.types[resourceType].searchParams;
|
|
23
|
+
const searchParams = globalSchema.types[resourceType].searchParams ?? {};
|
|
24
24
|
const filters = search.filters || [];
|
|
25
25
|
return (React.createElement(Modal, { title: "Filters", closeButtonProps: { 'aria-label': 'Close' }, size: 900, opened: props.visible, onClose: props.onCancel },
|
|
26
26
|
React.createElement("div", null,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SearchFilterEditor.mjs","sources":["../../../src/SearchFilterEditor/SearchFilterEditor.tsx"],"sourcesContent":["import { Button, Group, Modal, NativeSelect } from '@mantine/core';\nimport { Filter, globalSchema, Operator, SearchRequest, stringify } from '@medplum/core';\nimport { SearchParameter } from '@medplum/fhirtypes';\nimport React, { useEffect, useRef, useState } from 'react';\nimport {\n addFilter,\n buildFieldNameString,\n deleteFilter,\n getOpString,\n getSearchOperators,\n setFilters,\n} from '../SearchControl/SearchUtils';\nimport { SearchFilterValueDisplay } from '../SearchFilterValueDisplay/SearchFilterValueDisplay';\nimport { SearchFilterValueInput } from '../SearchFilterValueInput/SearchFilterValueInput';\n\nexport interface SearchFilterEditorProps {\n visible: boolean;\n search: SearchRequest;\n onOk: (search: SearchRequest) => void;\n onCancel: () => void;\n}\n\nexport function SearchFilterEditor(props: SearchFilterEditorProps): JSX.Element | null {\n const [search, setSearch] = useState<SearchRequest>(JSON.parse(stringify(props.search)) as SearchRequest);\n const [editingIndex, setEditingIndex] = useState<number>(-1);\n\n const searchRef = useRef<SearchRequest>(search);\n searchRef.current = search;\n\n useEffect(() => {\n setSearch(JSON.parse(stringify(props.search)) as SearchRequest);\n }, [props.search]);\n\n function onAddFilter(filter: Filter): void {\n setSearch(addFilter(searchRef.current, filter.code, filter.operator, filter.value));\n }\n\n if (!props.visible) {\n return null;\n }\n\n const resourceType = props.search.resourceType;\n const searchParams = globalSchema.types[resourceType].searchParams as Record<string, SearchParameter>;\n const filters = search.filters || [];\n\n return (\n <Modal\n title=\"Filters\"\n closeButtonProps={{ 'aria-label': 'Close' }}\n size={900}\n opened={props.visible}\n onClose={props.onCancel}\n >\n <div>\n <table>\n <colgroup>\n <col style={{ width: 200 }} />\n <col style={{ width: 200 }} />\n <col style={{ width: 380 }} />\n <col style={{ width: 120 }} />\n </colgroup>\n <thead>\n <tr>\n <th>Field</th>\n <th>Operation</th>\n <th>Value</th>\n <th>Actions</th>\n </tr>\n </thead>\n <tbody>\n {filters.map((filter: Filter, index: number) => {\n if (index === editingIndex) {\n return (\n <FilterRowInput\n key={`filter-${index}-${filters.length}-input`}\n resourceType={resourceType}\n searchParams={searchParams}\n defaultValue={filter}\n okText=\"Save\"\n onOk={(newFilter: Filter) => {\n const newFilters = [...filters];\n newFilters[index] = newFilter;\n setSearch(setFilters(searchRef.current, newFilters));\n setEditingIndex(-1);\n }}\n onCancel={() => setEditingIndex(-1)}\n />\n );\n } else {\n return (\n <FilterRowDisplay\n key={`filter-${index}-${filters.length}-display`}\n resourceType={resourceType}\n searchParams={searchParams}\n filter={filter}\n onEdit={() => setEditingIndex(index)}\n onDelete={() => setSearch(deleteFilter(searchRef.current, index))}\n />\n );\n }\n })}\n <FilterRowInput resourceType={resourceType} searchParams={searchParams} okText=\"Add\" onOk={onAddFilter} />\n </tbody>\n </table>\n </div>\n <Group position=\"right\" mt=\"xl\">\n <Button onClick={() => props.onOk(searchRef.current)}>OK</Button>\n </Group>\n </Modal>\n );\n}\n\ninterface FilterRowDisplayProps {\n readonly searchParams: Record<string, SearchParameter>;\n readonly resourceType: string;\n readonly filter: Filter;\n readonly onEdit: () => void;\n readonly onDelete: () => void;\n}\n\nfunction FilterRowDisplay(props: FilterRowDisplayProps): JSX.Element | null {\n const { filter } = props;\n return (\n <tr>\n <td>{buildFieldNameString(filter.code)}</td>\n <td>{getOpString(filter.operator)}</td>\n <td>\n <SearchFilterValueDisplay resourceType={props.resourceType} filter={filter} />\n </td>\n <td>\n <Button compact variant=\"outline\" onClick={props.onEdit}>\n Edit\n </Button>\n <Button compact variant=\"outline\" onClick={props.onDelete}>\n Delete\n </Button>\n </td>\n </tr>\n );\n}\n\ninterface FilterRowInputProps {\n resourceType: string;\n searchParams: Record<string, SearchParameter>;\n defaultValue?: Filter;\n okText: string;\n onOk: (value: Filter) => void;\n onCancel?: () => void;\n}\n\nfunction FilterRowInput(props: FilterRowInputProps): JSX.Element {\n const [value, setValue] = useState<Filter>(props.defaultValue ?? ({} as Filter));\n const valueRef = useRef<Filter>(value);\n valueRef.current = value;\n\n function setFilterCode(newCode: string): void {\n setValue({ ...valueRef.current, code: newCode });\n }\n\n function setFilterOperator(newOperator: Operator): void {\n setValue({ ...valueRef.current, operator: newOperator });\n }\n\n function setFilterValue(newFilterValue: string): void {\n setValue({ ...valueRef.current, value: newFilterValue });\n }\n\n const searchParam = props.searchParams[value.code];\n const operators = searchParam && getSearchOperators(searchParam);\n\n return (\n <tr>\n <td>\n <NativeSelect\n data-testid=\"filter-field\"\n defaultValue={valueRef.current.code}\n onChange={(e) => setFilterCode(e.currentTarget.value)}\n data={Object.keys(props.searchParams).map((param) => ({ value: param, label: buildFieldNameString(param) }))}\n />\n </td>\n <td>\n {operators && (\n <NativeSelect\n data-testid=\"filter-operation\"\n defaultValue={value.operator}\n onChange={(e) => setFilterOperator(e.currentTarget.value as Operator)}\n data={['', ...operators.map((op) => ({ value: op, label: getOpString(op) }))]}\n />\n )}\n </td>\n <td>\n {searchParam && value.operator && (\n <SearchFilterValueInput\n resourceType={props.resourceType}\n searchParam={searchParam}\n defaultValue={value.value}\n onChange={setFilterValue}\n />\n )}\n </td>\n <td>\n {value.code && value.operator && value.value && (\n <Button\n compact\n variant=\"outline\"\n onClick={() => {\n props.onOk(valueRef.current);\n setValue({} as Filter);\n }}\n >\n {props.okText}\n </Button>\n )}\n {props.onCancel && (\n <Button compact variant=\"outline\" onClick={props.onCancel}>\n Cancel\n </Button>\n )}\n </td>\n </tr>\n );\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"SearchFilterEditor.mjs","sources":["../../../src/SearchFilterEditor/SearchFilterEditor.tsx"],"sourcesContent":["import { Button, Group, Modal, NativeSelect } from '@mantine/core';\nimport { Filter, globalSchema, Operator, SearchRequest, stringify } from '@medplum/core';\nimport { SearchParameter } from '@medplum/fhirtypes';\nimport React, { useEffect, useRef, useState } from 'react';\nimport {\n addFilter,\n buildFieldNameString,\n deleteFilter,\n getOpString,\n getSearchOperators,\n setFilters,\n} from '../SearchControl/SearchUtils';\nimport { SearchFilterValueDisplay } from '../SearchFilterValueDisplay/SearchFilterValueDisplay';\nimport { SearchFilterValueInput } from '../SearchFilterValueInput/SearchFilterValueInput';\n\nexport interface SearchFilterEditorProps {\n visible: boolean;\n search: SearchRequest;\n onOk: (search: SearchRequest) => void;\n onCancel: () => void;\n}\n\nexport function SearchFilterEditor(props: SearchFilterEditorProps): JSX.Element | null {\n const [search, setSearch] = useState<SearchRequest>(JSON.parse(stringify(props.search)) as SearchRequest);\n const [editingIndex, setEditingIndex] = useState<number>(-1);\n\n const searchRef = useRef<SearchRequest>(search);\n searchRef.current = search;\n\n useEffect(() => {\n setSearch(JSON.parse(stringify(props.search)) as SearchRequest);\n }, [props.search]);\n\n function onAddFilter(filter: Filter): void {\n setSearch(addFilter(searchRef.current, filter.code, filter.operator, filter.value));\n }\n\n if (!props.visible) {\n return null;\n }\n\n const resourceType = props.search.resourceType;\n const searchParams = (globalSchema.types[resourceType].searchParams as Record<string, SearchParameter>) ?? {};\n const filters = search.filters || [];\n\n return (\n <Modal\n title=\"Filters\"\n closeButtonProps={{ 'aria-label': 'Close' }}\n size={900}\n opened={props.visible}\n onClose={props.onCancel}\n >\n <div>\n <table>\n <colgroup>\n <col style={{ width: 200 }} />\n <col style={{ width: 200 }} />\n <col style={{ width: 380 }} />\n <col style={{ width: 120 }} />\n </colgroup>\n <thead>\n <tr>\n <th>Field</th>\n <th>Operation</th>\n <th>Value</th>\n <th>Actions</th>\n </tr>\n </thead>\n <tbody>\n {filters.map((filter: Filter, index: number) => {\n if (index === editingIndex) {\n return (\n <FilterRowInput\n key={`filter-${index}-${filters.length}-input`}\n resourceType={resourceType}\n searchParams={searchParams}\n defaultValue={filter}\n okText=\"Save\"\n onOk={(newFilter: Filter) => {\n const newFilters = [...filters];\n newFilters[index] = newFilter;\n setSearch(setFilters(searchRef.current, newFilters));\n setEditingIndex(-1);\n }}\n onCancel={() => setEditingIndex(-1)}\n />\n );\n } else {\n return (\n <FilterRowDisplay\n key={`filter-${index}-${filters.length}-display`}\n resourceType={resourceType}\n searchParams={searchParams}\n filter={filter}\n onEdit={() => setEditingIndex(index)}\n onDelete={() => setSearch(deleteFilter(searchRef.current, index))}\n />\n );\n }\n })}\n <FilterRowInput resourceType={resourceType} searchParams={searchParams} okText=\"Add\" onOk={onAddFilter} />\n </tbody>\n </table>\n </div>\n <Group position=\"right\" mt=\"xl\">\n <Button onClick={() => props.onOk(searchRef.current)}>OK</Button>\n </Group>\n </Modal>\n );\n}\n\ninterface FilterRowDisplayProps {\n readonly searchParams: Record<string, SearchParameter>;\n readonly resourceType: string;\n readonly filter: Filter;\n readonly onEdit: () => void;\n readonly onDelete: () => void;\n}\n\nfunction FilterRowDisplay(props: FilterRowDisplayProps): JSX.Element | null {\n const { filter } = props;\n return (\n <tr>\n <td>{buildFieldNameString(filter.code)}</td>\n <td>{getOpString(filter.operator)}</td>\n <td>\n <SearchFilterValueDisplay resourceType={props.resourceType} filter={filter} />\n </td>\n <td>\n <Button compact variant=\"outline\" onClick={props.onEdit}>\n Edit\n </Button>\n <Button compact variant=\"outline\" onClick={props.onDelete}>\n Delete\n </Button>\n </td>\n </tr>\n );\n}\n\ninterface FilterRowInputProps {\n resourceType: string;\n searchParams: Record<string, SearchParameter>;\n defaultValue?: Filter;\n okText: string;\n onOk: (value: Filter) => void;\n onCancel?: () => void;\n}\n\nfunction FilterRowInput(props: FilterRowInputProps): JSX.Element {\n const [value, setValue] = useState<Filter>(props.defaultValue ?? ({} as Filter));\n const valueRef = useRef<Filter>(value);\n valueRef.current = value;\n\n function setFilterCode(newCode: string): void {\n setValue({ ...valueRef.current, code: newCode });\n }\n\n function setFilterOperator(newOperator: Operator): void {\n setValue({ ...valueRef.current, operator: newOperator });\n }\n\n function setFilterValue(newFilterValue: string): void {\n setValue({ ...valueRef.current, value: newFilterValue });\n }\n\n const searchParam = props.searchParams[value.code];\n const operators = searchParam && getSearchOperators(searchParam);\n\n return (\n <tr>\n <td>\n <NativeSelect\n data-testid=\"filter-field\"\n defaultValue={valueRef.current.code}\n onChange={(e) => setFilterCode(e.currentTarget.value)}\n data={Object.keys(props.searchParams).map((param) => ({ value: param, label: buildFieldNameString(param) }))}\n />\n </td>\n <td>\n {operators && (\n <NativeSelect\n data-testid=\"filter-operation\"\n defaultValue={value.operator}\n onChange={(e) => setFilterOperator(e.currentTarget.value as Operator)}\n data={['', ...operators.map((op) => ({ value: op, label: getOpString(op) }))]}\n />\n )}\n </td>\n <td>\n {searchParam && value.operator && (\n <SearchFilterValueInput\n resourceType={props.resourceType}\n searchParam={searchParam}\n defaultValue={value.value}\n onChange={setFilterValue}\n />\n )}\n </td>\n <td>\n {value.code && value.operator && value.value && (\n <Button\n compact\n variant=\"outline\"\n onClick={() => {\n props.onOk(valueRef.current);\n setValue({} as Filter);\n }}\n >\n {props.okText}\n </Button>\n )}\n {props.onCancel && (\n <Button compact variant=\"outline\" onClick={props.onCancel}>\n Cancel\n </Button>\n )}\n </td>\n </tr>\n );\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -3,12 +3,15 @@ import React from 'react';
|
|
|
3
3
|
import { ResourceTimeline } from '../ResourceTimeline/ResourceTimeline.mjs';
|
|
4
4
|
|
|
5
5
|
function ServiceRequestTimeline(props) {
|
|
6
|
-
return (React.createElement(ResourceTimeline, { value: props.serviceRequest, loadTimelineResources: async (medplum,
|
|
6
|
+
return (React.createElement(ResourceTimeline, { value: props.serviceRequest, loadTimelineResources: async (medplum, resourceType, id) => {
|
|
7
|
+
const ref = `${resourceType}/${id}`;
|
|
8
|
+
const _count = 100;
|
|
7
9
|
return Promise.allSettled([
|
|
8
10
|
medplum.readHistory('ServiceRequest', id),
|
|
9
|
-
medplum.search('Communication', 'based-on
|
|
10
|
-
medplum.search('
|
|
11
|
-
medplum.search('
|
|
11
|
+
medplum.search('Communication', { 'based-on': ref, _count }),
|
|
12
|
+
medplum.search('DiagnosticReport', { 'based-on': ref, _count }),
|
|
13
|
+
medplum.search('Media', { 'based-on': ref, _count }),
|
|
14
|
+
medplum.search('Task', { _filter: `based-on eq ${ref} or focus eq ${ref} or subject eq ${ref}`, _count }),
|
|
12
15
|
]);
|
|
13
16
|
}, createCommunication: (resource, sender, text) => ({
|
|
14
17
|
resourceType: 'Communication',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ServiceRequestTimeline.mjs","sources":["../../../src/ServiceRequestTimeline/ServiceRequestTimeline.tsx"],"sourcesContent":["import { createReference, MedplumClient, ProfileResource } from '@medplum/core';\nimport { Attachment, Group, Patient, Reference, ResourceType, ServiceRequest } from '@medplum/fhirtypes';\nimport React from 'react';\nimport { ResourceTimeline } from '../ResourceTimeline/ResourceTimeline';\n\nexport interface ServiceRequestTimelineProps {\n serviceRequest: ServiceRequest | Reference<ServiceRequest>;\n}\n\nexport function ServiceRequestTimeline(props: ServiceRequestTimelineProps): JSX.Element {\n return (\n <ResourceTimeline\n value={props.serviceRequest}\n loadTimelineResources={async (medplum: MedplumClient,
|
|
1
|
+
{"version":3,"file":"ServiceRequestTimeline.mjs","sources":["../../../src/ServiceRequestTimeline/ServiceRequestTimeline.tsx"],"sourcesContent":["import { createReference, MedplumClient, ProfileResource } from '@medplum/core';\nimport { Attachment, Group, Patient, Reference, ResourceType, ServiceRequest } from '@medplum/fhirtypes';\nimport React from 'react';\nimport { ResourceTimeline } from '../ResourceTimeline/ResourceTimeline';\n\nexport interface ServiceRequestTimelineProps {\n serviceRequest: ServiceRequest | Reference<ServiceRequest>;\n}\n\nexport function ServiceRequestTimeline(props: ServiceRequestTimelineProps): JSX.Element {\n return (\n <ResourceTimeline\n value={props.serviceRequest}\n loadTimelineResources={async (medplum: MedplumClient, resourceType: ResourceType, id: string) => {\n const ref = `${resourceType}/${id}`;\n const _count = 100;\n return Promise.allSettled([\n medplum.readHistory('ServiceRequest', id),\n medplum.search('Communication', { 'based-on': ref, _count }),\n medplum.search('DiagnosticReport', { 'based-on': ref, _count }),\n medplum.search('Media', { 'based-on': ref, _count }),\n medplum.search('Task', { _filter: `based-on eq ${ref} or focus eq ${ref} or subject eq ${ref}`, _count }),\n ]);\n }}\n createCommunication={(resource: ServiceRequest, sender: ProfileResource, text: string) => ({\n resourceType: 'Communication',\n status: 'completed',\n basedOn: [createReference(resource)],\n subject: resource.subject as Reference<Group | Patient>,\n sender: createReference(sender),\n sent: new Date().toISOString(),\n payload: [{ contentString: text }],\n })}\n createMedia={(resource: ServiceRequest, operator: ProfileResource, content: Attachment) => ({\n resourceType: 'Media',\n status: 'completed',\n basedOn: [createReference(resource)],\n subject: resource.subject,\n operator: createReference(operator),\n issued: new Date().toISOString(),\n content,\n })}\n />\n );\n}\n"],"names":[],"mappings":";;;;AASM,SAAU,sBAAsB,CAAC,KAAkC,EAAA;IACvE,QACE,oBAAC,gBAAgB,EAAA,EACf,KAAK,EAAE,KAAK,CAAC,cAAc,EAC3B,qBAAqB,EAAE,OAAO,OAAsB,EAAE,YAA0B,EAAE,EAAU,KAAI;AAC9F,YAAA,MAAM,GAAG,GAAG,CAAA,EAAG,YAAY,CAAI,CAAA,EAAA,EAAE,EAAE,CAAC;YACpC,MAAM,MAAM,GAAG,GAAG,CAAC;YACnB,OAAO,OAAO,CAAC,UAAU,CAAC;AACxB,gBAAA,OAAO,CAAC,WAAW,CAAC,gBAAgB,EAAE,EAAE,CAAC;AACzC,gBAAA,OAAO,CAAC,MAAM,CAAC,eAAe,EAAE,EAAE,UAAU,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC;AAC5D,gBAAA,OAAO,CAAC,MAAM,CAAC,kBAAkB,EAAE,EAAE,UAAU,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC;AAC/D,gBAAA,OAAO,CAAC,MAAM,CAAC,OAAO,EAAE,EAAE,UAAU,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC;AACpD,gBAAA,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,EAAE,OAAO,EAAE,CAAA,YAAA,EAAe,GAAG,CAAA,aAAA,EAAgB,GAAG,CAAkB,eAAA,EAAA,GAAG,EAAE,EAAE,MAAM,EAAE,CAAC;AAC1G,aAAA,CAAC,CAAC;AACL,SAAC,EACD,mBAAmB,EAAE,CAAC,QAAwB,EAAE,MAAuB,EAAE,IAAY,MAAM;AACzF,YAAA,YAAY,EAAE,eAAe;AAC7B,YAAA,MAAM,EAAE,WAAW;AACnB,YAAA,OAAO,EAAE,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC;YACpC,OAAO,EAAE,QAAQ,CAAC,OAAqC;AACvD,YAAA,MAAM,EAAE,eAAe,CAAC,MAAM,CAAC;AAC/B,YAAA,IAAI,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;AAC9B,YAAA,OAAO,EAAE,CAAC,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC;AACnC,SAAA,CAAC,EACF,WAAW,EAAE,CAAC,QAAwB,EAAE,QAAyB,EAAE,OAAmB,MAAM;AAC1F,YAAA,YAAY,EAAE,OAAO;AACrB,YAAA,MAAM,EAAE,WAAW;AACnB,YAAA,OAAO,EAAE,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC;YACpC,OAAO,EAAE,QAAQ,CAAC,OAAO;AACzB,YAAA,QAAQ,EAAE,eAAe,CAAC,QAAQ,CAAC;AACnC,YAAA,MAAM,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YAChC,OAAO;SACR,CAAC,EAAA,CACF,EACF;AACJ;;;;"}
|
|
@@ -78,7 +78,7 @@ function PasswordForm(props) {
|
|
|
78
78
|
React.createElement(Center, { sx: { flexDirection: 'column' } }, children),
|
|
79
79
|
React.createElement(OperationOutcomeAlert, { issues: issues }),
|
|
80
80
|
React.createElement(Stack, { spacing: "xl" },
|
|
81
|
-
React.createElement(PasswordInput, { name: "password", label: "Password", autoComplete: "off", required: true, error: getErrorsForInput(outcome, 'password') })),
|
|
81
|
+
React.createElement(PasswordInput, { name: "password", label: "Password", autoComplete: "off", required: true, autoFocus: true, error: getErrorsForInput(outcome, 'password') })),
|
|
82
82
|
React.createElement(Group, { position: "apart", mt: "xl", spacing: 0, noWrap: true },
|
|
83
83
|
onForgotPassword && (React.createElement(Anchor, { component: "button", type: "button", color: "dimmed", onClick: onForgotPassword, size: "xs" }, "Forgot password")),
|
|
84
84
|
React.createElement(Checkbox, { id: "remember", name: "remember", label: "Remember me", size: "xs", sx: { lineHeight: 1 } }),
|