@medplum/react 0.9.28 → 0.9.29

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 (205) hide show
  1. package/dist/cjs/AddressDisplay.d.ts +6 -0
  2. package/dist/cjs/AddressInput.d.ts +8 -0
  3. package/dist/cjs/AnnotationInput.d.ts +8 -0
  4. package/dist/cjs/AttachmentArrayDisplay.d.ts +7 -0
  5. package/dist/cjs/AttachmentArrayInput.d.ts +9 -0
  6. package/dist/cjs/AttachmentDisplay.d.ts +7 -0
  7. package/dist/cjs/AttachmentInput.d.ts +9 -0
  8. package/dist/cjs/Autocomplete.d.ts +20 -0
  9. package/dist/cjs/Avatar.d.ts +12 -0
  10. package/dist/cjs/BackboneElementDisplay.d.ts +9 -0
  11. package/dist/cjs/BackboneElementInput.d.ts +9 -0
  12. package/dist/cjs/Button.d.ts +15 -0
  13. package/dist/cjs/CalendarInput.d.ts +16 -0
  14. package/dist/cjs/Checkbox.d.ts +12 -0
  15. package/dist/cjs/CheckboxFormSection.d.ts +9 -0
  16. package/dist/cjs/CodeInput.d.ts +9 -0
  17. package/dist/cjs/CodeableConceptDisplay.d.ts +6 -0
  18. package/dist/cjs/CodeableConceptInput.d.ts +9 -0
  19. package/dist/cjs/CodingDisplay.d.ts +6 -0
  20. package/dist/cjs/CodingInput.d.ts +9 -0
  21. package/dist/cjs/ContactDetailDisplay.d.ts +6 -0
  22. package/dist/cjs/ContactDetailInput.d.ts +8 -0
  23. package/dist/cjs/ContactPointDisplay.d.ts +6 -0
  24. package/dist/cjs/ContactPointInput.d.ts +8 -0
  25. package/dist/cjs/DateTimeInput.d.ts +23 -0
  26. package/dist/cjs/DefaultResourceTimeline.d.ts +6 -0
  27. package/dist/cjs/DescriptionList.d.ts +12 -0
  28. package/dist/cjs/DiagnosticReportDisplay.d.ts +12 -0
  29. package/dist/cjs/Dialog.d.ts +10 -0
  30. package/dist/cjs/Document.d.ts +7 -0
  31. package/dist/cjs/EncounterTimeline.d.ts +6 -0
  32. package/dist/cjs/ErrorBoundary.d.ts +18 -0
  33. package/dist/cjs/ExtensionInput.d.ts +8 -0
  34. package/dist/cjs/FhirPathDisplay.d.ts +9 -0
  35. package/dist/cjs/FhirPathTable.d.ts +29 -0
  36. package/dist/cjs/FooterLinks.d.ts +6 -0
  37. package/dist/cjs/Form.d.ts +8 -0
  38. package/dist/cjs/FormSection.d.ts +11 -0
  39. package/dist/cjs/FormUtils.d.ts +5 -0
  40. package/dist/cjs/GoogleButton.d.ts +8 -0
  41. package/dist/cjs/Header.d.ts +12 -0
  42. package/dist/cjs/HeaderSearchInput.d.ts +10 -0
  43. package/dist/cjs/HumanNameDisplay.d.ts +8 -0
  44. package/dist/cjs/HumanNameInput.d.ts +8 -0
  45. package/dist/cjs/IdentifierDisplay.d.ts +6 -0
  46. package/dist/cjs/IdentifierInput.d.ts +8 -0
  47. package/dist/cjs/Input.d.ts +22 -0
  48. package/dist/cjs/InputRow.d.ts +7 -0
  49. package/dist/cjs/Loading.d.ts +3 -0
  50. package/dist/cjs/Logo.d.ts +6 -0
  51. package/dist/cjs/MedplumLink.d.ts +13 -0
  52. package/dist/cjs/MedplumProvider.d.ts +34 -0
  53. package/dist/cjs/MenuItem.d.ts +9 -0
  54. package/dist/cjs/MenuSeparator.d.ts +3 -0
  55. package/dist/cjs/PatientTimeline.d.ts +6 -0
  56. package/dist/cjs/PeriodInput.d.ts +8 -0
  57. package/dist/cjs/PlanDefinitionBuilder.d.ts +7 -0
  58. package/dist/cjs/Popup.d.ts +14 -0
  59. package/dist/cjs/QuantityDisplay.d.ts +7 -0
  60. package/dist/cjs/QuantityInput.d.ts +8 -0
  61. package/dist/cjs/QuestionnaireBuilder.d.ts +8 -0
  62. package/dist/cjs/QuestionnaireForm.d.ts +14 -0
  63. package/dist/cjs/QuestionnaireUtils.d.ts +30 -0
  64. package/dist/cjs/RangeDisplay.d.ts +7 -0
  65. package/dist/cjs/RangeInput.d.ts +14 -0
  66. package/dist/cjs/RatioDisplay.d.ts +6 -0
  67. package/dist/cjs/RatioInput.d.ts +14 -0
  68. package/dist/cjs/ReferenceDisplay.d.ts +7 -0
  69. package/dist/cjs/ReferenceInput.d.ts +9 -0
  70. package/dist/cjs/RegisterForm.d.ts +18 -0
  71. package/dist/cjs/RequestGroupDisplay.d.ts +9 -0
  72. package/dist/cjs/ResourceArrayDisplay.d.ts +11 -0
  73. package/dist/cjs/ResourceArrayInput.d.ts +11 -0
  74. package/dist/cjs/ResourceBadge.d.ts +9 -0
  75. package/dist/cjs/ResourceBlame.d.ts +10 -0
  76. package/dist/cjs/ResourceDiff.d.ts +9 -0
  77. package/dist/cjs/ResourceDiffTable.d.ts +9 -0
  78. package/dist/cjs/ResourceForm.d.ts +10 -0
  79. package/dist/cjs/ResourceHistoryTable.d.ts +9 -0
  80. package/dist/cjs/ResourceInput.d.ts +12 -0
  81. package/dist/cjs/ResourceName.d.ts +7 -0
  82. package/dist/cjs/ResourcePropertyDisplay.d.ts +24 -0
  83. package/dist/cjs/ResourcePropertyInput.d.ts +21 -0
  84. package/dist/cjs/ResourceTable.d.ts +7 -0
  85. package/dist/cjs/ResourceTimeline.d.ts +11 -0
  86. package/dist/cjs/Scheduler.d.ts +7 -0
  87. package/dist/cjs/Scrollable.d.ts +9 -0
  88. package/dist/cjs/SearchControl.d.ts +40 -0
  89. package/dist/cjs/SearchControlField.d.ts +41 -0
  90. package/dist/cjs/SearchFieldEditor.d.ts +11 -0
  91. package/dist/cjs/SearchFilterEditor.d.ts +11 -0
  92. package/dist/cjs/SearchFilterValueDialog.d.ts +15 -0
  93. package/dist/cjs/SearchFilterValueDisplay.d.ts +7 -0
  94. package/dist/cjs/SearchFilterValueInput.d.ts +12 -0
  95. package/dist/cjs/SearchPopupMenu.d.ts +15 -0
  96. package/dist/cjs/SearchUtils.d.ts +174 -0
  97. package/dist/cjs/Select.d.ts +16 -0
  98. package/dist/cjs/ServiceRequestTimeline.d.ts +6 -0
  99. package/dist/cjs/SignInForm.d.ts +17 -0
  100. package/dist/cjs/StatusBadge.d.ts +6 -0
  101. package/dist/cjs/SubMenu.d.ts +7 -0
  102. package/dist/cjs/Tab.d.ts +12 -0
  103. package/dist/cjs/TabList.d.ts +10 -0
  104. package/dist/cjs/TabPanel.d.ts +6 -0
  105. package/dist/cjs/TabSwitch.d.ts +6 -0
  106. package/dist/cjs/TextArea.d.ts +18 -0
  107. package/dist/cjs/Timeline.d.ts +17 -0
  108. package/dist/cjs/TimingInput.d.ts +8 -0
  109. package/dist/cjs/TitleBar.d.ts +6 -0
  110. package/dist/cjs/UploadButton.d.ts +7 -0
  111. package/dist/cjs/constants.d.ts +1 -0
  112. package/dist/cjs/index.d.ts +86 -0
  113. package/dist/cjs/index.js +75 -41
  114. package/dist/cjs/index.js.map +1 -1
  115. package/dist/cjs/index.min.js +1 -1
  116. package/dist/cjs/index.min.js.map +1 -1
  117. package/dist/cjs/stories/AddressInput.stories.d.ts +6 -0
  118. package/dist/cjs/stories/AttachmentArrayInput.stories.d.ts +6 -0
  119. package/dist/cjs/stories/AttachmentInput.stories.d.ts +6 -0
  120. package/dist/cjs/stories/Autocomplete.stories.d.ts +9 -0
  121. package/dist/cjs/stories/Avatar.stories.d.ts +10 -0
  122. package/dist/cjs/stories/Button.stories.d.ts +9 -0
  123. package/dist/cjs/stories/CodeableConceptDisplay.stories.d.ts +8 -0
  124. package/dist/cjs/stories/DiagnosticReportDisplay.stories.d.ts +5 -0
  125. package/dist/cjs/stories/Dialog.stories.d.ts +5 -0
  126. package/dist/cjs/stories/EncounterTimeline.stories.d.ts +5 -0
  127. package/dist/cjs/stories/FhirPathDisplay.stories.d.ts +7 -0
  128. package/dist/cjs/stories/FormSection.stories.d.ts +6 -0
  129. package/dist/cjs/stories/Header.stories.d.ts +8 -0
  130. package/dist/cjs/stories/Input.stories.d.ts +6 -0
  131. package/dist/cjs/stories/Loading.stories.d.ts +5 -0
  132. package/dist/cjs/stories/Logo.stories.d.ts +5 -0
  133. package/dist/cjs/stories/PatientTimeline.stories.d.ts +5 -0
  134. package/dist/cjs/stories/PlanDefinitionBuilder.stories.d.ts +5 -0
  135. package/dist/cjs/stories/QuestionnaireBuilder.stories.d.ts +7 -0
  136. package/dist/cjs/stories/QuestionnaireForm.stories.d.ts +11 -0
  137. package/dist/cjs/stories/ReferenceInput.stories.d.ts +6 -0
  138. package/dist/cjs/stories/RegisterForm.stories.d.ts +7 -0
  139. package/dist/cjs/stories/RequestGroupDisplay.stories.d.ts +5 -0
  140. package/dist/cjs/stories/ResourceBlame.stories.d.ts +5 -0
  141. package/dist/cjs/stories/ResourceForm.stories.d.ts +12 -0
  142. package/dist/cjs/stories/ResourceHistoryTable.stories.d.ts +5 -0
  143. package/dist/cjs/stories/ResourceTable.stories.d.ts +7 -0
  144. package/dist/cjs/stories/Scheduler.stories.d.ts +5 -0
  145. package/dist/cjs/stories/SearchControl.stories.d.ts +13 -0
  146. package/dist/cjs/stories/Select.stories.d.ts +6 -0
  147. package/dist/cjs/stories/SignInForm.stories.d.ts +8 -0
  148. package/dist/cjs/stories/StatusBadge.stories.d.ts +5 -0
  149. package/dist/cjs/stories/Tabs.stories.d.ts +6 -0
  150. package/dist/cjs/stories/Timeline.stories.d.ts +5 -0
  151. package/dist/cjs/stories/TimingInput.stories.d.ts +6 -0
  152. package/dist/cjs/stories/UploadButton.stories.d.ts +6 -0
  153. package/dist/cjs/styles.css +52 -51
  154. package/dist/cjs/test.setup.d.ts +1 -0
  155. package/dist/cjs/useResource.d.ts +8 -0
  156. package/dist/cjs/utils/blame.d.ts +8 -0
  157. package/dist/cjs/utils/date.d.ts +6 -0
  158. package/dist/cjs/utils/diff.d.ts +16 -0
  159. package/dist/cjs/utils/dom.d.ts +15 -0
  160. package/dist/cjs/utils/outcomes.d.ts +2 -0
  161. package/dist/cjs/utils/recaptcha.d.ts +12 -0
  162. package/dist/cjs/utils.d.ts +5 -0
  163. package/dist/esm/CalendarInput.d.ts +1 -0
  164. package/dist/esm/CalendarInput.js +6 -5
  165. package/dist/esm/CalendarInput.js.map +1 -1
  166. package/dist/esm/FhirPathTable.js +5 -2
  167. package/dist/esm/FhirPathTable.js.map +1 -1
  168. package/dist/esm/GoogleButton.js +1 -1
  169. package/dist/esm/GoogleButton.js.map +1 -1
  170. package/dist/esm/Header.js +7 -3
  171. package/dist/esm/Header.js.map +1 -1
  172. package/dist/esm/PlanDefinitionBuilder.js +1 -1
  173. package/dist/esm/PlanDefinitionBuilder.js.map +1 -1
  174. package/dist/esm/QuestionnaireBuilder.js +1 -1
  175. package/dist/esm/QuestionnaireBuilder.js.map +1 -1
  176. package/dist/esm/QuestionnaireForm.js +2 -1
  177. package/dist/esm/QuestionnaireForm.js.map +1 -1
  178. package/dist/esm/RegisterForm.js +2 -2
  179. package/dist/esm/RegisterForm.js.map +1 -1
  180. package/dist/esm/RequestGroupDisplay.js +1 -1
  181. package/dist/esm/RequestGroupDisplay.js.map +1 -1
  182. package/dist/esm/ResourceBlame.js +1 -1
  183. package/dist/esm/ResourceBlame.js.map +1 -1
  184. package/dist/esm/ResourceDiffTable.js +1 -1
  185. package/dist/esm/ResourceDiffTable.js.map +1 -1
  186. package/dist/esm/ResourceForm.js +1 -1
  187. package/dist/esm/ResourceForm.js.map +1 -1
  188. package/dist/esm/ResourceHistoryTable.js +4 -1
  189. package/dist/esm/ResourceHistoryTable.js.map +1 -1
  190. package/dist/esm/ResourceTable.js +1 -1
  191. package/dist/esm/ResourceTable.js.map +1 -1
  192. package/dist/esm/ResourceTimeline.js +13 -7
  193. package/dist/esm/ResourceTimeline.js.map +1 -1
  194. package/dist/esm/Scheduler.js +13 -6
  195. package/dist/esm/Scheduler.js.map +1 -1
  196. package/dist/esm/SearchControl.js +5 -2
  197. package/dist/esm/SearchControl.js.map +1 -1
  198. package/dist/esm/SignInForm.js +2 -1
  199. package/dist/esm/SignInForm.js.map +1 -1
  200. package/dist/esm/index.min.js +1 -1
  201. package/dist/esm/index.min.js.map +1 -1
  202. package/dist/esm/styles.css +52 -51
  203. package/dist/esm/utils/recaptcha.js +10 -4
  204. package/dist/esm/utils/recaptcha.js.map +1 -1
  205. package/package.json +6 -6
