@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
@@ -1,545 +0,0 @@
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
- import type {
19
- Coding,
20
- Expression,
21
- Extension,
22
- FhirResource,
23
- OperationOutcome,
24
- Parameters,
25
- ParametersParameter,
26
- Patient,
27
- Practitioner,
28
- Questionnaire,
29
- QuestionnaireResponse,
30
- Reference
31
- } from 'fhir/r4';
32
- import type {
33
- InputParameters,
34
- IssuesParameter,
35
- OutputParameters,
36
- ResponseParameter
37
- } from '@aehrc/sdc-populate';
38
- import { isInputParameters, isOutputParameters, populate } from '@aehrc/sdc-populate';
39
- import type { RequestConfig } from './populateCallbackForStorybook';
40
- import { fetchResourceCallback } from './populateCallbackForStorybook';
41
-
42
- export interface PopulateResult {
43
- populated: QuestionnaireResponse;
44
- hasWarnings: boolean;
45
- }
46
-
47
- export async function populateQuestionnaire(
48
- questionnaire: Questionnaire,
49
- patient: Patient,
50
- user: Practitioner,
51
- requestConfig: RequestConfig
52
- ): Promise<{
53
- populateSuccess: boolean;
54
- populateResult: PopulateResult | null;
55
- }> {
56
- const fhirPathContext: Record<string, any> = {};
57
-
58
- // Get launch contexts, source queries and questionnaire-level variables
59
- const launchContexts = getLaunchContexts(questionnaire);
60
- const sourceQueries = getSourceQueries(questionnaire);
61
- const questionnaireLevelVariables = getQuestionnaireLevelXFhirQueryVariables(questionnaire);
62
-
63
- if (
64
- launchContexts.length === 0 &&
65
- sourceQueries.length === 0 &&
66
- questionnaireLevelVariables.length === 0
67
- ) {
68
- return {
69
- populateSuccess: false,
70
- populateResult: null
71
- };
72
- }
73
-
74
- // Define population input parameters from launch contexts, source queries and questionnaire-level variables
75
- const inputParameters = createPopulateInputParameters(
76
- questionnaire,
77
- patient,
78
- user,
79
- launchContexts,
80
- sourceQueries,
81
- questionnaireLevelVariables,
82
- fhirPathContext
83
- );
84
-
85
- if (!inputParameters) {
86
- return {
87
- populateSuccess: false,
88
- populateResult: null
89
- };
90
- }
91
-
92
- if (!isInputParameters(inputParameters)) {
93
- return {
94
- populateSuccess: false,
95
- populateResult: null
96
- };
97
- }
98
-
99
- // Perform population if parameters satisfies input parameters
100
- const outputParameters = await requestPopulate(inputParameters, requestConfig);
101
-
102
- if (outputParameters.resourceType === 'OperationOutcome') {
103
- return {
104
- populateSuccess: false,
105
- populateResult: null
106
- };
107
- }
108
-
109
- const responseParameter = outputParameters.parameter.find(
110
- (param) => param.name === 'response'
111
- ) as ResponseParameter;
112
- const issuesParameter = outputParameters.parameter.find((param) => param.name === 'issues') as
113
- | IssuesParameter
114
- | undefined;
115
-
116
- if (issuesParameter) {
117
- for (const issue of issuesParameter.resource.issue) {
118
- if (issue.details?.text) {
119
- console.warn(issue.details.text);
120
- }
121
- }
122
- return {
123
- populateSuccess: true,
124
- populateResult: {
125
- populated: responseParameter.resource,
126
- hasWarnings: true
127
- }
128
- };
129
- }
130
-
131
- return {
132
- populateSuccess: true,
133
- populateResult: {
134
- populated: responseParameter.resource,
135
- hasWarnings: false
136
- }
137
- };
138
- }
139
-
140
- async function requestPopulate(
141
- inputParameters: InputParameters,
142
- requestConfig: RequestConfig
143
- ): Promise<OutputParameters | OperationOutcome> {
144
- const populatePromise = populate(inputParameters, fetchResourceCallback, requestConfig);
145
-
146
- try {
147
- const promiseResult = await addTimeoutToPromise(populatePromise, 10000);
148
-
149
- if (promiseResult.timeout) {
150
- return {
151
- resourceType: 'OperationOutcome',
152
- issue: [
153
- {
154
- severity: 'error',
155
- code: 'timeout',
156
- details: { text: '$populate operation timed out.' }
157
- }
158
- ]
159
- };
160
- }
161
-
162
- if (isOutputParameters(promiseResult)) {
163
- return promiseResult;
164
- }
165
-
166
- return {
167
- resourceType: 'OperationOutcome',
168
- issue: [
169
- {
170
- severity: 'error',
171
- code: 'invalid',
172
- details: {
173
- text: 'Output parameters do not match the specification.'
174
- }
175
- }
176
- ]
177
- };
178
- } catch (error) {
179
- console.error('Error:', error);
180
- return {
181
- resourceType: 'OperationOutcome',
182
- issue: [
183
- {
184
- severity: 'error',
185
- code: 'unknown',
186
- details: { text: 'An unknown error occurred.' }
187
- }
188
- ]
189
- };
190
- }
191
- }
192
-
193
- async function addTimeoutToPromise(promise: Promise<any>, timeoutMs: number) {
194
- const timeoutPromise = new Promise((_, reject) => {
195
- setTimeout(() => {
196
- reject(new Error(`Promise timed out after ${timeoutMs} milliseconds`));
197
- }, timeoutMs);
198
- });
199
-
200
- // Use Promise.race to wait for either the original promise or the timeout promise
201
- return Promise.race([promise, timeoutPromise]);
202
- }
203
-
204
- function isLaunchContext(extension: Extension): extension is LaunchContext {
205
- const hasLaunchContextName =
206
- extension.url ===
207
- 'http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-launchContext' &&
208
- !!extension.extension?.find(
209
- (ext) =>
210
- ext.url === 'name' &&
211
- (ext.valueId ||
212
- (ext.valueCoding &&
213
- (ext.valueCoding.code === 'patient' ||
214
- ext.valueCoding.code === 'encounter' ||
215
- ext.valueCoding.code === 'location' ||
216
- ext.valueCoding.code === 'user' ||
217
- ext.valueCoding.code === 'study' ||
218
- ext.valueCoding.code === 'sourceQueries')))
219
- );
220
-
221
- const hasLaunchContextType = !!extension.extension?.find(
222
- (ext) =>
223
- ext.url === 'type' &&
224
- ext.valueCode &&
225
- (ext.valueCode === 'Patient' ||
226
- ext.valueCode === 'Practitioner' ||
227
- ext.valueCode === 'Encounter')
228
- );
229
-
230
- return (
231
- extension.url ===
232
- 'http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-launchContext' &&
233
- hasLaunchContextName &&
234
- hasLaunchContextType
235
- );
236
- }
237
-
238
- function getLaunchContexts(questionnaire: Questionnaire): LaunchContext[] {
239
- if (questionnaire.extension && questionnaire.extension.length > 0) {
240
- return questionnaire.extension.filter((extension) =>
241
- isLaunchContext(extension)
242
- ) as LaunchContext[];
243
- }
244
-
245
- return [];
246
- }
247
-
248
- function isSourceQuery(extension: Extension): extension is SourceQuery {
249
- return (
250
- extension.url ===
251
- 'http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-sourceQueries' &&
252
- !!extension.valueReference
253
- );
254
- }
255
-
256
- function getSourceQueries(questionnaire: Questionnaire): SourceQuery[] {
257
- if (questionnaire.extension && questionnaire.extension.length > 0) {
258
- return questionnaire.extension.filter((extension) => isSourceQuery(extension)) as SourceQuery[];
259
- }
260
-
261
- return [];
262
- }
263
-
264
- function isXFhirQueryVariable(
265
- extension: Extension
266
- ): extension is QuestionnaireLevelXFhirQueryVariable {
267
- return (
268
- extension.url === 'http://hl7.org/fhir/StructureDefinition/variable' &&
269
- !!extension.valueExpression?.name &&
270
- extension.valueExpression?.language === 'application/x-fhir-query' &&
271
- !!extension.valueExpression?.expression
272
- );
273
- }
274
-
275
- function getQuestionnaireLevelXFhirQueryVariables(
276
- questionnaire: Questionnaire
277
- ): QuestionnaireLevelXFhirQueryVariable[] {
278
- if (questionnaire.extension && questionnaire.extension.length > 0) {
279
- return questionnaire.extension.filter((extension) =>
280
- isXFhirQueryVariable(extension)
281
- ) as QuestionnaireLevelXFhirQueryVariable[];
282
- }
283
-
284
- return [];
285
- }
286
-
287
- // PopulateInputParameter private functions
288
- function createPopulateInputParameters(
289
- questionnaire: Questionnaire,
290
- patient: Patient,
291
- user: Practitioner,
292
- launchContexts: LaunchContext[],
293
- sourceQueries: SourceQuery[],
294
- questionnaireLevelVariables: QuestionnaireLevelXFhirQueryVariable[],
295
- fhirPathContext: Record<string, any>
296
- ): Parameters | null {
297
- const patientSubject = createPatientSubject(questionnaire, patient);
298
- if (!patientSubject) {
299
- return null;
300
- }
301
-
302
- const inputParameters: Parameters = {
303
- resourceType: 'Parameters',
304
- parameter: [
305
- {
306
- name: 'questionnaire',
307
- resource: questionnaire
308
- },
309
- {
310
- name: 'subject',
311
- valueReference: patientSubject
312
- }
313
- ]
314
- };
315
-
316
- // canonical
317
- if (questionnaire.url) {
318
- inputParameters.parameter?.push(createCanonicalParam(questionnaire.url));
319
- }
320
-
321
- // contexts
322
- const contexts: ParametersParameter[] = [];
323
- // add launch contexts
324
- if (launchContexts.length > 0) {
325
- for (const launchContext of launchContexts) {
326
- const launchContextParam = createLaunchContextParam(
327
- launchContext,
328
- patient,
329
- user,
330
- fhirPathContext
331
- );
332
- if (launchContextParam) {
333
- contexts.push(launchContextParam);
334
- }
335
- }
336
- }
337
-
338
- // add source queries
339
- if (sourceQueries.length > 0) {
340
- for (let index = 0; index < sourceQueries.length; index++) {
341
- const sourceQuery = sourceQueries[index];
342
- contexts.push(createSourceQueryParams(sourceQuery, index));
343
- }
344
- }
345
-
346
- // add questionnaire-level variables
347
- if (questionnaireLevelVariables.length > 0) {
348
- for (const variable of questionnaireLevelVariables) {
349
- contexts.push(createVariableParam(variable));
350
- }
351
- }
352
-
353
- if (contexts.length > 0) {
354
- inputParameters.parameter?.push(...contexts);
355
- }
356
-
357
- // local
358
- inputParameters.parameter?.push(createLocalParam());
359
-
360
- return inputParameters;
361
- }
362
-
363
- function createPatientSubject(questionnaire: Questionnaire, patient: Patient): Reference | null {
364
- const subjectTypes = questionnaire.subjectType;
365
-
366
- // If subjectTypes array is not empty AND "Patient" is not in the array, we cannot create a Patient subject reference.
367
- if (subjectTypes && subjectTypes.length > 0) {
368
- const patientSubject = subjectTypes.find((subject) => subject === 'Patient');
369
- if (!patientSubject) {
370
- return null;
371
- }
372
- }
373
-
374
- return {
375
- type: 'Patient',
376
- reference: 'Patient/' + patient.id
377
- };
378
- }
379
-
380
- function createCanonicalParam(canonicalUrl: string): ParametersParameter {
381
- return {
382
- name: 'canonical',
383
- valueString: canonicalUrl
384
- };
385
- }
386
-
387
- // setting local parameter as false as we are calling $populate with an NPM package, not a server
388
- // package doesn't contain any fhir resources to "know" the context from
389
- function createLocalParam(): ParametersParameter {
390
- return {
391
- name: 'local',
392
- valueBoolean: false
393
- };
394
- }
395
-
396
- function createLaunchContextParam(
397
- launchContext: LaunchContext,
398
- patient: Patient,
399
- user: Practitioner,
400
- fhirPathContext: Record<string, any>
401
- ): ParametersParameter | null {
402
- const name = launchContext.extension[0].valueId ?? launchContext.extension[0].valueCoding?.code;
403
- if (!name) {
404
- return null;
405
- }
406
-
407
- const resourceType = launchContext.extension[1].valueCode;
408
- let resource: FhirResource | null;
409
- if (name === 'patient' && resourceType === 'Patient') {
410
- resource = patient;
411
- } else if (name === 'user' && resourceType === 'Practitioner') {
412
- resource = user;
413
- } else {
414
- return null;
415
- }
416
-
417
- if (!resource) {
418
- return null;
419
- }
420
-
421
- // Update fhirPathContext with launchContext resources
422
- fhirPathContext[name] = resource;
423
-
424
- return {
425
- name: 'context',
426
- part: [
427
- {
428
- name: 'name',
429
- valueString: name
430
- },
431
- {
432
- name: 'content',
433
- resource: resource
434
- }
435
- ]
436
- };
437
- }
438
-
439
- function createSourceQueryParams(sourceQuery: SourceQuery, index: number): ParametersParameter {
440
- const reference = sourceQuery.valueReference.reference;
441
- if (reference && reference.startsWith('#')) {
442
- const containedReference = reference.slice(1);
443
- return {
444
- name: 'context',
445
- part: [
446
- {
447
- name: 'name',
448
- valueString: containedReference
449
- },
450
- {
451
- name: 'content',
452
- valueReference: sourceQuery.valueReference
453
- }
454
- ]
455
- };
456
- }
457
-
458
- // if sourceQuery cannot be referenced to a contained bundle, return itself as a context
459
- // this most likely shouldn't happen
460
- return {
461
- name: 'context',
462
- part: [
463
- {
464
- name: 'name',
465
- valueString: `sourceQuery${index}`
466
- },
467
- {
468
- name: 'content',
469
- valueReference: sourceQuery.valueReference
470
- }
471
- ]
472
- };
473
- }
474
-
475
- function createVariableParam(variable: QuestionnaireLevelXFhirQueryVariable): ParametersParameter {
476
- const query = variable.valueExpression.expression;
477
- const resourceType = query.split('?')[0];
478
-
479
- return {
480
- name: 'context',
481
- part: [
482
- {
483
- name: 'name',
484
- valueString: variable.valueExpression.name
485
- },
486
- {
487
- name: 'content',
488
- valueReference: { reference: query, type: resourceType }
489
- }
490
- ]
491
- };
492
- }
493
-
494
- // interfaces
495
- interface LaunchContext extends Extension {
496
- url: 'http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-launchContext';
497
- extension: LaunchContextExtensions;
498
- }
499
-
500
- type LaunchContextExtensions =
501
- | [LaunchContextName, LaunchContextType]
502
- | [LaunchContextName, LaunchContextType, LaunchContextDescription];
503
-
504
- type LaunchContextName = LaunchContextNameId | LaunchContextNameCoding;
505
-
506
- // for backwards compatibility with old questionnaires (though it is not conformant)
507
- interface LaunchContextNameId extends Extension {
508
- url: 'name';
509
- valueId: string;
510
- }
511
-
512
- interface LaunchContextNameCoding extends Extension {
513
- url: 'name';
514
- valueCoding: LaunchContextNameCodingValueCoding;
515
- }
516
-
517
- interface LaunchContextNameCodingValueCoding extends Coding {
518
- code: 'patient' | 'encounter' | 'location' | 'user' | 'study';
519
- }
520
-
521
- interface LaunchContextType extends Extension {
522
- url: 'type';
523
- valueCode: string;
524
- }
525
-
526
- interface LaunchContextDescription extends Extension {
527
- url: 'description';
528
- valueString: string;
529
- }
530
-
531
- interface SourceQuery extends Extension {
532
- url: 'http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-sourceQueries';
533
- valueReference: Reference;
534
- }
535
-
536
- interface QuestionnaireLevelXFhirQueryVariable extends Extension {
537
- url: 'http://hl7.org/fhir/StructureDefinition/variable';
538
- valueExpression: XFhirQueryVariableExpression;
539
- }
540
-
541
- interface XFhirQueryVariableExpression extends Expression {
542
- name: string;
543
- language: 'application/x-fhir-query';
544
- expression: string;
545
- }
@@ -1,23 +0,0 @@
1
- import type { Questionnaire, QuestionnaireResponse } from 'fhir/r4';
2
- import { questionnaireResponseStore, questionnaireStore } from '../stores';
3
- import { initialiseQuestionnaireResponse } from './initialise';
4
-
5
- /**
6
- * Build the form with an initial Questionnaire and an optional filled QuestionnaireResponse.
7
- * If a QuestionnaireResponse is not provided, an empty QuestionnaireResponse is set as the initial QuestionnaireResponse.
8
- *
9
- * @author Sean Fong
10
- */
11
- export async function buildForm(
12
- questionnaire: Questionnaire,
13
- questionnaireResponse?: QuestionnaireResponse
14
- ): Promise<void> {
15
- await questionnaireStore.getState().buildSourceQuestionnaire(questionnaire);
16
-
17
- const initialisedQuestionnaireResponse = initialiseQuestionnaireResponse(
18
- questionnaire,
19
- questionnaireResponse
20
- );
21
- questionnaireResponseStore.getState().buildSourceResponse(initialisedQuestionnaireResponse);
22
- questionnaireStore.getState().updatePopulatedProperties(initialisedQuestionnaireResponse);
23
- }
File without changes