@aehrc/smart-forms-renderer 0.30.1 → 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 (271) 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/ItemParts/ItemLabelText.js +2 -2
  18. package/lib/components/FormComponents/ItemParts/ItemLabelText.js.map +1 -1
  19. package/lib/components/FormComponents/RepeatGroup/RepeatGroup.d.ts +6 -0
  20. package/lib/components/FormComponents/RepeatGroup/RepeatGroup.js +6 -0
  21. package/lib/components/FormComponents/RepeatGroup/RepeatGroup.js.map +1 -1
  22. package/lib/components/FormComponents/RepeatItem/RepeatItem.d.ts +5 -0
  23. package/lib/components/FormComponents/RepeatItem/RepeatItem.js +5 -0
  24. package/lib/components/FormComponents/RepeatItem/RepeatItem.js.map +1 -1
  25. package/lib/components/FormComponents/SingleItem/SingleItem.d.ts +6 -0
  26. package/lib/components/FormComponents/SingleItem/SingleItem.js +6 -0
  27. package/lib/components/FormComponents/SingleItem/SingleItem.js.map +1 -1
  28. package/lib/components/FormComponents/Tables/GroupTable.d.ts +6 -0
  29. package/lib/components/FormComponents/Tables/GroupTable.js +6 -0
  30. package/lib/components/FormComponents/Tables/GroupTable.js.map +1 -1
  31. package/lib/components/FormComponents/index.d.ts +6 -6
  32. package/lib/components/FormComponents/index.js +6 -6
  33. package/lib/components/FormComponents/index.js.map +1 -1
  34. package/lib/components/Renderer/BaseRenderer.d.ts +7 -0
  35. package/lib/components/Renderer/BaseRenderer.js +7 -0
  36. package/lib/components/Renderer/BaseRenderer.js.map +1 -1
  37. package/lib/components/Renderer/SmartFormsRenderer.d.ts +22 -1
  38. package/lib/components/Renderer/SmartFormsRenderer.js +16 -6
  39. package/lib/components/Renderer/SmartFormsRenderer.js.map +1 -1
  40. package/lib/components/Renderer/index.d.ts +1 -0
  41. package/lib/components/Renderer/index.js.map +1 -1
  42. package/lib/components/index.d.ts +3 -2
  43. package/lib/components/index.js +2 -2
  44. package/lib/components/index.js.map +1 -1
  45. package/lib/hooks/index.d.ts +2 -0
  46. package/lib/hooks/index.js +2 -0
  47. package/lib/hooks/index.js.map +1 -1
  48. package/lib/hooks/useBuildForm.d.ts +15 -0
  49. package/lib/hooks/useBuildForm.js +41 -0
  50. package/lib/hooks/useBuildForm.js.map +1 -0
  51. package/lib/hooks/useDisplayCqfAndCalculatedExpression.d.ts +3 -0
  52. package/lib/hooks/useDisplayCqfAndCalculatedExpression.js +40 -0
  53. package/lib/hooks/useDisplayCqfAndCalculatedExpression.js.map +1 -0
  54. package/lib/hooks/useHidden.d.ts +6 -0
  55. package/lib/hooks/useHidden.js +6 -0
  56. package/lib/hooks/useHidden.js.map +1 -1
  57. package/lib/hooks/useInitaliseFhirClient.d.ts +1 -0
  58. package/lib/hooks/useInitaliseFhirClient.js +55 -0
  59. package/lib/hooks/useInitaliseFhirClient.js.map +1 -0
  60. package/lib/hooks/useInitialiseForm.d.ts +20 -0
  61. package/lib/hooks/useInitialiseForm.js +72 -0
  62. package/lib/hooks/useInitialiseForm.js.map +1 -0
  63. package/lib/hooks/useInitialiseRenderer.d.ts +1 -1
  64. package/lib/hooks/useInitialiseRenderer.js +8 -31
  65. package/lib/hooks/useInitialiseRenderer.js.map +1 -1
  66. package/lib/hooks/useRendererQueryClient.d.ts +10 -0
  67. package/lib/hooks/useRendererQueryClient.js +36 -0
  68. package/lib/hooks/useRendererQueryClient.js.map +1 -0
  69. package/lib/hooks/useValueSetCodings.js +1 -0
  70. package/lib/hooks/useValueSetCodings.js.map +1 -1
  71. package/lib/index.d.ts +10 -40
  72. package/lib/index.js +8 -77
  73. package/lib/index.js.map +1 -1
  74. package/lib/interfaces/calculatedExpression.interface.d.ts +7 -0
  75. package/lib/interfaces/calculatedExpression.interface.js +16 -0
  76. package/lib/interfaces/calculatedExpression.interface.js.map +1 -1
  77. package/lib/interfaces/enableWhen.interface.d.ts +12 -0
  78. package/lib/interfaces/index.d.ts +4 -1
  79. package/lib/interfaces/index.js +16 -0
  80. package/lib/interfaces/index.js.map +1 -1
  81. package/lib/interfaces/populate.interface.d.ts +6 -0
  82. package/lib/interfaces/repopulateItems.interface.d.ts +0 -0
  83. package/lib/interfaces/repopulateItems.interface.js +2 -0
  84. package/lib/interfaces/repopulateItems.interface.js.map +1 -0
  85. package/lib/interfaces/tab.interface.d.ts +10 -0
  86. package/lib/interfaces/tab.interface.js +16 -0
  87. package/lib/interfaces/tab.interface.js.map +1 -1
  88. package/lib/interfaces/variables.interface.d.ts +12 -0
  89. package/lib/stores/index.d.ts +4 -0
  90. package/lib/stores/index.js.map +1 -1
  91. package/lib/stores/questionnaireResponseStore.d.ts +37 -2
  92. package/lib/stores/questionnaireResponseStore.js +72 -22
  93. package/lib/stores/questionnaireResponseStore.js.map +1 -1
  94. package/lib/stores/questionnaireStore.d.ts +59 -3
  95. package/lib/stores/questionnaireStore.js +18 -0
  96. package/lib/stores/questionnaireStore.js.map +1 -1
  97. package/lib/stores/smartConfigStore.d.ts +37 -0
  98. package/lib/stores/smartConfigStore.js +21 -0
  99. package/lib/stores/smartConfigStore.js.map +1 -1
  100. package/lib/stores/terminologyServerStore.d.ts +28 -2
  101. package/lib/stores/terminologyServerStore.js +16 -0
  102. package/lib/stores/terminologyServerStore.js.map +1 -1
  103. package/lib/stories/InitialiseFormWrapperForStorybook.d.ts +29 -0
  104. package/lib/stories/InitialiseFormWrapperForStorybook.js +65 -0
  105. package/lib/stories/InitialiseFormWrapperForStorybook.js.map +1 -0
  106. package/lib/stories/StorybookWrappers/BuildFormButtonForStorybook.d.ts +8 -0
  107. package/lib/stories/StorybookWrappers/BuildFormButtonForStorybook.js +44 -0
  108. package/lib/stories/StorybookWrappers/BuildFormButtonForStorybook.js.map +1 -0
  109. package/lib/stories/StorybookWrappers/BuildFormButtonTesterWrapperForStorybook.d.ts +18 -0
  110. package/lib/stories/StorybookWrappers/BuildFormButtonTesterWrapperForStorybook.js +48 -0
  111. package/lib/stories/StorybookWrappers/BuildFormButtonTesterWrapperForStorybook.js.map +1 -0
  112. package/lib/stories/StorybookWrappers/InitialiseFormWrapperForStorybook.d.ts +31 -0
  113. package/lib/stories/StorybookWrappers/InitialiseFormWrapperForStorybook.js +67 -0
  114. package/lib/stories/StorybookWrappers/InitialiseFormWrapperForStorybook.js.map +1 -0
  115. package/lib/stories/StorybookWrappers/PrePopButtonForStorybook.d.ts +7 -0
  116. package/lib/stories/StorybookWrappers/PrePopButtonForStorybook.js +32 -0
  117. package/lib/stories/StorybookWrappers/PrePopButtonForStorybook.js.map +1 -0
  118. package/lib/stories/StorybookWrappers/PrePopWrapperForStorybook.d.ts +21 -0
  119. package/lib/stories/StorybookWrappers/PrePopWrapperForStorybook.js +83 -0
  120. package/lib/stories/StorybookWrappers/PrePopWrapperForStorybook.js.map +1 -0
  121. package/lib/stories/StorybookWrappers/index.d.ts +3 -0
  122. package/lib/stories/StorybookWrappers/index.js +20 -0
  123. package/lib/stories/StorybookWrappers/index.js.map +1 -0
  124. package/lib/stories/StorybookWrappers/populateCallbackForStorybook.d.ts +8 -0
  125. package/lib/stories/StorybookWrappers/populateCallbackForStorybook.js +46 -0
  126. package/lib/stories/StorybookWrappers/populateCallbackForStorybook.js.map +1 -0
  127. package/lib/stories/index.d.ts +1 -0
  128. package/lib/stories/index.js +18 -0
  129. package/lib/stories/index.js.map +1 -0
  130. package/lib/theme/Theme.d.ts +8 -2
  131. package/lib/theme/Theme.js +8 -2
  132. package/lib/theme/Theme.js.map +1 -1
  133. package/lib/theme/index.d.ts +1 -0
  134. package/lib/theme/index.js +2 -0
  135. package/lib/theme/index.js.map +1 -0
  136. package/lib/utils/debounce.d.ts +1 -1
  137. package/lib/utils/debounce.js +1 -1
  138. package/lib/utils/enableWhen.d.ts +1 -1
  139. package/lib/utils/enableWhenExpression.d.ts +1 -1
  140. package/lib/utils/fhirpath.d.ts +1 -1
  141. package/lib/utils/getExpressionsFromItem.js +16 -3
  142. package/lib/utils/getExpressionsFromItem.js.map +1 -1
  143. package/lib/utils/index.d.ts +5 -3
  144. package/lib/utils/index.js +4 -3
  145. package/lib/utils/index.js.map +1 -1
  146. package/lib/utils/initialise.d.ts +2 -2
  147. package/lib/utils/initialise.js +1 -1
  148. package/lib/utils/manageForm.d.ts +45 -0
  149. package/lib/utils/manageForm.js +101 -0
  150. package/lib/utils/manageForm.js.map +1 -0
  151. package/lib/utils/qItem.d.ts +1 -1
  152. package/lib/utils/questionnaireStoreUtils/extractOtherExtensions.d.ts +1 -1
  153. package/lib/utils/removeEmptyAnswers.d.ts +1 -1
  154. package/lib/utils/repopulateIntoResponse.d.ts +6 -0
  155. package/lib/utils/repopulateIntoResponse.js +11 -0
  156. package/lib/utils/repopulateIntoResponse.js.map +1 -1
  157. package/lib/utils/repopulateItems.d.ts +19 -1
  158. package/lib/utils/repopulateItems.js +23 -0
  159. package/lib/utils/repopulateItems.js.map +1 -1
  160. package/lib/utils/tabs.d.ts +2 -2
  161. package/lib/utils/tabs.js +1 -1
  162. package/lib/utils/validateQuestionnaire.d.ts +0 -4
  163. package/lib/utils/validateQuestionnaire.js +9 -5
  164. package/lib/utils/validateQuestionnaire.js.map +1 -1
  165. package/package.json +1 -1
  166. package/src/components/FormComponents/BooleanItem/BooleanField.tsx +11 -9
  167. package/src/components/FormComponents/ChoiceItems/ChoiceRadioAnswerOptionFields.tsx +11 -9
  168. package/src/components/FormComponents/ChoiceItems/ChoiceRadioAnswerValueSetFields.tsx +11 -9
  169. package/src/components/FormComponents/DateTimeItems/index.ts +1 -1
  170. package/src/components/FormComponents/DateTimeItems/utils/parseDate.ts +5 -0
  171. package/src/components/FormComponents/GridGroup/GridGroup.tsx +6 -0
  172. package/src/components/FormComponents/ItemParts/ItemLabelText.tsx +2 -2
  173. package/src/components/FormComponents/RepeatGroup/RepeatGroup.tsx +6 -0
  174. package/src/components/FormComponents/RepeatItem/RepeatItem.tsx +5 -0
  175. package/src/components/FormComponents/SingleItem/SingleItem.tsx +6 -0
  176. package/src/components/FormComponents/Tables/GroupTable.tsx +6 -0
  177. package/src/components/FormComponents/index.ts +6 -6
  178. package/src/components/Renderer/BaseRenderer.tsx +7 -0
  179. package/src/components/Renderer/SmartFormsRenderer.tsx +34 -11
  180. package/src/components/Renderer/index.ts +1 -0
  181. package/src/components/index.ts +10 -2
  182. package/src/hooks/index.ts +2 -0
  183. package/src/hooks/useBuildForm.ts +58 -0
  184. package/src/hooks/{useDisplayCalculatedExpression.ts → useDisplayCqfAndCalculatedExpression.ts} +11 -11
  185. package/src/hooks/useHidden.ts +6 -0
  186. package/src/hooks/useInitialiseForm.ts +93 -0
  187. package/src/hooks/{useQueryClient.ts → useRendererQueryClient.ts} +9 -2
  188. package/src/hooks/useValueSetCodings.ts +1 -0
  189. package/src/index.ts +59 -96
  190. package/src/interfaces/calculatedExpression.interface.ts +24 -0
  191. package/src/interfaces/enableWhen.interface.ts +12 -0
  192. package/src/interfaces/index.ts +21 -10
  193. package/src/interfaces/populate.interface.ts +6 -0
  194. package/src/interfaces/tab.interface.ts +12 -0
  195. package/src/interfaces/variables.interface.ts +12 -0
  196. package/src/stores/index.ts +7 -0
  197. package/src/stores/questionnaireResponseStore.ts +90 -19
  198. package/src/stores/questionnaireStore.ts +62 -2
  199. package/src/stores/smartConfigStore.ts +37 -0
  200. package/src/stores/terminologyServerStore.ts +28 -1
  201. package/src/stories/{BuildFormButtonForStorybook.tsx → StorybookWrappers/BuildFormButtonForStorybook.tsx} +12 -5
  202. package/src/stories/StorybookWrappers/BuildFormButtonTesterWrapperForStorybook.tsx +70 -0
  203. package/src/stories/{BuildFormWrapper.tsx → StorybookWrappers/BuildFormWrapperForStorybook.tsx} +11 -12
  204. package/src/stories/{BuildFormButtonTesterWrapper.tsx → StorybookWrappers/FormValidationTesterWrapperForStorybook.tsx} +22 -19
  205. package/src/stories/{useBuildFormForStorybook.ts → StorybookWrappers/FormValidationViewerForStorybook.tsx} +7 -16
  206. package/src/stories/StorybookWrappers/InitialiseFormWrapperForStorybook.tsx +105 -0
  207. package/src/stories/{PrePopButtonForStorybook.tsx → StorybookWrappers/PrePopButtonForStorybook.tsx} +12 -10
  208. package/src/stories/{PrePopWrapper.tsx → StorybookWrappers/PrePopWrapperForStorybook.tsx} +22 -14
  209. package/src/stories/StorybookWrappers/ValidateFormButtonForStorybook.tsx +41 -0
  210. package/src/stories/StorybookWrappers/index.ts +20 -0
  211. package/src/stories/{populateCallbackForStorybook.ts → StorybookWrappers/populateCallbackForStorybook.ts} +8 -2
  212. package/src/stories/assets/questionnaires/QButtonTester.ts +380 -0
  213. package/src/stories/assets/questionnaires/QDisplay.ts +77 -0
  214. package/src/stories/assets/questionnaires/QValidateTester.ts +118 -0
  215. package/src/stories/assets/questionnaires/index.ts +0 -2
  216. package/src/stories/itemTypes/Attachment.stories.tsx +3 -3
  217. package/src/stories/itemTypes/Boolean.stories.tsx +3 -3
  218. package/src/stories/itemTypes/Choice.stories.tsx +3 -3
  219. package/src/stories/itemTypes/Date.stories.tsx +3 -3
  220. package/src/stories/itemTypes/DateTime.stories.tsx +3 -3
  221. package/src/stories/itemTypes/Decimal.stories.tsx +3 -3
  222. package/src/stories/itemTypes/Display.stories.tsx +10 -4
  223. package/src/stories/itemTypes/Group.stories.tsx +3 -3
  224. package/src/stories/itemTypes/Integer.stories.tsx +3 -3
  225. package/src/stories/itemTypes/OpenChoice.stories.tsx +3 -3
  226. package/src/stories/itemTypes/Quantity.stories.tsx +3 -3
  227. package/src/stories/itemTypes/Reference.stories.tsx +3 -3
  228. package/src/stories/itemTypes/String.stories.tsx +3 -3
  229. package/src/stories/itemTypes/Text.stories.tsx +3 -3
  230. package/src/stories/itemTypes/Time.stories.tsx +3 -3
  231. package/src/stories/itemTypes/Url.stories.tsx +3 -3
  232. package/src/stories/sdc/AdvancedAdditionalDisplayContent.stories.tsx +3 -3
  233. package/src/stories/sdc/AdvancedControlAppearance.stories.tsx +3 -3
  234. package/src/stories/sdc/AdvancedOther.stories.tsx +3 -3
  235. package/src/stories/sdc/AdvancedTextAppearance.stories.tsx +3 -3
  236. package/src/stories/sdc/BehaviorCalculations.stories.tsx +3 -3
  237. package/src/stories/sdc/BehaviorChoiceRestriction.stories.tsx +3 -3
  238. package/src/stories/sdc/BehaviorOther.stories.tsx +3 -3
  239. package/src/stories/sdc/BehaviorValueConstraints.stories.tsx +3 -3
  240. package/src/stories/sdc/FormPopulation.stories.tsx +3 -3
  241. package/src/stories/sdc/ItemControlDisplay.stories.tsx +3 -3
  242. package/src/stories/sdc/ItemControlGroup.stories.tsx +3 -3
  243. package/src/stories/sdc/ItemControlQuestion.stories.tsx +3 -3
  244. package/src/stories/{rebuildForm/BuildFormTesterWrapper.stories.tsx → testing/BuildFormButtonTesterWrapper.stories.tsx} +6 -9
  245. package/src/stories/testing/PrePopButtonTesterWrapper.stories.tsx +45 -0
  246. package/src/stories/testing/ValidateFormTesterWrapper.stories.tsx +39 -0
  247. package/src/tests/enableWhen.test.ts +6 -2
  248. package/src/theme/Theme.tsx +8 -2
  249. package/src/theme/index.ts +1 -0
  250. package/src/utils/debounce.ts +1 -1
  251. package/src/utils/enableWhen.ts +1 -1
  252. package/src/utils/enableWhenExpression.ts +1 -1
  253. package/src/utils/fhirpath.ts +1 -1
  254. package/src/utils/getExpressionsFromItem.ts +16 -4
  255. package/src/utils/index.ts +5 -7
  256. package/src/utils/initialise.ts +2 -2
  257. package/src/utils/manageForm.ts +110 -0
  258. package/src/utils/qItem.ts +1 -1
  259. package/src/utils/questionnaireStoreUtils/extractOtherExtensions.ts +1 -1
  260. package/src/utils/removeEmptyAnswers.ts +1 -1
  261. package/src/utils/repopulateIntoResponse.ts +17 -0
  262. package/src/utils/repopulateItems.ts +38 -1
  263. package/src/utils/tabs.ts +2 -2
  264. package/src/utils/validateQuestionnaire.ts +12 -17
  265. package/vite.config.ts +1 -1
  266. package/src/hooks/useInitialiseRenderer.ts +0 -114
  267. package/src/stories/assets/questionnaires/QBuildFormButtonTester.ts +0 -270
  268. package/src/stories/populateUtilsForStorybook.ts +0 -545
  269. package/src/utils/buildForm.ts +0 -23
  270. package/storybook.log +0 -6
  271. /package/.storybook/{preview.ts → preview.tsx} +0 -0
