@medplum/react 0.9.25 → 0.9.26

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 (407) hide show
  1. package/dist/cjs/index.js.map +1 -1
  2. package/dist/cjs/index.min.js.map +1 -1
  3. package/dist/{types → esm}/AddressDisplay.d.ts +0 -0
  4. package/dist/esm/AddressDisplay.js +13 -0
  5. package/dist/esm/AddressDisplay.js.map +1 -0
  6. package/dist/{types → esm}/AddressInput.d.ts +0 -0
  7. package/dist/esm/AddressInput.js +69 -0
  8. package/dist/esm/AddressInput.js.map +1 -0
  9. package/dist/{types → esm}/AnnotationInput.d.ts +0 -0
  10. package/dist/esm/AnnotationInput.js +28 -0
  11. package/dist/esm/AnnotationInput.js.map +1 -0
  12. package/dist/{types → esm}/AttachmentArrayDisplay.d.ts +0 -0
  13. package/dist/esm/AttachmentArrayDisplay.js +11 -0
  14. package/dist/esm/AttachmentArrayDisplay.js.map +1 -0
  15. package/dist/{types → esm}/AttachmentArrayInput.d.ts +0 -0
  16. package/dist/esm/AttachmentArrayInput.js +42 -0
  17. package/dist/esm/AttachmentArrayInput.js.map +1 -0
  18. package/dist/{types → esm}/AttachmentDisplay.d.ts +0 -0
  19. package/dist/esm/AttachmentDisplay.js +20 -0
  20. package/dist/esm/AttachmentDisplay.js.map +1 -0
  21. package/dist/{types → esm}/AttachmentInput.d.ts +0 -0
  22. package/dist/esm/AttachmentInput.js +27 -0
  23. package/dist/esm/AttachmentInput.js.map +1 -0
  24. package/dist/{types → esm}/Autocomplete.d.ts +0 -0
  25. package/dist/esm/Autocomplete.js +284 -0
  26. package/dist/esm/Autocomplete.js.map +1 -0
  27. package/dist/{types → esm}/Avatar.d.ts +0 -0
  28. package/dist/esm/Avatar.js +24 -0
  29. package/dist/esm/Avatar.js.map +1 -0
  30. package/dist/{types → esm}/BackboneElementDisplay.d.ts +0 -0
  31. package/dist/esm/BackboneElementDisplay.js +43 -0
  32. package/dist/esm/BackboneElementDisplay.js.map +1 -0
  33. package/dist/{types → esm}/BackboneElementInput.d.ts +0 -0
  34. package/dist/esm/BackboneElementInput.js +51 -0
  35. package/dist/esm/BackboneElementInput.js.map +1 -0
  36. package/dist/{types → esm}/Button.d.ts +0 -0
  37. package/dist/esm/Button.js +13 -0
  38. package/dist/esm/Button.js.map +1 -0
  39. package/dist/{types → esm}/CalendarInput.d.ts +0 -0
  40. package/dist/esm/CalendarInput.js +96 -0
  41. package/dist/esm/CalendarInput.js.map +1 -0
  42. package/dist/{types → esm}/Checkbox.d.ts +0 -0
  43. package/dist/esm/Checkbox.js +13 -0
  44. package/dist/esm/Checkbox.js.map +1 -0
  45. package/dist/{types → esm}/CheckboxFormSection.d.ts +0 -0
  46. package/dist/esm/CheckboxFormSection.js +12 -0
  47. package/dist/esm/CheckboxFormSection.js.map +1 -0
  48. package/dist/{types → esm}/CodeInput.d.ts +0 -0
  49. package/dist/esm/CodeInput.js +28 -0
  50. package/dist/esm/CodeInput.js.map +1 -0
  51. package/dist/{types → esm}/CodeableConceptDisplay.d.ts +0 -0
  52. package/dist/esm/CodeableConceptDisplay.js +19 -0
  53. package/dist/esm/CodeableConceptDisplay.js.map +1 -0
  54. package/dist/{types → esm}/CodeableConceptInput.d.ts +0 -0
  55. package/dist/esm/CodeableConceptInput.js +52 -0
  56. package/dist/esm/CodeableConceptInput.js.map +1 -0
  57. package/dist/{types → esm}/CodingDisplay.d.ts +0 -0
  58. package/dist/esm/CodingDisplay.js +9 -0
  59. package/dist/esm/CodingDisplay.js.map +1 -0
  60. package/dist/{types → esm}/CodingInput.d.ts +0 -0
  61. package/dist/esm/CodingInput.js +30 -0
  62. package/dist/esm/CodingInput.js.map +1 -0
  63. package/dist/{types → esm}/ContactDetailDisplay.d.ts +0 -0
  64. package/dist/esm/ContactDetailDisplay.js +17 -0
  65. package/dist/esm/ContactDetailDisplay.js.map +1 -0
  66. package/dist/{types → esm}/ContactDetailInput.d.ts +0 -0
  67. package/dist/esm/ContactDetailInput.js +37 -0
  68. package/dist/esm/ContactDetailInput.js.map +1 -0
  69. package/dist/{types → esm}/ContactPointDisplay.d.ts +0 -0
  70. package/dist/esm/ContactPointDisplay.js +29 -0
  71. package/dist/esm/ContactPointDisplay.js.map +1 -0
  72. package/dist/{types → esm}/ContactPointInput.d.ts +0 -0
  73. package/dist/esm/ContactPointInput.js +60 -0
  74. package/dist/esm/ContactPointInput.js.map +1 -0
  75. package/dist/{types → esm}/DateTimeDisplay.d.ts +0 -0
  76. package/dist/esm/DateTimeDisplay.js +11 -0
  77. package/dist/esm/DateTimeDisplay.js.map +1 -0
  78. package/dist/{types → esm}/DateTimeInput.d.ts +0 -0
  79. package/dist/esm/DateTimeInput.js +62 -0
  80. package/dist/esm/DateTimeInput.js.map +1 -0
  81. package/dist/{types → esm}/DefaultResourceTimeline.d.ts +0 -0
  82. package/dist/esm/DefaultResourceTimeline.js +27 -0
  83. package/dist/esm/DefaultResourceTimeline.js.map +1 -0
  84. package/dist/{types → esm}/DescriptionList.d.ts +0 -0
  85. package/dist/esm/DescriptionList.js +13 -0
  86. package/dist/esm/DescriptionList.js.map +1 -0
  87. package/dist/{types → esm}/DiagnosticReportDisplay.d.ts +0 -0
  88. package/dist/esm/DiagnosticReportDisplay.js +103 -0
  89. package/dist/esm/DiagnosticReportDisplay.js.map +1 -0
  90. package/dist/{types → esm}/Dialog.d.ts +0 -0
  91. package/dist/esm/Dialog.js +43 -0
  92. package/dist/esm/Dialog.js.map +1 -0
  93. package/dist/{types → esm}/Document.d.ts +0 -0
  94. package/dist/esm/Document.js +9 -0
  95. package/dist/esm/Document.js.map +1 -0
  96. package/dist/{types → esm}/EncounterTimeline.d.ts +0 -0
  97. package/dist/esm/EncounterTimeline.js +47 -0
  98. package/dist/esm/EncounterTimeline.js.map +1 -0
  99. package/dist/{types → esm}/ErrorBoundary.d.ts +0 -0
  100. package/dist/esm/ErrorBoundary.js +27 -0
  101. package/dist/esm/ErrorBoundary.js.map +1 -0
  102. package/dist/{types → esm}/ExtensionInput.d.ts +0 -0
  103. package/dist/esm/ExtensionInput.js +14 -0
  104. package/dist/esm/ExtensionInput.js.map +1 -0
  105. package/dist/{types → esm}/FhirPathDisplay.d.ts +0 -0
  106. package/dist/esm/FhirPathDisplay.js +23 -0
  107. package/dist/esm/FhirPathDisplay.js.map +1 -0
  108. package/dist/{types → esm}/FhirPathTable.d.ts +0 -0
  109. package/dist/esm/FhirPathTable.js +117 -0
  110. package/dist/esm/FhirPathTable.js.map +1 -0
  111. package/dist/{types → esm}/FooterLinks.d.ts +0 -0
  112. package/dist/esm/FooterLinks.js +8 -0
  113. package/dist/esm/FooterLinks.js.map +1 -0
  114. package/dist/{types → esm}/Form.d.ts +0 -0
  115. package/dist/esm/Form.js +15 -0
  116. package/dist/esm/Form.js.map +1 -0
  117. package/dist/{types → esm}/FormSection.d.ts +0 -0
  118. package/dist/esm/FormSection.js +18 -0
  119. package/dist/esm/FormSection.js.map +1 -0
  120. package/dist/{types → esm}/FormUtils.d.ts +0 -0
  121. package/dist/esm/FormUtils.js +49 -0
  122. package/dist/esm/FormUtils.js.map +1 -0
  123. package/dist/{types → esm}/GoogleButton.d.ts +0 -0
  124. package/dist/esm/GoogleButton.js +48 -0
  125. package/dist/esm/GoogleButton.js.map +1 -0
  126. package/dist/{types → esm}/Header.d.ts +0 -0
  127. package/dist/esm/Header.js +95 -0
  128. package/dist/esm/Header.js.map +1 -0
  129. package/dist/{types → esm}/HeaderSearchInput.d.ts +0 -0
  130. package/dist/esm/HeaderSearchInput.js +181 -0
  131. package/dist/esm/HeaderSearchInput.js.map +1 -0
  132. package/dist/{types → esm}/HumanNameDisplay.d.ts +0 -0
  133. package/dist/esm/HumanNameDisplay.js +13 -0
  134. package/dist/esm/HumanNameDisplay.js.map +1 -0
  135. package/dist/{types → esm}/HumanNameInput.d.ts +0 -0
  136. package/dist/esm/HumanNameInput.js +49 -0
  137. package/dist/esm/HumanNameInput.js.map +1 -0
  138. package/dist/{types → esm}/IdentifierDisplay.d.ts +0 -0
  139. package/dist/esm/IdentifierDisplay.js +12 -0
  140. package/dist/esm/IdentifierDisplay.js.map +1 -0
  141. package/dist/{types → esm}/IdentifierInput.d.ts +0 -0
  142. package/dist/esm/IdentifierInput.js +19 -0
  143. package/dist/esm/IdentifierInput.js.map +1 -0
  144. package/dist/{types → esm}/Input.d.ts +0 -0
  145. package/dist/esm/Input.js +26 -0
  146. package/dist/esm/Input.js.map +1 -0
  147. package/dist/{types → esm}/InputRow.d.ts +0 -0
  148. package/dist/esm/InputRow.js +8 -0
  149. package/dist/esm/InputRow.js.map +1 -0
  150. package/dist/{types → esm}/Loading.d.ts +0 -0
  151. package/dist/esm/Loading.js +11 -0
  152. package/dist/esm/Loading.js.map +1 -0
  153. package/dist/{types → esm}/Logo.d.ts +0 -0
  154. package/dist/esm/Logo.js +14 -0
  155. package/dist/esm/Logo.js.map +1 -0
  156. package/dist/{types → esm}/MedplumLink.d.ts +0 -0
  157. package/dist/esm/MedplumLink.js +34 -0
  158. package/dist/esm/MedplumLink.js.map +1 -0
  159. package/dist/{types → esm}/MedplumProvider.d.ts +0 -0
  160. package/dist/esm/MedplumProvider.js +50 -0
  161. package/dist/esm/MedplumProvider.js.map +1 -0
  162. package/dist/{types → esm}/MenuItem.d.ts +0 -0
  163. package/dist/esm/MenuItem.js +8 -0
  164. package/dist/esm/MenuItem.js.map +1 -0
  165. package/dist/{types → esm}/MenuSeparator.d.ts +0 -0
  166. package/dist/esm/MenuSeparator.js +8 -0
  167. package/dist/esm/MenuSeparator.js.map +1 -0
  168. package/dist/{types → esm}/PatientTimeline.d.ts +0 -0
  169. package/dist/esm/PatientTimeline.js +40 -0
  170. package/dist/esm/PatientTimeline.js.map +1 -0
  171. package/dist/{types → esm}/PeriodDisplay.d.ts +0 -0
  172. package/dist/esm/PeriodDisplay.js +16 -0
  173. package/dist/esm/PeriodDisplay.js.map +1 -0
  174. package/dist/{types → esm}/PeriodInput.d.ts +0 -0
  175. package/dist/esm/PeriodInput.js +19 -0
  176. package/dist/esm/PeriodInput.js.map +1 -0
  177. package/dist/{types → esm}/PlanDefinitionBuilder.d.ts +0 -0
  178. package/dist/esm/PlanDefinitionBuilder.js +155 -0
  179. package/dist/esm/PlanDefinitionBuilder.js.map +1 -0
  180. package/dist/{types → esm}/Popup.d.ts +0 -0
  181. package/dist/esm/Popup.js +64 -0
  182. package/dist/esm/Popup.js.map +1 -0
  183. package/dist/{types → esm}/QuantityDisplay.d.ts +0 -0
  184. package/dist/esm/QuantityDisplay.js +28 -0
  185. package/dist/esm/QuantityDisplay.js.map +1 -0
  186. package/dist/{types → esm}/QuantityInput.d.ts +0 -0
  187. package/dist/esm/QuantityInput.js +33 -0
  188. package/dist/esm/QuantityInput.js.map +1 -0
  189. package/dist/{types → esm}/QuestionnaireBuilder.d.ts +0 -0
  190. package/dist/esm/QuestionnaireBuilder.js +217 -0
  191. package/dist/esm/QuestionnaireBuilder.js.map +1 -0
  192. package/dist/{types → esm}/QuestionnaireForm.d.ts +0 -0
  193. package/dist/esm/QuestionnaireForm.js +215 -0
  194. package/dist/esm/QuestionnaireForm.js.map +1 -0
  195. package/dist/{types → esm}/QuestionnaireUtils.d.ts +0 -0
  196. package/dist/esm/QuestionnaireUtils.js +103 -0
  197. package/dist/esm/QuestionnaireUtils.js.map +1 -0
  198. package/dist/{types → esm}/RangeDisplay.d.ts +0 -0
  199. package/dist/esm/RangeDisplay.js +21 -0
  200. package/dist/esm/RangeDisplay.js.map +1 -0
  201. package/dist/{types → esm}/RangeInput.d.ts +0 -0
  202. package/dist/esm/RangeInput.js +25 -0
  203. package/dist/esm/RangeInput.js.map +1 -0
  204. package/dist/{types → esm}/RatioDisplay.d.ts +0 -0
  205. package/dist/esm/RatioDisplay.js +16 -0
  206. package/dist/esm/RatioDisplay.js.map +1 -0
  207. package/dist/{types → esm}/RatioInput.d.ts +0 -0
  208. package/dist/esm/RatioInput.js +25 -0
  209. package/dist/esm/RatioInput.js.map +1 -0
  210. package/dist/{types → esm}/ReferenceDisplay.d.ts +0 -0
  211. package/dist/esm/ReferenceDisplay.js +21 -0
  212. package/dist/esm/ReferenceDisplay.js.map +1 -0
  213. package/dist/{types → esm}/ReferenceInput.d.ts +0 -0
  214. package/dist/esm/ReferenceInput.js +42 -0
  215. package/dist/esm/ReferenceInput.js.map +1 -0
  216. package/dist/{types → esm}/RegisterForm.d.ts +0 -0
  217. package/dist/esm/RegisterForm.js +110 -0
  218. package/dist/esm/RegisterForm.js.map +1 -0
  219. package/dist/{types → esm}/RequestGroupDisplay.d.ts +0 -0
  220. package/dist/esm/RequestGroupDisplay.js +73 -0
  221. package/dist/esm/RequestGroupDisplay.js.map +1 -0
  222. package/dist/{types → esm}/ResourceArrayDisplay.d.ts +0 -0
  223. package/dist/esm/ResourceArrayDisplay.js +14 -0
  224. package/dist/esm/ResourceArrayDisplay.js.map +1 -0
  225. package/dist/{types → esm}/ResourceArrayInput.d.ts +0 -0
  226. package/dist/esm/ResourceArrayInput.js +48 -0
  227. package/dist/esm/ResourceArrayInput.js.map +1 -0
  228. package/dist/{types → esm}/ResourceBadge.d.ts +0 -0
  229. package/dist/esm/ResourceBadge.js +13 -0
  230. package/dist/esm/ResourceBadge.js.map +1 -0
  231. package/dist/{types → esm}/ResourceBlame.d.ts +0 -0
  232. package/dist/esm/ResourceBlame.js +65 -0
  233. package/dist/esm/ResourceBlame.js.map +1 -0
  234. package/dist/{types → esm}/ResourceDiff.d.ts +0 -0
  235. package/dist/esm/ResourceDiff.js +28 -0
  236. package/dist/esm/ResourceDiff.js.map +1 -0
  237. package/dist/{types → esm}/ResourceDiffTable.d.ts +0 -0
  238. package/dist/esm/ResourceDiffTable.js +58 -0
  239. package/dist/esm/ResourceDiffTable.js.map +1 -0
  240. package/dist/{types → esm}/ResourceForm.d.ts +0 -0
  241. package/dist/esm/ResourceForm.js +55 -0
  242. package/dist/esm/ResourceForm.js.map +1 -0
  243. package/dist/{types → esm}/ResourceHistoryTable.d.ts +0 -0
  244. package/dist/esm/ResourceHistoryTable.js +46 -0
  245. package/dist/esm/ResourceHistoryTable.js.map +1 -0
  246. package/dist/{types → esm}/ResourceInput.d.ts +0 -0
  247. package/dist/esm/ResourceInput.js +40 -0
  248. package/dist/esm/ResourceInput.js.map +1 -0
  249. package/dist/{types → esm}/ResourceName.d.ts +0 -0
  250. package/dist/esm/ResourceName.js +16 -0
  251. package/dist/esm/ResourceName.js.map +1 -0
  252. package/dist/{types → esm}/ResourcePropertyDisplay.d.ts +0 -0
  253. package/dist/esm/ResourcePropertyDisplay.js +107 -0
  254. package/dist/esm/ResourcePropertyDisplay.js.map +1 -0
  255. package/dist/{types → esm}/ResourcePropertyInput.d.ts +0 -0
  256. package/dist/esm/ResourcePropertyInput.js +151 -0
  257. package/dist/esm/ResourcePropertyInput.js.map +1 -0
  258. package/dist/{types → esm}/ResourceTable.d.ts +0 -0
  259. package/dist/esm/ResourceTable.js +22 -0
  260. package/dist/esm/ResourceTable.js.map +1 -0
  261. package/dist/{types → esm}/ResourceTimeline.d.ts +0 -0
  262. package/dist/esm/ResourceTimeline.js +221 -0
  263. package/dist/esm/ResourceTimeline.js.map +1 -0
  264. package/dist/{types → esm}/Scheduler.d.ts +0 -0
  265. package/dist/esm/Scheduler.js +82 -0
  266. package/dist/esm/Scheduler.js.map +1 -0
  267. package/dist/{types → esm}/Scrollable.d.ts +0 -0
  268. package/dist/esm/Scrollable.js +12 -0
  269. package/dist/esm/Scrollable.js.map +1 -0
  270. package/dist/{types → esm}/SearchControl.d.ts +0 -0
  271. package/dist/esm/SearchControl.js +268 -0
  272. package/dist/esm/SearchControl.js.map +1 -0
  273. package/dist/{types → esm}/SearchControlField.d.ts +0 -0
  274. package/dist/esm/SearchControlField.js +98 -0
  275. package/dist/esm/SearchControlField.js.map +1 -0
  276. package/dist/{types → esm}/SearchFieldEditor.d.ts +0 -0
  277. package/dist/esm/SearchFieldEditor.js +192 -0
  278. package/dist/esm/SearchFieldEditor.js.map +1 -0
  279. package/dist/{types → esm}/SearchFilterEditor.d.ts +0 -0
  280. package/dist/esm/SearchFilterEditor.js +103 -0
  281. package/dist/esm/SearchFilterEditor.js.map +1 -0
  282. package/dist/{types → esm}/SearchFilterValueDialog.d.ts +0 -0
  283. package/dist/esm/SearchFilterValueDialog.js +22 -0
  284. package/dist/esm/SearchFilterValueDialog.js.map +1 -0
  285. package/dist/{types → esm}/SearchFilterValueDisplay.d.ts +0 -0
  286. package/dist/esm/SearchFilterValueDisplay.js +22 -0
  287. package/dist/esm/SearchFilterValueDisplay.js.map +1 -0
  288. package/dist/{types → esm}/SearchFilterValueInput.d.ts +0 -0
  289. package/dist/esm/SearchFilterValueInput.js +59 -0
  290. package/dist/esm/SearchFilterValueInput.js.map +1 -0
  291. package/dist/{types → esm}/SearchPopupMenu.d.ts +0 -0
  292. package/dist/esm/SearchPopupMenu.js +135 -0
  293. package/dist/esm/SearchPopupMenu.js.map +1 -0
  294. package/dist/{types → esm}/SearchUtils.d.ts +0 -0
  295. package/dist/esm/SearchUtils.js +488 -0
  296. package/dist/esm/SearchUtils.js.map +1 -0
  297. package/dist/{types → esm}/Select.d.ts +0 -0
  298. package/dist/esm/Select.js +16 -0
  299. package/dist/esm/Select.js.map +1 -0
  300. package/dist/{types → esm}/ServiceRequestTimeline.d.ts +0 -0
  301. package/dist/esm/ServiceRequestTimeline.js +53 -0
  302. package/dist/esm/ServiceRequestTimeline.js.map +1 -0
  303. package/dist/{types → esm}/SignInForm.d.ts +0 -0
  304. package/dist/esm/SignInForm.js +130 -0
  305. package/dist/esm/SignInForm.js.map +1 -0
  306. package/dist/{types → esm}/StatusBadge.d.ts +0 -0
  307. package/dist/esm/StatusBadge.js +8 -0
  308. package/dist/esm/StatusBadge.js.map +1 -0
  309. package/dist/{types → esm}/SubMenu.d.ts +0 -0
  310. package/dist/esm/SubMenu.js +38 -0
  311. package/dist/esm/SubMenu.js.map +1 -0
  312. package/dist/{types → esm}/Tab.d.ts +0 -0
  313. package/dist/esm/Tab.js +19 -0
  314. package/dist/esm/Tab.js.map +1 -0
  315. package/dist/{types → esm}/TabList.d.ts +0 -0
  316. package/dist/esm/TabList.js +23 -0
  317. package/dist/esm/TabList.js.map +1 -0
  318. package/dist/{types → esm}/TabPanel.d.ts +0 -0
  319. package/dist/esm/TabPanel.js +8 -0
  320. package/dist/esm/TabPanel.js.map +1 -0
  321. package/dist/{types → esm}/TabSwitch.d.ts +0 -0
  322. package/dist/esm/TabSwitch.js +16 -0
  323. package/dist/esm/TabSwitch.js.map +1 -0
  324. package/dist/{types → esm}/TextArea.d.ts +0 -0
  325. package/dist/esm/TextArea.js +16 -0
  326. package/dist/esm/TextArea.js.map +1 -0
  327. package/dist/{types → esm}/Timeline.d.ts +0 -0
  328. package/dist/esm/Timeline.js +50 -0
  329. package/dist/esm/Timeline.js.map +1 -0
  330. package/dist/{types → esm}/TitleBar.d.ts +0 -0
  331. package/dist/esm/TitleBar.js +8 -0
  332. package/dist/esm/TitleBar.js.map +1 -0
  333. package/dist/{types → esm}/UploadButton.d.ts +0 -0
  334. package/dist/esm/UploadButton.js +55 -0
  335. package/dist/esm/UploadButton.js.map +1 -0
  336. package/dist/{types → esm}/constants.d.ts +0 -0
  337. package/dist/esm/constants.js +12 -0
  338. package/dist/esm/constants.js.map +1 -0
  339. package/dist/{types → esm}/index.d.ts +0 -0
  340. package/dist/esm/index.js +87 -5814
  341. package/dist/esm/index.js.map +1 -1
  342. package/dist/esm/index.min.js.map +1 -1
  343. package/dist/esm/node_modules/tslib/tslib.es6.js +27 -0
  344. package/dist/esm/node_modules/tslib/tslib.es6.js.map +1 -0
  345. package/dist/{types → esm}/stories/AddressInput.stories.d.ts +0 -0
  346. package/dist/{types → esm}/stories/AttachmentArrayInput.stories.d.ts +0 -0
  347. package/dist/{types → esm}/stories/AttachmentInput.stories.d.ts +0 -0
  348. package/dist/{types → esm}/stories/Autocomplete.stories.d.ts +0 -0
  349. package/dist/{types → esm}/stories/Avatar.stories.d.ts +0 -0
  350. package/dist/{types → esm}/stories/Button.stories.d.ts +0 -0
  351. package/dist/{types → esm}/stories/DiagnosticReportDisplay.stories.d.ts +0 -0
  352. package/dist/{types → esm}/stories/Dialog.stories.d.ts +0 -0
  353. package/dist/{types → esm}/stories/EncounterTimeline.stories.d.ts +0 -0
  354. package/dist/{types → esm}/stories/FhirPathDisplay.stories.d.ts +0 -0
  355. package/dist/{types → esm}/stories/FormSection.stories.d.ts +0 -0
  356. package/dist/{types → esm}/stories/Header.stories.d.ts +0 -0
  357. package/dist/{types → esm}/stories/Input.stories.d.ts +0 -0
  358. package/dist/{types → esm}/stories/Loading.stories.d.ts +0 -0
  359. package/dist/{types → esm}/stories/Logo.stories.d.ts +0 -0
  360. package/dist/{types → esm}/stories/PatientTimeline.stories.d.ts +0 -0
  361. package/dist/{types → esm}/stories/PlanDefinitionBuilder.stories.d.ts +0 -0
  362. package/dist/{types → esm}/stories/QuestionnaireBuilder.stories.d.ts +0 -0
  363. package/dist/{types → esm}/stories/QuestionnaireForm.stories.d.ts +0 -0
  364. package/dist/{types → esm}/stories/ReferenceInput.stories.d.ts +0 -0
  365. package/dist/{types → esm}/stories/RegisterForm.stories.d.ts +0 -0
  366. package/dist/{types → esm}/stories/RequestGroupDisplay.stories.d.ts +0 -0
  367. package/dist/{types → esm}/stories/ResourceBlame.stories.d.ts +0 -0
  368. package/dist/{types → esm}/stories/ResourceForm.stories.d.ts +0 -0
  369. package/dist/{types → esm}/stories/ResourceHistoryTable.stories.d.ts +0 -0
  370. package/dist/{types → esm}/stories/ResourceTable.stories.d.ts +0 -0
  371. package/dist/{types → esm}/stories/Scheduler.stories.d.ts +0 -0
  372. package/dist/{types → esm}/stories/SearchControl.stories.d.ts +0 -0
  373. package/dist/{types → esm}/stories/Select.stories.d.ts +0 -0
  374. package/dist/{types → esm}/stories/SignInForm.stories.d.ts +0 -0
  375. package/dist/{types → esm}/stories/StatusBadge.stories.d.ts +0 -0
  376. package/dist/{types → esm}/stories/Tabs.stories.d.ts +0 -0
  377. package/dist/{types → esm}/stories/Timeline.stories.d.ts +0 -0
  378. package/dist/{types → esm}/stories/UploadButton.stories.d.ts +0 -0
  379. package/dist/{types → esm}/test.setup.d.ts +0 -0
  380. package/dist/{types → esm}/useResource.d.ts +0 -0
  381. package/dist/esm/useResource.js +65 -0
  382. package/dist/esm/useResource.js.map +1 -0
  383. package/dist/{types → esm}/utils/blame.d.ts +0 -0
  384. package/dist/esm/utils/blame.js +74 -0
  385. package/dist/esm/utils/blame.js.map +1 -0
  386. package/dist/{types → esm}/utils/date.d.ts +0 -0
  387. package/dist/esm/utils/date.js +48 -0
  388. package/dist/esm/utils/date.js.map +1 -0
  389. package/dist/{types → esm}/utils/diff.d.ts +0 -0
  390. package/dist/esm/utils/diff.js +118 -0
  391. package/dist/esm/utils/diff.js.map +1 -0
  392. package/dist/{types → esm}/utils/dom.d.ts +0 -0
  393. package/dist/esm/utils/dom.js +34 -0
  394. package/dist/esm/utils/dom.js.map +1 -0
  395. package/dist/{types → esm}/utils/outcomes.d.ts +0 -0
  396. package/dist/esm/utils/outcomes.js +7 -0
  397. package/dist/esm/utils/outcomes.js.map +1 -0
  398. package/dist/{types → esm}/utils/recaptcha.d.ts +0 -0
  399. package/dist/esm/utils/recaptcha.js +27 -0
  400. package/dist/esm/utils/recaptcha.js.map +1 -0
  401. package/dist/{types → esm}/utils.d.ts +0 -0
  402. package/dist/esm/utils.js +15 -0
  403. package/dist/esm/utils.js.map +1 -0
  404. package/package.json +7 -7
  405. package/stats.html +4034 -0
  406. package/tsconfig.cjs.json +7 -0
  407. package/tsconfig.esm.json +7 -0
