@medplum/react 0.9.30 → 0.9.33

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. package/dist/cjs/QuestionnaireForm.d.ts +1 -0
  2. package/dist/cjs/Scheduler.d.ts +2 -1
  3. package/dist/cjs/auth/AuthenticationForm.d.ts +16 -0
  4. package/dist/cjs/auth/ChooseProfileForm.d.ts +8 -0
  5. package/dist/cjs/auth/NewProjectForm.d.ts +7 -0
  6. package/dist/cjs/auth/NewUserForm.d.ts +10 -0
  7. package/dist/cjs/auth/RegisterForm.d.ts +12 -0
  8. package/dist/cjs/{SignInForm.d.ts → auth/SignInForm.d.ts} +3 -1
  9. package/dist/cjs/index.d.ts +2 -2
  10. package/dist/cjs/index.js +700 -678
  11. package/dist/cjs/index.js.map +1 -1
  12. package/dist/cjs/index.min.js +1 -1
  13. package/dist/cjs/index.min.js.map +1 -1
  14. package/dist/cjs/styles.css +197 -197
  15. package/dist/esm/MedplumLink.js +29 -14
  16. package/dist/esm/MedplumLink.js.map +1 -1
  17. package/dist/esm/QuestionnaireForm.d.ts +1 -0
  18. package/dist/esm/QuestionnaireForm.js +1 -1
  19. package/dist/esm/QuestionnaireForm.js.map +1 -1
  20. package/dist/esm/ResourceHistoryTable.js +15 -11
  21. package/dist/esm/ResourceHistoryTable.js.map +1 -1
  22. package/dist/esm/ResourceTimeline.js +3 -1
  23. package/dist/esm/ResourceTimeline.js.map +1 -1
  24. package/dist/esm/Scheduler.d.ts +2 -1
  25. package/dist/esm/Scheduler.js +18 -24
  26. package/dist/esm/Scheduler.js.map +1 -1
  27. package/dist/esm/ServiceRequestTimeline.js +3 -3
  28. package/dist/esm/ServiceRequestTimeline.js.map +1 -1
  29. package/dist/esm/auth/AuthenticationForm.d.ts +16 -0
  30. package/dist/esm/auth/AuthenticationForm.js +71 -0
  31. package/dist/esm/auth/AuthenticationForm.js.map +1 -0
  32. package/dist/esm/auth/ChooseProfileForm.d.ts +8 -0
  33. package/dist/esm/auth/ChooseProfileForm.js +32 -0
  34. package/dist/esm/auth/ChooseProfileForm.js.map +1 -0
  35. package/dist/esm/auth/NewProjectForm.d.ts +7 -0
  36. package/dist/esm/auth/NewProjectForm.js +42 -0
  37. package/dist/esm/auth/NewProjectForm.js.map +1 -0
  38. package/dist/esm/auth/NewUserForm.d.ts +10 -0
  39. package/dist/esm/auth/NewUserForm.js +87 -0
  40. package/dist/esm/auth/NewUserForm.js.map +1 -0
  41. package/dist/esm/auth/RegisterForm.d.ts +12 -0
  42. package/dist/esm/auth/RegisterForm.js +39 -0
  43. package/dist/esm/auth/RegisterForm.js.map +1 -0
  44. package/dist/esm/{SignInForm.d.ts → auth/SignInForm.d.ts} +3 -1
  45. package/dist/esm/auth/SignInForm.js +52 -0
  46. package/dist/esm/auth/SignInForm.js.map +1 -0
  47. package/dist/esm/index.d.ts +2 -2
  48. package/dist/esm/index.js +2 -2
  49. package/dist/esm/index.min.js +1 -1
  50. package/dist/esm/index.min.js.map +1 -1
  51. package/dist/esm/styles.css +197 -197
  52. package/package.json +21 -23
  53. package/dist/cjs/RegisterForm.d.ts +0 -18
  54. package/dist/esm/RegisterForm.d.ts +0 -18
  55. package/dist/esm/RegisterForm.js +0 -121
  56. package/dist/esm/RegisterForm.js.map +0 -1
  57. package/dist/esm/SignInForm.js +0 -167
  58. package/dist/esm/SignInForm.js.map +0 -1
@@ -1,4 +1,4 @@
1
- import { formatDateTime } from '@medplum/core';
1
+ import { formatDateTime, normalizeErrorString } from '@medplum/core';
2
2
  import React, { useState, useEffect } from 'react';
3
3
  import { MedplumLink } from './MedplumLink.js';
4
4
  import { useMedplum } from './MedplumProvider.js';
@@ -25,19 +25,23 @@ function ResourceHistoryTable(props) {
25
25
  React.createElement("th", null, "Author"),
26
26
  React.createElement("th", null, "Date"),
27
27
  React.createElement("th", null, "Version"))),
28
- React.createElement("tbody", null, (_a = value.entry) === null || _a === void 0 ? void 0 : _a.map((entry) => {
29
- var _a, _b;
30
- return (React.createElement(HistoryRow, { key: (_b = (_a = entry.resource) === null || _a === void 0 ? void 0 : _a.meta) === null || _b === void 0 ? void 0 : _b.versionId, version: entry.resource }));
31
- }))));
28
+ React.createElement("tbody", null, (_a = value.entry) === null || _a === void 0 ? void 0 : _a.map((entry, index) => (React.createElement(HistoryRow, { key: 'entry-' + index, entry: entry }))))));
32
29
  }
33
30
  function HistoryRow(props) {
34
31
  var _a, _b, _c;
35
- return (React.createElement("tr", null,
36
- React.createElement("td", null,
37
- React.createElement(ResourceBadge, { value: (_a = props.version.meta) === null || _a === void 0 ? void 0 : _a.author, link: true })),
38
- React.createElement("td", null, formatDateTime((_b = props.version.meta) === null || _b === void 0 ? void 0 : _b.lastUpdated)),
39
- React.createElement("td", null,
40
- React.createElement(MedplumLink, { to: getVersionUrl(props.version) }, (_c = props.version.meta) === null || _c === void 0 ? void 0 : _c.versionId))));
32
+ const { response, resource } = props.entry;
33
+ if (resource) {
34
+ return (React.createElement("tr", null,
35
+ React.createElement("td", null,
36
+ React.createElement(ResourceBadge, { value: (_a = resource.meta) === null || _a === void 0 ? void 0 : _a.author, link: true })),
37
+ React.createElement("td", null, formatDateTime((_b = resource.meta) === null || _b === void 0 ? void 0 : _b.lastUpdated)),
38
+ React.createElement("td", null,
39
+ React.createElement(MedplumLink, { to: getVersionUrl(resource) }, (_c = resource.meta) === null || _c === void 0 ? void 0 : _c.versionId))));
40
+ }
41
+ else {
42
+ return (React.createElement("tr", null,
43
+ React.createElement("td", { colSpan: 3 }, normalizeErrorString(response === null || response === void 0 ? void 0 : response.outcome))));
44
+ }
41
45
  }