@@ -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);\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.createResource(props.createCommunication(resource, sender, contentString)).then((result) => {\n addResources([result]);\n });\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.createResource(props.createMedia(resource, sender, attachment)).then((result) => {\n addResources([result]);\n });\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);\n }\n\n function onUnpin(communication: Communication): void {\n setPriority(communication, 'routine').then(loadTimeline);\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 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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"}
@@ -2,7 +2,7 @@ import { getReferenceString } from '@medplum/core';
2
2
  import React, { useState, useRef, useEffect } from 'react';
3
3
  import { Avatar } from './Avatar.js';
4
4
  import { Button } from './Button.js';
5
- import { CalendarInput } from './CalendarInput.js';
5
+ import { getStartMonth, CalendarInput } from './CalendarInput.js';
6
6
  import { FormSection } from './FormSection.js';
7
7
  import { Input } from './Input.js';
8
8
  import { useMedplum } from './MedplumProvider.js';
@@ -16,20 +16,27 @@ function Scheduler(props) {
16
16
  const [slots, setSlots] = useState();
17
17
  const slotsRef = useRef();
18
18
  slotsRef.current = slots;
19
+ const [month, setMonth] = useState(getStartMonth());
19
20
  const [date, setDate] = useState();
20
21
  const [slot, setSlot] = useState();
21
22
  const [info, setInfo] = useState();
22
23
  const [form, setForm] = useState();
23
24
  useEffect(() => {
24
25
  if (schedule) {
25
- medplum.search('Slot', 'schedule=' + getReferenceString(schedule)).then((bundle) => {
26
- setSlots(bundle.entry.map((entry) => entry.resource));
27
- });
26
+ setSlots([]);
27
+ medplum
28
+ .searchResources('Slot', new URLSearchParams([
29
+ ['schedule', getReferenceString(schedule)],
30
+ ['start', 'gt' + month.toISOString()],
31
+ ['start', 'lt' + new Date(month.getTime() + 31 * 24 * 60 * 60 * 1000).toISOString()],
32
+ ]))
33
+ .then(setSlots)
34
+ .catch(console.log);
28
35
  }
29
36
  else {
30
37
  setSlots(undefined);
31
38
  }
32
- }, [medplum, schedule]);
39
+ }, [medplum, schedule, month]);
33
40
  if (!schedule || !slots) {
34
41
  return null;
35
42
  }
