@aehrc/smart-forms-renderer 0.30.2 → 0.31.0

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 (255) hide show
  1. package/README.md +6 -6
  2. package/lib/components/FormComponents/BooleanItem/BooleanField.js +5 -4
  3. package/lib/components/FormComponents/BooleanItem/BooleanField.js.map +1 -1
  4. package/lib/components/FormComponents/ChoiceItems/ChoiceRadioAnswerOptionFields.js +5 -4
  5. package/lib/components/FormComponents/ChoiceItems/ChoiceRadioAnswerOptionFields.js.map +1 -1
  6. package/lib/components/FormComponents/ChoiceItems/ChoiceRadioAnswerValueSetFields.js +5 -4
  7. package/lib/components/FormComponents/ChoiceItems/ChoiceRadioAnswerValueSetFields.js.map +1 -1
  8. package/lib/components/FormComponents/DateTimeItems/index.d.ts +1 -1
  9. package/lib/components/FormComponents/DateTimeItems/index.js +1 -1
  10. package/lib/components/FormComponents/DateTimeItems/index.js.map +1 -1
  11. package/lib/components/FormComponents/DateTimeItems/utils/parseDate.d.ts +5 -0
  12. package/lib/components/FormComponents/DateTimeItems/utils/parseDate.js +5 -0
  13. package/lib/components/FormComponents/DateTimeItems/utils/parseDate.js.map +1 -1
  14. package/lib/components/FormComponents/GridGroup/GridGroup.d.ts +6 -0
  15. package/lib/components/FormComponents/GridGroup/GridGroup.js +6 -0
  16. package/lib/components/FormComponents/GridGroup/GridGroup.js.map +1 -1
  17. package/lib/components/FormComponents/RepeatGroup/RepeatGroup.d.ts +6 -0
  18. package/lib/components/FormComponents/RepeatGroup/RepeatGroup.js +6 -0
  19. package/lib/components/FormComponents/RepeatGroup/RepeatGroup.js.map +1 -1
  20. package/lib/components/FormComponents/RepeatItem/RepeatItem.d.ts +5 -0
  21. package/lib/components/FormComponents/RepeatItem/RepeatItem.js +5 -0
  22. package/lib/components/FormComponents/RepeatItem/RepeatItem.js.map +1 -1
  23. package/lib/components/FormComponents/SingleItem/SingleItem.d.ts +6 -0
  24. package/lib/components/FormComponents/SingleItem/SingleItem.js +6 -0
  25. package/lib/components/FormComponents/SingleItem/SingleItem.js.map +1 -1
  26. package/lib/components/FormComponents/Tables/GroupTable.d.ts +6 -0
  27. package/lib/components/FormComponents/Tables/GroupTable.js +6 -0
  28. package/lib/components/FormComponents/Tables/GroupTable.js.map +1 -1
  29. package/lib/components/FormComponents/index.d.ts +6 -6
  30. package/lib/components/FormComponents/index.js +6 -6
  31. package/lib/components/FormComponents/index.js.map +1 -1
  32. package/lib/components/Renderer/BaseRenderer.d.ts +7 -0
  33. package/lib/components/Renderer/BaseRenderer.js +7 -0
  34. package/lib/components/Renderer/BaseRenderer.js.map +1 -1
  35. package/lib/components/Renderer/SmartFormsRenderer.d.ts +22 -1
  36. package/lib/components/Renderer/SmartFormsRenderer.js +16 -6
  37. package/lib/components/Renderer/SmartFormsRenderer.js.map +1 -1
  38. package/lib/components/Renderer/index.d.ts +1 -0
  39. package/lib/components/Renderer/index.js.map +1 -1
  40. package/lib/components/index.d.ts +3 -2
  41. package/lib/components/index.js +2 -2
  42. package/lib/components/index.js.map +1 -1
  43. package/lib/hooks/index.d.ts +2 -0
  44. package/lib/hooks/index.js +2 -0
  45. package/lib/hooks/index.js.map +1 -1
  46. package/lib/hooks/useBuildForm.d.ts +15 -0
  47. package/lib/hooks/useBuildForm.js +41 -0
  48. package/lib/hooks/useBuildForm.js.map +1 -0
  49. package/lib/hooks/useHidden.d.ts +6 -0
  50. package/lib/hooks/useHidden.js +6 -0
  51. package/lib/hooks/useHidden.js.map +1 -1
  52. package/lib/hooks/useInitaliseFhirClient.d.ts +1 -0
  53. package/lib/hooks/useInitaliseFhirClient.js +55 -0
  54. package/lib/hooks/useInitaliseFhirClient.js.map +1 -0
  55. package/lib/hooks/useInitialiseForm.d.ts +20 -0
  56. package/lib/hooks/useInitialiseForm.js +72 -0
  57. package/lib/hooks/useInitialiseForm.js.map +1 -0
  58. package/lib/hooks/useInitialiseRenderer.d.ts +1 -1
  59. package/lib/hooks/useInitialiseRenderer.js +8 -31
  60. package/lib/hooks/useInitialiseRenderer.js.map +1 -1
  61. package/lib/hooks/useRendererQueryClient.d.ts +10 -0
  62. package/lib/hooks/useRendererQueryClient.js +36 -0
  63. package/lib/hooks/useRendererQueryClient.js.map +1 -0
  64. package/lib/hooks/useValueSetCodings.js +1 -0
  65. package/lib/hooks/useValueSetCodings.js.map +1 -1
  66. package/lib/index.d.ts +10 -40
  67. package/lib/index.js +8 -77
  68. package/lib/index.js.map +1 -1
  69. package/lib/interfaces/calculatedExpression.interface.d.ts +7 -0
  70. package/lib/interfaces/calculatedExpression.interface.js +16 -0
  71. package/lib/interfaces/calculatedExpression.interface.js.map +1 -1
  72. package/lib/interfaces/enableWhen.interface.d.ts +12 -0
  73. package/lib/interfaces/index.d.ts +4 -1
  74. package/lib/interfaces/index.js +16 -0
  75. package/lib/interfaces/index.js.map +1 -1
  76. package/lib/interfaces/populate.interface.d.ts +6 -0
  77. package/lib/interfaces/repopulateItems.interface.d.ts +0 -0
  78. package/lib/interfaces/repopulateItems.interface.js +2 -0
  79. package/lib/interfaces/repopulateItems.interface.js.map +1 -0
  80. package/lib/interfaces/tab.interface.d.ts +10 -0
  81. package/lib/interfaces/tab.interface.js +16 -0
  82. package/lib/interfaces/tab.interface.js.map +1 -1
  83. package/lib/interfaces/variables.interface.d.ts +12 -0
  84. package/lib/stores/index.d.ts +4 -0
  85. package/lib/stores/index.js.map +1 -1
  86. package/lib/stores/questionnaireResponseStore.d.ts +37 -2
  87. package/lib/stores/questionnaireResponseStore.js +72 -22
  88. package/lib/stores/questionnaireResponseStore.js.map +1 -1
  89. package/lib/stores/questionnaireStore.d.ts +59 -3
  90. package/lib/stores/questionnaireStore.js +18 -0
  91. package/lib/stores/questionnaireStore.js.map +1 -1
  92. package/lib/stores/smartConfigStore.d.ts +37 -0
  93. package/lib/stores/smartConfigStore.js +21 -0
  94. package/lib/stores/smartConfigStore.js.map +1 -1
  95. package/lib/stores/terminologyServerStore.d.ts +28 -2
  96. package/lib/stores/terminologyServerStore.js +16 -0
  97. package/lib/stores/terminologyServerStore.js.map +1 -1
  98. package/lib/stories/InitialiseFormWrapperForStorybook.d.ts +29 -0
  99. package/lib/stories/InitialiseFormWrapperForStorybook.js +65 -0
  100. package/lib/stories/InitialiseFormWrapperForStorybook.js.map +1 -0
  101. package/lib/stories/StorybookWrappers/BuildFormButtonForStorybook.d.ts +8 -0
  102. package/lib/stories/StorybookWrappers/BuildFormButtonForStorybook.js +44 -0
  103. package/lib/stories/StorybookWrappers/BuildFormButtonForStorybook.js.map +1 -0
  104. package/lib/stories/StorybookWrappers/BuildFormButtonTesterWrapperForStorybook.d.ts +18 -0
  105. package/lib/stories/StorybookWrappers/BuildFormButtonTesterWrapperForStorybook.js +48 -0
  106. package/lib/stories/StorybookWrappers/BuildFormButtonTesterWrapperForStorybook.js.map +1 -0
  107. package/lib/stories/StorybookWrappers/InitialiseFormWrapperForStorybook.d.ts +31 -0
  108. package/lib/stories/StorybookWrappers/InitialiseFormWrapperForStorybook.js +67 -0
  109. package/lib/stories/StorybookWrappers/InitialiseFormWrapperForStorybook.js.map +1 -0
  110. package/lib/stories/StorybookWrappers/PrePopButtonForStorybook.d.ts +7 -0
  111. package/lib/stories/StorybookWrappers/PrePopButtonForStorybook.js +32 -0
  112. package/lib/stories/StorybookWrappers/PrePopButtonForStorybook.js.map +1 -0
  113. package/lib/stories/StorybookWrappers/PrePopWrapperForStorybook.d.ts +21 -0
  114. package/lib/stories/StorybookWrappers/PrePopWrapperForStorybook.js +83 -0
  115. package/lib/stories/StorybookWrappers/PrePopWrapperForStorybook.js.map +1 -0
  116. package/lib/stories/StorybookWrappers/index.d.ts +3 -0
  117. package/lib/stories/StorybookWrappers/index.js +20 -0
  118. package/lib/stories/StorybookWrappers/index.js.map +1 -0
  119. package/lib/stories/StorybookWrappers/populateCallbackForStorybook.d.ts +8 -0
  120. package/lib/stories/StorybookWrappers/populateCallbackForStorybook.js +46 -0
  121. package/lib/stories/StorybookWrappers/populateCallbackForStorybook.js.map +1 -0
  122. package/lib/stories/index.d.ts +1 -0
  123. package/lib/stories/index.js +18 -0
  124. package/lib/stories/index.js.map +1 -0
  125. package/lib/theme/Theme.d.ts +8 -2
  126. package/lib/theme/Theme.js +8 -2
  127. package/lib/theme/Theme.js.map +1 -1
  128. package/lib/theme/index.d.ts +1 -0
  129. package/lib/theme/index.js +2 -0
  130. package/lib/theme/index.js.map +1 -0
  131. package/lib/utils/enableWhen.d.ts +1 -1
  132. package/lib/utils/enableWhenExpression.d.ts +1 -1
  133. package/lib/utils/fhirpath.d.ts +1 -1
  134. package/lib/utils/index.d.ts +5 -3
  135. package/lib/utils/index.js +4 -3
  136. package/lib/utils/index.js.map +1 -1
  137. package/lib/utils/initialise.d.ts +2 -2
  138. package/lib/utils/initialise.js +1 -1
  139. package/lib/utils/manageForm.d.ts +45 -0
  140. package/lib/utils/manageForm.js +101 -0
  141. package/lib/utils/manageForm.js.map +1 -0
  142. package/lib/utils/qItem.d.ts +1 -1
  143. package/lib/utils/questionnaireStoreUtils/extractOtherExtensions.d.ts +1 -1
  144. package/lib/utils/removeEmptyAnswers.d.ts +1 -1
  145. package/lib/utils/repopulateIntoResponse.d.ts +6 -0
  146. package/lib/utils/repopulateIntoResponse.js +11 -0
  147. package/lib/utils/repopulateIntoResponse.js.map +1 -1
  148. package/lib/utils/repopulateItems.d.ts +19 -1
  149. package/lib/utils/repopulateItems.js +23 -0
  150. package/lib/utils/repopulateItems.js.map +1 -1
  151. package/lib/utils/tabs.d.ts +2 -2
  152. package/lib/utils/tabs.js +1 -1
  153. package/lib/utils/validateQuestionnaire.d.ts +0 -4
  154. package/lib/utils/validateQuestionnaire.js +9 -5
  155. package/lib/utils/validateQuestionnaire.js.map +1 -1
  156. package/package.json +1 -1
  157. package/src/components/FormComponents/BooleanItem/BooleanField.tsx +11 -9
  158. package/src/components/FormComponents/ChoiceItems/ChoiceRadioAnswerOptionFields.tsx +11 -9
  159. package/src/components/FormComponents/ChoiceItems/ChoiceRadioAnswerValueSetFields.tsx +11 -9
  160. package/src/components/FormComponents/DateTimeItems/index.ts +1 -1
  161. package/src/components/FormComponents/DateTimeItems/utils/parseDate.ts +5 -0
  162. package/src/components/FormComponents/GridGroup/GridGroup.tsx +6 -0
  163. package/src/components/FormComponents/RepeatGroup/RepeatGroup.tsx +6 -0
  164. package/src/components/FormComponents/RepeatItem/RepeatItem.tsx +5 -0
  165. package/src/components/FormComponents/SingleItem/SingleItem.tsx +6 -0
  166. package/src/components/FormComponents/Tables/GroupTable.tsx +6 -0
  167. package/src/components/FormComponents/index.ts +6 -6
  168. package/src/components/Renderer/BaseRenderer.tsx +7 -0
  169. package/src/components/Renderer/SmartFormsRenderer.tsx +34 -11
  170. package/src/components/Renderer/index.ts +1 -0
  171. package/src/components/index.ts +10 -2
  172. package/src/hooks/index.ts +2 -0
  173. package/src/hooks/useBuildForm.ts +58 -0
  174. package/src/hooks/useHidden.ts +6 -0
  175. package/src/hooks/useInitialiseForm.ts +93 -0
  176. package/src/hooks/{useQueryClient.ts → useRendererQueryClient.ts} +9 -2
  177. package/src/hooks/useValueSetCodings.ts +1 -0
  178. package/src/index.ts +59 -96
  179. package/src/interfaces/calculatedExpression.interface.ts +24 -0
  180. package/src/interfaces/enableWhen.interface.ts +12 -0
  181. package/src/interfaces/index.ts +21 -10
  182. package/src/interfaces/populate.interface.ts +6 -0
  183. package/src/interfaces/tab.interface.ts +12 -0
  184. package/src/interfaces/variables.interface.ts +12 -0
  185. package/src/stores/index.ts +7 -0
  186. package/src/stores/questionnaireResponseStore.ts +90 -19
  187. package/src/stores/questionnaireStore.ts +62 -2
  188. package/src/stores/smartConfigStore.ts +37 -0
  189. package/src/stores/terminologyServerStore.ts +28 -1
  190. package/src/stories/{BuildFormButtonForStorybook.tsx → StorybookWrappers/BuildFormButtonForStorybook.tsx} +12 -5
  191. package/src/stories/StorybookWrappers/BuildFormButtonTesterWrapperForStorybook.tsx +70 -0
  192. package/src/stories/{BuildFormWrapper.tsx → StorybookWrappers/BuildFormWrapperForStorybook.tsx} +11 -12
  193. package/src/stories/{BuildFormButtonTesterWrapper.tsx → StorybookWrappers/FormValidationTesterWrapperForStorybook.tsx} +22 -19
  194. package/src/stories/{useBuildFormForStorybook.ts → StorybookWrappers/FormValidationViewerForStorybook.tsx} +7 -16
  195. package/src/stories/StorybookWrappers/InitialiseFormWrapperForStorybook.tsx +105 -0
  196. package/src/stories/{PrePopButtonForStorybook.tsx → StorybookWrappers/PrePopButtonForStorybook.tsx} +12 -10
  197. package/src/stories/{PrePopWrapper.tsx → StorybookWrappers/PrePopWrapperForStorybook.tsx} +22 -14
  198. package/src/stories/StorybookWrappers/ValidateFormButtonForStorybook.tsx +41 -0
  199. package/src/stories/StorybookWrappers/index.ts +20 -0
  200. package/src/stories/{populateCallbackForStorybook.ts → StorybookWrappers/populateCallbackForStorybook.ts} +8 -2
  201. package/src/stories/assets/questionnaires/QButtonTester.ts +380 -0
  202. package/src/stories/assets/questionnaires/QValidateTester.ts +118 -0
  203. package/src/stories/itemTypes/Attachment.stories.tsx +3 -3
  204. package/src/stories/itemTypes/Boolean.stories.tsx +3 -3
  205. package/src/stories/itemTypes/Choice.stories.tsx +3 -3
  206. package/src/stories/itemTypes/Date.stories.tsx +3 -3
  207. package/src/stories/itemTypes/DateTime.stories.tsx +3 -3
  208. package/src/stories/itemTypes/Decimal.stories.tsx +3 -3
  209. package/src/stories/itemTypes/Display.stories.tsx +3 -3
  210. package/src/stories/itemTypes/Group.stories.tsx +3 -3
  211. package/src/stories/itemTypes/Integer.stories.tsx +3 -3
  212. package/src/stories/itemTypes/OpenChoice.stories.tsx +3 -3
  213. package/src/stories/itemTypes/Quantity.stories.tsx +3 -3
  214. package/src/stories/itemTypes/Reference.stories.tsx +3 -3
  215. package/src/stories/itemTypes/String.stories.tsx +3 -3
  216. package/src/stories/itemTypes/Text.stories.tsx +3 -3
  217. package/src/stories/itemTypes/Time.stories.tsx +3 -3
  218. package/src/stories/itemTypes/Url.stories.tsx +3 -3
  219. package/src/stories/sdc/AdvancedAdditionalDisplayContent.stories.tsx +3 -3
  220. package/src/stories/sdc/AdvancedControlAppearance.stories.tsx +3 -3
  221. package/src/stories/sdc/AdvancedOther.stories.tsx +3 -3
  222. package/src/stories/sdc/AdvancedTextAppearance.stories.tsx +3 -3
  223. package/src/stories/sdc/BehaviorCalculations.stories.tsx +3 -3
  224. package/src/stories/sdc/BehaviorChoiceRestriction.stories.tsx +3 -3
  225. package/src/stories/sdc/BehaviorOther.stories.tsx +3 -3
  226. package/src/stories/sdc/BehaviorValueConstraints.stories.tsx +3 -3
  227. package/src/stories/sdc/FormPopulation.stories.tsx +3 -3
  228. package/src/stories/sdc/ItemControlDisplay.stories.tsx +3 -3
  229. package/src/stories/sdc/ItemControlGroup.stories.tsx +3 -3
  230. package/src/stories/sdc/ItemControlQuestion.stories.tsx +3 -3
  231. package/src/stories/{rebuildForm/BuildFormTesterWrapper.stories.tsx → testing/BuildFormButtonTesterWrapper.stories.tsx} +6 -9
  232. package/src/stories/testing/PrePopButtonTesterWrapper.stories.tsx +45 -0
  233. package/src/stories/testing/ValidateFormTesterWrapper.stories.tsx +39 -0
  234. package/src/tests/enableWhen.test.ts +6 -2
  235. package/src/theme/Theme.tsx +8 -2
  236. package/src/theme/index.ts +1 -0
  237. package/src/utils/enableWhen.ts +1 -1
  238. package/src/utils/enableWhenExpression.ts +1 -1
  239. package/src/utils/fhirpath.ts +1 -1
  240. package/src/utils/index.ts +5 -7
  241. package/src/utils/initialise.ts +2 -2
  242. package/src/utils/manageForm.ts +110 -0
  243. package/src/utils/qItem.ts +1 -1
  244. package/src/utils/questionnaireStoreUtils/extractOtherExtensions.ts +1 -1
  245. package/src/utils/removeEmptyAnswers.ts +1 -1
  246. package/src/utils/repopulateIntoResponse.ts +17 -0
  247. package/src/utils/repopulateItems.ts +38 -1
  248. package/src/utils/tabs.ts +2 -2
  249. package/src/utils/validateQuestionnaire.ts +12 -17
  250. package/vite.config.ts +1 -1
  251. package/src/hooks/useInitialiseRenderer.ts +0 -114
  252. package/src/stories/assets/questionnaires/QBuildFormButtonTester.ts +0 -270
  253. package/src/stories/populateUtilsForStorybook.ts +0 -545
  254. package/src/utils/buildForm.ts +0 -23
  255. /package/.storybook/{preview.ts → preview.tsx} +0 -0