42
46
  function getVersionUrl(resource) {
43
47
  var _a;
@@ -1 +1 @@
1
- {"version":3,"file":"ResourceHistoryTable.js","sources":["../../src/ResourceHistoryTable.tsx"],"sourcesContent":["import { formatDateTime } from '@medplum/core';\nimport { Bundle, Resource, ResourceType } from '@medplum/fhirtypes';\nimport React, { useEffect, useState } from 'react';\nimport { MedplumLink } from './MedplumLink';\nimport { useMedplum } from './MedplumProvider';\nimport { ResourceBadge } from './ResourceBadge';\nimport './Table.css';\n\nexport interface ResourceHistoryTableProps {\n history?: Bundle;\n resourceType?: string;\n id?: string;\n}\n\nexport function ResourceHistoryTable(props: ResourceHistoryTableProps): JSX.Element {\n const medplum = useMedplum();\n const [value, setValue] = useState<Bundle | undefined>(props.history);\n\n useEffect(() => {\n if (!props.history && props.resourceType && props.id) {\n medplum\n .readHistory(props.resourceType as ResourceType, props.id)\n .then(setValue)\n .catch(console.log);\n }\n }, [medplum, props.history, props.resourceType, props.id]);\n\n if (!value) {\n return <div>Loading...</div>;\n }\n\n return (\n <table className=\"medplum-table\">\n <thead>\n <tr>\n <th>Author</th>\n <th>Date</th>\n <th>Version</th>\n </tr>\n </thead>\n <tbody>\n {value.entry?.map((entry) => (\n <HistoryRow key={entry.resource?.meta?.versionId} version={entry.resource as Resource} />\n ))}\n </tbody>\n </table>\n );\n}\n\ninterface HistoryRowProps {\n version: Resource;\n}\n\nfunction HistoryRow(props: HistoryRowProps): JSX.Element {\n return (\n <tr>\n <td>\n <ResourceBadge value={props.version.meta?.author} link={true} />\n </td>\n <td>{formatDateTime(props.version.meta?.lastUpdated)}</td>\n <td>\n <MedplumLink to={getVersionUrl(props.version)}>{props.version.meta?.versionId}</MedplumLink>\n </td>\n </tr>\n );\n}\n\nfunction getVersionUrl(resource: Resource): string {\n return `/${resource.resourceType}/${resource.id}/_history/${resource.meta?.versionId}`;\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ResourceHistoryTable.js","sources":["../../src/ResourceHistoryTable.tsx"],"sourcesContent":["import { formatDateTime, normalizeErrorString } from '@medplum/core';\nimport { Bundle, BundleEntry, Resource, ResourceType } from '@medplum/fhirtypes';\nimport React, { useEffect, useState } from 'react';\nimport { MedplumLink } from './MedplumLink';\nimport { useMedplum } from './MedplumProvider';\nimport { ResourceBadge } from './ResourceBadge';\nimport './Table.css';\n\nexport interface ResourceHistoryTableProps {\n history?: Bundle;\n resourceType?: string;\n id?: string;\n}\n\nexport function ResourceHistoryTable(props: ResourceHistoryTableProps): JSX.Element {\n const medplum = useMedplum();\n const [value, setValue] = useState<Bundle | undefined>(props.history);\n\n useEffect(() => {\n if (!props.history && props.resourceType && props.id) {\n medplum\n .readHistory(props.resourceType as ResourceType, props.id)\n .then(setValue)\n .catch(console.log);\n }\n }, [medplum, props.history, props.resourceType, props.id]);\n\n if (!value) {\n return <div>Loading...</div>;\n }\n\n return (\n <table className=\"medplum-table\">\n <thead>\n <tr>\n <th>Author</th>\n <th>Date</th>\n <th>Version</th>\n </tr>\n </thead>\n <tbody>\n {value.entry?.map((entry, index) => (\n <HistoryRow key={'entry-' + index} entry={entry} />\n ))}\n </tbody>\n </table>\n );\n}\n\ninterface HistoryRowProps {\n entry: BundleEntry;\n}\n\nfunction HistoryRow(props: HistoryRowProps): JSX.Element {\n const { response, resource } = props.entry;\n if (resource) {\n return (\n <tr>\n <td>\n <ResourceBadge value={resource.meta?.author} link={true} />\n </td>\n <td>{formatDateTime(resource.meta?.lastUpdated)}</td>\n <td>\n <MedplumLink to={getVersionUrl(resource)}>{resource.meta?.versionId}</MedplumLink>\n </td>\n </tr>\n );\n } else {\n return (\n <tr>\n <td colSpan={3}>{normalizeErrorString(response?.outcome)}</td>\n </tr>\n );\n }\n}\n\nfunction getVersionUrl(resource: Resource): string {\n return `/${resource.resourceType}/${resource.id}/_history/${resource.meta?.versionId}`;\n}\n"],"names":[],"mappings":";;;;;;AAcM,SAAU,oBAAoB,CAAC,KAAgC,EAAA;;AACnE,IAAA,MAAM,OAAO,GAAG,UAAU,EAAE,CAAC;AAC7B,IAAA,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAqB,KAAK,CAAC,OAAO,CAAC,CAAC;IAEtE,SAAS,CAAC,MAAK;AACb,QAAA,IAAI,CAAC,KAAK,CAAC,OAAO,IAAI,KAAK,CAAC,YAAY,IAAI,KAAK,CAAC,EAAE,EAAE;YACpD,OAAO;iBACJ,WAAW,CAAC,KAAK,CAAC,YAA4B,EAAE,KAAK,CAAC,EAAE,CAAC;iBACzD,IAAI,CAAC,QAAQ,CAAC;AACd,iBAAA,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;AACvB,SAAA;AACH,KAAC,EAAE,CAAC,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,YAAY,EAAE,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC;IAE3D,IAAI,CAAC,KAAK,EAAE;AACV,QAAA,OAAO,8CAAqB,CAAC;AAC9B,KAAA;AAED,IAAA,QACE,KAAA,CAAA,aAAA,CAAA,OAAA,EAAA,EAAO,SAAS,EAAC,eAAe,EAAA;AAC9B,QAAA,KAAA,CAAA,aAAA,CAAA,OAAA,EAAA,IAAA;AACE,YAAA,KAAA,CAAA,aAAA,CAAA,IAAA,EAAA,IAAA;gBACE,KAAe,CAAA,aAAA,CAAA,IAAA,EAAA,IAAA,EAAA,QAAA,CAAA;gBACf,KAAa,CAAA,aAAA,CAAA,IAAA,EAAA,IAAA,EAAA,MAAA,CAAA;AACb,gBAAA,KAAA,CAAA,aAAA,CAAA,IAAA,EAAA,IAAA,EAAA,SAAA,CAAgB,CACb,CACC;AACR,QAAA,KAAA,CAAA,aAAA,CAAA,OAAA,EAAA,IAAA,EACG,CAAA,EAAA,GAAA,KAAK,CAAC,KAAK,0CAAE,GAAG,CAAC,CAAC,KAAK,EAAE,KAAK,MAC7B,KAAA,CAAA,aAAA,CAAC,UAAU,EAAA,EAAC,GAAG,EAAE,QAAQ,GAAG,KAAK,EAAE,KAAK,EAAE,KAAK,GAAI,CACpD,CAAC,CACI,CACF,EACR;AACJ,CAAC;AAMD,SAAS,UAAU,CAAC,KAAsB,EAAA;;IACxC,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,GAAG,KAAK,CAAC,KAAK,CAAC;AAC3C,IAAA,IAAI,QAAQ,EAAE;AACZ,QAAA,QACE,KAAA,CAAA,aAAA,CAAA,IAAA,EAAA,IAAA;AACE,YAAA,KAAA,CAAA,aAAA,CAAA,IAAA,EAAA,IAAA;AACE,gBAAA,KAAA,CAAA,aAAA,CAAC,aAAa,EAAA,EAAC,KAAK,EAAE,MAAA,QAAQ,CAAC,IAAI,MAAA,IAAA,IAAA,EAAA,KAAA,KAAA,CAAA,GAAA,KAAA,CAAA,GAAA,EAAA,CAAE,MAAM,EAAE,IAAI,EAAE,IAAI,GAAI,CACxD;YACL,KAAK,CAAA,aAAA,CAAA,IAAA,EAAA,IAAA,EAAA,cAAc,CAAC,CAAA,EAAA,GAAA,QAAQ,CAAC,IAAI,MAAA,IAAA,IAAA,EAAA,KAAA,KAAA,CAAA,GAAA,KAAA,CAAA,GAAA,EAAA,CAAE,WAAW,CAAC,CAAM;AACrD,YAAA,KAAA,CAAA,aAAA,CAAA,IAAA,EAAA,IAAA;AACE,gBAAA,KAAA,CAAA,aAAA,CAAC,WAAW,EAAC,EAAA,EAAE,EAAE,aAAa,CAAC,QAAQ,CAAC,EAAA,EAAG,MAAA,QAAQ,CAAC,IAAI,MAAE,IAAA,IAAA,EAAA,KAAA,KAAA,CAAA,GAAA,KAAA,CAAA,GAAA,EAAA,CAAA,SAAS,CAAe,CAC/E,CACF,EACL;AACH,KAAA;AAAM,SAAA;AACL,QAAA,QACE,KAAA,CAAA,aAAA,CAAA,IAAA,EAAA,IAAA;AACE,YAAA,KAAA,CAAA,aAAA,CAAA,IAAA,EAAA,EAAI,OAAO,EAAE,CAAC,EAAG,EAAA,oBAAoB,CAAC,QAAQ,KAAA,IAAA,IAAR,QAAQ,KAAA,KAAA,CAAA,GAAA,KAAA,CAAA,GAAR,QAAQ,CAAE,OAAO,CAAC,CAAM,CAC3D,EACL;AACH,KAAA;AACH,CAAC;AAED,SAAS,aAAa,CAAC,QAAkB,EAAA;;AACvC,IAAA,OAAO,IAAI,QAAQ,CAAC,YAAY,CAAA,CAAA,EAAI,QAAQ,CAAC,EAAE,CAAa,UAAA,EAAA,CAAA,EAAA,GAAA,QAAQ,CAAC,IAAI,MAAE,IAAA,IAAA,EAAA,KAAA,KAAA,CAAA,GAAA,KAAA,CAAA,GAAA,EAAA,CAAA,SAAS,EAAE,CAAC;AACzF;;;;"}
@@ -57,7 +57,9 @@ function ResourceTimeline(props) {
57
57
  }
58
58
  if (bundle.entry) {
59
59
  for (const entry of bundle.entry) {
60
- newItems.push(entry.resource);
60
+ if (entry.resource) {
61
+ newItems.push(entry.resource);
62
+ }
61
63
  }
62
64
  }
63
65
  }
@@ -1 +1 @@
1
- {"version":3,"file":"ResourceTimeline.js","sources":["../../src/ResourceTimeline.tsx"],"sourcesContent":["import { getReferenceString, ProfileResource } from '@medplum/core';\nimport {\n Attachment,\n AuditEvent,\n Bundle,\n BundleEntry,\n Communication,\n DiagnosticReport,\n Media,\n Reference,\n Resource,\n} from '@medplum/fhirtypes';\nimport React, { useCallback, useEffect, useRef, useState } from 'react';\nimport { useNavigate } from 'react-router-dom';\nimport { AttachmentDisplay } from './AttachmentDisplay';\nimport { Button } from './Button';\nimport { DiagnosticReportDisplay } from './DiagnosticReportDisplay';\nimport { Form } from './Form';\nimport { Input } from './Input';\nimport { Loading } from './Loading';\nimport { useMedplum } from './MedplumProvider';\nimport { MenuItem } from './MenuItem';\nimport { ResourceDiffTable } from './ResourceDiffTable';\nimport { ResourceTable } from './ResourceTable';\nimport { Scrollable } from './Scrollable';\nimport { Timeline, TimelineItem } from './Timeline';\nimport { UploadButton } from './UploadButton';\nimport { useResource } from './useResource';\nimport { sortByDateAndPriority } from './utils/date';\nimport './ResourceTimeline.css';\n\nexport interface ResourceTimelineProps<T extends Resource> {\n value: T | Reference<T>;\n buildSearchRequests: (resource: T) => Bundle;\n createCommunication?: (resource: T, sender: ProfileResource, text: string) => Communication;\n createMedia?: (resource: T, operator: ProfileResource, attachment: Attachment) => Media;\n}\n\nexport function ResourceTimeline<T extends Resource>(props: ResourceTimelineProps<T>): JSX.Element {\n const navigate = useNavigate();\n const medplum = useMedplum();\n const sender = medplum.getProfile() as ProfileResource;\n const inputRef = useRef<HTMLInputElement>(null);\n const resource = useResource(props.value);\n const [history, setHistory] = useState<Bundle>();\n const [items, setItems] = useState<Resource[]>([]);\n const buildSearchRequests = props.buildSearchRequests;\n\n const itemsRef = useRef<Resource[]>(items);\n itemsRef.current = items;\n\n const loadTimeline = useCallback(() => {\n if (!resource) {\n setItems([]);\n setHistory({} as Bundle);\n return;\n }\n medplum.executeBatch(buildSearchRequests(resource)).then(handleBatchResponse).catch(console.log);\n }, [medplum, resource, buildSearchRequests]);\n\n useEffect(() => {\n loadTimeline();\n }, [loadTimeline]);\n\n /**\n * Handles a batch request response.\n * @param batchResponse The batch response.\n */\n function handleBatchResponse(batchResponse: Bundle): void {\n const newItems = [];\n\n if (batchResponse.entry) {\n for (const batchEntry of batchResponse.entry) {\n const bundle = batchEntry.resource as Bundle;\n if (!bundle) {\n // User may not have access to all resource types\n continue;\n }\n\n if (bundle.type === 'history') {\n setHistory(bundle);\n }\n\n if (bundle.entry) {\n for (const entry of bundle.entry) {\n newItems.push(entry.resource as Resource);\n }\n }\n }\n\n sortByDateAndPriority(newItems);\n newItems.reverse();\n }\n\n setItems(newItems);\n }\n\n /**\n * Adds an array of resources to the timeline.\n * @param resources Array of resources.\n */\n function addResources(resources: Resource[]): void {\n const newItems = [...itemsRef.current, ...resources];\n sortByDateAndPriority(newItems);\n newItems.reverse();\n setItems(newItems);\n }\n\n /**\n * Adds a Communication resource to the timeline.\n * @param contentString The comment content.\n */\n function createComment(contentString: string): void {\n if (!resource || !props.createCommunication) {\n // Encounter not loaded yet\n return;\n }\n medplum\n .createResource(props.createCommunication(resource, sender, contentString))\n .then((result) => {\n addResources([result]);\n })\n .catch(console.log);\n }\n\n /**\n * Adds a Media resource to the timeline.\n * @param attachment The media attachment.\n */\n function createMedia(attachment: Attachment): void {\n if (!resource || !props.createMedia) {\n // Encounter not loaded yet\n return;\n }\n medplum\n .createResource(props.createMedia(resource, sender, attachment))\n .then((result) => {\n addResources([result]);\n })\n .catch(console.log);\n }\n\n function setPriority(communication: Communication, priority: string): Promise<Communication> {\n return medplum.updateResource({ ...communication, priority });\n }\n\n function onPin(communication: Communication): void {\n setPriority(communication, 'stat').then(loadTimeline).catch(console.log);\n }\n\n function onUnpin(communication: Communication): void {\n setPriority(communication, 'routine').then(loadTimeline).catch(console.log);\n }\n\n function onDetails(timelineItem: Resource): void {\n navigate(`/${timelineItem.resourceType}/${timelineItem.id}`);\n }\n\n function onEdit(timelineItem: Resource): void {\n navigate(`/${timelineItem.resourceType}/${timelineItem.id}/edit`);\n }\n\n function onDelete(timelineItem: Resource): void {\n navigate(`/${timelineItem.resourceType}/${timelineItem.id}/delete`);\n }\n\n function onVersionDetails(version: Resource): void {\n navigate(`/${version.resourceType}/${version.id}/_history/${version.meta?.versionId}`);\n }\n\n if (!resource || !history) {\n return <Loading />;\n }\n\n return (\n <Timeline>\n {props.createCommunication && (\n <article className=\"medplum-timeline-item\">\n <div className=\"medplum-timeline-item-header\">\n <Form\n testid=\"timeline-form\"\n onSubmit={(formData: Record<string, string>) => {\n createComment(formData.text);\n\n const input = inputRef.current;\n if (input) {\n input.value = '';\n input.focus();\n }\n }}\n >\n <Input name=\"text\" testid=\"timeline-input\" inputRef={inputRef} />\n <Button type=\"submit\">Comment</Button>\n <UploadButton onUpload={createMedia} />\n </Form>\n </div>\n </article>\n )}\n {items.map((item) => {\n if (item.resourceType === resource.resourceType && item.id === resource.id) {\n return (\n <HistoryTimelineItem\n key={item.meta?.versionId}\n history={history}\n resource={item}\n onDetails={onVersionDetails}\n />\n );\n }\n const key = `${item.resourceType}/${item.id}`;\n switch (item.resourceType) {\n case 'AuditEvent':\n return <AuditEventTimelineItem key={key} resource={item} onDetails={onDetails} />;\n case 'Communication':\n return (\n <CommunicationTimelineItem\n key={key}\n resource={item}\n onPin={item.priority !== 'stat' ? onPin : undefined}\n onUnpin={item.priority === 'stat' ? onUnpin : undefined}\n onDetails={onDetails}\n onEdit={onEdit}\n onDelete={onDelete}\n />\n );\n case 'DiagnosticReport':\n return (\n <DiagnosticReportTimelineItem\n key={key}\n resource={item}\n onDetails={onDetails}\n onEdit={onEdit}\n onDelete={onDelete}\n />\n );\n case 'Media':\n return (\n <MediaTimelineItem key={key} resource={item} onDetails={onDetails} onEdit={onEdit} onDelete={onDelete} />\n );\n default:\n return (\n <TimelineItem key={key} resource={item} padding={true}>\n <ResourceTable value={item} ignoreMissingValues={true} />\n </TimelineItem>\n );\n }\n })}\n </Timeline>\n );\n}\n\ninterface BaseTimelineItemProps<T extends Resource> {\n resource: T;\n onPin?: (resource: T) => void;\n onUnpin?: (resource: T) => void;\n onDetails?: (resource: T) => void;\n onEdit?: (resource: T) => void;\n onDelete?: (resource: T) => void;\n}\n\nfunction TimelineItemPopupMenu<T extends Resource>(props: BaseTimelineItemProps<T>): JSX.Element {\n return (\n <>\n {props.onPin && (\n <MenuItem\n onClick={() => (props.onPin as (resource: T) => void)(props.resource)}\n label={`Pin ${getReferenceString(props.resource)}`}\n >\n Pin\n </MenuItem>\n )}\n {props.onUnpin && (\n <MenuItem\n onClick={() => (props.onUnpin as (resource: T) => void)(props.resource)}\n label={`Unpin ${getReferenceString(props.resource)}`}\n >\n Unpin\n </MenuItem>\n )}\n {props.onDetails && (\n <MenuItem\n onClick={() => (props.onDetails as (resource: T) => void)(props.resource)}\n label={`Details ${getReferenceString(props.resource)}`}\n >\n Details\n </MenuItem>\n )}\n {props.onEdit && (\n <MenuItem\n onClick={() => (props.onEdit as (resource: T) => void)(props.resource)}\n label={`Edit ${getReferenceString(props.resource)}`}\n >\n Edit\n </MenuItem>\n )}\n {props.onDelete && (\n <MenuItem\n onClick={() => (props.onDelete as (resource: T) => void)(props.resource)}\n label={`Delete ${getReferenceString(props.resource)}`}\n >\n Delete\n </MenuItem>\n )}\n </>\n );\n}\n\ninterface HistoryTimelineItemProps extends BaseTimelineItemProps<Resource> {\n history: Bundle;\n}\n\nfunction HistoryTimelineItem(props: HistoryTimelineItemProps): JSX.Element {\n const previous = getPrevious(props.history, props.resource);\n if (previous) {\n return (\n <TimelineItem resource={props.resource} padding={true} popupMenuItems={<TimelineItemPopupMenu {...props} />}>\n <ResourceDiffTable original={previous} revised={props.resource} />\n </TimelineItem>\n );\n } else {\n return (\n <TimelineItem resource={props.resource} padding={true} popupMenuItems={<TimelineItemPopupMenu {...props} />}>\n <h3>Created</h3>\n <ResourceTable value={props.resource} ignoreMissingValues={true} />\n </TimelineItem>\n );\n }\n}\n\nfunction getPrevious(history: Bundle, version: Resource): Resource | undefined {\n const entries = history.entry as BundleEntry[];\n const index = entries.findIndex((entry) => entry.resource?.meta?.versionId === version.meta?.versionId);\n if (index >= entries.length - 1) {\n return undefined;\n }\n return entries[index + 1].resource;\n}\n\nfunction CommunicationTimelineItem(props: BaseTimelineItemProps<Communication>): JSX.Element {\n const routine = !props.resource.priority || props.resource.priority === 'routine';\n const className = routine ? 'medplum-timeline-item' : 'medplum-timeline-item medplum-timeline-item-pinned';\n return (\n <TimelineItem\n resource={props.resource}\n profile={props.resource.sender}\n padding={true}\n className={className}\n popupMenuItems={<TimelineItemPopupMenu {...props} />}\n >\n <p>{props.resource.payload?.[0]?.contentString}</p>\n </TimelineItem>\n );\n}\n\nfunction MediaTimelineItem(props: BaseTimelineItemProps<Media>): JSX.Element {\n const contentType = props.resource.content?.contentType;\n const padding =\n contentType &&\n !contentType.startsWith('image/') &&\n !contentType.startsWith('video/') &&\n contentType !== 'application/pdf';\n return (\n <TimelineItem resource={props.resource} padding={!!padding} popupMenuItems={<TimelineItemPopupMenu {...props} />}>\n <AttachmentDisplay value={props.resource.content} />\n </TimelineItem>\n );\n}\n\nfunction AuditEventTimelineItem(props: BaseTimelineItemProps<AuditEvent>): JSX.Element {\n return (\n <TimelineItem resource={props.resource} padding={true} popupMenuItems={<TimelineItemPopupMenu {...props} />}>\n <Scrollable>\n <pre>{props.resource.outcomeDesc}</pre>\n </Scrollable>\n </TimelineItem>\n );\n}\n\nfunction DiagnosticReportTimelineItem(props: BaseTimelineItemProps<DiagnosticReport>): JSX.Element {\n return (\n <TimelineItem resource={props.resource} padding={true} popupMenuItems={<TimelineItemPopupMenu {...props} />}>\n <DiagnosticReportDisplay value={props.resource} />\n </TimelineItem>\n );\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ResourceTimeline.js","sources":["../../src/ResourceTimeline.tsx"],"sourcesContent":["import { getReferenceString, ProfileResource } from '@medplum/core';\nimport {\n Attachment,\n AuditEvent,\n Bundle,\n BundleEntry,\n Communication,\n DiagnosticReport,\n Media,\n Reference,\n Resource,\n} from '@medplum/fhirtypes';\nimport React, { useCallback, useEffect, useRef, useState } from 'react';\nimport { useNavigate } from 'react-router-dom';\nimport { AttachmentDisplay } from './AttachmentDisplay';\nimport { Button } from './Button';\nimport { DiagnosticReportDisplay } from './DiagnosticReportDisplay';\nimport { Form } from './Form';\nimport { Input } from './Input';\nimport { Loading } from './Loading';\nimport { useMedplum } from './MedplumProvider';\nimport { MenuItem } from './MenuItem';\nimport { ResourceDiffTable } from './ResourceDiffTable';\nimport { ResourceTable } from './ResourceTable';\nimport { Scrollable } from './Scrollable';\nimport { Timeline, TimelineItem } from './Timeline';\nimport { UploadButton } from './UploadButton';\nimport { useResource } from './useResource';\nimport { sortByDateAndPriority } from './utils/date';\nimport './ResourceTimeline.css';\n\nexport interface ResourceTimelineProps<T extends Resource> {\n value: T | Reference<T>;\n buildSearchRequests: (resource: T) => Bundle;\n createCommunication?: (resource: T, sender: ProfileResource, text: string) => Communication;\n createMedia?: (resource: T, operator: ProfileResource, attachment: Attachment) => Media;\n}\n\nexport function ResourceTimeline<T extends Resource>(props: ResourceTimelineProps<T>): JSX.Element {\n const navigate = useNavigate();\n const medplum = useMedplum();\n const sender = medplum.getProfile() as ProfileResource;\n const inputRef = useRef<HTMLInputElement>(null);\n const resource = useResource(props.value);\n const [history, setHistory] = useState<Bundle>();\n const [items, setItems] = useState<Resource[]>([]);\n const buildSearchRequests = props.buildSearchRequests;\n\n const itemsRef = useRef<Resource[]>(items);\n itemsRef.current = items;\n\n const loadTimeline = useCallback(() => {\n if (!resource) {\n setItems([]);\n setHistory({} as Bundle);\n return;\n }\n medplum.executeBatch(buildSearchRequests(resource)).then(handleBatchResponse).catch(console.log);\n }, [medplum, resource, buildSearchRequests]);\n\n useEffect(() => {\n loadTimeline();\n }, [loadTimeline]);\n\n /**\n * Handles a batch request response.\n * @param batchResponse The batch response.\n */\n function handleBatchResponse(batchResponse: Bundle): void {\n const newItems = [];\n\n if (batchResponse.entry) {\n for (const batchEntry of batchResponse.entry) {\n const bundle = batchEntry.resource as Bundle;\n if (!bundle) {\n // User may not have access to all resource types\n continue;\n }\n\n if (bundle.type === 'history') {\n setHistory(bundle);\n }\n\n if (bundle.entry) {\n for (const entry of bundle.entry) {\n if (entry.resource) {\n newItems.push(entry.resource);\n }\n }\n }\n }\n\n sortByDateAndPriority(newItems);\n newItems.reverse();\n }\n\n setItems(newItems);\n }\n\n /**\n * Adds an array of resources to the timeline.\n * @param resources Array of resources.\n */\n function addResources(resources: Resource[]): void {\n const newItems = [...itemsRef.current, ...resources];\n sortByDateAndPriority(newItems);\n newItems.reverse();\n setItems(newItems);\n }\n\n /**\n * Adds a Communication resource to the timeline.\n * @param contentString The comment content.\n */\n function createComment(contentString: string): void {\n if (!resource || !props.createCommunication) {\n // Encounter not loaded yet\n return;\n }\n medplum\n .createResource(props.createCommunication(resource, sender, contentString))\n .then((result) => {\n addResources([result]);\n })\n .catch(console.log);\n }\n\n /**\n * Adds a Media resource to the timeline.\n * @param attachment The media attachment.\n */\n function createMedia(attachment: Attachment): void {\n if (!resource || !props.createMedia) {\n // Encounter not loaded yet\n return;\n }\n medplum\n .createResource(props.createMedia(resource, sender, attachment))\n .then((result) => {\n addResources([result]);\n })\n .catch(console.log);\n }\n\n function setPriority(communication: Communication, priority: string): Promise<Communication> {\n return medplum.updateResource({ ...communication, priority });\n }\n\n function onPin(communication: Communication): void {\n setPriority(communication, 'stat').then(loadTimeline).catch(console.log);\n }\n\n function onUnpin(communication: Communication): void {\n setPriority(communication, 'routine').then(loadTimeline).catch(console.log);\n }\n\n function onDetails(timelineItem: Resource): void {\n navigate(`/${timelineItem.resourceType}/${timelineItem.id}`);\n }\n\n function onEdit(timelineItem: Resource): void {\n navigate(`/${timelineItem.resourceType}/${timelineItem.id}/edit`);\n }\n\n function onDelete(timelineItem: Resource): void {\n navigate(`/${timelineItem.resourceType}/${timelineItem.id}/delete`);\n }\n\n function onVersionDetails(version: Resource): void {\n navigate(`/${version.resourceType}/${version.id}/_history/${version.meta?.versionId}`);\n }\n\n if (!resource || !history) {\n return <Loading />;\n }\n\n return (\n <Timeline>\n {props.createCommunication && (\n <article className=\"medplum-timeline-item\">\n <div className=\"medplum-timeline-item-header\">\n <Form\n testid=\"timeline-form\"\n onSubmit={(formData: Record<string, string>) => {\n createComment(formData.text);\n\n const input = inputRef.current;\n if (input) {\n input.value = '';\n input.focus();\n }\n }}\n >\n <Input name=\"text\" testid=\"timeline-input\" inputRef={inputRef} />\n <Button type=\"submit\">Comment</Button>\n <UploadButton onUpload={createMedia} />\n </Form>\n </div>\n </article>\n )}\n {items.map((item) => {\n if (item.resourceType === resource.resourceType && item.id === resource.id) {\n return (\n <HistoryTimelineItem\n key={item.meta?.versionId}\n history={history}\n resource={item}\n onDetails={onVersionDetails}\n />\n );\n }\n const key = `${item.resourceType}/${item.id}`;\n switch (item.resourceType) {\n case 'AuditEvent':\n return <AuditEventTimelineItem key={key} resource={item} onDetails={onDetails} />;\n case 'Communication':\n return (\n <CommunicationTimelineItem\n key={key}\n resource={item}\n onPin={item.priority !== 'stat' ? onPin : undefined}\n onUnpin={item.priority === 'stat' ? onUnpin : undefined}\n onDetails={onDetails}\n onEdit={onEdit}\n onDelete={onDelete}\n />\n );\n case 'DiagnosticReport':\n return (\n <DiagnosticReportTimelineItem\n key={key}\n resource={item}\n onDetails={onDetails}\n onEdit={onEdit}\n onDelete={onDelete}\n />\n );\n case 'Media':\n return (\n <MediaTimelineItem key={key} resource={item} onDetails={onDetails} onEdit={onEdit} onDelete={onDelete} />\n );\n default:\n return (\n <TimelineItem key={key} resource={item} padding={true}>\n <ResourceTable value={item} ignoreMissingValues={true} />\n </TimelineItem>\n );\n }\n })}\n </Timeline>\n );\n}\n\ninterface BaseTimelineItemProps<T extends Resource> {\n resource: T;\n onPin?: (resource: T) => void;\n onUnpin?: (resource: T) => void;\n onDetails?: (resource: T) => void;\n onEdit?: (resource: T) => void;\n onDelete?: (resource: T) => void;\n}\n\nfunction TimelineItemPopupMenu<T extends Resource>(props: BaseTimelineItemProps<T>): JSX.Element {\n return (\n <>\n {props.onPin && (\n <MenuItem\n onClick={() => (props.onPin as (resource: T) => void)(props.resource)}\n label={`Pin ${getReferenceString(props.resource)}`}\n >\n Pin\n </MenuItem>\n )}\n {props.onUnpin && (\n <MenuItem\n onClick={() => (props.onUnpin as (resource: T) => void)(props.resource)}\n label={`Unpin ${getReferenceString(props.resource)}`}\n >\n Unpin\n </MenuItem>\n )}\n {props.onDetails && (\n <MenuItem\n onClick={() => (props.onDetails as (resource: T) => void)(props.resource)}\n label={`Details ${getReferenceString(props.resource)}`}\n >\n Details\n </MenuItem>\n )}\n {props.onEdit && (\n <MenuItem\n onClick={() => (props.onEdit as (resource: T) => void)(props.resource)}\n label={`Edit ${getReferenceString(props.resource)}`}\n >\n Edit\n </MenuItem>\n )}\n {props.onDelete && (\n <MenuItem\n onClick={() => (props.onDelete as (resource: T) => void)(props.resource)}\n label={`Delete ${getReferenceString(props.resource)}`}\n >\n Delete\n </MenuItem>\n )}\n </>\n );\n}\n\ninterface HistoryTimelineItemProps extends BaseTimelineItemProps<Resource> {\n history: Bundle;\n}\n\nfunction HistoryTimelineItem(props: HistoryTimelineItemProps): JSX.Element {\n const previous = getPrevious(props.history, props.resource);\n if (previous) {\n return (\n <TimelineItem resource={props.resource} padding={true} popupMenuItems={<TimelineItemPopupMenu {...props} />}>\n <ResourceDiffTable original={previous} revised={props.resource} />\n </TimelineItem>\n );\n } else {\n return (\n <TimelineItem resource={props.resource} padding={true} popupMenuItems={<TimelineItemPopupMenu {...props} />}>\n <h3>Created</h3>\n <ResourceTable value={props.resource} ignoreMissingValues={true} />\n </TimelineItem>\n );\n }\n}\n\nfunction getPrevious(history: Bundle, version: Resource): Resource | undefined {\n const entries = history.entry as BundleEntry[];\n const index = entries.findIndex((entry) => entry.resource?.meta?.versionId === version.meta?.versionId);\n if (index >= entries.length - 1) {\n return undefined;\n }\n return entries[index + 1].resource;\n}\n\nfunction CommunicationTimelineItem(props: BaseTimelineItemProps<Communication>): JSX.Element {\n const routine = !props.resource.priority || props.resource.priority === 'routine';\n const className = routine ? 'medplum-timeline-item' : 'medplum-timeline-item medplum-timeline-item-pinned';\n return (\n <TimelineItem\n resource={props.resource}\n profile={props.resource.sender}\n padding={true}\n className={className}\n popupMenuItems={<TimelineItemPopupMenu {...props} />}\n >\n <p>{props.resource.payload?.[0]?.contentString}</p>\n </TimelineItem>\n );\n}\n\nfunction MediaTimelineItem(props: BaseTimelineItemProps<Media>): JSX.Element {\n const contentType = props.resource.content?.contentType;\n const padding =\n contentType &&\n !contentType.startsWith('image/') &&\n !contentType.startsWith('video/') &&\n contentType !== 'application/pdf';\n return (\n <TimelineItem resource={props.resource} padding={!!padding} popupMenuItems={<TimelineItemPopupMenu {...props} />}>\n <AttachmentDisplay value={props.resource.content} />\n </TimelineItem>\n );\n}\n\nfunction AuditEventTimelineItem(props: BaseTimelineItemProps<AuditEvent>): JSX.Element {\n return (\n <TimelineItem resource={props.resource} padding={true} popupMenuItems={<TimelineItemPopupMenu {...props} />}>\n <Scrollable>\n <pre>{props.resource.outcomeDesc}</pre>\n </Scrollable>\n </TimelineItem>\n );\n}\n\nfunction DiagnosticReportTimelineItem(props: BaseTimelineItemProps<DiagnosticReport>): JSX.Element {\n return (\n <TimelineItem resource={props.resource} padding={true} popupMenuItems={<TimelineItemPopupMenu {...props} />}>\n <DiagnosticReportDisplay value={props.resource} />\n </TimelineItem>\n );\n}\n"],"names":[],"mappings":"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"}
@@ -1,7 +1,8 @@
1
1
  /// <reference types="react" />
2
- import { Reference, Schedule } from '@medplum/fhirtypes';
2
+ import { Questionnaire, Reference, Schedule } from '@medplum/fhirtypes';
3
3
  import './Scheduler.css';
4
4
  export interface SchedulerProps {
5
5
  schedule: Schedule | Reference<Schedule>;
6
+ questionnaire: Questionnaire | Reference<Questionnaire>;
6
7
  }
7
8
  export declare function Scheduler(props: SchedulerProps): JSX.Element | null;
@@ -3,9 +3,8 @@ import React, { useState, useRef, useEffect } from 'react';
3
3
  import { Avatar } from './Avatar.js';
4
4
  import { Button } from './Button.js';
5
5
  import { getStartMonth, CalendarInput } from './CalendarInput.js';
6
- import { FormSection } from './FormSection.js';
7
- import { Input } from './Input.js';
8
6
  import { useMedplum } from './MedplumProvider.js';
7
+ import { QuestionnaireForm } from './QuestionnaireForm.js';
9
8
  import { ResourceName } from './ResourceName.js';
10
9
  import { useResource } from './useResource.js';
11
10
 
@@ -13,22 +12,23 @@ function Scheduler(props) {
13
12
  var _a;
14
13
  const medplum = useMedplum();
15
14
  const schedule = useResource(props.schedule);
15
+ const questionnaire = useResource(props.questionnaire);
16
16
  const [slots, setSlots] = useState();
17
17
  const slotsRef = useRef();
18
18
  slotsRef.current = slots;
19
19
  const [month, setMonth] = useState(getStartMonth());
20
20
  const [date, setDate] = useState();
21
21
  const [slot, setSlot] = useState();
22
- const [info, setInfo] = useState();
23
- const [form, setForm] = useState();
22
+ const [response, setResponse] = useState();
24
23
  useEffect(() => {
25
24
  if (schedule) {
26
25
  setSlots([]);
27
26
  medplum
28
27
  .searchResources('Slot', new URLSearchParams([
28
+ ['_count', (30 * 24).toString()],
29
29
  ['schedule', getReferenceString(schedule)],
30
- ['start', 'gt' + month.toISOString()],
31
- ['start', 'lt' + new Date(month.getTime() + 31 * 24 * 60 * 60 * 1000).toISOString()],
30
+ ['start', 'gt' + getStart(month)],
31
+ ['start', 'lt' + getEnd(month)],
32
32
  ]))
33
33
  .then(setSlots)
34
34
  .catch(console.log);
@@ -37,7 +37,7 @@ function Scheduler(props) {
37
37
  setSlots(undefined);
38
38
  }
39
39
  }, [medplum, schedule, month]);
40
- if (!schedule || !slots) {
40
+ if (!schedule || !slots || !questionnaire) {
41
41
  return null;
42
42
  }
43
43
  const actor = (_a = schedule.actor) === null || _a === void 0 ? void 0 : _a[0];
@@ -61,26 +61,20 @@ function Scheduler(props) {
61
61
  slotStart.getTime() < date.getTime() + 24 * 3600 * 1000 && (React.createElement("div", { key: s.id },
62
62
  React.createElement(Button, { style: { width: 150 }, onClick: () => setSlot(s) }, formatTime(slotStart)))));
63
63
  }))),
64
- date && slot && !info && (React.createElement("div", null,
65
- React.createElement("h3", null, "Enter your info"),
66
- React.createElement(FormSection, { title: "Name", htmlFor: "name" },
67
- React.createElement(Input, { name: "name" })),
68
- React.createElement(FormSection, { title: "Email", htmlFor: "email" },
69
- React.createElement(Input, { name: "email" })),
70
- React.createElement(Button, { primary: true, onClick: () => setInfo('info') }, "Next"))),
71
- date && slot && info && !form && (React.createElement("div", null,
72
- React.createElement("h3", null, "Custom questions"),
73
- React.createElement(FormSection, { title: "Question 1", htmlFor: "q1" },
74
- React.createElement(Input, { name: "q1" })),
75
- React.createElement(FormSection, { title: "Question 2", htmlFor: "q2" },
76
- React.createElement(Input, { name: "email" })),
77
- React.createElement(FormSection, { title: "Question 3", htmlFor: "q3" },
78
- React.createElement(Input, { name: "email" })),
79
- React.createElement(Button, { primary: true, onClick: () => setForm('form') }, "Next"))),
80
- date && slot && info && form && (React.createElement("div", null,
64
+ date && slot && !response && (React.createElement(QuestionnaireForm, { questionnaire: questionnaire, submitButtonText: 'Next', onSubmit: setResponse })),
65
+ date && slot && response && (React.createElement("div", null,
81
66
  React.createElement("h3", null, "You're all set!"),
82
67
  React.createElement("p", null, "Check your email for a calendar invite."))))));
