@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.
- package/README.md +6 -6
- package/lib/components/FormComponents/BooleanItem/BooleanField.js +5 -4
- package/lib/components/FormComponents/BooleanItem/BooleanField.js.map +1 -1
- package/lib/components/FormComponents/ChoiceItems/ChoiceRadioAnswerOptionFields.js +5 -4
- package/lib/components/FormComponents/ChoiceItems/ChoiceRadioAnswerOptionFields.js.map +1 -1
- package/lib/components/FormComponents/ChoiceItems/ChoiceRadioAnswerValueSetFields.js +5 -4
- package/lib/components/FormComponents/ChoiceItems/ChoiceRadioAnswerValueSetFields.js.map +1 -1
- package/lib/components/FormComponents/DateTimeItems/index.d.ts +1 -1
- package/lib/components/FormComponents/DateTimeItems/index.js +1 -1
- package/lib/components/FormComponents/DateTimeItems/index.js.map +1 -1
- package/lib/components/FormComponents/DateTimeItems/utils/parseDate.d.ts +5 -0
- package/lib/components/FormComponents/DateTimeItems/utils/parseDate.js +5 -0
- package/lib/components/FormComponents/DateTimeItems/utils/parseDate.js.map +1 -1
- package/lib/components/FormComponents/GridGroup/GridGroup.d.ts +6 -0
- package/lib/components/FormComponents/GridGroup/GridGroup.js +6 -0
- package/lib/components/FormComponents/GridGroup/GridGroup.js.map +1 -1
- package/lib/components/FormComponents/RepeatGroup/RepeatGroup.d.ts +6 -0
- package/lib/components/FormComponents/RepeatGroup/RepeatGroup.js +6 -0
- package/lib/components/FormComponents/RepeatGroup/RepeatGroup.js.map +1 -1
- package/lib/components/FormComponents/RepeatItem/RepeatItem.d.ts +5 -0
- package/lib/components/FormComponents/RepeatItem/RepeatItem.js +5 -0
- package/lib/components/FormComponents/RepeatItem/RepeatItem.js.map +1 -1
- package/lib/components/FormComponents/SingleItem/SingleItem.d.ts +6 -0
- package/lib/components/FormComponents/SingleItem/SingleItem.js +6 -0
- package/lib/components/FormComponents/SingleItem/SingleItem.js.map +1 -1
- package/lib/components/FormComponents/Tables/GroupTable.d.ts +6 -0
- package/lib/components/FormComponents/Tables/GroupTable.js +6 -0
- package/lib/components/FormComponents/Tables/GroupTable.js.map +1 -1
- package/lib/components/FormComponents/index.d.ts +6 -6
- package/lib/components/FormComponents/index.js +6 -6
- package/lib/components/FormComponents/index.js.map +1 -1
- package/lib/components/Renderer/BaseRenderer.d.ts +7 -0
- package/lib/components/Renderer/BaseRenderer.js +7 -0
- package/lib/components/Renderer/BaseRenderer.js.map +1 -1
- package/lib/components/Renderer/SmartFormsRenderer.d.ts +22 -1
- package/lib/components/Renderer/SmartFormsRenderer.js +16 -6
- package/lib/components/Renderer/SmartFormsRenderer.js.map +1 -1
- package/lib/components/Renderer/index.d.ts +1 -0
- package/lib/components/Renderer/index.js.map +1 -1
- package/lib/components/index.d.ts +3 -2
- package/lib/components/index.js +2 -2
- package/lib/components/index.js.map +1 -1
- package/lib/hooks/index.d.ts +2 -0
- package/lib/hooks/index.js +2 -0
- package/lib/hooks/index.js.map +1 -1
- package/lib/hooks/useBuildForm.d.ts +15 -0
- package/lib/hooks/useBuildForm.js +41 -0
- package/lib/hooks/useBuildForm.js.map +1 -0
- package/lib/hooks/useHidden.d.ts +6 -0
- package/lib/hooks/useHidden.js +6 -0
- package/lib/hooks/useHidden.js.map +1 -1
- package/lib/hooks/useInitaliseFhirClient.d.ts +1 -0
- package/lib/hooks/useInitaliseFhirClient.js +55 -0
- package/lib/hooks/useInitaliseFhirClient.js.map +1 -0
- package/lib/hooks/useInitialiseForm.d.ts +20 -0
- package/lib/hooks/useInitialiseForm.js +72 -0
- package/lib/hooks/useInitialiseForm.js.map +1 -0
- package/lib/hooks/useInitialiseRenderer.d.ts +1 -1
- package/lib/hooks/useInitialiseRenderer.js +8 -31
- package/lib/hooks/useInitialiseRenderer.js.map +1 -1
- package/lib/hooks/useRendererQueryClient.d.ts +10 -0
- package/lib/hooks/useRendererQueryClient.js +36 -0
- package/lib/hooks/useRendererQueryClient.js.map +1 -0
- package/lib/hooks/useValueSetCodings.js +1 -0
- package/lib/hooks/useValueSetCodings.js.map +1 -1
- package/lib/index.d.ts +10 -40
- package/lib/index.js +8 -77
- package/lib/index.js.map +1 -1
- package/lib/interfaces/calculatedExpression.interface.d.ts +7 -0
- package/lib/interfaces/calculatedExpression.interface.js +16 -0
- package/lib/interfaces/calculatedExpression.interface.js.map +1 -1
- package/lib/interfaces/enableWhen.interface.d.ts +12 -0
- package/lib/interfaces/index.d.ts +4 -1
- package/lib/interfaces/index.js +16 -0
- package/lib/interfaces/index.js.map +1 -1
- package/lib/interfaces/populate.interface.d.ts +6 -0
- package/lib/interfaces/repopulateItems.interface.d.ts +0 -0
- package/lib/interfaces/repopulateItems.interface.js +2 -0
- package/lib/interfaces/repopulateItems.interface.js.map +1 -0
- package/lib/interfaces/tab.interface.d.ts +10 -0
- package/lib/interfaces/tab.interface.js +16 -0
- package/lib/interfaces/tab.interface.js.map +1 -1
- package/lib/interfaces/variables.interface.d.ts +12 -0
- package/lib/stores/index.d.ts +4 -0
- package/lib/stores/index.js.map +1 -1
- package/lib/stores/questionnaireResponseStore.d.ts +37 -2
- package/lib/stores/questionnaireResponseStore.js +72 -22
- package/lib/stores/questionnaireResponseStore.js.map +1 -1
- package/lib/stores/questionnaireStore.d.ts +59 -3
- package/lib/stores/questionnaireStore.js +18 -0
- package/lib/stores/questionnaireStore.js.map +1 -1
- package/lib/stores/smartConfigStore.d.ts +37 -0
- package/lib/stores/smartConfigStore.js +21 -0
- package/lib/stores/smartConfigStore.js.map +1 -1
- package/lib/stores/terminologyServerStore.d.ts +28 -2
- package/lib/stores/terminologyServerStore.js +16 -0
- package/lib/stores/terminologyServerStore.js.map +1 -1
- package/lib/stories/InitialiseFormWrapperForStorybook.d.ts +29 -0
- package/lib/stories/InitialiseFormWrapperForStorybook.js +65 -0
- package/lib/stories/InitialiseFormWrapperForStorybook.js.map +1 -0
- package/lib/stories/StorybookWrappers/BuildFormButtonForStorybook.d.ts +8 -0
- package/lib/stories/StorybookWrappers/BuildFormButtonForStorybook.js +44 -0
- package/lib/stories/StorybookWrappers/BuildFormButtonForStorybook.js.map +1 -0
- package/lib/stories/StorybookWrappers/BuildFormButtonTesterWrapperForStorybook.d.ts +18 -0
- package/lib/stories/StorybookWrappers/BuildFormButtonTesterWrapperForStorybook.js +48 -0
- package/lib/stories/StorybookWrappers/BuildFormButtonTesterWrapperForStorybook.js.map +1 -0
- package/lib/stories/StorybookWrappers/InitialiseFormWrapperForStorybook.d.ts +31 -0
- package/lib/stories/StorybookWrappers/InitialiseFormWrapperForStorybook.js +67 -0
- package/lib/stories/StorybookWrappers/InitialiseFormWrapperForStorybook.js.map +1 -0
- package/lib/stories/StorybookWrappers/PrePopButtonForStorybook.d.ts +7 -0
- package/lib/stories/StorybookWrappers/PrePopButtonForStorybook.js +32 -0
- package/lib/stories/StorybookWrappers/PrePopButtonForStorybook.js.map +1 -0
- package/lib/stories/StorybookWrappers/PrePopWrapperForStorybook.d.ts +21 -0
- package/lib/stories/StorybookWrappers/PrePopWrapperForStorybook.js +83 -0
- package/lib/stories/StorybookWrappers/PrePopWrapperForStorybook.js.map +1 -0
- package/lib/stories/StorybookWrappers/index.d.ts +3 -0
- package/lib/stories/StorybookWrappers/index.js +20 -0
- package/lib/stories/StorybookWrappers/index.js.map +1 -0
- package/lib/stories/StorybookWrappers/populateCallbackForStorybook.d.ts +8 -0
- package/lib/stories/StorybookWrappers/populateCallbackForStorybook.js +46 -0
- package/lib/stories/StorybookWrappers/populateCallbackForStorybook.js.map +1 -0
- package/lib/stories/index.d.ts +1 -0
- package/lib/stories/index.js +18 -0
- package/lib/stories/index.js.map +1 -0
- package/lib/theme/Theme.d.ts +8 -2
- package/lib/theme/Theme.js +8 -2
- package/lib/theme/Theme.js.map +1 -1
- package/lib/theme/index.d.ts +1 -0
- package/lib/theme/index.js +2 -0
- package/lib/theme/index.js.map +1 -0
- package/lib/utils/enableWhen.d.ts +1 -1
- package/lib/utils/enableWhenExpression.d.ts +1 -1
- package/lib/utils/fhirpath.d.ts +1 -1
- package/lib/utils/index.d.ts +5 -3
- package/lib/utils/index.js +4 -3
- package/lib/utils/index.js.map +1 -1
- package/lib/utils/initialise.d.ts +2 -2
- package/lib/utils/initialise.js +1 -1
- package/lib/utils/manageForm.d.ts +45 -0
- package/lib/utils/manageForm.js +101 -0
- package/lib/utils/manageForm.js.map +1 -0
- package/lib/utils/qItem.d.ts +1 -1
- package/lib/utils/questionnaireStoreUtils/extractOtherExtensions.d.ts +1 -1
- package/lib/utils/removeEmptyAnswers.d.ts +1 -1
- package/lib/utils/repopulateIntoResponse.d.ts +6 -0
- package/lib/utils/repopulateIntoResponse.js +11 -0
- package/lib/utils/repopulateIntoResponse.js.map +1 -1
- package/lib/utils/repopulateItems.d.ts +19 -1
- package/lib/utils/repopulateItems.js +23 -0
- package/lib/utils/repopulateItems.js.map +1 -1
- package/lib/utils/tabs.d.ts +2 -2
- package/lib/utils/tabs.js +1 -1
- package/lib/utils/validateQuestionnaire.d.ts +0 -4
- package/lib/utils/validateQuestionnaire.js +9 -5
- package/lib/utils/validateQuestionnaire.js.map +1 -1
- package/package.json +1 -1
- package/src/components/FormComponents/BooleanItem/BooleanField.tsx +11 -9
- package/src/components/FormComponents/ChoiceItems/ChoiceRadioAnswerOptionFields.tsx +11 -9
- package/src/components/FormComponents/ChoiceItems/ChoiceRadioAnswerValueSetFields.tsx +11 -9
- package/src/components/FormComponents/DateTimeItems/index.ts +1 -1
- package/src/components/FormComponents/DateTimeItems/utils/parseDate.ts +5 -0
- package/src/components/FormComponents/GridGroup/GridGroup.tsx +6 -0
- package/src/components/FormComponents/RepeatGroup/RepeatGroup.tsx +6 -0
- package/src/components/FormComponents/RepeatItem/RepeatItem.tsx +5 -0
- package/src/components/FormComponents/SingleItem/SingleItem.tsx +6 -0
- package/src/components/FormComponents/Tables/GroupTable.tsx +6 -0
- package/src/components/FormComponents/index.ts +6 -6
- package/src/components/Renderer/BaseRenderer.tsx +7 -0
- package/src/components/Renderer/SmartFormsRenderer.tsx +34 -11
- package/src/components/Renderer/index.ts +1 -0
- package/src/components/index.ts +10 -2
- package/src/hooks/index.ts +2 -0
- package/src/hooks/useBuildForm.ts +58 -0
- package/src/hooks/useHidden.ts +6 -0
- package/src/hooks/useInitialiseForm.ts +93 -0
- package/src/hooks/{useQueryClient.ts → useRendererQueryClient.ts} +9 -2
- package/src/hooks/useValueSetCodings.ts +1 -0
- package/src/index.ts +59 -96
- package/src/interfaces/calculatedExpression.interface.ts +24 -0
- package/src/interfaces/enableWhen.interface.ts +12 -0
- package/src/interfaces/index.ts +21 -10
- package/src/interfaces/populate.interface.ts +6 -0
- package/src/interfaces/tab.interface.ts +12 -0
- package/src/interfaces/variables.interface.ts +12 -0
- package/src/stores/index.ts +7 -0
- package/src/stores/questionnaireResponseStore.ts +90 -19
- package/src/stores/questionnaireStore.ts +62 -2
- package/src/stores/smartConfigStore.ts +37 -0
- package/src/stores/terminologyServerStore.ts +28 -1
- package/src/stories/{BuildFormButtonForStorybook.tsx → StorybookWrappers/BuildFormButtonForStorybook.tsx} +12 -5
- package/src/stories/StorybookWrappers/BuildFormButtonTesterWrapperForStorybook.tsx +70 -0
- package/src/stories/{BuildFormWrapper.tsx → StorybookWrappers/BuildFormWrapperForStorybook.tsx} +11 -12
- package/src/stories/{BuildFormButtonTesterWrapper.tsx → StorybookWrappers/FormValidationTesterWrapperForStorybook.tsx} +22 -19
- package/src/stories/{useBuildFormForStorybook.ts → StorybookWrappers/FormValidationViewerForStorybook.tsx} +7 -16
- package/src/stories/StorybookWrappers/InitialiseFormWrapperForStorybook.tsx +105 -0
- package/src/stories/{PrePopButtonForStorybook.tsx → StorybookWrappers/PrePopButtonForStorybook.tsx} +12 -10
- package/src/stories/{PrePopWrapper.tsx → StorybookWrappers/PrePopWrapperForStorybook.tsx} +22 -14
- package/src/stories/StorybookWrappers/ValidateFormButtonForStorybook.tsx +41 -0
- package/src/stories/StorybookWrappers/index.ts +20 -0
- package/src/stories/{populateCallbackForStorybook.ts → StorybookWrappers/populateCallbackForStorybook.ts} +8 -2
- package/src/stories/assets/questionnaires/QButtonTester.ts +380 -0
- package/src/stories/assets/questionnaires/QValidateTester.ts +118 -0
- package/src/stories/itemTypes/Attachment.stories.tsx +3 -3
- package/src/stories/itemTypes/Boolean.stories.tsx +3 -3
- package/src/stories/itemTypes/Choice.stories.tsx +3 -3
- package/src/stories/itemTypes/Date.stories.tsx +3 -3
- package/src/stories/itemTypes/DateTime.stories.tsx +3 -3
- package/src/stories/itemTypes/Decimal.stories.tsx +3 -3
- package/src/stories/itemTypes/Display.stories.tsx +3 -3
- package/src/stories/itemTypes/Group.stories.tsx +3 -3
- package/src/stories/itemTypes/Integer.stories.tsx +3 -3
- package/src/stories/itemTypes/OpenChoice.stories.tsx +3 -3
- package/src/stories/itemTypes/Quantity.stories.tsx +3 -3
- package/src/stories/itemTypes/Reference.stories.tsx +3 -3
- package/src/stories/itemTypes/String.stories.tsx +3 -3
- package/src/stories/itemTypes/Text.stories.tsx +3 -3
- package/src/stories/itemTypes/Time.stories.tsx +3 -3
- package/src/stories/itemTypes/Url.stories.tsx +3 -3
- package/src/stories/sdc/AdvancedAdditionalDisplayContent.stories.tsx +3 -3
- package/src/stories/sdc/AdvancedControlAppearance.stories.tsx +3 -3
- package/src/stories/sdc/AdvancedOther.stories.tsx +3 -3
- package/src/stories/sdc/AdvancedTextAppearance.stories.tsx +3 -3
- package/src/stories/sdc/BehaviorCalculations.stories.tsx +3 -3
- package/src/stories/sdc/BehaviorChoiceRestriction.stories.tsx +3 -3
- package/src/stories/sdc/BehaviorOther.stories.tsx +3 -3
- package/src/stories/sdc/BehaviorValueConstraints.stories.tsx +3 -3
- package/src/stories/sdc/FormPopulation.stories.tsx +3 -3
- package/src/stories/sdc/ItemControlDisplay.stories.tsx +3 -3
- package/src/stories/sdc/ItemControlGroup.stories.tsx +3 -3
- package/src/stories/sdc/ItemControlQuestion.stories.tsx +3 -3
- package/src/stories/{rebuildForm/BuildFormTesterWrapper.stories.tsx → testing/BuildFormButtonTesterWrapper.stories.tsx} +6 -9
- package/src/stories/testing/PrePopButtonTesterWrapper.stories.tsx +45 -0
- package/src/stories/testing/ValidateFormTesterWrapper.stories.tsx +39 -0
- package/src/tests/enableWhen.test.ts +6 -2
- package/src/theme/Theme.tsx +8 -2
- package/src/theme/index.ts +1 -0
- package/src/utils/enableWhen.ts +1 -1
- package/src/utils/enableWhenExpression.ts +1 -1
- package/src/utils/fhirpath.ts +1 -1
- package/src/utils/index.ts +5 -7
- package/src/utils/initialise.ts +2 -2
- package/src/utils/manageForm.ts +110 -0
- package/src/utils/qItem.ts +1 -1
- package/src/utils/questionnaireStoreUtils/extractOtherExtensions.ts +1 -1
- package/src/utils/removeEmptyAnswers.ts +1 -1
- package/src/utils/repopulateIntoResponse.ts +17 -0
- package/src/utils/repopulateItems.ts +38 -1
- package/src/utils/tabs.ts +2 -2
- package/src/utils/validateQuestionnaire.ts +12 -17
- package/vite.config.ts +1 -1
- package/src/hooks/useInitialiseRenderer.ts +0 -114
- package/src/stories/assets/questionnaires/QBuildFormButtonTester.ts +0 -270
- package/src/stories/populateUtilsForStorybook.ts +0 -545
- package/src/utils/buildForm.ts +0 -23
- /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
|
-
}
|
package/src/utils/buildForm.ts
DELETED
|
@@ -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
|