@@ -0,0 +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;;;;"}
File without changes
@@ -0,0 +1,12 @@
1
+ import React from 'react';
2
+
3
+ function Scrollable(props) {
4
+ const containerHeight = props.height || '100%';
5
+ const contentHeight = props.height ? props.height + 25 : '100%';
6
+ const className = 'medplum-scrollable-content' + (props.className ? ` ${props.className}` : '');
7
+ return (React.createElement("div", { className: "medplum-scrollable-container", style: { height: containerHeight } },
8
+ React.createElement("div", { className: className, role: props.role, style: { height: contentHeight } }, props.children)));
9
+ }
10
+
11
+ export { Scrollable };
12
+ //# sourceMappingURL=Scrollable.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Scrollable.js","sources":["../../src/Scrollable.tsx"],"sourcesContent":["import React from 'react';\nimport './Scrollable.css';\n\nexport interface ScrollableProps {\n readonly role?: string;\n readonly className?: string;\n readonly height?: number;\n readonly children: React.ReactNode;\n}\n\nexport function Scrollable(props: ScrollableProps): JSX.Element {\n const containerHeight = props.height || '100%';\n const contentHeight = props.height ? props.height + 25 : '100%';\n const className = 'medplum-scrollable-content' + (props.className ? ` ${props.className}` : '');\n return (\n <div className=\"medplum-scrollable-container\" style={{ height: containerHeight }}>\n <div className={className} role={props.role} style={{ height: contentHeight }}>\n {props.children}\n </div>\n </div>\n );\n}\n"],"names":[],"mappings":";;AAUM,SAAU,UAAU,CAAC,KAAsB,EAAA;AAC/C,IAAA,MAAM,eAAe,GAAG,KAAK,CAAC,MAAM,IAAI,MAAM,CAAC;AAC/C,IAAA,MAAM,aAAa,GAAG,KAAK,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,GAAG,EAAE,GAAG,MAAM,CAAC;IAChE,MAAM,SAAS,GAAG,4BAA4B,IAAI,KAAK,CAAC,SAAS,GAAG,CAAI,CAAA,EAAA,KAAK,CAAC,SAAS,CAAA,CAAE,GAAG,EAAE,CAAC,CAAC;AAChG,IAAA,QACE,KAAA,CAAA,aAAA,CAAA,KAAA,EAAA,EAAK,SAAS,EAAC,8BAA8B,EAAC,KAAK,EAAE,EAAE,MAAM,EAAE,eAAe,EAAE,EAAA;QAC9E,KAAK,CAAA,aAAA,CAAA,KAAA,EAAA,EAAA,SAAS,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,aAAa,EAAE,EAC1E,EAAA,KAAK,CAAC,QAAQ,CACX,CACF,EACN;AACJ;;;;"}
File without changes
@@ -0,0 +1,268 @@
1
+ import { formatSearchQuery, parseSearchDefinition, DEFAULT_SEARCH_COUNT } from '@medplum/core';
2
+ import React, { useState, useRef, useEffect } from 'react';
3
+ import { Button } from './Button.js';
4
+ import { Loading } from './Loading.js';
5
+ import { useMedplum } from './MedplumProvider.js';
6
+ import { getFieldDefinitions } from './SearchControlField.js';
7
+ import { SearchFieldEditor } from './SearchFieldEditor.js';
8
+ import { SearchFilterEditor } from './SearchFilterEditor.js';
9
+ import { SearchFilterValueDialog } from './SearchFilterValueDialog.js';
10
+ import { SearchFilterValueDisplay } from './SearchFilterValueDisplay.js';
11
+ import { SearchPopupMenu } from './SearchPopupMenu.js';
12
+ import { movePage, buildFieldNameString, renderValue, addFilter, getOpString } from './SearchUtils.js';
13
+ import { Select } from './Select.js';
14
+ import { TitleBar } from './TitleBar.js';
15
+ import { killEvent, isCheckboxCell } from './utils/dom.js';
16
+
17
+ class SearchChangeEvent extends Event {
18
+ constructor(definition) {
19
+ super('change');
20
+ this.definition = definition;
21
+ }
22
+ }
23
+ class SearchLoadEvent extends Event {
24
+ constructor(response) {
25
+ super('load');
26
+ this.response = response;
27
+ }
28
+ }
29
+ class SearchClickEvent extends Event {
30
+ constructor(resource, browserEvent) {
31
+ super('click');
32
+ this.resource = resource;
33
+ this.browserEvent = browserEvent;
34
+ }
35
+ }
36
+ /**
37
+ * The SearchControl component represents the embeddable search table control.
38
+ * It includes the table, rows, headers, sorting, etc.
39
+ * It does not include the field editor, filter editor, pagination buttons.
40
+ */
41
+ function SearchControl(props) {
42
+ var _a, _b, _c, _d;
43
+ const medplum = useMedplum();
44
+ const [schema, setSchema] = useState();
45
+ const [outcome, setOutcome] = useState();
46
+ const { search, onLoad } = props;
47
+ const [state, setState] = useState({
48
+ selected: {},
49
+ popupVisible: false,
50
+ popupX: 0,
51
+ popupY: 0,
52
+ popupSearchParams: undefined,
53
+ fieldEditorVisible: false,
54
+ filterEditorVisible: false,
55
+ filterDialogVisible: false,
56
+ });
57
+ const stateRef = useRef(state);
58
+ stateRef.current = state;
59
+ useEffect(() => {
60
+ setOutcome(undefined);
61
+ medplum
62
+ .search(search.resourceType, formatSearchQuery(Object.assign(Object.assign({}, search), { total: 'accurate' })))
63
+ .then((response) => {
64
+ setState(Object.assign(Object.assign({}, stateRef.current), { searchResponse: response }));
65
+ if (onLoad) {
66
+ onLoad(new SearchLoadEvent(response));
67
+ }
68
+ })
69
+ .catch((reason) => {
70
+ setState(Object.assign(Object.assign({}, stateRef.current), { searchResponse: undefined }));
71
+ setOutcome(reason);
72
+ });
73
+ }, [medplum, search, onLoad]);
74
+ function handleSingleCheckboxClick(e, id) {
75
+ e.stopPropagation();
76
+ const el = e.target;
77
+ const checked = el.checked;
78
+ const newSelected = Object.assign({}, stateRef.current.selected);
79
+ if (checked) {
80
+ newSelected[id] = true;
81
+ }
82
+ else {
83
+ delete newSelected[id];
84
+ }
85
+ setState(Object.assign(Object.assign({}, stateRef.current), { selected: newSelected }));
86
+ }
87
+ function handleAllCheckboxClick(e) {
88
+ var _a;
89
+ e.stopPropagation();
90
+ const el = e.target;
91
+ const checked = el.checked;
92
+ const newSelected = {};
93
+ const searchResponse = (_a = stateRef.current) === null || _a === void 0 ? void 0 : _a.searchResponse;
94
+ if (checked && (searchResponse === null || searchResponse === void 0 ? void 0 : searchResponse.entry)) {
95
+ searchResponse.entry.forEach((entry) => {
96
+ var _a;
97
+ if ((_a = entry.resource) === null || _a === void 0 ? void 0 : _a.id) {
98
+ newSelected[entry.resource.id] = true;
99
+ }
100
+ });
101
+ }
102
+ setState(Object.assign(Object.assign({}, stateRef.current), { selected: newSelected }));
103
+ }
104
+ function isAllSelected() {
105
+ var _a, _b;
106
+ const state = stateRef.current;
107
+ if (!((_a = state.searchResponse) === null || _a === void 0 ? void 0 : _a.entry) || state.searchResponse.entry.length === 0) {
108
+ return false;
109
+ }
110
+ for (const e of state.searchResponse.entry) {
111
+ if (((_b = e.resource) === null || _b === void 0 ? void 0 : _b.id) && !state.selected[e.resource.id]) {
112
+ return false;
113
+ }
114
+ }
115
+ return true;
116
+ }
117
+ /**
118
+ * Handles a click on a column header cell.
119
+ * @param e The click event.
120
+ * @param key The field key.
121
+ */
122
+ function handleSortClick(e, searchParams) {
123
+ setState(Object.assign(Object.assign({}, stateRef.current), { popupVisible: true, popupX: e.clientX, popupY: e.clientY, popupSearchParams: searchParams }));
124
+ }
125
+ /**
126
+ * Emits a change event to the optional change listener.
127
+ * @param newSearch The new search definition.
128
+ */
129
+ function emitSearchChange(newSearch) {
130
+ if (props.onChange) {
131
+ props.onChange(new SearchChangeEvent(newSearch));
132
+ }
133
+ }
134
+ /**
135
+ * Handles a click on a order row.
136
+ *
137
+ * @param e The click event.
138
+ * @param resource The FHIR resource.
139
+ */
140
+ function handleRowClick(e, resource) {
141
+ if (isCheckboxCell(e.target)) {
142
+ // Ignore clicks on checkboxes
143
+ return;
144
+ }
145
+ killEvent(e);
146
+ if (e.button !== 1 && props.onClick) {
147
+ props.onClick(new SearchClickEvent(resource, e));
148
+ }
149
+ if (e.button === 1 && props.onAuxClick) {
150
+ props.onAuxClick(new SearchClickEvent(resource, e));
151
+ }
152
+ }
153
+ useEffect(() => {
154
+ medplum.requestSchema(props.search.resourceType).then((newSchema) => {
155
+ // The schema could have the same object identity,
156
+ // so need to use the spread operator to kick React re-render.
157
+ setSchema(Object.assign({}, newSchema));
158
+ });
159
+ }, [medplum, props.search.resourceType]);
160
+ const typeSchema = (_a = schema === null || schema === void 0 ? void 0 : schema.types) === null || _a === void 0 ? void 0 : _a[props.search.resourceType];
161
+ if (!typeSchema) {
162
+ return React.createElement(Loading, null);
163
+ }
164
+ const checkboxColumn = props.checkboxesEnabled;
165
+ const fields = getFieldDefinitions(schema, search);
166
+ const resourceType = search.resourceType;
167
+ const lastResult = state.searchResponse;
168
+ const entries = lastResult === null || lastResult === void 0 ? void 0 : lastResult.entry;
169
+ const resources = entries === null || entries === void 0 ? void 0 : entries.map((e) => e.resource);
170
+ const savedSearches = (_c = (_b = props.userConfig) === null || _b === void 0 ? void 0 : _b.search) === null || _c === void 0 ? void 0 : _c.filter((s) => { var _a; return (_a = s.criteria) === null || _a === void 0 ? void 0 : _a.startsWith(resourceType); });
171
+ return (React.createElement("div", { className: "medplum-search-control", onContextMenu: (e) => killEvent(e), "data-testid": "search-control" },
172
+ !props.hideToolbar && (React.createElement(TitleBar, null,
173
+ React.createElement("div", null,
174
+ React.createElement("h1", null,
175
+ React.createElement("a", { href: `https://www.hl7.org/fhir/${resourceType.toLowerCase()}.html`, target: "_blank", rel: "noopener" }, resourceType)),
176
+ savedSearches && (React.createElement(Select, { testid: "saved-search-select", style: { width: 80 }, onChange: (newValue) => {
177
+ emitSearchChange(parseSearchDefinition(newValue));
178
+ } },
179
+ React.createElement("option", null),
180
+ savedSearches.map((s, index) => (React.createElement("option", { key: `${index}-${savedSearches.length}`, value: s.criteria }, s.name))))),
181
+ React.createElement(Button, { testid: "fields-button", size: "small", onClick: () => setState(Object.assign(Object.assign({}, stateRef.current), { fieldEditorVisible: true })) }, "Fields"),
182
+ React.createElement(Button, { testid: "filters-button", size: "small", onClick: () => setState(Object.assign(Object.assign({}, stateRef.current), { filterEditorVisible: true })) }, "Filters"),
183
+ props.onNew && (React.createElement(Button, { size: "small", onClick: props.onNew }, "New...")),
184
+ props.onExport && (React.createElement(Button, { size: "small", onClick: props.onExport }, "Export...")),
185
+ props.onDelete && (React.createElement(Button, { size: "small", onClick: () => props.onDelete(Object.keys(state.selected)) }, "Delete...")),
186
+ props.onBulk && (React.createElement(Button, { size: "small", onClick: () => props.onBulk(Object.keys(state.selected)) }, "Bulk..."))),
187
+ lastResult && (React.createElement("div", null,
188
+ React.createElement("span", { className: "medplum-search-summary" },
189
+ getStart(search, lastResult.total),
190
+ "-",
191
+ getEnd(search, lastResult.total),
192
+ " of",
193
+ ' ', (_d = lastResult.total) === null || _d === void 0 ? void 0 :
194
+ _d.toLocaleString()),
195
+ React.createElement(Button, { testid: "prev-page-button", size: "small", onClick: () => emitSearchChange(movePage(search, -1)) }, "<<"),
196
+ React.createElement(Button, { testid: "next-page-button", size: "small", onClick: () => emitSearchChange(movePage(search, 1)) }, ">>"))))),
197
+ React.createElement("table", null,
198
+ React.createElement("thead", null,
199
+ React.createElement("tr", null,
200
+ checkboxColumn && (React.createElement("th", { className: "medplum-search-icon-cell" },
201
+ React.createElement("input", { type: "checkbox", value: "checked", "aria-label": "all-checkbox", "data-testid": "all-checkbox", checked: isAllSelected(), onChange: (e) => handleAllCheckboxClick(e) }))),
202
+ fields.map((field) => (React.createElement("th", { key: field.name, onClick: (e) => handleSortClick(e, field.searchParams) },
203
+ buildFieldNameString(field.name),
204
+ field.searchParams && React.createElement(FilterIcon, null))))),
205
+ !props.hideFilters && (React.createElement("tr", null,
206
+ checkboxColumn && React.createElement("th", { className: "filters medplum-search-icon-cell" }),
207
+ fields.map((field) => (React.createElement("th", { key: field.name, className: "filters" }, field.searchParams && (React.createElement(FilterDescription, { resourceType: resourceType, searchParams: field.searchParams, filters: props.search.filters })))))))),
208
+ React.createElement("tbody", null, resources === null || resources === void 0 ? void 0 : resources.map((resource) => resource && (React.createElement("tr", { key: resource.id, "data-testid": "search-control-row", onClick: (e) => handleRowClick(e, resource), onAuxClick: (e) => handleRowClick(e, resource) },
209
+ checkboxColumn && (React.createElement("td", { className: "medplum-search-icon-cell" },
210
+ React.createElement("input", { type: "checkbox", value: "checked", "data-testid": "row-checkbox", "aria-label": `Checkbox for ${resource.id}`, checked: !!state.selected[resource.id], onChange: (e) => handleSingleCheckboxClick(e, resource.id) }))),
211
+ fields.map((field) => (React.createElement("td", { key: field.name }, renderValue(resource, field))))))))),
212
+ (resources === null || resources === void 0 ? void 0 : resources.length) === 0 && (React.createElement("div", { "data-testid": "empty-search", className: "medplum-empty-search" }, "No results")),
213
+ outcome && (React.createElement("div", { "data-testid": "search-error", className: "medplum-empty-search" },
214
+ React.createElement("pre", { style: { textAlign: 'left' } }, JSON.stringify(outcome, undefined, 2)))),
215
+ React.createElement(SearchPopupMenu, { schema: schema, search: props.search, visible: state.popupVisible, x: state.popupX, y: state.popupY, searchParams: state.popupSearchParams, onPrompt: (searchParam, filter) => {
216
+ setState(Object.assign(Object.assign({}, stateRef.current), { popupVisible: false, filterDialogVisible: true, filterDialogSearchParam: searchParam, filterDialogFilter: filter }));
217
+ }, onChange: (result) => {
218
+ emitSearchChange(result);
219
+ setState(Object.assign(Object.assign({}, stateRef.current), { popupVisible: false, popupSearchParams: undefined }));
220
+ }, onClose: () => {
221
+ setState(Object.assign(Object.assign({}, stateRef.current), { popupVisible: false, popupSearchParams: undefined }));
222
+ } }),
223
+ React.createElement(SearchFieldEditor, { schema: schema, search: props.search, visible: stateRef.current.fieldEditorVisible, onOk: (result) => {
224
+ emitSearchChange(result);
225
+ setState(Object.assign(Object.assign({}, stateRef.current), { fieldEditorVisible: false }));
226
+ }, onCancel: () => {
227
+ setState(Object.assign(Object.assign({}, stateRef.current), { fieldEditorVisible: false }));
228
+ } }),
229
+ React.createElement(SearchFilterEditor, { schema: schema, search: props.search, visible: stateRef.current.filterEditorVisible, onOk: (result) => {
230
+ emitSearchChange(result);
231
+ setState(Object.assign(Object.assign({}, stateRef.current), { filterEditorVisible: false }));
232
+ }, onCancel: () => {
233
+ setState(Object.assign(Object.assign({}, stateRef.current), { filterEditorVisible: false }));
234
+ } }),
235
+ React.createElement(SearchFilterValueDialog, { visible: stateRef.current.filterDialogVisible, title: 'Input', schema: schema, resourceType: resourceType, searchParam: state.filterDialogSearchParam, filter: state.filterDialogFilter, defaultValue: '', onOk: (filter) => {
236
+ emitSearchChange(addFilter(props.search, filter.code, filter.operator, filter.value));
237
+ setState(Object.assign(Object.assign({}, stateRef.current), { filterDialogVisible: false }));
238
+ }, onCancel: () => {
239
+ setState(Object.assign(Object.assign({}, stateRef.current), { filterDialogVisible: false }));
240
+ } })));
241
+ }
242
+ const MemoizedSearchControl = React.memo(SearchControl);
243
+ function FilterDescription(props) {
244
+ var _a;
245
+ const filters = ((_a = props.filters) !== null && _a !== void 0 ? _a : []).filter((f) => props.searchParams.find((p) => p.code === f.code));
246
+ if (filters.length === 0) {
247
+ return React.createElement("span", null, "no filters");
248
+ }
249
+ return (React.createElement(React.Fragment, null, filters.map((filter, index) => (React.createElement("div", { key: `filter-${index}-${filters.length}` },
250
+ getOpString(filter.operator),
251
+ "\u00A0",
252
+ React.createElement(SearchFilterValueDisplay, { resourceType: props.resourceType, filter: filter }))))));
253
+ }
254
+ function FilterIcon() {
255
+ return (React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", className: "h-6 w-6", fill: "none", viewBox: "0 0 24 24", stroke: "rgba(0, 0, 0, 0.3)", strokeWidth: 2 },
256
+ React.createElement("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M4 6h16M4 12h16m-7 6h7" })));
257
+ }
258
+ function getStart(search, total) {
259
+ var _a;
260
+ return Math.min(total, ((_a = search.offset) !== null && _a !== void 0 ? _a : 0) + 1);
261
+ }
262
+ function getEnd(search, total) {
263
+ var _a, _b;
264
+ return Math.min(total, (((_a = search.offset) !== null && _a !== void 0 ? _a : 0) + 1) * ((_b = search.count) !== null && _b !== void 0 ? _b : DEFAULT_SEARCH_COUNT));
265
+ }
266
+
267
+ export { MemoizedSearchControl, SearchChangeEvent, SearchClickEvent, SearchControl, SearchLoadEvent };
268
+ //# sourceMappingURL=SearchControl.js.map
@@ -0,0 +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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"}
File without changes
@@ -0,0 +1,98 @@
1
+ import { getSearchParameterDetails } from '@medplum/core';
2
+
3
+ /**
4
+ * Returns the collection of field definitions for the search request.
5
+ * @param typeSchema The schema for the resource type
6
+ * @param search The search request definition.
7
+ * @returns An array of field definitions.
8
+ */
9
+ function getFieldDefinitions(schema, search) {
10
+ const resourceType = search.resourceType;
11
+ const fields = [];
12
+ for (const name of search.fields || ['id', '_lastUpdated']) {
13
+ fields.push(getFieldDefinition(schema, resourceType, name));
14
+ }
15
+ return fields;
16
+ }
17
+ /**
18
+ * Return the field definition for a given field name.
19
+ * Field names can be either property names or search parameter codes.
20
+ * @param typeSchema The schema for the resource type
21
+ * @param resourceType The resource type.
22
+ * @param name The search field name (either property name or search parameter code).
23
+ * @returns The field definition.
24
+ */
25
+ function getFieldDefinition(schema, resourceType, name) {
26
+ var _a;
27
+ if (name === '_lastUpdated') {
28
+ return {
29
+ name: '_lastUpdated',
30
+ searchParams: [
31
+ {
32
+ resourceType: 'SearchParameter',
33
+ base: ['Resource'],
34
+ code: '_lastUpdated',
35
+ name: '_lastUpdated',
36
+ type: 'date',
37
+ expression: 'Resource.meta.lastUpdated',
38
+ },
39
+ ],
40
+ };
41
+ }
42
+ if (name === 'meta.versionId') {
43
+ return {
44
+ name: 'meta.versionId',
45
+ searchParams: [
46
+ {
47
+ resourceType: 'SearchParameter',
48
+ base: ['Resource'],
49
+ code: '_versionId',
50
+ name: '_versionId',
51
+ type: 'token',
52
+ expression: 'Resource.meta.versionId',
53
+ },
54
+ ],
55
+ };
56
+ }
57
+ const typeSchema = schema.types[resourceType];
58
+ const exactElementDefinition = typeSchema.properties[name];
59
+ const exactSearchParam = (_a = typeSchema.searchParams) === null || _a === void 0 ? void 0 : _a[name.toLowerCase()];
60
+ // Best case: Exact match of element definition or search parameter.
61
+ // Examples: ServiceRequest.subject, Patient.name, Patient.birthDate
62
+ // In this case, we only show the one search parameter.
63
+ if (exactElementDefinition && exactSearchParam) {
64
+ return { name, elementDefinition: exactElementDefinition, searchParams: [exactSearchParam] };
65
+ }
66
+ // Next best case: Exact match of element definition
67
+ // Examples: Observation.value
68
+ // In this case, there could be zero or more search parameters that are a function of the element definition.
69
+ // So search for those search parameters.
70
+ if (exactElementDefinition) {
71
+ let searchParams = undefined;
72
+ if (typeSchema.searchParams) {
73
+ const path = `${resourceType}.${name.replaceAll('[x]', '')}`;
74
+ searchParams = Object.values(typeSchema.searchParams).filter((p) => { var _a; return (_a = p.expression) === null || _a === void 0 ? void 0 : _a.includes(path); });
75
+ if (searchParams.length === 0) {
76
+ searchParams = undefined;
77
+ }
78
+ }
79
+ return { name, elementDefinition: exactElementDefinition, searchParams };
80
+ }
81
+ // Search parameter case: Exact match of search parameter
82
+ // Examples: Observation.value-quantity, Patient.email
83
+ // Here we have a search parameter, but no element definition.
84
+ // Observation.value-quantity is a search parameter for the Observation.value element.
85
+ // Patient.email is a search parameter for the Patient.telecom element.
86
+ // So we need to walk backwards to find the element definition.
87
+ if (exactSearchParam) {
88
+ const details = getSearchParameterDetails(schema, resourceType, exactSearchParam);
89
+ return { name, elementDefinition: details.elementDefinition, searchParams: [exactSearchParam] };
90
+ }
91
+ // Worst case: no element definition and no search parameter.
92
+ // This is probably a malformed URL that includes an unknown field.
93
+ // We will render the column header, but all cells will be empty.
94
+ return { name };
95
+ }
96
+
97
+ export { getFieldDefinitions };
98
+ //# sourceMappingURL=SearchControlField.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SearchControlField.js","sources":["../../src/SearchControlField.ts"],"sourcesContent":["import { getSearchParameterDetails, IndexedStructureDefinition, SearchRequest } from '@medplum/core';\nimport { ElementDefinition, SearchParameter } from '@medplum/fhirtypes';\n\n/**\n * The SearchControlField type describes a field in the search control.\n *\n * In a SearchRequest, a field is a simple string. Strings can be one of the following:\n * 1) Simple property names, which refer to ElementDefinition objects\n * 2) Search parameter names, which refer to SearchParameter resources\n *\n * Consider a few examples of how this becomes complicated.\n *\n * \"name\" (easy)\n * - element definition path=\"Patient.name\"\n * - search parameter code=\"name\"\n *\n * \"birthDate\" (medium)\n * - refers to the element definition path=\"Patient.birthDate\"\n * - refers to the search parameter code=\"birthdate\" (note the capitalization)\n *\n * \"email\" (hard)\n * - refers to the search parameter code=\"email\"\n * - refers to the element definition path=\"Patient.telecom\"\n *\n * In the last case, we start with the search parameter, and walk backwards to the\n * element definition in order to get type details for rendering.\n *\n * Overall, we want columns, fields, properties, and search parameters to feel seamless,\n * so we try our darndest to make this work.\n */\nexport interface SearchControlField {\n readonly name: string;\n readonly elementDefinition?: ElementDefinition;\n readonly searchParams?: SearchParameter[];\n}\n\n/**\n * Returns the collection of field definitions for the search request.\n * @param typeSchema The schema for the resource type\n * @param search The search request definition.\n * @returns An array of field definitions.\n */\nexport function getFieldDefinitions(schema: IndexedStructureDefinition, search: SearchRequest): SearchControlField[] {\n const resourceType = search.resourceType;\n const fields = [] as SearchControlField[];\n\n for (const name of search.fields || ['id', '_lastUpdated']) {\n fields.push(getFieldDefinition(schema, resourceType, name));\n }\n return fields;\n}\n\n/**\n * Return the field definition for a given field name.\n * Field names can be either property names or search parameter codes.\n * @param typeSchema The schema for the resource type\n * @param resourceType The resource type.\n * @param name The search field name (either property name or search parameter code).\n * @returns The field definition.\n */\nfunction getFieldDefinition(\n schema: IndexedStructureDefinition,\n resourceType: string,\n name: string\n): SearchControlField {\n if (name === '_lastUpdated') {\n return {\n name: '_lastUpdated',\n searchParams: [\n {\n resourceType: 'SearchParameter',\n base: ['Resource'],\n code: '_lastUpdated',\n name: '_lastUpdated',\n type: 'date',\n expression: 'Resource.meta.lastUpdated',\n },\n ],\n };\n }\n\n if (name === 'meta.versionId') {\n return {\n name: 'meta.versionId',\n searchParams: [\n {\n resourceType: 'SearchParameter',\n base: ['Resource'],\n code: '_versionId',\n name: '_versionId',\n type: 'token',\n expression: 'Resource.meta.versionId',\n },\n ],\n };\n }\n\n const typeSchema = schema.types[resourceType];\n const exactElementDefinition: ElementDefinition | undefined = typeSchema.properties[name];\n const exactSearchParam: SearchParameter | undefined = typeSchema.searchParams?.[name.toLowerCase()];\n\n // Best case: Exact match of element definition or search parameter.\n // Examples: ServiceRequest.subject, Patient.name, Patient.birthDate\n // In this case, we only show the one search parameter.\n if (exactElementDefinition && exactSearchParam) {\n return { name, elementDefinition: exactElementDefinition, searchParams: [exactSearchParam] };\n }\n\n // Next best case: Exact match of element definition\n // Examples: Observation.value\n // In this case, there could be zero or more search parameters that are a function of the element definition.\n // So search for those search parameters.\n if (exactElementDefinition) {\n let searchParams: SearchParameter[] | undefined = undefined;\n if (typeSchema.searchParams) {\n const path = `${resourceType}.${name.replaceAll('[x]', '')}`;\n searchParams = Object.values(typeSchema.searchParams).filter((p) => p.expression?.includes(path));\n if (searchParams.length === 0) {\n searchParams = undefined;\n }\n }\n return { name, elementDefinition: exactElementDefinition, searchParams };\n }\n\n // Search parameter case: Exact match of search parameter\n // Examples: Observation.value-quantity, Patient.email\n // Here we have a search parameter, but no element definition.\n // Observation.value-quantity is a search parameter for the Observation.value element.\n // Patient.email is a search parameter for the Patient.telecom element.\n // So we need to walk backwards to find the element definition.\n if (exactSearchParam) {\n const details = getSearchParameterDetails(schema, resourceType, exactSearchParam);\n return { name, elementDefinition: details.elementDefinition, searchParams: [exactSearchParam] };\n }\n\n // Worst case: no element definition and no search parameter.\n // This is probably a malformed URL that includes an unknown field.\n // We will render the column header, but all cells will be empty.\n return { name };\n}\n"],"names":[],"mappings":"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"}
File without changes