@@ -31,7 +31,28 @@ import { validateQuestionnaire } from '../utils/validateQuestionnaire';
31
31
  import { questionnaireStore } from './questionnaireStore';
32
32
  import { createQuestionnaireResponseItemMap } from '../utils/questionnaireResponseStoreUtils/updatableResponseItems';
33
33
 
34
- interface QuestionnaireResponseStoreType {
34
+ /**
35
+ * QuestionnaireResponseStore properties and methods
36
+ * Properties can be accessed for fine-grain details.
37
+ * Methods are usually used internally, using them from an external source is not recommended.
38
+ *
39
+ * @property sourceResponse - The original response created when the form is first initialised i.e. empty, pre-populated, opened saved draft
40
+ * @property updatableResponse - The current state of the response that is being updated via form fields
41
+ * @property updatableResponseItems - Key-value pair of updatableResponse items `Record<linkId, QR.item(s)>`
42
+ * @property formChangesHistory - Array of form changes history in the form of deep-diff objects
43
+ * @property invalidItems - Key-value pair of invalid items based on defined value constraints in the questionnaire `Record<linkId, OperationOutcome>`
44
+ * @property responseIsValid - Whether there are any invalid items in the response
45
+ * @method validateQuestionnaire - Used to validate the questionnaire response based on the questionnaire
46
+ * @method buildSourceResponse - Used to build the source response when the form is first initialised
47
+ * @method setUpdatableResponseAsPopulated - Used to set a pre-populated response as the current response
48
+ * @method updateResponse - Used to update the current response
49
+ * @method setUpdatableResponseAsSaved - Used to set a saved response as the current response
50
+ * @method setUpdatableResponseAsEmpty - Used to set an empty response as the current response
51
+ * @method destroySourceResponse - Used to destroy the source response and reset all properties
52
+ *
53
+ * @author Sean Fong
54
+ */
55
+ export interface QuestionnaireResponseStoreType {
35
56
  sourceResponse: QuestionnaireResponse;
36
57
  updatableResponse: QuestionnaireResponse;
37
58
  updatableResponseItems: Record<string, QuestionnaireResponseItem[]>;
@@ -50,6 +71,13 @@ interface QuestionnaireResponseStoreType {
50
71
  destroySourceResponse: () => void;
51
72
  }
52
73
 
74
+ /**
75
+ * QuestionnaireResponse state management store which contains all properties and methods to manage the state of the questionnaireResponse.
76
+ * This is the vanilla version of the store which can be used in non-React environments.
77
+ * @see {QuestionnaireResponseStoreType} for available properties and methods.
78
+ *
79
+ * @author Sean Fong
80
+ */
53
81
  export const questionnaireResponseStore = createStore<QuestionnaireResponseStoreType>()(
54
82
  (set, get) => ({
55
83
  sourceResponse: cloneDeep(emptyResponse),
@@ -62,16 +90,9 @@ export const questionnaireResponseStore = createStore<QuestionnaireResponseStore
62
90
  questionnaire: Questionnaire,
63
91
  updatedResponse: QuestionnaireResponse
64
92
  ) => {
65
- const enableWhenIsActivated = questionnaireStore.getState().enableWhenIsActivated;
66
- const enableWhenItems = questionnaireStore.getState().enableWhenItems;
67
- const enableWhenExpressions = questionnaireStore.getState().enableWhenExpressions;
68
-
69
93
  const updatedInvalidItems = validateQuestionnaire({
70
94
  questionnaire,
71
- questionnaireResponse: updatedResponse,
72
- enableWhenIsActivated,
73
- enableWhenItems,
74
- enableWhenExpressions
95
+ questionnaireResponse: updatedResponse
75
96
  });
76
97
 
77
98
  set(() => ({
@@ -80,49 +101,99 @@ export const questionnaireResponseStore = createStore<QuestionnaireResponseStore
80
101
  }));
81
102
  },
82
103
  buildSourceResponse: (questionnaireResponse: QuestionnaireResponse) => {
104
+ const sourceQuestionnaire = questionnaireStore.getState().sourceQuestionnaire;
105
+ const initialInvalidItems = validateQuestionnaire({
106
+ questionnaire: sourceQuestionnaire,
107
+ questionnaireResponse: questionnaireResponse
108
+ });
109
+
83
110
  set(() => ({
84
111
  sourceResponse: questionnaireResponse,
85
112
  updatableResponse: questionnaireResponse,
86
- updatableResponseItems: createQuestionnaireResponseItemMap(questionnaireResponse)
113
+ updatableResponseItems: createQuestionnaireResponseItemMap(questionnaireResponse),
114
+ invalidItems: initialInvalidItems,
115
+ responseIsValid: Object.keys(initialInvalidItems).length === 0
87
116
  }));
88
117
  },
89
118
  setUpdatableResponseAsPopulated: (populatedResponse: QuestionnaireResponse) => {
119
+ const sourceQuestionnaire = questionnaireStore.getState().sourceQuestionnaire;
90
120
  const formChanges = diff(get().updatableResponse, populatedResponse) ?? null;
121
+ const updatedInvalidItems = validateQuestionnaire({
122
+ questionnaire: sourceQuestionnaire,
123
+ questionnaireResponse: populatedResponse
124
+ });
91
125
  set(() => ({
92
126
  updatableResponse: populatedResponse,
93
127
  updatableResponseItems: createQuestionnaireResponseItemMap(populatedResponse),
94
- formChangesHistory: [...get().formChangesHistory, formChanges]
128
+ formChangesHistory: [...get().formChangesHistory, formChanges],
129
+ invalidItems: updatedInvalidItems,
130
+ responseIsValid: Object.keys(updatedInvalidItems).length === 0
95
131
  }));
96
132
  },
97
133
  updateResponse: (updatedResponse: QuestionnaireResponse) => {
134
+ const sourceQuestionnaire = questionnaireStore.getState().sourceQuestionnaire;
98
135
  const formChanges = diff(get().updatableResponse, updatedResponse) ?? null;
136
+ const updatedInvalidItems = validateQuestionnaire({
137
+ questionnaire: sourceQuestionnaire,
138
+ questionnaireResponse: updatedResponse
139
+ });
99
140
  set(() => ({
100
141
  updatableResponse: updatedResponse,
101
142
  updatableResponseItems: createQuestionnaireResponseItemMap(updatedResponse),
102
- formChangesHistory: [...get().formChangesHistory, formChanges]
143
+ formChangesHistory: [...get().formChangesHistory, formChanges],
144
+ invalidItems: updatedInvalidItems,
145
+ responseIsValid: Object.keys(updatedInvalidItems).length === 0
103
146
  }));
104
147
  },
105
- setUpdatableResponseAsSaved: (savedResponse: QuestionnaireResponse) =>
148
+ setUpdatableResponseAsSaved: (savedResponse: QuestionnaireResponse) => {
149
+ const sourceQuestionnaire = questionnaireStore.getState().sourceQuestionnaire;
150
+ const updatedInvalidItems = validateQuestionnaire({
151
+ questionnaire: sourceQuestionnaire,
152
+ questionnaireResponse: savedResponse
153
+ });
154
+
106
155
  set(() => ({
107
156
  sourceResponse: savedResponse,
108
157
  updatableResponse: savedResponse,
109
158
  updatableResponseItems: createQuestionnaireResponseItemMap(savedResponse),
110
- formChangesHistory: []
111
- })),
112
- setUpdatableResponseAsEmpty: (clearedResponse: QuestionnaireResponse) =>
159
+ formChangesHistory: [],
160
+ invalidItems: updatedInvalidItems,
161
+ responseIsValid: Object.keys(updatedInvalidItems).length === 0
162
+ }));
163
+ },
164
+ setUpdatableResponseAsEmpty: (clearedResponse: QuestionnaireResponse) => {
165
+ const sourceQuestionnaire = questionnaireStore.getState().sourceQuestionnaire;
166
+ const updatedInvalidItems = validateQuestionnaire({
167
+ questionnaire: sourceQuestionnaire,
168
+ questionnaireResponse: clearedResponse
169
+ });
170
+
113
171
  set(() => ({
114
172
  updatableResponse: clearedResponse,
115
173
  updatableResponseItems: createQuestionnaireResponseItemMap(clearedResponse),
116
- formChangesHistory: []
117
- })),
174
+ formChangesHistory: [],
175
+ invalidItems: updatedInvalidItems,
176
+ responseIsValid: Object.keys(updatedInvalidItems).length === 0
177
+ }));
178
+ },
118
179
  destroySourceResponse: () =>