83
68
  }
69
+ function getStart(month) {
70
+ return formatSlotInstant(month.getTime());
71
+ }
72
+ function getEnd(month) {
73
+ return formatSlotInstant(month.getTime() + 31 * 24 * 60 * 60 * 1000);
74
+ }
75
+ function formatSlotInstant(time) {
76
+ return new Date(Math.max(Date.now(), time)).toISOString();
77
+ }
84
78
  function formatTime(date) {
85
79
  return date.toLocaleTimeString([], { hour: 'numeric', minute: '2-digit' });
86
80
  }
@@ -1 +1 @@
1
- {"version":3,"file":"Scheduler.js","sources":["../../src/Scheduler.tsx"],"sourcesContent":["import { getReferenceString } from '@medplum/core';\nimport { Reference, Schedule, Slot } from '@medplum/fhirtypes';\nimport React, { useEffect, useRef, useState } from 'react';\nimport { Avatar } from './Avatar';\nimport { Button } from './Button';\nimport { CalendarInput, getStartMonth } from './CalendarInput';\nimport { FormSection } from './FormSection';\nimport { Input } from './Input';\nimport { useMedplum } from './MedplumProvider';\nimport { ResourceName } from './ResourceName';\nimport './Scheduler.css';\nimport { useResource } from './useResource';\n\nexport interface SchedulerProps {\n schedule: Schedule | Reference<Schedule>;\n}\n\nexport function Scheduler(props: SchedulerProps): JSX.Element | null {\n const medplum = useMedplum();\n const schedule = useResource(props.schedule);\n\n const [slots, setSlots] = useState<Slot[]>();\n const slotsRef = useRef<Slot[]>();\n slotsRef.current = slots;\n\n const [month, setMonth] = useState<Date>(getStartMonth());\n const [date, setDate] = useState<Date>();\n const [slot, setSlot] = useState<Slot>();\n const [info, setInfo] = useState<string>();\n const [form, setForm] = useState<string>();\n\n useEffect(() => {\n if (schedule) {\n setSlots([]);\n medplum\n .searchResources(\n 'Slot',\n new URLSearchParams([\n ['schedule', getReferenceString(schedule)],\n ['start', 'gt' + month.toISOString()],\n ['start', 'lt' + new Date(month.getTime() + 31 * 24 * 60 * 60 * 1000).toISOString()],\n ])\n )\n .then(setSlots)\n .catch(console.log);\n } else {\n setSlots(undefined);\n }\n }, [medplum, schedule, month]);\n\n if (!schedule || !slots) {\n return null;\n }\n\n const actor = schedule.actor?.[0];\n\n return (\n <div className=\"medplum-calendar-container\" data-testid=\"scheduler\">\n <div className=\"medplum-calendar-info-pane\">\n {actor && <Avatar value={actor} size=\"large\" />}\n {actor && (\n <h1>\n <ResourceName value={actor} />\n </h1>\n )}\n <p>1 hour</p>\n {date && <p>{date.toLocaleDateString()}</p>}\n {slot && <p>{formatTime(new Date(slot.start as string))}</p>}\n </div>\n <div className=\"medplum-calendar-selection-pane\">\n {!date && (\n <div>\n <h3>Select date</h3>\n <CalendarInput slots={slots} onChangeMonth={setMonth} onClick={setDate} />\n </div>\n )}\n {date && !slot && (\n <div>\n <h3>Select time</h3>\n {slots.map((s) => {\n const slotStart = new Date(s.start as string);\n return (\n slotStart.getTime() > date.getTime() &&\n slotStart.getTime() < date.getTime() + 24 * 3600 * 1000 && (\n <div key={s.id}>\n <Button style={{ width: 150 }} onClick={() => setSlot(s)}>\n {formatTime(slotStart)}\n </Button>\n </div>\n )\n );\n })}\n </div>\n )}\n {date && slot && !info && (\n <div>\n <h3>Enter your info</h3>\n <FormSection title=\"Name\" htmlFor=\"name\">\n <Input name=\"name\" />\n </FormSection>\n <FormSection title=\"Email\" htmlFor=\"email\">\n <Input name=\"email\" />\n </FormSection>\n <Button primary={true} onClick={() => setInfo('info')}>\n Next\n </Button>\n </div>\n )}\n {date && slot && info && !form && (\n <div>\n <h3>Custom questions</h3>\n <FormSection title=\"Question 1\" htmlFor=\"q1\">\n <Input name=\"q1\" />\n </FormSection>\n <FormSection title=\"Question 2\" htmlFor=\"q2\">\n <Input name=\"email\" />\n </FormSection>\n <FormSection title=\"Question 3\" htmlFor=\"q3\">\n <Input name=\"email\" />\n </FormSection>\n <Button primary={true} onClick={() => setForm('form')}>\n Next\n </Button>\n </div>\n )}\n {date && slot && info && form && (\n <div>\n <h3>You're all set!</h3>\n <p>Check your email for a calendar invite.</p>\n </div>\n )}\n </div>\n </div>\n );\n}\n\nfunction formatTime(date: Date): string {\n return date.toLocaleTimeString([], { hour: 'numeric', minute: '2-digit' });\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Scheduler.js","sources":["../../src/Scheduler.tsx"],"sourcesContent":["import { getReferenceString } from '@medplum/core';\nimport { Questionnaire, QuestionnaireResponse, Reference, Schedule, Slot } from '@medplum/fhirtypes';\nimport React, { useEffect, useRef, useState } from 'react';\nimport { Avatar } from './Avatar';\nimport { Button } from './Button';\nimport { CalendarInput, getStartMonth } from './CalendarInput';\nimport { useMedplum } from './MedplumProvider';\nimport { QuestionnaireForm } from './QuestionnaireForm';\nimport { ResourceName } from './ResourceName';\nimport { useResource } from './useResource';\nimport './Scheduler.css';\n\nexport interface SchedulerProps {\n schedule: Schedule | Reference<Schedule>;\n questionnaire: Questionnaire | Reference<Questionnaire>;\n}\n\nexport function Scheduler(props: SchedulerProps): JSX.Element | null {\n const medplum = useMedplum();\n const schedule = useResource(props.schedule);\n const questionnaire = useResource(props.questionnaire);\n\n const [slots, setSlots] = useState<Slot[]>();\n const slotsRef = useRef<Slot[]>();\n slotsRef.current = slots;\n\n const [month, setMonth] = useState<Date>(getStartMonth());\n const [date, setDate] = useState<Date>();\n const [slot, setSlot] = useState<Slot>();\n const [response, setResponse] = useState<QuestionnaireResponse>();\n\n useEffect(() => {\n if (schedule) {\n setSlots([]);\n medplum\n .searchResources(\n 'Slot',\n new URLSearchParams([\n ['_count', (30 * 24).toString()],\n ['schedule', getReferenceString(schedule)],\n ['start', 'gt' + getStart(month)],\n ['start', 'lt' + getEnd(month)],\n ])\n )\n .then(setSlots)\n .catch(console.log);\n } else {\n setSlots(undefined);\n }\n }, [medplum, schedule, month]);\n\n if (!schedule || !slots || !questionnaire) {\n return null;\n }\n\n const actor = schedule.actor?.[0];\n\n return (\n <div className=\"medplum-calendar-container\" data-testid=\"scheduler\">\n <div className=\"medplum-calendar-info-pane\">\n {actor && <Avatar value={actor} size=\"large\" />}\n {actor && (\n <h1>\n <ResourceName value={actor} />\n </h1>\n )}\n <p>1 hour</p>\n {date && <p>{date.toLocaleDateString()}</p>}\n {slot && <p>{formatTime(new Date(slot.start as string))}</p>}\n </div>\n <div className=\"medplum-calendar-selection-pane\">\n {!date && (\n <div>\n <h3>Select date</h3>\n <CalendarInput slots={slots} onChangeMonth={setMonth} onClick={setDate} />\n </div>\n )}\n {date && !slot && (\n <div>\n <h3>Select time</h3>\n {slots.map((s) => {\n const slotStart = new Date(s.start as string);\n return (\n slotStart.getTime() > date.getTime() &&\n slotStart.getTime() < date.getTime() + 24 * 3600 * 1000 && (\n <div key={s.id}>\n <Button style={{ width: 150 }} onClick={() => setSlot(s)}>\n {formatTime(slotStart)}\n </Button>\n </div>\n )\n );\n })}\n </div>\n )}\n {date && slot && !response && (\n <QuestionnaireForm questionnaire={questionnaire} submitButtonText={'Next'} onSubmit={setResponse} />\n )}\n {date && slot && response && (\n <div>\n <h3>You're all set!</h3>\n <p>Check your email for a calendar invite.</p>\n </div>\n )}\n </div>\n </div>\n );\n}\n\nfunction getStart(month: Date): string {\n return formatSlotInstant(month.getTime());\n}\n\nfunction getEnd(month: Date): string {\n return formatSlotInstant(month.getTime() + 31 * 24 * 60 * 60 * 1000);\n}\n\nfunction formatSlotInstant(time: number): string {\n return new Date(Math.max(Date.now(), time)).toISOString();\n}\n\nfunction formatTime(date: Date): string {\n return date.toLocaleTimeString([], { hour: 'numeric', minute: '2-digit' });\n}\n"],"names":[],"mappings":"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"}
@@ -16,19 +16,19 @@ function ServiceRequestTimeline(props) {
16
16
  {
17
17
  request: {
18
18
  method: 'GET',
19
- url: `Communication?based-on=${getReferenceString(resource)}`,
19
+ url: `Communication?based-on=${getReferenceString(resource)}&_sort=-_lastUpdated`,
20
20
  },
21
21
  },
22
22
  {
23
23
  request: {
24
24
  method: 'GET',
25
- url: `Media?_count=100&based-on=${getReferenceString(resource)}`,
25
+ url: `Media?_count=100&based-on=${getReferenceString(resource)}&_sort=-_lastUpdated`,
26
26
  },
27
27
  },
28
28
  {
29
29
  request: {
30
30
  method: 'GET',
31
- url: `DiagnosticReport?based-on=${getReferenceString(resource)}`,
31
+ url: `DiagnosticReport?based-on=${getReferenceString(resource)}&_sort=-_lastUpdated`,
32
32
  },
33
33
  },
34
34
  ],
@@ -1 +1 @@
1
- {"version":3,"file":"ServiceRequestTimeline.js","sources":["../../src/ServiceRequestTimeline.tsx"],"sourcesContent":["import { createReference, getReferenceString, ProfileResource } from '@medplum/core';\nimport { Attachment, Group, Patient, Reference, Resource, ServiceRequest } from '@medplum/fhirtypes';\nimport React from 'react';\nimport { ResourceTimeline } from './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 buildSearchRequests={(resource: Resource) => ({\n resourceType: 'Bundle',\n type: 'batch',\n entry: [\n {\n request: {\n method: 'GET',\n url: `${getReferenceString(resource)}/_history`,\n },\n },\n {\n request: {\n method: 'GET',\n url: `Communication?based-on=${getReferenceString(resource)}`,\n },\n },\n {\n request: {\n method: 'GET',\n url: `Media?_count=100&based-on=${getReferenceString(resource)}`,\n },\n },\n {\n request: {\n method: 'GET',\n url: `DiagnosticReport?based-on=${getReferenceString(resource)}`,\n },\n },\n ],\n })}\n createCommunication={(resource: ServiceRequest, sender: ProfileResource, text: string) => ({\n resourceType: 'Communication',\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 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;AACvE,IAAA,QACE,KAAC,CAAA,aAAA,CAAA,gBAAgB,EACf,EAAA,KAAK,EAAE,KAAK,CAAC,cAAc,EAC3B,mBAAmB,EAAE,CAAC,QAAkB,MAAM;AAC5C,YAAA,YAAY,EAAE,QAAQ;AACtB,YAAA,IAAI,EAAE,OAAO;AACb,YAAA,KAAK,EAAE;AACL,gBAAA;AACE,oBAAA,OAAO,EAAE;AACP,wBAAA,MAAM,EAAE,KAAK;AACb,wBAAA,GAAG,EAAE,CAAG,EAAA,kBAAkB,CAAC,QAAQ,CAAC,CAAW,SAAA,CAAA;AAChD,qBAAA;AACF,iBAAA;AACD,gBAAA;AACE,oBAAA,OAAO,EAAE;AACP,wBAAA,MAAM,EAAE,KAAK;AACb,wBAAA,GAAG,EAAE,CAA0B,uBAAA,EAAA,kBAAkB,CAAC,QAAQ,CAAC,CAAE,CAAA;AAC9D,qBAAA;AACF,iBAAA;AACD,gBAAA;AACE,oBAAA,OAAO,EAAE;AACP,wBAAA,MAAM,EAAE,KAAK;AACb,wBAAA,GAAG,EAAE,CAA6B,0BAAA,EAAA,kBAAkB,CAAC,QAAQ,CAAC,CAAE,CAAA;AACjE,qBAAA;AACF,iBAAA;AACD,gBAAA;AACE,oBAAA,OAAO,EAAE;AACP,wBAAA,MAAM,EAAE,KAAK;AACb,wBAAA,GAAG,EAAE,CAA6B,0BAAA,EAAA,kBAAkB,CAAC,QAAQ,CAAC,CAAE,CAAA;AACjE,qBAAA;AACF,iBAAA;AACF,aAAA;AACF,SAAA,CAAC,EACF,mBAAmB,EAAE,CAAC,QAAwB,EAAE,MAAuB,EAAE,IAAY,MAAM;AACzF,YAAA,YAAY,EAAE,eAAe;AAC7B,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,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;;;;"}
1
+ {"version":3,"file":"ServiceRequestTimeline.js","sources":["../../src/ServiceRequestTimeline.tsx"],"sourcesContent":["import { createReference, getReferenceString, ProfileResource } from '@medplum/core';\nimport { Attachment, Group, Patient, Reference, Resource, ServiceRequest } from '@medplum/fhirtypes';\nimport React from 'react';\nimport { ResourceTimeline } from './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 buildSearchRequests={(resource: Resource) => ({\n resourceType: 'Bundle',\n type: 'batch',\n entry: [\n {\n request: {\n method: 'GET',\n url: `${getReferenceString(resource)}/_history`,\n },\n },\n {\n request: {\n method: 'GET',\n url: `Communication?based-on=${getReferenceString(resource)}&_sort=-_lastUpdated`,\n },\n },\n {\n request: {\n method: 'GET',\n url: `Media?_count=100&based-on=${getReferenceString(resource)}&_sort=-_lastUpdated`,\n },\n },\n {\n request: {\n method: 'GET',\n url: `DiagnosticReport?based-on=${getReferenceString(resource)}&_sort=-_lastUpdated`,\n },\n },\n ],\n })}\n createCommunication={(resource: ServiceRequest, sender: ProfileResource, text: string) => ({\n resourceType: 'Communication',\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 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;AACvE,IAAA,QACE,KAAC,CAAA,aAAA,CAAA,gBAAgB,EACf,EAAA,KAAK,EAAE,KAAK,CAAC,cAAc,EAC3B,mBAAmB,EAAE,CAAC,QAAkB,MAAM;AAC5C,YAAA,YAAY,EAAE,QAAQ;AACtB,YAAA,IAAI,EAAE,OAAO;AACb,YAAA,KAAK,EAAE;AACL,gBAAA;AACE,oBAAA,OAAO,EAAE;AACP,wBAAA,MAAM,EAAE,KAAK;AACb,wBAAA,GAAG,EAAE,CAAG,EAAA,kBAAkB,CAAC,QAAQ,CAAC,CAAW,SAAA,CAAA;AAChD,qBAAA;AACF,iBAAA;AACD,gBAAA;AACE,oBAAA,OAAO,EAAE;AACP,wBAAA,MAAM,EAAE,KAAK;AACb,wBAAA,GAAG,EAAE,CAA0B,uBAAA,EAAA,kBAAkB,CAAC,QAAQ,CAAC,CAAsB,oBAAA,CAAA;AAClF,qBAAA;AACF,iBAAA;AACD,gBAAA;AACE,oBAAA,OAAO,EAAE;AACP,wBAAA,MAAM,EAAE,KAAK;AACb,wBAAA,GAAG,EAAE,CAA6B,0BAAA,EAAA,kBAAkB,CAAC,QAAQ,CAAC,CAAsB,oBAAA,CAAA;AACrF,qBAAA;AACF,iBAAA;AACD,gBAAA;AACE,oBAAA,OAAO,EAAE;AACP,wBAAA,MAAM,EAAE,KAAK;AACb,wBAAA,GAAG,EAAE,CAA6B,0BAAA,EAAA,kBAAkB,CAAC,QAAQ,CAAC,CAAsB,oBAAA,CAAA;AACrF,qBAAA;AACF,iBAAA;AACF,aAAA;AACF,SAAA,CAAC,EACF,mBAAmB,EAAE,CAAC,QAAwB,EAAE,MAAuB,EAAE,IAAY,MAAM;AACzF,YAAA,YAAY,EAAE,eAAe;AAC7B,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,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;;;;"}
@@ -0,0 +1,16 @@
1
+ import { LoginAuthenticationResponse } from '@medplum/core';
2
+ import React from 'react';
3
+ export interface AuthenticationFormProps {
4
+ readonly projectId?: string;
5
+ readonly clientId?: string;
6
+ readonly scope?: string;
7
+ readonly nonce?: string;
8
+ readonly googleClientId?: string;
9
+ readonly codeChallenge?: string;
10
+ readonly codeChallengeMethod?: string;
11
+ readonly onForgotPassword?: () => void;
12
+ readonly onRegister?: () => void;
13
+ readonly handleAuthResponse: (response: LoginAuthenticationResponse) => void;
14
+ readonly children?: React.ReactNode;
15
+ }
16
+ export declare function AuthenticationForm(props: AuthenticationFormProps): JSX.Element;
@@ -0,0 +1,71 @@
1
+ import React, { useState } from 'react';
2
+ import { Button } from '../Button.js';
3
+ import { Form } from '../Form.js';
4
+ import { FormSection } from '../FormSection.js';
5
+ import { getGoogleClientId, GoogleButton } from '../GoogleButton.js';
6
+ import { Input } from '../Input.js';
7
+ import { MedplumLink } from '../MedplumLink.js';
8
+ import { useMedplum } from '../MedplumProvider.js';
9
+ import { getIssuesForExpression } from '../utils/outcomes.js';
10
+
11
+ function AuthenticationForm(props) {
12
+ const medplum = useMedplum();
13
+ const googleClientId = getGoogleClientId(props.googleClientId);
14
+ const [outcome, setOutcome] = useState();
15
+ const issues = getIssuesForExpression(outcome, undefined);
16
+ return (React.createElement(Form, { style: { maxWidth: 400 }, onSubmit: (formData) => {
17
+ medplum
18
+ .startLogin({
19
+ projectId: props.projectId,
20
+ clientId: props.clientId,
21
+ scope: props.scope,
22
+ nonce: props.nonce,
23
+ codeChallenge: props.codeChallenge,
24
+ codeChallengeMethod: props.codeChallengeMethod,
25
+ email: formData.email,
26
+ password: formData.password,
27
+ remember: formData.remember === 'true',
28
+ })
29
+ .then(props.handleAuthResponse)
30
+ .catch(setOutcome);
31
+ } },
32
+ React.createElement("div", { className: "medplum-center" }, props.children),
33
+ issues && (React.createElement("div", { className: "medplum-input-error" }, issues.map((issue) => {
34
+ var _a, _b;
35
+ return (React.createElement("div", { "data-testid": "text-field-error", key: (_a = issue.details) === null || _a === void 0 ? void 0 : _a.text }, (_b = issue.details) === null || _b === void 0 ? void 0 : _b.text));
36
+ }))),
37
+ googleClientId && (React.createElement(React.Fragment, null,
38
+ React.createElement("div", { className: "medplum-signin-google-container" },
39
+ React.createElement(GoogleButton, { googleClientId: googleClientId, handleGoogleCredential: (response) => {
40
+ medplum
41
+ .startGoogleLogin({
42
+ projectId: props.projectId,
43
+ clientId: props.clientId,
44
+ scope: props.scope,
45
+ nonce: props.nonce,
46
+ codeChallenge: props.codeChallenge,
47
+ codeChallengeMethod: props.codeChallengeMethod,
48
+ googleClientId: response.clientId,
49
+ googleCredential: response.credential,
50
+ })
51
+ .then(props.handleAuthResponse)
52
+ .catch(setOutcome);
53
+ } })),
54
+ React.createElement("div", { className: "medplum-signin-separator" }, "or"))),
55
+ React.createElement(FormSection, { title: "Email", htmlFor: "email", outcome: outcome },
56
+ React.createElement(Input, { name: "email", type: "email", testid: "email", required: true, autoFocus: true, outcome: outcome })),
57
+ React.createElement(FormSection, { title: "Password", htmlFor: "password", outcome: outcome },
58
+ React.createElement(Input, { name: "password", type: "password", testid: "password", autoComplete: "off", required: true, outcome: outcome })),
59
+ React.createElement("div", { className: "medplum-signin-buttons" },
60
+ (props.onForgotPassword || props.onRegister) && (React.createElement("div", null,
61
+ props.onForgotPassword && (React.createElement(MedplumLink, { testid: "forgotpassword", onClick: props.onForgotPassword }, "Forgot password")),
62
+ props.onRegister && (React.createElement(MedplumLink, { testid: "register", onClick: props.onRegister }, "Register")))),
63
+ React.createElement("div", null,
64
+ React.createElement("input", { type: "checkbox", id: "remember", name: "remember", value: "true" }),
65
+ React.createElement("label", { htmlFor: "remember" }, "Remember me")),
66
+ React.createElement("div", null,
67
+ React.createElement(Button, { type: "submit", testid: "submit" }, "Sign in")))));
68
+ }
69
+
70
+ export { AuthenticationForm };
71
+ //# sourceMappingURL=AuthenticationForm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AuthenticationForm.js","sources":["../../../src/auth/AuthenticationForm.tsx"],"sourcesContent":["import { GoogleCredentialResponse, LoginAuthenticationResponse } from '@medplum/core';\nimport { OperationOutcome } from '@medplum/fhirtypes';\nimport React, { useState } from 'react';\nimport { Button } from '../Button';\nimport { Form } from '../Form';\nimport { FormSection } from '../FormSection';\nimport { getGoogleClientId, GoogleButton } from '../GoogleButton';\nimport { Input } from '../Input';\nimport { MedplumLink } from '../MedplumLink';\nimport { useMedplum } from '../MedplumProvider';\nimport { getIssuesForExpression } from '../utils/outcomes';\n\nexport interface AuthenticationFormProps {\n readonly projectId?: string;\n readonly clientId?: string;\n readonly scope?: string;\n readonly nonce?: string;\n readonly googleClientId?: string;\n readonly codeChallenge?: string;\n readonly codeChallengeMethod?: string;\n readonly onForgotPassword?: () => void;\n readonly onRegister?: () => void;\n readonly handleAuthResponse: (response: LoginAuthenticationResponse) => void;\n readonly children?: React.ReactNode;\n}\n\nexport function AuthenticationForm(props: AuthenticationFormProps): JSX.Element {\n const medplum = useMedplum();\n const googleClientId = getGoogleClientId(props.googleClientId);\n const [outcome, setOutcome] = useState<OperationOutcome>();\n const issues = getIssuesForExpression(outcome, undefined);\n\n return (\n <Form\n style={{ maxWidth: 400 }}\n onSubmit={(formData: Record<string, string>) => {\n medplum\n .startLogin({\n projectId: props.projectId,\n clientId: props.clientId,\n scope: props.scope,\n nonce: props.nonce,\n codeChallenge: props.codeChallenge,\n codeChallengeMethod: props.codeChallengeMethod,\n email: formData.email,\n password: formData.password,\n remember: formData.remember === 'true',\n })\n .then(props.handleAuthResponse)\n .catch(setOutcome);\n }}\n >\n <div className=\"medplum-center\">{props.children}</div>\n {issues && (\n <div className=\"medplum-input-error\">\n {issues.map((issue) => (\n <div data-testid=\"text-field-error\" key={issue.details?.text}>\n {issue.details?.text}\n </div>\n ))}\n </div>\n )}\n {googleClientId && (\n <>\n <div className=\"medplum-signin-google-container\">\n <GoogleButton\n googleClientId={googleClientId}\n handleGoogleCredential={(response: GoogleCredentialResponse) => {\n medplum\n .startGoogleLogin({\n projectId: props.projectId,\n clientId: props.clientId,\n scope: props.scope,\n nonce: props.nonce,\n codeChallenge: props.codeChallenge,\n codeChallengeMethod: props.codeChallengeMethod,\n googleClientId: response.clientId,\n googleCredential: response.credential,\n })\n .then(props.handleAuthResponse)\n .catch(setOutcome);\n }}\n />\n </div>\n <div className=\"medplum-signin-separator\">or</div>\n </>\n )}\n <FormSection title=\"Email\" htmlFor=\"email\" outcome={outcome}>\n <Input name=\"email\" type=\"email\" testid=\"email\" required={true} autoFocus={true} outcome={outcome} />\n </FormSection>\n <FormSection title=\"Password\" htmlFor=\"password\" outcome={outcome}>\n <Input name=\"password\" type=\"password\" testid=\"password\" autoComplete=\"off\" required={true} outcome={outcome} />\n </FormSection>\n <div className=\"medplum-signin-buttons\">\n {(props.onForgotPassword || props.onRegister) && (\n <div>\n {props.onForgotPassword && (\n <MedplumLink testid=\"forgotpassword\" onClick={props.onForgotPassword}>\n Forgot password\n </MedplumLink>\n )}\n {props.onRegister && (\n <MedplumLink testid=\"register\" onClick={props.onRegister}>\n Register\n </MedplumLink>\n )}\n </div>\n )}\n <div>\n <input type=\"checkbox\" id=\"remember\" name=\"remember\" value=\"true\" />\n <label htmlFor=\"remember\">Remember me</label>\n </div>\n <div>\n <Button type=\"submit\" testid=\"submit\">\n Sign in\n </Button>\n </div>\n </div>\n </Form>\n );\n}\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ /// <reference types="react" />
2
+ import { ProjectMembership } from '@medplum/fhirtypes';
3
+ export interface ChooseProfileFormProps {
4
+ login: string;
5
+ memberships: ProjectMembership[];
6
+ handleAuthResponse: (response: any) => void;
7
+ }
8
+ export declare function ChooseProfileForm(props: ChooseProfileFormProps): JSX.Element;
@@ -0,0 +1,32 @@
1
+ import React from 'react';
2
+ import { Avatar } from '../Avatar.js';
3
+ import { Logo } from '../Logo.js';
4
+ import { useMedplum } from '../MedplumProvider.js';
5
+
6
+ function ChooseProfileForm(props) {
7
+ const medplum = useMedplum();
8
+ return (React.createElement("div", null,
9
+ React.createElement("div", { className: "medplum-center" },
10
+ React.createElement(Logo, { size: 32 }),
11
+ React.createElement("h1", null, "Choose profile")),
12
+ props.memberships.map((membership) => {
13
+ var _a, _b, _c;
14
+ return (React.createElement("div", { className: "medplum-nav-menu-profile", key: membership.id, onClick: () => {
15
+ medplum
16
+ .post('auth/profile', {
17
+ login: props.login,
18
+ profile: membership.id,
19
+ })
20
+ .then(props.handleAuthResponse)
21
+ .catch(console.log);
22
+ } },
23
+ React.createElement("div", { className: "medplum-nav-menu-profile-icon" },
24
+ React.createElement(Avatar, { alt: (_a = membership.profile) === null || _a === void 0 ? void 0 : _a.display })),
25
+ React.createElement("div", { className: "medplum-nav-menu-profile-label" }, (_b = membership.profile) === null || _b === void 0 ? void 0 :
26
+ _b.display,
27
+ React.createElement("div", { className: "medplum-nav-menu-profile-help-text" }, (_c = membership.project) === null || _c === void 0 ? void 0 : _c.display))));
28
+ })));
29
+ }
30
+
31
+ export { ChooseProfileForm };
32
+ //# sourceMappingURL=ChooseProfileForm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ChooseProfileForm.js","sources":["../../../src/auth/ChooseProfileForm.tsx"],"sourcesContent":["import { ProjectMembership } from '@medplum/fhirtypes';\nimport React from 'react';\nimport { Avatar } from '../Avatar';\nimport { Logo } from '../Logo';\nimport { useMedplum } from '../MedplumProvider';\n\nexport interface ChooseProfileFormProps {\n login: string;\n memberships: ProjectMembership[];\n handleAuthResponse: (response: any) => void;\n}\n\nexport function ChooseProfileForm(props: ChooseProfileFormProps): JSX.Element {\n const medplum = useMedplum();\n return (\n <div>\n <div className=\"medplum-center\">\n <Logo size={32} />\n <h1>Choose profile</h1>\n </div>\n {props.memberships.map((membership: ProjectMembership) => (\n <div\n className=\"medplum-nav-menu-profile\"\n key={membership.id}\n onClick={() => {\n medplum\n .post('auth/profile', {\n login: props.login,\n profile: membership.id,\n })\n .then(props.handleAuthResponse)\n .catch(console.log);\n }}\n >\n <div className=\"medplum-nav-menu-profile-icon\">\n <Avatar alt={membership.profile?.display} />\n </div>\n <div className=\"medplum-nav-menu-profile-label\">\n {membership.profile?.display}\n <div className=\"medplum-nav-menu-profile-help-text\">{membership.project?.display}</div>\n </div>\n </div>\n ))}\n </div>\n );\n}\n"],"names":[],"mappings":";;;;;AAYM,SAAU,iBAAiB,CAAC,KAA6B,EAAA;AAC7D,IAAA,MAAM,OAAO,GAAG,UAAU,EAAE,CAAC;AAC7B,IAAA,QACE,KAAA,CAAA,aAAA,CAAA,KAAA,EAAA,IAAA;QACE,KAAK,CAAA,aAAA,CAAA,KAAA,EAAA,EAAA,SAAS,EAAC,gBAAgB,EAAA;AAC7B,YAAA,KAAA,CAAA,aAAA,CAAC,IAAI,EAAA,EAAC,IAAI,EAAE,EAAE,EAAI,CAAA;AAClB,YAAA,KAAA,CAAA,aAAA,CAAA,IAAA,EAAA,IAAA,EAAA,gBAAA,CAAuB,CACnB;QACL,KAAK,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,UAA6B,KAAI;;AAAC,YAAA,QACxD,KAAA,CAAA,aAAA,CAAA,KAAA,EAAA,EACE,SAAS,EAAC,0BAA0B,EACpC,GAAG,EAAE,UAAU,CAAC,EAAE,EAClB,OAAO,EAAE,MAAK;oBACZ,OAAO;yBACJ,IAAI,CAAC,cAAc,EAAE;wBACpB,KAAK,EAAE,KAAK,CAAC,KAAK;wBAClB,OAAO,EAAE,UAAU,CAAC,EAAE;qBACvB,CAAC;AACD,yBAAA,IAAI,CAAC,KAAK,CAAC,kBAAkB,CAAC;AAC9B,yBAAA,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;iBACvB,EAAA;gBAED,KAAK,CAAA,aAAA,CAAA,KAAA,EAAA,EAAA,SAAS,EAAC,+BAA+B,EAAA;oBAC5C,KAAC,CAAA,aAAA,CAAA,MAAM,EAAC,EAAA,GAAG,EAAE,CAAA,EAAA,GAAA,UAAU,CAAC,OAAO,MAAA,IAAA,IAAA,EAAA,KAAA,KAAA,CAAA,GAAA,KAAA,CAAA,GAAA,EAAA,CAAE,OAAO,EAAA,CAAI,CACxC;AACN,gBAAA,KAAA,CAAA,aAAA,CAAA,KAAA,EAAA,EAAK,SAAS,EAAC,gCAAgC,IAC5C,CAAA,EAAA,GAAA,UAAU,CAAC,OAAO,MAAA,IAAA,IAAA,EAAA,KAAA,KAAA,CAAA,GAAA,KAAA,CAAA;uBAAE,OAAO;AAC5B,oBAAA,KAAA,CAAA,aAAA,CAAA,KAAA,EAAA,EAAK,SAAS,EAAC,oCAAoC,EAAA,EAAE,MAAA,UAAU,CAAC,OAAO,MAAA,IAAA,IAAA,EAAA,KAAA,KAAA,CAAA,GAAA,KAAA,CAAA,GAAA,EAAA,CAAE,OAAO,CAAO,CACnF,CACF,EACP;SAAA,CAAC,CACE,EACN;AACJ;;;;"}
@@ -0,0 +1,7 @@
1
+ /// <reference types="react" />
2
+ import { LoginAuthenticationResponse } from '@medplum/core';
3
+ export interface NewProjectFormProps {
4
+ login: string;
5
+ handleAuthResponse: (response: LoginAuthenticationResponse) => void;
6
+ }
7
+ export declare function NewProjectForm(props: NewProjectFormProps): JSX.Element;