@@ -45,7 +52,7 @@ function Scheduler(props) {
45
52
  React.createElement("div", { className: "medplum-calendar-selection-pane" },
46
53
  !date && (React.createElement("div", null,
47
54
  React.createElement("h3", null, "Select date"),
48
- React.createElement(CalendarInput, { slots: slots, onClick: setDate }))),
55
+ React.createElement(CalendarInput, { slots: slots, onChangeMonth: setMonth, onClick: setDate }))),
49
56
  date && !slot && (React.createElement("div", null,
50
57
  React.createElement("h3", null, "Select time"),
51
58
  slots.map((s) => {
@@ -1 +1 @@
1
- {"version":3,"file":"Scheduler.js","sources":["../../src/Scheduler.tsx"],"sourcesContent":["import { getReferenceString } from '@medplum/core';\nimport { BundleEntry, Reference, Schedule, Slot } from '@medplum/fhirtypes';\nimport React, { useEffect, useRef, useState } from 'react';\nimport { Avatar } from './Avatar';\nimport { Button } from './Button';\nimport { CalendarInput } from './CalendarInput';\nimport { FormSection } from './FormSection';\nimport { Input } from './Input';\nimport { useMedplum } from './MedplumProvider';\nimport { ResourceName } from './ResourceName';\nimport { useResource } from './useResource';\nimport './Scheduler.css';\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 [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 medplum.search('Slot', 'schedule=' + getReferenceString(schedule)).then((bundle) => {\n setSlots((bundle.entry as BundleEntry<Slot>[]).map((entry) => entry.resource as Slot));\n });\n } else {\n setSlots(undefined);\n }\n }, [medplum, schedule]);\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} 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":";;;;;;;;;;;AAiBM,SAAU,SAAS,CAAC,KAAqB,EAAA;;AAC7C,IAAA,MAAM,OAAO,GAAG,UAAU,EAAE,CAAC;IAC7B,MAAM,QAAQ,GAAG,WAAW,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IAE7C,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,EAAU,CAAC;AAC7C,IAAA,MAAM,QAAQ,GAAG,MAAM,EAAU,CAAC;AAClC,IAAA,QAAQ,CAAC,OAAO,GAAG,KAAK,CAAC;IAEzB,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,QAAQ,EAAQ,CAAC;IACzC,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,QAAQ,EAAQ,CAAC;IACzC,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,QAAQ,EAAU,CAAC;IAC3C,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,QAAQ,EAAU,CAAC;IAE3C,SAAS,CAAC,MAAK;AACb,QAAA,IAAI,QAAQ,EAAE;AACZ,YAAA,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,WAAW,GAAG,kBAAkB,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,KAAI;AACjF,gBAAA,QAAQ,CAAE,MAAM,CAAC,KAA6B,CAAC,GAAG,CAAC,CAAC,KAAK,KAAK,KAAK,CAAC,QAAgB,CAAC,CAAC,CAAC;AACzF,aAAC,CAAC,CAAC;AACJ,SAAA;AAAM,aAAA;YACL,QAAQ,CAAC,SAAS,CAAC,CAAC;AACrB,SAAA;AACH,KAAC,EAAE,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC;AAExB,IAAA,IAAI,CAAC,QAAQ,IAAI,CAAC,KAAK,EAAE;AACvB,QAAA,OAAO,IAAI,CAAC;AACb,KAAA;IAED,MAAM,KAAK,GAAG,CAAA,EAAA,GAAA,QAAQ,CAAC,KAAK,MAAA,IAAA,IAAA,EAAA,KAAA,KAAA,CAAA,GAAA,KAAA,CAAA,GAAA,EAAA,CAAG,CAAC,CAAC,CAAC;AAElC,IAAA,QACE,KAAK,CAAA,aAAA,CAAA,KAAA,EAAA,EAAA,SAAS,EAAC,4BAA4B,iBAAa,WAAW,EAAA;QACjE,KAAK,CAAA,aAAA,CAAA,KAAA,EAAA,EAAA,SAAS,EAAC,4BAA4B,EAAA;YACxC,KAAK,IAAI,KAAC,CAAA,aAAA,CAAA,MAAM,EAAC,EAAA,KAAK,EAAE,KAAK,EAAE,IAAI,EAAC,OAAO,EAAG,CAAA;AAC9C,YAAA,KAAK,KACJ,KAAA,CAAA,aAAA,CAAA,IAAA,EAAA,IAAA;AACE,gBAAA,KAAA,CAAA,aAAA,CAAC,YAAY,EAAC,EAAA,KAAK,EAAE,KAAK,EAAA,CAAI,CAC3B,CACN;YACD,KAAa,CAAA,aAAA,CAAA,GAAA,EAAA,IAAA,EAAA,QAAA,CAAA;AACZ,YAAA,IAAI,IAAI,KAAI,CAAA,aAAA,CAAA,GAAA,EAAA,IAAA,EAAA,IAAI,CAAC,kBAAkB,EAAE,CAAK;AAC1C,YAAA,IAAI,IAAI,KAAA,CAAA,aAAA,CAAA,GAAA,EAAA,IAAA,EAAI,UAAU,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,KAAe,CAAC,CAAC,CAAK,CACxD;QACN,KAAK,CAAA,aAAA,CAAA,KAAA,EAAA,EAAA,SAAS,EAAC,iCAAiC,EAAA;YAC7C,CAAC,IAAI,KACJ,KAAA,CAAA,aAAA,CAAA,KAAA,EAAA,IAAA;gBACE,KAAoB,CAAA,aAAA,CAAA,IAAA,EAAA,IAAA,EAAA,aAAA,CAAA;gBACpB,KAAC,CAAA,aAAA,CAAA,aAAa,EAAC,EAAA,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAI,CAAA,CAC7C,CACP;AACA,YAAA,IAAI,IAAI,CAAC,IAAI,KACZ,KAAA,CAAA,aAAA,CAAA,KAAA,EAAA,IAAA;gBACE,KAAoB,CAAA,aAAA,CAAA,IAAA,EAAA,IAAA,EAAA,aAAA,CAAA;AACnB,gBAAA,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,KAAI;oBACf,MAAM,SAAS,GAAG,IAAI,IAAI,CAAC,CAAC,CAAC,KAAe,CAAC,CAAC;oBAC9C,QACE,SAAS,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,OAAO,EAAE;wBACpC,SAAS,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE,GAAG,IAAI,GAAG,IAAI,KACrD,6BAAK,GAAG,EAAE,CAAC,CAAC,EAAE,EAAA;AACZ,wBAAA,KAAA,CAAA,aAAA,CAAC,MAAM,EAAA,EAAC,KAAK,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EAAA,EACrD,UAAU,CAAC,SAAS,CAAC,CACf,CACL,CACP,EACD;iBACH,CAAC,CACE,CACP;AACA,YAAA,IAAI,IAAI,IAAI,IAAI,CAAC,IAAI,KACpB,KAAA,CAAA,aAAA,CAAA,KAAA,EAAA,IAAA;gBACE,KAAwB,CAAA,aAAA,CAAA,IAAA,EAAA,IAAA,EAAA,iBAAA,CAAA;gBACxB,KAAC,CAAA,aAAA,CAAA,WAAW,IAAC,KAAK,EAAC,MAAM,EAAC,OAAO,EAAC,MAAM,EAAA;AACtC,oBAAA,KAAA,CAAA,aAAA,CAAC,KAAK,EAAC,EAAA,IAAI,EAAC,MAAM,GAAG,CACT;gBACd,KAAC,CAAA,aAAA,CAAA,WAAW,IAAC,KAAK,EAAC,OAAO,EAAC,OAAO,EAAC,OAAO,EAAA;AACxC,oBAAA,KAAA,CAAA,aAAA,CAAC,KAAK,EAAC,EAAA,IAAI,EAAC,OAAO,GAAG,CACV;AACd,gBAAA,KAAA,CAAA,aAAA,CAAC,MAAM,EAAC,EAAA,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,EAAA,EAAA,MAAA,CAE5C,CACL,CACP;YACA,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,CAAC,IAAI,KAC5B,KAAA,CAAA,aAAA,CAAA,KAAA,EAAA,IAAA;gBACE,KAAyB,CAAA,aAAA,CAAA,IAAA,EAAA,IAAA,EAAA,kBAAA,CAAA;gBACzB,KAAC,CAAA,aAAA,CAAA,WAAW,IAAC,KAAK,EAAC,YAAY,EAAC,OAAO,EAAC,IAAI,EAAA;AAC1C,oBAAA,KAAA,CAAA,aAAA,CAAC,KAAK,EAAC,EAAA,IAAI,EAAC,IAAI,GAAG,CACP;gBACd,KAAC,CAAA,aAAA,CAAA,WAAW,IAAC,KAAK,EAAC,YAAY,EAAC,OAAO,EAAC,IAAI,EAAA;AAC1C,oBAAA,KAAA,CAAA,aAAA,CAAC,KAAK,EAAC,EAAA,IAAI,EAAC,OAAO,GAAG,CACV;gBACd,KAAC,CAAA,aAAA,CAAA,WAAW,IAAC,KAAK,EAAC,YAAY,EAAC,OAAO,EAAC,IAAI,EAAA;AAC1C,oBAAA,KAAA,CAAA,aAAA,CAAC,KAAK,EAAC,EAAA,IAAI,EAAC,OAAO,GAAG,CACV;AACd,gBAAA,KAAA,CAAA,aAAA,CAAC,MAAM,EAAC,EAAA,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,EAAA,EAAA,MAAA,CAE5C,CACL,CACP;AACA,YAAA,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,KAC3B,KAAA,CAAA,aAAA,CAAA,KAAA,EAAA,IAAA;gBACE,KAAwB,CAAA,aAAA,CAAA,IAAA,EAAA,IAAA,EAAA,iBAAA,CAAA;AACxB,gBAAA,KAAA,CAAA,aAAA,CAAA,GAAA,EAAA,IAAA,EAAA,yCAAA,CAA8C,CAC1C,CACP,CACG,CACF,EACN;AACJ,CAAC;AAED,SAAS,UAAU,CAAC,IAAU,EAAA;AAC5B,IAAA,OAAO,IAAI,CAAC,kBAAkB,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC;AAC7E;;;;"}
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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"}
@@ -151,11 +151,14 @@ function SearchControl(props) {
151
151
  }
152
152
  }
153
153
  useEffect(() => {
154
- medplum.requestSchema(props.search.resourceType).then((newSchema) => {
154
+ medplum
155
+ .requestSchema(props.search.resourceType)
156
+ .then((newSchema) => {
155
157
  // The schema could have the same object identity,
156
158
  // so need to use the spread operator to kick React re-render.
157
159
  setSchema(Object.assign({}, newSchema));
158
- });
160
+ })
161
+ .catch(console.log);
159
162
  }, [medplum, props.search.resourceType]);
160
163
  const typeSchema = (_a = schema === null || schema === void 0 ? void 0 : schema.types) === null || _a === void 0 ? void 0 : _a[props.search.resourceType];
161
164
  if (!typeSchema) {
@@ -1 +1 @@
1
- {"version":3,"file":"SearchControl.js","sources":["../../src/SearchControl.tsx"],"sourcesContent":["import {\n DEFAULT_SEARCH_COUNT,\n Filter,\n formatSearchQuery,\n IndexedStructureDefinition,\n parseSearchDefinition,\n SearchRequest,\n} from '@medplum/core';\nimport {\n Bundle,\n OperationOutcome,\n Resource,\n ResourceType,\n SearchParameter,\n UserConfiguration,\n} from '@medplum/fhirtypes';\nimport React, { useEffect, useRef, useState } from 'react';\nimport { Button } from './Button';\nimport { Loading } from './Loading';\nimport { useMedplum } from './MedplumProvider';\nimport { getFieldDefinitions } from './SearchControlField';\nimport { SearchFieldEditor } from './SearchFieldEditor';\nimport { SearchFilterEditor } from './SearchFilterEditor';\nimport { SearchFilterValueDialog } from './SearchFilterValueDialog';\nimport { SearchFilterValueDisplay } from './SearchFilterValueDisplay';\nimport { SearchPopupMenu } from './SearchPopupMenu';\nimport { addFilter, buildFieldNameString, getOpString, movePage, renderValue } from './SearchUtils';\nimport { Select } from './Select';\nimport { TitleBar } from './TitleBar';\nimport { isCheckboxCell, killEvent } from './utils/dom';\nimport './SearchControl.css';\n\nexport class SearchChangeEvent extends Event {\n readonly definition: SearchRequest;\n\n constructor(definition: SearchRequest) {\n super('change');\n this.definition = definition;\n }\n}\n\nexport class SearchLoadEvent extends Event {\n readonly response: Bundle;\n\n constructor(response: Bundle) {\n super('load');\n this.response = response;\n }\n}\n\nexport class SearchClickEvent extends Event {\n readonly resource: Resource;\n readonly browserEvent: React.MouseEvent;\n\n constructor(resource: Resource, browserEvent: React.MouseEvent) {\n super('click');\n this.resource = resource;\n this.browserEvent = browserEvent;\n }\n}\n\nexport interface SearchControlProps {\n search: SearchRequest;\n userConfig?: UserConfiguration;\n checkboxesEnabled?: boolean;\n hideToolbar?: boolean;\n hideFilters?: boolean;\n onLoad?: (e: SearchLoadEvent) => void;\n onChange?: (e: SearchChangeEvent) => void;\n onClick?: (e: SearchClickEvent) => void;\n onAuxClick?: (e: SearchClickEvent) => void;\n onNew?: () => void;\n onExport?: () => void;\n onDelete?: (ids: string[]) => void;\n onPatch?: (ids: string[]) => void;\n onBulk?: (ids: string[]) => void;\n}\n\ninterface SearchControlState {\n searchResponse?: Bundle;\n selected: { [id: string]: boolean };\n popupVisible: boolean;\n popupX: number;\n popupY: number;\n popupSearchParams?: SearchParameter[];\n fieldEditorVisible: boolean;\n filterEditorVisible: boolean;\n filterDialogVisible: boolean;\n filterDialogFilter?: Filter;\n filterDialogSearchParam?: SearchParameter;\n}\n\n/**\n * The SearchControl component represents the embeddable search table control.\n * It includes the table, rows, headers, sorting, etc.\n * It does not include the field editor, filter editor, pagination buttons.\n */\nexport function SearchControl(props: SearchControlProps): JSX.Element {\n const medplum = useMedplum();\n const [schema, setSchema] = useState<IndexedStructureDefinition | undefined>();\n const [outcome, setOutcome] = useState<OperationOutcome | undefined>();\n const { search, onLoad } = props;\n\n const [state, setState] = useState<SearchControlState>({\n selected: {},\n popupVisible: false,\n popupX: 0,\n popupY: 0,\n popupSearchParams: undefined,\n fieldEditorVisible: false,\n filterEditorVisible: false,\n filterDialogVisible: false,\n });\n\n const stateRef = useRef<SearchControlState>(state);\n stateRef.current = state;\n\n useEffect(() => {\n setOutcome(undefined);\n medplum\n .search(search.resourceType as ResourceType, formatSearchQuery({ ...search, total: 'accurate' }))\n .then((response) => {\n setState({ ...stateRef.current, searchResponse: response });\n if (onLoad) {\n onLoad(new SearchLoadEvent(response));\n }\n })\n .catch((reason) => {\n setState({ ...stateRef.current, searchResponse: undefined });\n setOutcome(reason);\n });\n }, [medplum, search, onLoad]);\n\n function handleSingleCheckboxClick(e: React.ChangeEvent, id: string): void {\n e.stopPropagation();\n\n const el = e.target as HTMLInputElement;\n const checked = el.checked;\n const newSelected = { ...stateRef.current.selected };\n if (checked) {\n newSelected[id] = true;\n } else {\n delete newSelected[id];\n }\n setState({ ...stateRef.current, selected: newSelected });\n }\n\n function handleAllCheckboxClick(e: React.ChangeEvent): void {\n e.stopPropagation();\n\n const el = e.target as HTMLInputElement;\n const checked = el.checked;\n const newSelected = {} as { [id: string]: boolean };\n const searchResponse = stateRef.current?.searchResponse;\n if (checked && searchResponse?.entry) {\n searchResponse.entry.forEach((entry) => {\n if (entry.resource?.id) {\n newSelected[entry.resource.id] = true;\n }\n });\n }\n setState({ ...stateRef.current, selected: newSelected });\n }\n\n function isAllSelected(): boolean {\n const state = stateRef.current;\n if (!state.searchResponse?.entry || state.searchResponse.entry.length === 0) {\n return false;\n }\n for (const e of state.searchResponse.entry) {\n if (e.resource?.id && !state.selected[e.resource.id]) {\n return false;\n }\n }\n return true;\n }\n\n /**\n * Handles a click on a column header cell.\n * @param e The click event.\n * @param key The field key.\n */\n function handleSortClick(e: React.MouseEvent, searchParams: SearchParameter[] | undefined): void {\n setState({\n ...stateRef.current,\n popupVisible: true,\n popupX: e.clientX,\n popupY: e.clientY,\n popupSearchParams: searchParams,\n });\n }\n\n /**\n * Emits a change event to the optional change listener.\n * @param newSearch The new search definition.\n */\n function emitSearchChange(newSearch: SearchRequest): void {\n if (props.onChange) {\n props.onChange(new SearchChangeEvent(newSearch));\n }\n }\n\n /**\n * Handles a click on a order row.\n *\n * @param e The click event.\n * @param resource The FHIR resource.\n */\n function handleRowClick(e: React.MouseEvent, resource: Resource): void {\n if (isCheckboxCell(e.target as Element)) {\n // Ignore clicks on checkboxes\n return;\n }\n\n killEvent(e);\n\n if (e.button !== 1 && props.onClick) {\n props.onClick(new SearchClickEvent(resource, e));\n }\n\n if (e.button === 1 && props.onAuxClick) {\n props.onAuxClick(new SearchClickEvent(resource, e));\n }\n }\n\n useEffect(() => {\n medplum.requestSchema(props.search.resourceType as ResourceType).then((newSchema) => {\n // The schema could have the same object identity,\n // so need to use the spread operator to kick React re-render.\n setSchema({ ...newSchema });\n });\n }, [medplum, props.search.resourceType]);\n\n const typeSchema = schema?.types?.[props.search.resourceType];\n if (!typeSchema) {\n return <Loading />;\n }\n\n const checkboxColumn = props.checkboxesEnabled;\n const fields = getFieldDefinitions(schema, search);\n const resourceType = search.resourceType;\n const lastResult = state.searchResponse;\n const entries = lastResult?.entry;\n const resources = entries?.map((e) => e.resource);\n const savedSearches = props.userConfig?.search?.filter((s) => s.criteria?.startsWith(resourceType));\n\n return (\n <div className=\"medplum-search-control\" onContextMenu={(e) => killEvent(e)} data-testid=\"search-control\">\n {!props.hideToolbar && (\n <TitleBar>\n <div>\n <h1>\n <a href={`https://www.hl7.org/fhir/${resourceType.toLowerCase()}.html`} target=\"_blank\" rel=\"noopener\">\n {resourceType}\n </a>\n </h1>\n {savedSearches && (\n <Select\n testid=\"saved-search-select\"\n style={{ width: 80 }}\n onChange={(newValue) => {\n emitSearchChange(parseSearchDefinition(newValue));\n }}\n >\n <option></option>\n {savedSearches.map((s, index) => (\n <option key={`${index}-${savedSearches.length}`} value={s.criteria}>\n {s.name}\n </option>\n ))}\n </Select>\n )}\n <Button\n testid=\"fields-button\"\n size=\"small\"\n onClick={() => setState({ ...stateRef.current, fieldEditorVisible: true })}\n >\n Fields\n </Button>\n <Button\n testid=\"filters-button\"\n size=\"small\"\n onClick={() => setState({ ...stateRef.current, filterEditorVisible: true })}\n >\n Filters\n </Button>\n {props.onNew && (\n <Button size=\"small\" onClick={props.onNew}>\n New...\n </Button>\n )}\n {props.onExport && (\n <Button size=\"small\" onClick={props.onExport}>\n Export...\n </Button>\n )}\n {props.onDelete && (\n <Button\n size=\"small\"\n onClick={() => (props.onDelete as (ids: string[]) => any)(Object.keys(state.selected))}\n >\n Delete...\n </Button>\n )}\n {props.onBulk && (\n <Button\n size=\"small\"\n onClick={() => (props.onBulk as (ids: string[]) => any)(Object.keys(state.selected))}\n >\n Bulk...\n </Button>\n )}\n </div>\n {lastResult && (\n <div>\n <span className=\"medplum-search-summary\">\n {getStart(search, lastResult.total as number)}-{getEnd(search, lastResult.total as number)} of{' '}\n {lastResult.total?.toLocaleString()}\n </span>\n <Button testid=\"prev-page-button\" size=\"small\" onClick={() => emitSearchChange(movePage(search, -1))}>\n &lt;&lt;\n </Button>\n <Button testid=\"next-page-button\" size=\"small\" onClick={() => emitSearchChange(movePage(search, 1))}>\n &gt;&gt;\n </Button>\n </div>\n )}\n </TitleBar>\n )}\n <table>\n <thead>\n <tr>\n {checkboxColumn && (\n <th className=\"medplum-search-icon-cell\">\n <input\n type=\"checkbox\"\n value=\"checked\"\n aria-label=\"all-checkbox\"\n data-testid=\"all-checkbox\"\n checked={isAllSelected()}\n onChange={(e) => handleAllCheckboxClick(e)}\n />\n </th>\n )}\n {fields.map((field) => (\n <th key={field.name} onClick={(e) => handleSortClick(e, field.searchParams)}>\n {buildFieldNameString(field.name)}\n {field.searchParams && <FilterIcon />}\n </th>\n ))}\n </tr>\n {!props.hideFilters && (\n <tr>\n {checkboxColumn && <th className=\"filters medplum-search-icon-cell\" />}\n {fields.map((field) => (\n <th key={field.name} className=\"filters\">\n {field.searchParams && (\n <FilterDescription\n resourceType={resourceType}\n searchParams={field.searchParams}\n filters={props.search.filters}\n />\n )}\n </th>\n ))}\n </tr>\n )}\n </thead>\n <tbody>\n {resources?.map(\n (resource) =>\n resource && (\n <tr\n key={resource.id}\n data-testid=\"search-control-row\"\n onClick={(e) => handleRowClick(e, resource)}\n onAuxClick={(e) => handleRowClick(e, resource)}\n >\n {checkboxColumn && (\n <td className=\"medplum-search-icon-cell\">\n <input\n type=\"checkbox\"\n value=\"checked\"\n data-testid=\"row-checkbox\"\n aria-label={`Checkbox for ${resource.id}`}\n checked={!!state.selected[resource.id as string]}\n onChange={(e) => handleSingleCheckboxClick(e, resource.id as string)}\n />\n </td>\n )}\n {fields.map((field) => (\n <td key={field.name}>{renderValue(resource, field)}</td>\n ))}\n </tr>\n )\n )}\n </tbody>\n </table>\n {resources?.length === 0 && (\n <div data-testid=\"empty-search\" className=\"medplum-empty-search\">\n No results\n </div>\n )}\n {outcome && (\n <div data-testid=\"search-error\" className=\"medplum-empty-search\">\n <pre style={{ textAlign: 'left' }}>{JSON.stringify(outcome, undefined, 2)}</pre>\n </div>\n )}\n <SearchPopupMenu\n schema={schema}\n search={props.search}\n visible={state.popupVisible}\n x={state.popupX}\n y={state.popupY}\n searchParams={state.popupSearchParams}\n onPrompt={(searchParam, filter) => {\n setState({\n ...stateRef.current,\n popupVisible: false,\n filterDialogVisible: true,\n filterDialogSearchParam: searchParam,\n filterDialogFilter: filter,\n });\n }}\n onChange={(result) => {\n emitSearchChange(result);\n setState({\n ...stateRef.current,\n popupVisible: false,\n popupSearchParams: undefined,\n });\n }}\n onClose={() => {\n setState({\n ...stateRef.current,\n popupVisible: false,\n popupSearchParams: undefined,\n });\n }}\n />\n <SearchFieldEditor\n schema={schema}\n search={props.search}\n visible={stateRef.current.fieldEditorVisible}\n onOk={(result) => {\n emitSearchChange(result);\n setState({\n ...stateRef.current,\n fieldEditorVisible: false,\n });\n }}\n onCancel={() => {\n setState({\n ...stateRef.current,\n fieldEditorVisible: false,\n });\n }}\n />\n <SearchFilterEditor\n schema={schema}\n search={props.search}\n visible={stateRef.current.filterEditorVisible}\n onOk={(result) => {\n emitSearchChange(result);\n setState({\n ...stateRef.current,\n filterEditorVisible: false,\n });\n }}\n onCancel={() => {\n setState({\n ...stateRef.current,\n filterEditorVisible: false,\n });\n }}\n />\n <SearchFilterValueDialog\n visible={stateRef.current.filterDialogVisible}\n title={'Input'}\n schema={schema}\n resourceType={resourceType}\n searchParam={state.filterDialogSearchParam}\n filter={state.filterDialogFilter}\n defaultValue={''}\n onOk={(filter) => {\n emitSearchChange(addFilter(props.search, filter.code, filter.operator, filter.value));\n setState({\n ...stateRef.current,\n filterDialogVisible: false,\n });\n }}\n onCancel={() => {\n setState({\n ...stateRef.current,\n filterDialogVisible: false,\n });\n }}\n />\n </div>\n );\n}\n\nexport const MemoizedSearchControl = React.memo(SearchControl);\n\ninterface FilterDescriptionProps {\n readonly resourceType: string;\n readonly searchParams: SearchParameter[];\n readonly filters?: Filter[];\n}\n\nfunction FilterDescription(props: FilterDescriptionProps): JSX.Element {\n const filters = (props.filters ?? []).filter((f) => props.searchParams.find((p) => p.code === f.code));\n if (filters.length === 0) {\n return <span>no filters</span>;\n }\n\n return (\n <>\n {filters.map((filter: Filter, index: number) => (\n <div key={`filter-${index}-${filters.length}`}>\n {getOpString(filter.operator)}\n &nbsp;\n <SearchFilterValueDisplay resourceType={props.resourceType} filter={filter} />\n </div>\n ))}\n </>\n );\n}\n\nfunction FilterIcon(): JSX.Element {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n className=\"h-6 w-6\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"rgba(0, 0, 0, 0.3)\"\n strokeWidth={2}\n >\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M4 6h16M4 12h16m-7 6h7\" />\n </svg>\n );\n}\n\nfunction getStart(search: SearchRequest, total: number): number {\n return Math.min(total, (search.offset ?? 0) + 1);\n}\n\nfunction getEnd(search: SearchRequest, total: number): number {\n return Math.min(total, ((search.offset ?? 0) + 1) * (search.count ?? DEFAULT_SEARCH_COUNT));\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"SearchControl.js","sources":["../../src/SearchControl.tsx"],"sourcesContent":["import {\n DEFAULT_SEARCH_COUNT,\n Filter,\n formatSearchQuery,\n IndexedStructureDefinition,\n parseSearchDefinition,\n SearchRequest,\n} from '@medplum/core';\nimport {\n Bundle,\n OperationOutcome,\n Resource,\n ResourceType,\n SearchParameter,\n UserConfiguration,\n} from '@medplum/fhirtypes';\nimport React, { useEffect, useRef, useState } from 'react';\nimport { Button } from './Button';\nimport { Loading } from './Loading';\nimport { useMedplum } from './MedplumProvider';\nimport './SearchControl.css';\nimport { getFieldDefinitions } from './SearchControlField';\nimport { SearchFieldEditor } from './SearchFieldEditor';\nimport { SearchFilterEditor } from './SearchFilterEditor';\nimport { SearchFilterValueDialog } from './SearchFilterValueDialog';\nimport { SearchFilterValueDisplay } from './SearchFilterValueDisplay';\nimport { SearchPopupMenu } from './SearchPopupMenu';\nimport { addFilter, buildFieldNameString, getOpString, movePage, renderValue } from './SearchUtils';\nimport { Select } from './Select';\nimport { TitleBar } from './TitleBar';\nimport { isCheckboxCell, killEvent } from './utils/dom';\n\nexport class SearchChangeEvent extends Event {\n readonly definition: SearchRequest;\n\n constructor(definition: SearchRequest) {\n super('change');\n this.definition = definition;\n }\n}\n\nexport class SearchLoadEvent extends Event {\n readonly response: Bundle;\n\n constructor(response: Bundle) {\n super('load');\n this.response = response;\n }\n}\n\nexport class SearchClickEvent extends Event {\n readonly resource: Resource;\n readonly browserEvent: React.MouseEvent;\n\n constructor(resource: Resource, browserEvent: React.MouseEvent) {\n super('click');\n this.resource = resource;\n this.browserEvent = browserEvent;\n }\n}\n\nexport interface SearchControlProps {\n search: SearchRequest;\n userConfig?: UserConfiguration;\n checkboxesEnabled?: boolean;\n hideToolbar?: boolean;\n hideFilters?: boolean;\n onLoad?: (e: SearchLoadEvent) => void;\n onChange?: (e: SearchChangeEvent) => void;\n onClick?: (e: SearchClickEvent) => void;\n onAuxClick?: (e: SearchClickEvent) => void;\n onNew?: () => void;\n onExport?: () => void;\n onDelete?: (ids: string[]) => void;\n onPatch?: (ids: string[]) => void;\n onBulk?: (ids: string[]) => void;\n}\n\ninterface SearchControlState {\n searchResponse?: Bundle;\n selected: { [id: string]: boolean };\n popupVisible: boolean;\n popupX: number;\n popupY: number;\n popupSearchParams?: SearchParameter[];\n fieldEditorVisible: boolean;\n filterEditorVisible: boolean;\n filterDialogVisible: boolean;\n filterDialogFilter?: Filter;\n filterDialogSearchParam?: SearchParameter;\n}\n\n/**\n * The SearchControl component represents the embeddable search table control.\n * It includes the table, rows, headers, sorting, etc.\n * It does not include the field editor, filter editor, pagination buttons.\n */\nexport function SearchControl(props: SearchControlProps): JSX.Element {\n const medplum = useMedplum();\n const [schema, setSchema] = useState<IndexedStructureDefinition | undefined>();\n const [outcome, setOutcome] = useState<OperationOutcome | undefined>();\n const { search, onLoad } = props;\n\n const [state, setState] = useState<SearchControlState>({\n selected: {},\n popupVisible: false,\n popupX: 0,\n popupY: 0,\n popupSearchParams: undefined,\n fieldEditorVisible: false,\n filterEditorVisible: false,\n filterDialogVisible: false,\n });\n\n const stateRef = useRef<SearchControlState>(state);\n stateRef.current = state;\n\n useEffect(() => {\n setOutcome(undefined);\n medplum\n .search(search.resourceType as ResourceType, formatSearchQuery({ ...search, total: 'accurate' }))\n .then((response) => {\n setState({ ...stateRef.current, searchResponse: response });\n if (onLoad) {\n onLoad(new SearchLoadEvent(response));\n }\n })\n .catch((reason) => {\n setState({ ...stateRef.current, searchResponse: undefined });\n setOutcome(reason);\n });\n }, [medplum, search, onLoad]);\n\n function handleSingleCheckboxClick(e: React.ChangeEvent, id: string): void {\n e.stopPropagation();\n\n const el = e.target as HTMLInputElement;\n const checked = el.checked;\n const newSelected = { ...stateRef.current.selected };\n if (checked) {\n newSelected[id] = true;\n } else {\n delete newSelected[id];\n }\n setState({ ...stateRef.current, selected: newSelected });\n }\n\n function handleAllCheckboxClick(e: React.ChangeEvent): void {\n e.stopPropagation();\n\n const el = e.target as HTMLInputElement;\n const checked = el.checked;\n const newSelected = {} as { [id: string]: boolean };\n const searchResponse = stateRef.current?.searchResponse;\n if (checked && searchResponse?.entry) {\n searchResponse.entry.forEach((entry) => {\n if (entry.resource?.id) {\n newSelected[entry.resource.id] = true;\n }\n });\n }\n setState({ ...stateRef.current, selected: newSelected });\n }\n\n function isAllSelected(): boolean {\n const state = stateRef.current;\n if (!state.searchResponse?.entry || state.searchResponse.entry.length === 0) {\n return false;\n }\n for (const e of state.searchResponse.entry) {\n if (e.resource?.id && !state.selected[e.resource.id]) {\n return false;\n }\n }\n return true;\n }\n\n /**\n * Handles a click on a column header cell.\n * @param e The click event.\n * @param key The field key.\n */\n function handleSortClick(e: React.MouseEvent, searchParams: SearchParameter[] | undefined): void {\n setState({\n ...stateRef.current,\n popupVisible: true,\n popupX: e.clientX,\n popupY: e.clientY,\n popupSearchParams: searchParams,\n });\n }\n\n /**\n * Emits a change event to the optional change listener.\n * @param newSearch The new search definition.\n */\n function emitSearchChange(newSearch: SearchRequest): void {\n if (props.onChange) {\n props.onChange(new SearchChangeEvent(newSearch));\n }\n }\n\n /**\n * Handles a click on a order row.\n *\n * @param e The click event.\n * @param resource The FHIR resource.\n */\n function handleRowClick(e: React.MouseEvent, resource: Resource): void {\n if (isCheckboxCell(e.target as Element)) {\n // Ignore clicks on checkboxes\n return;\n }\n\n killEvent(e);\n\n if (e.button !== 1 && props.onClick) {\n props.onClick(new SearchClickEvent(resource, e));\n }\n\n if (e.button === 1 && props.onAuxClick) {\n props.onAuxClick(new SearchClickEvent(resource, e));\n }\n }\n\n useEffect(() => {\n medplum\n .requestSchema(props.search.resourceType as ResourceType)\n .then((newSchema) => {\n // The schema could have the same object identity,\n // so need to use the spread operator to kick React re-render.\n setSchema({ ...newSchema });\n })\n .catch(console.log);\n }, [medplum, props.search.resourceType]);\n\n const typeSchema = schema?.types?.[props.search.resourceType];\n if (!typeSchema) {\n return <Loading />;\n }\n\n const checkboxColumn = props.checkboxesEnabled;\n const fields = getFieldDefinitions(schema, search);\n const resourceType = search.resourceType;\n const lastResult = state.searchResponse;\n const entries = lastResult?.entry;\n const resources = entries?.map((e) => e.resource);\n const savedSearches = props.userConfig?.search?.filter((s) => s.criteria?.startsWith(resourceType));\n\n return (\n <div className=\"medplum-search-control\" onContextMenu={(e) => killEvent(e)} data-testid=\"search-control\">\n {!props.hideToolbar && (\n <TitleBar>\n <div>\n <h1>\n <a href={`https://www.hl7.org/fhir/${resourceType.toLowerCase()}.html`} target=\"_blank\" rel=\"noopener\">\n {resourceType}\n </a>\n </h1>\n {savedSearches && (\n <Select\n testid=\"saved-search-select\"\n style={{ width: 80 }}\n onChange={(newValue) => {\n emitSearchChange(parseSearchDefinition(newValue));\n }}\n >\n <option></option>\n {savedSearches.map((s, index) => (\n <option key={`${index}-${savedSearches.length}`} value={s.criteria}>\n {s.name}\n </option>\n ))}\n </Select>\n )}\n <Button\n testid=\"fields-button\"\n size=\"small\"\n onClick={() => setState({ ...stateRef.current, fieldEditorVisible: true })}\n >\n Fields\n </Button>\n <Button\n testid=\"filters-button\"\n size=\"small\"\n onClick={() => setState({ ...stateRef.current, filterEditorVisible: true })}\n >\n Filters\n </Button>\n {props.onNew && (\n <Button size=\"small\" onClick={props.onNew}>\n New...\n </Button>\n )}\n {props.onExport && (\n <Button size=\"small\" onClick={props.onExport}>\n Export...\n </Button>\n )}\n {props.onDelete && (\n <Button\n size=\"small\"\n onClick={() => (props.onDelete as (ids: string[]) => any)(Object.keys(state.selected))}\n >\n Delete...\n </Button>\n )}\n {props.onBulk && (\n <Button\n size=\"small\"\n onClick={() => (props.onBulk as (ids: string[]) => any)(Object.keys(state.selected))}\n >\n Bulk...\n </Button>\n )}\n </div>\n {lastResult && (\n <div>\n <span className=\"medplum-search-summary\">\n {getStart(search, lastResult.total as number)}-{getEnd(search, lastResult.total as number)} of{' '}\n {lastResult.total?.toLocaleString()}\n </span>\n <Button testid=\"prev-page-button\" size=\"small\" onClick={() => emitSearchChange(movePage(search, -1))}>\n &lt;&lt;\n </Button>\n <Button testid=\"next-page-button\" size=\"small\" onClick={() => emitSearchChange(movePage(search, 1))}>\n &gt;&gt;\n </Button>\n </div>\n )}\n </TitleBar>\n )}\n <table>\n <thead>\n <tr>\n {checkboxColumn && (\n <th className=\"medplum-search-icon-cell\">\n <input\n type=\"checkbox\"\n value=\"checked\"\n aria-label=\"all-checkbox\"\n data-testid=\"all-checkbox\"\n checked={isAllSelected()}\n onChange={(e) => handleAllCheckboxClick(e)}\n />\n </th>\n )}\n {fields.map((field) => (\n <th key={field.name} onClick={(e) => handleSortClick(e, field.searchParams)}>\n {buildFieldNameString(field.name)}\n {field.searchParams && <FilterIcon />}\n </th>\n ))}\n </tr>\n {!props.hideFilters && (\n <tr>\n {checkboxColumn && <th className=\"filters medplum-search-icon-cell\" />}\n {fields.map((field) => (\n <th key={field.name} className=\"filters\">\n {field.searchParams && (\n <FilterDescription\n resourceType={resourceType}\n searchParams={field.searchParams}\n filters={props.search.filters}\n />\n )}\n </th>\n ))}\n </tr>\n )}\n </thead>\n <tbody>\n {resources?.map(\n (resource) =>\n resource && (\n <tr\n key={resource.id}\n data-testid=\"search-control-row\"\n onClick={(e) => handleRowClick(e, resource)}\n onAuxClick={(e) => handleRowClick(e, resource)}\n >\n {checkboxColumn && (\n <td className=\"medplum-search-icon-cell\">\n <input\n type=\"checkbox\"\n value=\"checked\"\n data-testid=\"row-checkbox\"\n aria-label={`Checkbox for ${resource.id}`}\n checked={!!state.selected[resource.id as string]}\n onChange={(e) => handleSingleCheckboxClick(e, resource.id as string)}\n />\n </td>\n )}\n {fields.map((field) => (\n <td key={field.name}>{renderValue(resource, field)}</td>\n ))}\n </tr>\n )\n )}\n </tbody>\n </table>\n {resources?.length === 0 && (\n <div data-testid=\"empty-search\" className=\"medplum-empty-search\">\n No results\n </div>\n )}\n {outcome && (\n <div data-testid=\"search-error\" className=\"medplum-empty-search\">\n <pre style={{ textAlign: 'left' }}>{JSON.stringify(outcome, undefined, 2)}</pre>\n </div>\n )}\n <SearchPopupMenu\n schema={schema}\n search={props.search}\n visible={state.popupVisible}\n x={state.popupX}\n y={state.popupY}\n searchParams={state.popupSearchParams}\n onPrompt={(searchParam, filter) => {\n setState({\n ...stateRef.current,\n popupVisible: false,\n filterDialogVisible: true,\n filterDialogSearchParam: searchParam,\n filterDialogFilter: filter,\n });\n }}\n onChange={(result) => {\n emitSearchChange(result);\n setState({\n ...stateRef.current,\n popupVisible: false,\n popupSearchParams: undefined,\n });\n }}\n onClose={() => {\n setState({\n ...stateRef.current,\n popupVisible: false,\n popupSearchParams: undefined,\n });\n }}\n />\n <SearchFieldEditor\n schema={schema}\n search={props.search}\n visible={stateRef.current.fieldEditorVisible}\n onOk={(result) => {\n emitSearchChange(result);\n setState({\n ...stateRef.current,\n fieldEditorVisible: false,\n });\n }}\n onCancel={() => {\n setState({\n ...stateRef.current,\n fieldEditorVisible: false,\n });\n }}\n />\n <SearchFilterEditor\n schema={schema}\n search={props.search}\n visible={stateRef.current.filterEditorVisible}\n onOk={(result) => {\n emitSearchChange(result);\n setState({\n ...stateRef.current,\n filterEditorVisible: false,\n });\n }}\n onCancel={() => {\n setState({\n ...stateRef.current,\n filterEditorVisible: false,\n });\n }}\n />\n <SearchFilterValueDialog\n visible={stateRef.current.filterDialogVisible}\n title={'Input'}\n schema={schema}\n resourceType={resourceType}\n searchParam={state.filterDialogSearchParam}\n filter={state.filterDialogFilter}\n defaultValue={''}\n onOk={(filter) => {\n emitSearchChange(addFilter(props.search, filter.code, filter.operator, filter.value));\n setState({\n ...stateRef.current,\n filterDialogVisible: false,\n });\n }}\n onCancel={() => {\n setState({\n ...stateRef.current,\n filterDialogVisible: false,\n });\n }}\n />\n </div>\n );\n}\n\nexport const MemoizedSearchControl = React.memo(SearchControl);\n\ninterface FilterDescriptionProps {\n readonly resourceType: string;\n readonly searchParams: SearchParameter[];\n readonly filters?: Filter[];\n}\n\nfunction FilterDescription(props: FilterDescriptionProps): JSX.Element {\n const filters = (props.filters ?? []).filter((f) => props.searchParams.find((p) => p.code === f.code));\n if (filters.length === 0) {\n return <span>no filters</span>;\n }\n\n return (\n <>\n {filters.map((filter: Filter, index: number) => (\n <div key={`filter-${index}-${filters.length}`}>\n {getOpString(filter.operator)}\n &nbsp;\n <SearchFilterValueDisplay resourceType={props.resourceType} filter={filter} />\n </div>\n ))}\n </>\n );\n}\n\nfunction FilterIcon(): JSX.Element {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n className=\"h-6 w-6\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"rgba(0, 0, 0, 0.3)\"\n strokeWidth={2}\n >\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M4 6h16M4 12h16m-7 6h7\" />\n </svg>\n );\n}\n\nfunction getStart(search: SearchRequest, total: number): number {\n return Math.min(total, (search.offset ?? 0) + 1);\n}\n\nfunction getEnd(search: SearchRequest, total: number): number {\n return Math.min(total, ((search.offset ?? 0) + 1) * (search.count ?? DEFAULT_SEARCH_COUNT));\n}\n"],"names":[],"mappings":"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"}
@@ -116,7 +116,8 @@ function ProfileForm(props) {
116
116
  login: props.login,
117
117
  profile: membership.id,
118
118
  })
119
- .then(props.handleAuthResponse);
119
+ .then(props.handleAuthResponse)
120
+ .catch(console.log);
120
121
  } },
121
122
  React.createElement("div", { className: "medplum-nav-menu-profile-icon" },
122
123
  React.createElement(Avatar, { alt: (_a = membership.profile) === null || _a === void 0 ? void 0 : _a.display })),
@@ -1 +1 @@
1
- {"version":3,"file":"SignInForm.js","sources":["../../src/SignInForm.tsx"],"sourcesContent":["import { GoogleCredentialResponse, LoginAuthenticationResponse } from '@medplum/core';\nimport { OperationOutcome, ProjectMembership } from '@medplum/fhirtypes';\nimport React, { useState } from 'react';\nimport { Avatar } from './Avatar';\nimport { Button } from './Button';\nimport { Document } from './Document';\nimport { Form } from './Form';\nimport { FormSection } from './FormSection';\nimport { getGoogleClientId, GoogleButton } from './GoogleButton';\nimport { Input } from './Input';\nimport { Logo } from './Logo';\nimport { MedplumLink } from './MedplumLink';\nimport { useMedplum } from './MedplumProvider';\nimport './SignInForm.css';\nimport './util.css';\nimport { getIssuesForExpression } from './utils/outcomes';\n\nexport interface SignInFormProps {\n readonly remember?: boolean;\n readonly projectId?: string;\n readonly googleClientId?: string;\n readonly clientId?: string;\n readonly scope?: string;\n readonly nonce?: string;\n readonly onSuccess?: () => void;\n readonly onForgotPassword?: () => void;\n readonly onRegister?: () => void;\n readonly onCode?: (code: string) => void;\n readonly children?: React.ReactNode;\n}\n\nexport function SignInForm(props: SignInFormProps): JSX.Element {\n const medplum = useMedplum();\n const [login, setLogin] = useState<string | undefined>(undefined);\n const [memberships, setMemberships] = useState<ProjectMembership[] | undefined>(undefined);\n\n function handleAuthResponse(response: LoginAuthenticationResponse): void {\n if (response.login) {\n setLogin(response.login);\n }\n\n if (response.memberships) {\n setMemberships(response.memberships);\n }\n\n if (response.code) {\n if (props.onCode) {\n props.onCode(response.code);\n } else {\n medplum\n .processCode(response.code)\n .then(() => {\n if (props.onSuccess) {\n props.onSuccess();\n }\n })\n .catch(console.log);\n }\n }\n }\n\n return (\n <Document width={450}>\n {(() => {\n if (!login) {\n return (\n <AuthenticationForm\n clientId={props.clientId}\n scope={props.scope}\n nonce={props.nonce}\n googleClientId={props.googleClientId}\n onForgotPassword={props.onForgotPassword}\n onRegister={props.onRegister}\n handleAuthResponse={handleAuthResponse}\n >\n {props.children}\n </AuthenticationForm>\n );\n } else if (memberships) {\n return <ProfileForm login={login} memberships={memberships} handleAuthResponse={handleAuthResponse} />;\n } else {\n return <div>Success</div>;\n }\n })()}\n </Document>\n );\n}\n\ninterface AuthenticationFormProps {\n readonly projectId?: string;\n readonly clientId?: string;\n readonly scope?: string;\n readonly nonce?: string;\n readonly googleClientId?: string;\n readonly onForgotPassword?: () => void;\n readonly onRegister?: () => void;\n readonly handleAuthResponse: (response: LoginAuthenticationResponse) => void;\n readonly children?: React.ReactNode;\n}\n\nfunction 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 clientId: props.clientId,\n scope: props.scope,\n nonce: props.nonce,\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 clientId: props.clientId,\n scope: props.scope,\n nonce: props.nonce,\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\ninterface ProfileFormProps {\n login: string;\n memberships: ProjectMembership[];\n handleAuthResponse: (response: any) => void;\n}\n\nfunction ProfileForm(props: ProfileFormProps): 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 }}\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":"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"}
1
+ {"version":3,"file":"SignInForm.js","sources":["../../src/SignInForm.tsx"],"sourcesContent":["import { GoogleCredentialResponse, LoginAuthenticationResponse } from '@medplum/core';\nimport { OperationOutcome, ProjectMembership } from '@medplum/fhirtypes';\nimport React, { useState } from 'react';\nimport { Avatar } from './Avatar';\nimport { Button } from './Button';\nimport { Document } from './Document';\nimport { Form } from './Form';\nimport { FormSection } from './FormSection';\nimport { getGoogleClientId, GoogleButton } from './GoogleButton';\nimport { Input } from './Input';\nimport { Logo } from './Logo';\nimport { MedplumLink } from './MedplumLink';\nimport { useMedplum } from './MedplumProvider';\nimport './SignInForm.css';\nimport './util.css';\nimport { getIssuesForExpression } from './utils/outcomes';\n\nexport interface SignInFormProps {\n readonly remember?: boolean;\n readonly projectId?: string;\n readonly googleClientId?: string;\n readonly clientId?: string;\n readonly scope?: string;\n readonly nonce?: string;\n readonly onSuccess?: () => void;\n readonly onForgotPassword?: () => void;\n readonly onRegister?: () => void;\n readonly onCode?: (code: string) => void;\n readonly children?: React.ReactNode;\n}\n\nexport function SignInForm(props: SignInFormProps): JSX.Element {\n const medplum = useMedplum();\n const [login, setLogin] = useState<string | undefined>(undefined);\n const [memberships, setMemberships] = useState<ProjectMembership[] | undefined>(undefined);\n\n function handleAuthResponse(response: LoginAuthenticationResponse): void {\n if (response.login) {\n setLogin(response.login);\n }\n\n if (response.memberships) {\n setMemberships(response.memberships);\n }\n\n if (response.code) {\n if (props.onCode) {\n props.onCode(response.code);\n } else {\n medplum\n .processCode(response.code)\n .then(() => {\n if (props.onSuccess) {\n props.onSuccess();\n }\n })\n .catch(console.log);\n }\n }\n }\n\n return (\n <Document width={450}>\n {(() => {\n if (!login) {\n return (\n <AuthenticationForm\n clientId={props.clientId}\n scope={props.scope}\n nonce={props.nonce}\n googleClientId={props.googleClientId}\n onForgotPassword={props.onForgotPassword}\n onRegister={props.onRegister}\n handleAuthResponse={handleAuthResponse}\n >\n {props.children}\n </AuthenticationForm>\n );\n } else if (memberships) {\n return <ProfileForm login={login} memberships={memberships} handleAuthResponse={handleAuthResponse} />;\n } else {\n return <div>Success</div>;\n }\n })()}\n </Document>\n );\n}\n\ninterface AuthenticationFormProps {\n readonly projectId?: string;\n readonly clientId?: string;\n readonly scope?: string;\n readonly nonce?: string;\n readonly googleClientId?: string;\n readonly onForgotPassword?: () => void;\n readonly onRegister?: () => void;\n readonly handleAuthResponse: (response: LoginAuthenticationResponse) => void;\n readonly children?: React.ReactNode;\n}\n\nfunction 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 clientId: props.clientId,\n scope: props.scope,\n nonce: props.nonce,\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 clientId: props.clientId,\n scope: props.scope,\n nonce: props.nonce,\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\ninterface ProfileFormProps {\n login: string;\n memberships: ProjectMembership[];\n handleAuthResponse: (response: any) => void;\n}\n\nfunction ProfileForm(props: ProfileFormProps): 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":"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"}