119
180
  set(() => ({
120
181
  sourceResponse: cloneDeep(emptyResponse),
121
182
  updatableResponse: cloneDeep(emptyResponse),
122
183
  updatableResponseItems: createQuestionnaireResponseItemMap(cloneDeep(emptyResponse)),
123
- formChangesHistory: []
184
+ formChangesHistory: [],
185
+ invalidItems: {},
186
+ responseIsValid: true
124
187
  }))
125
188
  })
126
189
  );
127
190
 
191
+ /**
192
+ * QuestionnaireResponse state management store which contains all properties and methods to manage the state of the questionnaire.
193
+ * This is the React version of the store which can be used as React hooks in React functional components.
194
+ * @see {QuestionnaireResponseStoreType} for available properties and methods.
195
+ * @see {questionnaireResponseStore} for the vanilla store.
196
+ *
197
+ * @author Sean Fong
198
+ */
128
199
  export const useQuestionnaireResponseStore = createSelectors(questionnaireResponseStore);
@@ -25,7 +25,7 @@ import type {
25
25
  import type { Variables } from '../interfaces/variables.interface';
26
26
  import type { LaunchContext } from '../interfaces/populate.interface';
27
27
  import type { CalculatedExpression } from '../interfaces/calculatedExpression.interface';
28
- import type { EnableWhenExpressions, EnableWhenItems } from '../interfaces';
28
+ import type { EnableWhenExpressions, EnableWhenItems } from '../interfaces/enableWhen.interface';
29
29
  import type { AnswerExpression } from '../interfaces/answerExpression.interface';
30
30
  import type { Tabs } from '../interfaces/tab.interface';
31
31
  import {
@@ -47,7 +47,47 @@ import { mutateRepeatEnableWhenExpressionInstances } from '../utils/enableWhenEx
47
47
  import { questionnaireResponseStore } from './questionnaireResponseStore';
48
48
  import { createQuestionnaireResponseItemMap } from '../utils/questionnaireResponseStoreUtils/updatableResponseItems';
49
49
 
50
- interface QuestionnaireStoreType {
50
+ /**
51
+ * QuestionnaireStore properties and methods
52
+ * Properties can be accessed for fine-grain details.
53
+ * Methods are usually used internally, using them from an external source is not recommended.
54
+ *
55
+ * @property sourceQuestionnaire - FHIR R4 Questionnaire to render
56
+ * @property itemTypes - Key-value pair of item types `Record<linkId, item.type>`
57
+ * @property tabs - Key-value pair of tabs `Record<linkId, Tab>`
58
+ * @property currentTabIndex - Index of the current tab
59
+ * @property variables - Questionnaire variables object containing FHIRPath and x-fhir-query variables
60
+ * @property launchContexts - Key-value pair of launch contexts `Record<launch context name, launch context properties>`
61
+ * @property enableWhenItems - EnableWhenItems object containing enableWhen items and their linked questions
62
+ * @property enableWhenLinkedQuestions - Key-value pair of linked questions to enableWhen items `Record<linkId, linkIds of linked questions>`
63
+ * @property enableWhenIsActivated - Flag to turn enableWhen checks on/off
64
+ * @property enableWhenExpressions - EnableWhenExpressions object containing enableWhen expressions
65
+ * @property calculatedExpressions - Key-value pair of calculated expressions `Record<linkId, array of calculated expression properties>`
66
+ * @property answerExpressions - Key-value pair of answer expressions `Record<linkId, answer expression properties>`
67
+ * @property processedValueSetCodings - Key-value pair of processed value set codings `Record<valueSetUrl, codings>`
68
+ * @property processedValueSetUrls - Key-value pair of contained value set urls `Record<valueSetName, valueSetUrl>`
69
+ * @property cachedValueSetCodings - Key-value pair of cached value set codings `Record<valueSetUrl, codings>`
70
+ * @property fhirPathContext - Key-value pair of evaluated FHIRPath values `Record<variable name, evaluated value(s)>`
71
+ * @property populatedContext - Key-value pair of one-off pre-populated FHIRPath values `Record<variable/launchContext/sourceQueries batch name, evaluated value(s)>`
72
+ * @property focusedLinkId - LinkId of the currently focused item
73
+ * @property readOnly - Flag to set the form to read-only mode
74
+ * @method buildSourceQuestionnaire - Used to build the source questionnaire with the provided questionnaire and optionally questionnaire response, additional variables, terminology server url and readyOnly flag
75
+ * @method destroySourceQuestionnaire - Used to destroy the source questionnaire and reset all properties
76
+ * @method switchTab - Used to switch the current tab index
77
+ * @method markTabAsComplete - Used to mark a tab index as complete
78
+ * @method updateEnableWhenItem - Used to update linked enableWhen items by updating a question with a new answer
79
+ * @method mutateRepeatEnableWhenItems - Used to add or remove instances of repeating enableWhen items
80
+ * @method toggleEnableWhenActivation - Used to toggle enableWhen checks on/off
81
+ * @method updateExpressions - Used to update all SDC expressions based on the updated questionnaire response
82
+ * @method addCodingToCache - Used to add a coding to the cached value set codings
83
+ * @method updatePopulatedProperties - Used to update all SDC expressions based on a pre-populated questionnaire response
84
+ * @method onFocusLinkId - Used to set the focused linkId
85
+ * @method setPopulatedContext - Used to set the populated contexts (launchContext, sourceQueries, x-fhir-query vars) for debugging purposes
86
+ * @method setFormAsReadOnly - Used to set the form as read-only
87
+ *
88
+ * @author Sean Fong
89
+ */
90
+ export interface QuestionnaireStoreType {
51
91
  sourceQuestionnaire: Questionnaire;
52
92
  itemTypes: Record<string, string>;
53
93
  tabs: Tabs;
@@ -97,8 +137,16 @@ interface QuestionnaireStoreType {
97
137
  ) => QuestionnaireResponse;
98
138
  onFocusLinkId: (linkId: string) => void;
99
139
  setPopulatedContext: (newPopulatedContext: Record<string, any>) => void;
140
+ setFormAsReadOnly: (readOnly: boolean) => void;
100
141
  }
101
142
 
143
+ /**
144
+ * Questionnaire state management store which contains all properties and methods to manage the state of the questionnaire.
145
+ * This is the vanilla version of the store which can be used in non-React environments.
146
+ * @see {QuestionnaireStoreType} for available properties and methods.
147
+ *
148
+ * @author Sean Fong
149
+ */
102
150
  export const questionnaireStore = createStore<QuestionnaireStoreType>()((set, get) => ({
103
151
  sourceQuestionnaire: cloneDeep(emptyQuestionnaire),
104
152
  itemTypes: {},
@@ -349,7 +397,19 @@ export const questionnaireStore = createStore<QuestionnaireStoreType>()((set, ge
349
397
  setPopulatedContext: (newPopulatedContext: Record<string, any>) =>
350
398
  set(() => ({
351
399
  populatedContext: newPopulatedContext
400
+ })),
401
+ setFormAsReadOnly: (readOnly: boolean) =>
402
+ set(() => ({
403
+ readOnly: readOnly
352
404
  }))
353
405
  }));
354
406
 
407
+ /**
408
+ * Questionnaire state management store which contains all properties and methods to manage the state of the questionnaire.
409
+ * This is the React version of the store which can be used as React hooks in React functional components.
410
+ * @see {QuestionnaireStoreType} for available properties and methods.
411
+ * @see {questionnaireStore} for the vanilla store.
412
+ *
413
+ * @author Sean Fong
414
+ */
355
415
  export const useQuestionnaireStore = createSelectors(questionnaireStore);
@@ -20,6 +20,22 @@ import type { Encounter, Patient, Practitioner } from 'fhir/r4';
20
20
  import type Client from 'fhirclient/lib/Client';
21
21
  import { createSelectors } from './selector';
22
22
 
23
+ /**
24
+ * SmartConfigStore 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 client - The FHIRClient object (https://github.com/smart-on-fhir/client-js)
29
+ * @property patient - The patient resource in context
30
+ * @property user - The user resource in context
31
+ * @property encounter - The encounter resource in context
32
+ * @method setClient - Set the FHIRClient object when launching via SMART App Launch
33
+ * @method setPatient - Set the patient resource in context
34
+ * @method setUser - Set the user resource in context
35
+ * @method setEncounter - Set the encounter resource in context
36
+ *
37
+ * @author Sean Fong
38
+ */
23
39
  export interface SmartConfigStoreType {
24
40
  client: Client | null;
25
41
  patient: Patient | null;
@@ -31,6 +47,16 @@ export interface SmartConfigStoreType {
31
47
  setEncounter: (encounter: Encounter) => void;
32
48
  }
33
49
 
50
+ /**
51
+ * Smart Config state management store. This is only used for answerExpressions.
52
+ * It is recommended to manage the state of the FHIRClient, patient, user, and encounter in the parent application, since the renderer doesn't provide pre-population capabilities.
53
+ * Will be deprecated in version 1.0.0.
54
+ *
55
+ * This is the vanilla version of the store which can be used in non-React environments.
56
+ * @see {SmartConfigStoreType} for available properties and methods.
57
+ *
58
+ * @author Sean Fong
59
+ */
34
60
  export const smartConfigStore = createStore<SmartConfigStoreType>()((set) => ({
35
61
  client: null,
36
62
  patient: null,
@@ -42,4 +68,15 @@ export const smartConfigStore = createStore<SmartConfigStoreType>()((set) => ({
42
68
  setEncounter: (encounter: Encounter) => set(() => ({ encounter: encounter }))
43
69
  }));
44
70
 
71
+ /**
72
+ * Smart Config state management store. This is only used for answerExpressions.
73
+ * It is recommended to manage the state of the FHIRClient, patient, user, and encounter in the parent application, since the renderer doesn't provide pre-population capabilities.
74
+ * Will be deprecated in version 1.0.0.
75
+ *
76
+ * This is the React version of the store which can be used as React hooks in React functional components.
77
+ * @see {SmartConfigStoreType} for available properties and methods.
78
+ * @see {smartConfigStore} for the vanilla store.
79
+ *
80
+ * @author Sean Fong
81
+ */
45
82
  export const useSmartConfigStore = createSelectors(smartConfigStore);
@@ -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;