@@ -20,16 +20,43 @@ import { createSelectors } from './selector';
20
20
 
21
21
  const ONTOSERVER_R4 = 'https://r4.ontoserver.csiro.au/fhir';
22
22
 
23
- interface TerminologyServerStoreType {
23
+ /**
24
+ * TerminologyServerStore properties and methods
25
+ * Properties can be accessed for fine-grain details.
26
+ * Methods are usually used internally, using them from an external source is not recommended.
27
+ *
28
+ * @property url - The current terminology server URL
29
+ * @method setUrl - Set the terminology server URL
30
+ * @method resetUrl - Reset the terminology server URL to the default
31
+ *
32
+ * @author Sean Fong
33
+ */
34
+ export interface TerminologyServerStoreType {
24
35
  url: string;
25
36
  setUrl: (newUrl: string) => void;
26
37
  resetUrl: () => void;
27
38
  }
28
39
 
40
+ /**
41
+ * Terminology server state management store. This is used for resolving valueSets externally.
42
+ * Defaults to use https://r4.ontoserver.csiro.au/fhir.
43
+ * This is the vanilla version of the store which can be used in non-React environments.
44
+ * @see {TerminologyServerStoreType} for available properties and methods.
45
+ *
46
+ * @author Sean Fong
47
+ */
29
48
  export const terminologyServerStore = createStore<TerminologyServerStoreType>()((set) => ({
30
49
  url: ONTOSERVER_R4,
31
50
  setUrl: (newUrl: string) => set(() => ({ url: newUrl })),
32
51
  resetUrl: () => set(() => ({ url: ONTOSERVER_R4 }))
33
52
  }));
34
53
 
54
+ /**
55
+ * Terminology server state management store. This is used for resolving valueSets externally.
56
+ * Defaults to use https://r4.ontoserver.csiro.au/fhir.
57
+ * This is the React version of the store which can be used as React hooks in React functional components.
58
+ * @see {TerminologyServerStoreType} for available properties and methods.
59
+ *
60
+ * @author Sean Fong
61
+ */
35
62
  export const useTerminologyServerStore = createSelectors(terminologyServerStore);
@@ -17,20 +17,27 @@
17
17
 
18
18
  // @ts-ignore
19
19
  import React from 'react';
20
+ import type { Questionnaire, QuestionnaireResponse } from 'fhir/r4';
20
21
  import { Box, IconButton, Tooltip } from '@mui/material';
21
- import Iconify from '../components/Iconify/Iconify';
22
+ import Iconify from '../../components/Iconify/Iconify';
23
+ import { buildForm } from '../../utils';
22
24
 
23
25
  interface BuildFormButtonProps {
24
- onBuild: () => void;
26
+ questionnaire: Questionnaire;
27
+ questionnaireResponse?: QuestionnaireResponse;
25
28
  }
26
29
 
27
30
  function BuildFormButtonForStorybook(props: BuildFormButtonProps) {
28
- const { onBuild } = props;
31
+ const { questionnaire, questionnaireResponse } = props;
32
+
33
+ async function handleBuildForm() {
34
+ await buildForm(questionnaire, questionnaireResponse);
35
+ }
29
36
 
30
37
  return (
31
38
  <Box display="flex" mb={0.5} alignItems="center" columnGap={3}>
32
- <Tooltip title="Build form" placement="right">
33
- <IconButton onClick={onBuild} size="small" color="primary">
39
+ <Tooltip title="Build form with questionnaire response" placement="right">
40
+ <IconButton onClick={handleBuildForm} size="small" color="primary">
34
41
  <Iconify icon="ph:hammer" sx={{ mb: 0.5 }} />
35
42
  </IconButton>
36
43
  </Tooltip>
@@ -0,0 +1,70 @@
1
+ /*
2
+ * Copyright 2024 Commonwealth Scientific and Industrial Research
3
+ * Organisation (CSIRO) ABN 41 687 119 230.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+ // @ts-ignore
19
+ import React from 'react';
20
+ import type { Questionnaire, QuestionnaireResponse } from 'fhir/r4';
21
+ import { BaseRenderer } from '../../components';
22
+ import { QueryClientProvider } from '@tanstack/react-query';
23
+ import { RendererThemeProvider } from '../../theme';
24
+ import { useBuildForm, useRendererQueryClient } from '../../hooks';
25
+ import BuildFormButtonForStorybook from './BuildFormButtonForStorybook';
26
+
27
+ interface BuildFormButtonTesterWrapperForStorybookProps {
28
+ questionnaire: Questionnaire;
29
+ questionnaireResponse?: QuestionnaireResponse;
30
+ }
31
+
32
+ /**
33
+ * This is a demo wrapper which initialises the BaseRenderer with the passed in questionnaire using useBuildForm.
34
+ * It also provides a button to build the form with the passed in questionnaire + questionnaireResponse.
35
+ * It was done as a two-step process for demo purposes.
36
+ *
37
+ * Use this pattern if you already have a pre-populated/pre-filled/draft response.
38
+ * If you want to pre-pop on the fly, see https://github.com/aehrc/smart-forms/blob/main/packages/smart-forms-renderer/src/stories/StorybookWrappers/PrePopWrapperForStorybook.tsx instead
39
+ *
40
+ * @author Sean Fong
41
+ */
42
+ function BuildFormButtonTesterWrapperForStorybook(
43
+ props: BuildFormButtonTesterWrapperForStorybookProps
44
+ ) {
45
+ const { questionnaire, questionnaireResponse } = props;
46
+
47
+ const queryClient = useRendererQueryClient();
48
+
49
+ const isBuilding = useBuildForm(questionnaire);
50
+
51
+ if (isBuilding) {
52
+ return <div>Loading...</div>;
53
+ }
54
+
55
+ return (
56
+ <RendererThemeProvider>
57
+ <QueryClientProvider client={queryClient}>
58
+ <div>
59
+ <BuildFormButtonForStorybook
60
+ questionnaire={questionnaire}
61
+ questionnaireResponse={questionnaireResponse}
62
+ />
63
+ <BaseRenderer />
64
+ </div>
65
+ </QueryClientProvider>
66
+ </RendererThemeProvider>
67
+ );
68
+ }
69
+
70
+ export default BuildFormButtonTesterWrapperForStorybook;
@@ -18,35 +18,34 @@
18
18
  // @ts-ignore
19
19
  import React from 'react';
20
20
  import type { Questionnaire, QuestionnaireResponse } from 'fhir/r4';
21
- import { BaseRenderer } from '../components';
21
+ import { BaseRenderer } from '../../components';
22
22
  import { QueryClientProvider } from '@tanstack/react-query';
23
- import ThemeProvider from '../theme/Theme';
24
- import useQueryClient from '../hooks/useQueryClient';
25
- import useBuildFormForStorybook from './useBuildFormForStorybook';
23
+ import RendererThemeProvider from '../../theme/Theme';
24
+ import { useBuildForm } from '../../hooks';
25
+ import useRendererQueryClient from '../../hooks/useRendererQueryClient';
26
26
 
27
- interface BuildFormWrapperProps {
27
+ interface BuildFormWrapperForStorybookProps {
28
28
  questionnaire: Questionnaire;
29
29
  questionnaireResponse?: QuestionnaireResponse;
30
30
  }
31
31
 
32
- function BuildFormWrapper(props: BuildFormWrapperProps) {
32
+ function BuildFormWrapperForStorybook(props: BuildFormWrapperForStorybookProps) {
33
33
  const { questionnaire, questionnaireResponse } = props;
34
34
 
35
- const queryClient = useQueryClient();
36
-
37
- const isBuilding = useBuildFormForStorybook(questionnaire, questionnaireResponse);
35
+ const queryClient = useRendererQueryClient();
36
+ const isBuilding = useBuildForm(questionnaire, questionnaireResponse);
38
37
 
39
38
  if (isBuilding) {
40
39
  return <div>Loading...</div>;
41
40
  }
42
41
 
43
42
  return (
44
- <ThemeProvider>
43
+ <RendererThemeProvider>
45
44
  <QueryClientProvider client={queryClient}>
46
45
  <BaseRenderer />
47
46
  </QueryClientProvider>
48
- </ThemeProvider>
47
+ </RendererThemeProvider>
49
48
  );
50
49
  }
51
50
 
52
- export default BuildFormWrapper;
51
+ export default BuildFormWrapperForStorybook;
@@ -18,44 +18,47 @@
18
18
  // @ts-ignore
19
19
  import React from 'react';
20
20
  import type { Questionnaire, QuestionnaireResponse } from 'fhir/r4';
21
- import { BaseRenderer } from '../components';
21
+ import { BaseRenderer } from '../../components';
22
22
  import { QueryClientProvider } from '@tanstack/react-query';
23
- import ThemeProvider from '../theme/Theme';
24
- import useQueryClient from '../hooks/useQueryClient';
25
- import useBuildFormForStorybook from './useBuildFormForStorybook';
26
- import { buildForm } from '../utils';
27
- import BuildFormButtonForStorybook from './BuildFormButtonForStorybook';
23
+ import { RendererThemeProvider } from '../../theme';
24
+ import { useBuildForm, useRendererQueryClient } from '../../hooks';
25
+ import { Grid } from '@mui/material';
26
+ import FormValidationViewerForStorybook from './FormValidationViewerForStorybook';
28
27
 
29
- interface BuildFormButtonTesterWrapperProps {
28
+ interface FormValidationTesterWrapperForStorybookProps {
30
29
  questionnaire: Questionnaire;
31
30
  questionnaireResponse?: QuestionnaireResponse;
32
31
  }
33
32
 
34
- function BuildFormButtonTesterWrapper(props: BuildFormButtonTesterWrapperProps) {
33
+ function FormValidationTesterWrapperForStorybook(
34
+ props: FormValidationTesterWrapperForStorybookProps
35
+ ) {
35
36
  const { questionnaire, questionnaireResponse } = props;
36
37
 
37
- const queryClient = useQueryClient();
38
+ const isBuilding = useBuildForm(questionnaire, questionnaireResponse);
38
39
 
39
- const isBuilding = useBuildFormForStorybook(questionnaire);
40
-
41
- async function handleBuildForm() {
42
- await buildForm(questionnaire, questionnaireResponse);
43
- }
40
+ const queryClient = useRendererQueryClient();
44
41
 
45
42
  if (isBuilding) {
46
43
  return <div>Loading...</div>;
47
44
  }
48
45
 
49
46
  return (
50
- <ThemeProvider>
47
+ <RendererThemeProvider>
51
48
  <QueryClientProvider client={queryClient}>
52
49
  <div>
53
- <BuildFormButtonForStorybook onBuild={handleBuildForm} />
54
- <BaseRenderer />
50
+ <Grid container>
51
+ <Grid item xs={6}>
52
+ <BaseRenderer />
53
+ </Grid>
54
+ <Grid item xs={6}>
55
+ <FormValidationViewerForStorybook />
56
+ </Grid>
57
+ </Grid>
55
58
  </div>
56
59
  </QueryClientProvider>
57
- </ThemeProvider>
60
+ </RendererThemeProvider>
58
61
  );
59
62
  }
60
63
 
61
- export default BuildFormButtonTesterWrapper;
64
+ export default FormValidationTesterWrapperForStorybook;
@@ -15,23 +15,14 @@
15
15
  * limitations under the License.
16
16
  */
17
17
 
18
- import { useLayoutEffect, useState } from 'react';
19
- import { buildForm } from '../utils';
20
- import type { Questionnaire, QuestionnaireResponse } from 'fhir/r4';
18
+ // @ts-ignore
19
+ import React from 'react';
20
+ import { useQuestionnaireResponseStore } from '../../stores';
21
21
 
22
- function useBuildFormForStorybook(
23
- questionnaire: Questionnaire,
24
- questionnaireResponse?: QuestionnaireResponse
25
- ) {
26
- const [isBuilding, setIsBuilding] = useState(true);
22
+ function FormValidationViewerForStorybook() {
23
+ const invalidItems = useQuestionnaireResponseStore.use.invalidItems();
27
24
 
28
- useLayoutEffect(() => {
29
- buildForm(questionnaire, questionnaireResponse).then(() => {
30
- setIsBuilding(false);
31
- });
32
- }, [questionnaire, questionnaireResponse]);
33
-
34
- return isBuilding;
25
+ return <pre style={{ fontSize: 9 }}>{JSON.stringify(invalidItems, null, 2)}</pre>;
35
26
  }
36
27
 
37
- export default useBuildFormForStorybook;
28
+ export default FormValidationViewerForStorybook;
@@ -0,0 +1,105 @@
1
+ /*
2
+ * Copyright 2024 Commonwealth Scientific and Industrial Research
3
+ * Organisation (CSIRO) ABN 41 687 119 230.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+ // @ts-ignore
19
+ import React from 'react';
20
+ import type { Questionnaire, QuestionnaireResponse } from 'fhir/r4';
21
+ import { BaseRenderer } from '../../components';
22
+ import { QueryClientProvider } from '@tanstack/react-query';
23
+ import RendererThemeProvider from '../../theme/Theme';
24
+ import useRendererQueryClient from '../../hooks/useRendererQueryClient';
25
+ import type Client from 'fhirclient/lib/Client';
26
+ import useInitialiseForm from '../../hooks/useInitialiseForm';
27
+ import Box from '@mui/material/Box';
28
+ import CircularProgress from '@mui/material/CircularProgress';
29
+ import Typography from '@mui/material/Typography';
30
+
31
+ interface InitialiseFormWrapperProps {
32
+ questionnaire: Questionnaire;
33
+ questionnaireResponse?: QuestionnaireResponse;
34
+ readOnly?: boolean;
35
+ terminologyServerUrl?: string;
36
+ additionalVariables?: Record<string, object>;
37
+ fhirClient?: Client;
38
+ }
39
+
40
+ /**
41
+ * This is a one-to-one replacement for the SmartFormsRenderer for demo purposes.
42
+ * Instead of using this React component, define your own wrapper component that uses the BaseRenderer directly.
43
+ * Things to note:
44
+ * - It is required to wrap the BaseRenderer with the QueryClientProvider to make requests.
45
+ * - You can wrap the BaseRenderer with the RendererThemeProvider to apply the default renderer theme used in Smart Forms. Optionally, you can define your own ThemeProvider.
46
+ * - Make your buildForm() call in a button click or other event handler. Alternatively, you can use the useInitialiseForm hook to initialise the form.
47
+ * - Make your own initialiseFhirClient() call in a button click or other event handler. Alternatively, you can use the useInitialiseForm hook to initialise the form.
48
+ * - The initialised FHIRClient is only used for further FHIR calls. It does not provide pre-population capabilities.
49
+ *
50
+ * For button click usage examples of buildForm(), see:
51
+ * - https://github.com/aehrc/smart-forms/blob/main/packages/smart-forms-renderer/src/stories/StorybookWrappers/BuildFormButtonTesterWrapperForStorybook.tsx
52
+ * - https://github.com/aehrc/smart-forms/blob/main/packages/smart-forms-renderer/src/stories/StorybookWrappers/BuildFormButtonForStorybook.tsx
53
+ * - https://github.com/aehrc/smart-forms/blob/main/packages/smart-forms-renderer/src/stories/StorybookWrappers/PrePopWrapperForStorybook.tsx
54
+ * - https://github.com/aehrc/smart-forms/blob/main/packages/smart-forms-renderer/src/stories/StorybookWrappers/PrePopButtonForStorybook.tsx
55
+ *
56
+ * @author Sean Fong
57
+ */
58
+ function InitialiseFormWrapperForStorybook(props: InitialiseFormWrapperProps) {
59
+ const {
60
+ questionnaire,
61
+ questionnaireResponse,
62
+ readOnly,
63
+ terminologyServerUrl,
64
+ additionalVariables,
65
+ fhirClient
66
+ } = props;
67
+
68
+ // The renderer requires a @tanstack/react-query QueryClientProvider to make requests
69
+ const queryClient = useRendererQueryClient();
70
+
71
+ /**
72
+ * The useInitialiseForm hook provides initialisation logic for the form
73
+ * Alternatively (and recommended to do so), you can initialise your form via a button click or other event handler.
74
+ *
75
+ * @see {@link https://github.com/aehrc/smart-forms/blob/main/packages/smart-forms-renderer/src/stories/BuildFormButtonForStorybook.tsx} for button click usage examples.
76
+ */
77
+ const isInitialising = useInitialiseForm(
78
+ questionnaire,
79
+ questionnaireResponse,
80
+ readOnly,
81
+ terminologyServerUrl,
82
+ additionalVariables,
83
+ fhirClient
84
+ );
85
+
86
+ // Free feel to customise your loading animation here
87
+ if (isInitialising) {
88
+ return (
89
+ <Box display="flex" alignItems="center" columnGap={2}>
90
+ <CircularProgress />
91
+ <Typography>Loading questionnaire...</Typography>
92
+ </Box>
93
+ );
94
+ }
95
+
96
+ return (
97
+ <RendererThemeProvider>
98
+ <QueryClientProvider client={queryClient}>
99
+ <BaseRenderer />
100
+ </QueryClientProvider>
101
+ </RendererThemeProvider>
102
+ );
103
+ }
104
+
105
+ export default InitialiseFormWrapperForStorybook;
@@ -18,27 +18,29 @@
18
18
  // @ts-ignore
19
19
  import React from 'react';
20
20
  import { Box, CircularProgress, Fade, IconButton, Tooltip } from '@mui/material';
21
- import PlayCircleIcon from '@mui/icons-material/PlayCircle';
21
+ import CloudDownloadIcon from '@mui/icons-material/CloudDownload';
22
22
  import Typography from '@mui/material/Typography';
23
23
 
24
- interface PrePopButtonProps {
24
+ interface PrePopButtonForStorybookProps {
25
25
  isPopulating: boolean;
26
26
  onPopulate: () => void;
27
27
  }
28
28
 
29
- function PrePopButtonForStorybook(props: PrePopButtonProps) {
29
+ function PrePopButtonForStorybook(props: PrePopButtonForStorybookProps) {
30
30
  const { isPopulating, onPopulate } = props;
31
31
 
32
32
  return (
33
33
  <Box display="flex" mb={0.5} alignItems="center" columnGap={3}>
34
34
  <Tooltip title="Pre-populate form" placement="right">
35
- <IconButton disabled={isPopulating} onClick={onPopulate} size="small" color="primary">
36
- {isPopulating ? (
37
- <CircularProgress size={20} color="inherit" sx={{ mb: 0.5 }} />
38
- ) : (
39
- <PlayCircleIcon />
40
- )}
41
- </IconButton>
35
+ <span>
36
+ <IconButton disabled={isPopulating} onClick={onPopulate} size="small" color="primary">
37
+ {isPopulating ? (
38
+ <CircularProgress size={20} color="inherit" sx={{ mb: 0.5 }} />
39
+ ) : (
40
+ <CloudDownloadIcon />
41
+ )}
42
+ </IconButton>
43
+ </span>
42
44
  </Tooltip>
43
45
  {isPopulating ? (
44
46
  <Fade in={true} timeout={100}>
@@ -18,32 +18,41 @@
18
18
  // @ts-ignore
19
19
  import React, { useState } from 'react';
20
20
  import type { Patient, Practitioner, Questionnaire } from 'fhir/r4';
21
- import { BaseRenderer } from '../components';
21
+ import { BaseRenderer } from '../../components';
22
22
  import { QueryClientProvider } from '@tanstack/react-query';
23
- import ThemeProvider from '../theme/Theme';
24
- import useQueryClient from '../hooks/useQueryClient';
23
+ import { RendererThemeProvider } from '../../theme';
24
+ import { useBuildForm, useRendererQueryClient } from '../../hooks';
25
25
  import type Client from 'fhirclient/lib/Client';
26
- import useBuildFormForStorybook from './useBuildFormForStorybook';
27
- import { buildForm } from '../utils';
28
26
  import PrePopButtonForStorybook from './PrePopButtonForStorybook';
29
27
  import { populateQuestionnaire } from '@aehrc/sdc-populate';
30
28
  import { fetchResourceCallback } from './populateCallbackForStorybook';
29
+ import { buildForm } from '../../utils';
31
30
 
32
- interface PrePopWrapperProps {
31
+ interface PrePopWrapperForStorybookProps {
33
32
  questionnaire: Questionnaire;
34
33
  fhirClient: Client;
35
34
  patient: Patient;
36
35
  user: Practitioner;
37
36
  }
38
37
 
39
- function PrePopWrapper(props: PrePopWrapperProps) {
38
+ /**
39
+ * This is a demo wrapper which initialises the BaseRenderer with the passed in questionnaire using useBuildForm.
40
+ * It also provides a button to pre-populate the questionnaire on the fly using populateQuestionnaire() from '@aehrc/sdc-populate'.
41
+ * This does in-app population and you have to define your own callback function to retrieve resources from your source server.
42
+ *
43
+ * Use this pattern if you do not have a pre-populated/pre-filled/draft response and want to pre-populate on the fly.
44
+ * If you already have a questionnaireResponse, see https://github.com/aehrc/smart-forms/blob/main/packages/smart-forms-renderer/src/stories/StorybookWrappers/BuildFormButtonTesterWrapperForStorybook.tsx instead
45
+ *
46
+ * @author Sean Fong
47
+ */
48
+ function PrePopWrapperForStorybook(props: PrePopWrapperForStorybookProps) {
40
49
  const { questionnaire, fhirClient, patient, user } = props;
41
50
 
42
51
  const [isPopulating, setIsPopulating] = useState(false);
43
52
 
44
- const isBuilding = useBuildFormForStorybook(questionnaire);
53
+ const isBuilding = useBuildForm(questionnaire);
45
54
 
46
- const queryClient = useQueryClient();
55
+ const queryClient = useRendererQueryClient();
47
56
 
48
57
  function handlePrepopulate() {
49
58
  setIsPopulating(true);
@@ -65,8 +74,7 @@ function PrePopWrapper(props: PrePopWrapperProps) {
65
74
 
66
75
  const { populatedResponse } = populateResult;
67
76
 
68
- // buildForm is used here because there is a really bizarre bug - using the store hooks directly doesn't update the baseRenderer
69
- // could be the fact that it doesn't play well with storybook
77
+ // Call to buildForm to pre-populate the QR which repaints the entire BaseRenderer view
70
78
  await buildForm(questionnaire, populatedResponse);
71
79
 
72
80
  setIsPopulating(false);
@@ -78,15 +86,15 @@ function PrePopWrapper(props: PrePopWrapperProps) {
78
86
  }
79
87
 
80
88
  return (
81
- <ThemeProvider>
89
+ <RendererThemeProvider>
82
90
  <QueryClientProvider client={queryClient}>
83
91
  <div>
84
92
  <PrePopButtonForStorybook isPopulating={isPopulating} onPopulate={handlePrepopulate} />
85
93
  {isPopulating ? null : <BaseRenderer />}
86
94
  </div>
87
95
  </QueryClientProvider>
88
- </ThemeProvider>
96
+ </RendererThemeProvider>
89
97
  );
90
98
  }
91
99
 
92
- export default PrePopWrapper;
100
+ export default PrePopWrapperForStorybook;
@@ -0,0 +1,41 @@
1
+ /*
2
+ * Copyright 2024 Commonwealth Scientific and Industrial Research
3
+ * Organisation (CSIRO) ABN 41 687 119 230.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+ // @ts-ignore
19
+ import React from 'react';
20
+ import { Box, IconButton, Tooltip } from '@mui/material';
21
+ import Iconify from '../../components/Iconify/Iconify';
22
+
23
+ interface ValidationFormButtonForStorybookProps {
24
+ onValidate: () => void;
25
+ }
26
+
27
+ function ValidationFormButtonForStorybook(props: ValidationFormButtonForStorybookProps) {
28
+ const { onValidate } = props;
29
+
30
+ return (
31
+ <Box display="flex" mb={0.5} alignItems="center" columnGap={3}>
32
+ <Tooltip title="Validate form" placement="right">
33
+ <IconButton onClick={onValidate} size="small" color="primary">
34
+ <Iconify icon="material-symbols:data-check" sx={{ mb: 0.5 }} />
35
+ </IconButton>
36
+ </Tooltip>
37
+ </Box>
38
+ );
39
+ }
40
+
41
+ export default ValidationFormButtonForStorybook;
@@ -0,0 +1,20 @@
1
+ /*
2
+ * Copyright 2024 Commonwealth Scientific and Industrial Research
3
+ * Organisation (CSIRO) ABN 41 687 119 230.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+ export { default as InitialiseFormWrapperForStorybook } from './InitialiseFormWrapperForStorybook';
19
+ export { default as BuildFormButtonTesterWrapperForStorybook } from './BuildFormButtonTesterWrapperForStorybook';
20
+ export { default as PrePopWrapperForStorybook } from './PrePopWrapperForStorybook';
@@ -20,11 +20,17 @@ import axios from 'axios';
20
20
 
21
21
  const ABSOLUTE_URL_REGEX = /^(https?|ftp):\/\/[^\s/$.?#].[^\s]*$/;
22
22
 
23
- export interface RequestConfig {
23
+ interface RequestConfig {
24
24
  clientEndpoint: string;
25
25
  authToken: string | null;
26
26
  }
27
27
 
28
+ /**
29
+ * Sample callback function to fetch resources from your source server when using populate() or populateQuestionnaire() from @aehrc/sdc-populate.
30
+ * See https://github.com/aehrc/smart-forms/blob/main/packages/smart-forms-renderer/src/stories/StorybookWrappers/PrePopWrapperForStorybook.tsx#L50-L59 for usage.
31
+ *
32
+ * @author Sean Fong
33
+ */
28
34
  export const fetchResourceCallback: FetchResourceCallback = (
29
35
  query: string,
30
36
  requestConfig: RequestConfig
@@ -32,7 +38,7 @@ export const fetchResourceCallback: FetchResourceCallback = (
32
38
  let { clientEndpoint } = requestConfig;
33
39
  const { authToken } = requestConfig;
34
40
 
35
- const headers = {
41
+ const headers: any = {
36
42
  Accept: 'application/json;charset=utf-8'
37
43
  };
38
44