@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
package/src/utils/initialise.ts
CHANGED
|
@@ -26,7 +26,7 @@ import type {
|
|
|
26
26
|
QuestionnaireResponseItem,
|
|
27
27
|
QuestionnaireResponseItemAnswer
|
|
28
28
|
} from 'fhir/r4';
|
|
29
|
-
import type { EnableWhenExpressions, EnableWhenItems } from '../interfaces';
|
|
29
|
+
import type { EnableWhenExpressions, EnableWhenItems } from '../interfaces/enableWhen.interface';
|
|
30
30
|
import type { Tabs } from '../interfaces/tab.interface';
|
|
31
31
|
import { assignPopulatedAnswersToEnableWhen } from './enableWhen';
|
|
32
32
|
import type { CalculatedExpression } from '../interfaces/calculatedExpression.interface';
|
|
@@ -34,7 +34,7 @@ import { evaluateInitialCalculatedExpressions } from './calculatedExpression';
|
|
|
34
34
|
import { createQuestionnaireResponseItemMap } from './questionnaireResponseStoreUtils/updatableResponseItems';
|
|
35
35
|
|
|
36
36
|
/**
|
|
37
|
-
* Initialise a
|
|
37
|
+
* Initialise a questionnaireResponse from a given questionnaire
|
|
38
38
|
* optionally takes in an existing questionnaireResponse to be initialised
|
|
39
39
|
*
|
|
40
40
|
* @author Sean Fong
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import type { Questionnaire, QuestionnaireResponse } from 'fhir/r4';
|
|
2
|
+
import { questionnaireResponseStore, questionnaireStore, smartConfigStore } from '../stores';
|
|
3
|
+
import { initialiseQuestionnaireResponse } from './initialise';
|
|
4
|
+
import { removeEmptyAnswers } from './removeEmptyAnswers';
|
|
5
|
+
import { readEncounter, readPatient, readUser } from '../api/smartClient';
|
|
6
|
+
import type Client from 'fhirclient/lib/Client';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Build the form with an initial Questionnaire and an optional filled QuestionnaireResponse.
|
|
10
|
+
* If a QuestionnaireResponse is not provided, an empty QuestionnaireResponse is set as the initial QuestionnaireResponse.
|
|
11
|
+
* There are other optional properties such as applying readOnly, providing a terminology server url and additional variables.
|
|
12
|
+
*
|
|
13
|
+
* @param questionnaire - Questionnaire to be rendered
|
|
14
|
+
* @param questionnaireResponse - Pre-populated/draft/loaded QuestionnaireResponse to be rendered (optional)
|
|
15
|
+
* @param readOnly - Applies read-only mode to all items in the form view
|
|
16
|
+
* @param terminologyServerUrl - Terminology server url to fetch terminology. If not provided, the default terminology server will be used. (optional)
|
|
17
|
+
* @param additionalVariables - Additional key-value pair of SDC variables `Record<name, variable extension>` for testing (optional)
|
|
18
|
+
*
|
|
19
|
+
* @author Sean Fong
|
|
20
|
+
*/
|
|
21
|
+
export async function buildForm(
|
|
22
|
+
questionnaire: Questionnaire,
|
|
23
|
+
questionnaireResponse?: QuestionnaireResponse,
|
|
24
|
+
readOnly?: boolean,
|
|
25
|
+
terminologyServerUrl?: string,
|
|
26
|
+
additionalVariables?: Record<string, object>
|
|
27
|
+
): Promise<void> {
|
|
28
|
+
// QR is set to undefined here to prevent it from being initialised twice. This is defined like that for backward compatibility purposes.
|
|
29
|
+
await questionnaireStore
|
|
30
|
+
.getState()
|
|
31
|
+
.buildSourceQuestionnaire(questionnaire, undefined, additionalVariables, terminologyServerUrl);
|
|
32
|
+
|
|
33
|
+
const initialisedQuestionnaireResponse = initialiseQuestionnaireResponse(
|
|
34
|
+
questionnaire,
|
|
35
|
+
questionnaireResponse
|
|
36
|
+
);
|
|
37
|
+
questionnaireResponseStore.getState().buildSourceResponse(initialisedQuestionnaireResponse);
|
|
38
|
+
questionnaireStore.getState().updatePopulatedProperties(initialisedQuestionnaireResponse);
|
|
39
|
+
|
|
40
|
+
if (readOnly) {
|
|
41
|
+
questionnaireStore.getState().setFormAsReadOnly(readOnly);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Destroy the form to clean up the questionnaire and questionnaireResponse stores.
|
|
47
|
+
*
|
|
48
|
+
* @author Sean Fong
|
|
49
|
+
*/
|
|
50
|
+
export function destroyForm(): void {
|
|
51
|
+
questionnaireStore.getState().destroySourceQuestionnaire();
|
|
52
|
+
questionnaireResponseStore.getState().destroySourceResponse();
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Initialise the FHIRClient object to make further FHIR calls in the renderer.
|
|
57
|
+
* Note that this does not provide pre-population capabilities.
|
|
58
|
+
*
|
|
59
|
+
* @param fhirClient - FHIRClient object to perform further FHIR calls. At the moment it's only used in answerExpressions
|
|
60
|
+
*
|
|
61
|
+
* @author Sean Fong
|
|
62
|
+
*/
|
|
63
|
+
export async function initialiseFhirClient(fhirClient: Client): Promise<void> {
|
|
64
|
+
smartConfigStore.getState().setClient(fhirClient);
|
|
65
|
+
const patientPromise = readPatient(fhirClient);
|
|
66
|
+
const userPromise = readUser(fhirClient);
|
|
67
|
+
const encounterPromise = readEncounter(fhirClient);
|
|
68
|
+
|
|
69
|
+
const [patient, user, encounter] = await Promise.all([
|
|
70
|
+
patientPromise,
|
|
71
|
+
userPromise,
|
|
72
|
+
encounterPromise
|
|
73
|
+
]);
|
|
74
|
+
smartConfigStore.getState().setPatient(patient);
|
|
75
|
+
smartConfigStore.getState().setUser(user);
|
|
76
|
+
smartConfigStore.getState().setEncounter(encounter);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Get the filled QuestionnaireResponse at its current state.
|
|
81
|
+
* If no changes have been made to the form, the initial QuestionnaireResponse is returned.
|
|
82
|
+
*
|
|
83
|
+
* @author Sean Fong
|
|
84
|
+
*/
|
|
85
|
+
export function getResponse(): QuestionnaireResponse {
|
|
86
|
+
return questionnaireResponseStore.getState().updatableResponse;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Remove all hidden answers from the filled QuestionnaireResponse.
|
|
91
|
+
* This takes into account enableWhens, enableWhenExpressions, items without item.answer, empty item.answer arrays and empty strings.
|
|
92
|
+
*
|
|
93
|
+
* @author Sean Fong
|
|
94
|
+
*/
|
|
95
|
+
export function removeEmptyAnswersFromResponse(
|
|
96
|
+
questionnaire: Questionnaire,
|
|
97
|
+
questionnaireResponse: QuestionnaireResponse
|
|
98
|
+
): QuestionnaireResponse {
|
|
99
|
+
const enableWhenIsActivated = questionnaireStore.getState().enableWhenIsActivated;
|
|
100
|
+
const enableWhenItems = questionnaireStore.getState().enableWhenItems;
|
|
101
|
+
const enableWhenExpressions = questionnaireStore.getState().enableWhenExpressions;
|
|
102
|
+
|
|
103
|
+
return removeEmptyAnswers({
|
|
104
|
+
questionnaire,
|
|
105
|
+
questionnaireResponse,
|
|
106
|
+
enableWhenIsActivated,
|
|
107
|
+
enableWhenItems,
|
|
108
|
+
enableWhenExpressions
|
|
109
|
+
});
|
|
110
|
+
}
|
package/src/utils/qItem.ts
CHANGED
|
@@ -19,7 +19,7 @@ import type { Extension, Questionnaire, QuestionnaireItem } from 'fhir/r4';
|
|
|
19
19
|
import { getChoiceControlType } from './choice';
|
|
20
20
|
import { ChoiceItemControl, OpenChoiceItemControl } from '../interfaces/choice.enum';
|
|
21
21
|
import { getOpenChoiceControlType } from './openChoice';
|
|
22
|
-
import type { EnableWhenExpressions, EnableWhenItems } from '../interfaces';
|
|
22
|
+
import type { EnableWhenExpressions, EnableWhenItems } from '../interfaces/enableWhen.interface';
|
|
23
23
|
|
|
24
24
|
interface isHiddenByEnableWhensParams {
|
|
25
25
|
linkId: string;
|
|
@@ -31,7 +31,7 @@ import type {
|
|
|
31
31
|
EnableWhenSingleExpression,
|
|
32
32
|
EnableWhenSingleItemProperties,
|
|
33
33
|
EnableWhenSingleLinkedItem
|
|
34
|
-
} from '../../interfaces';
|
|
34
|
+
} from '../../interfaces/enableWhen.interface';
|
|
35
35
|
import type { AnswerExpression } from '../../interfaces/answerExpression.interface';
|
|
36
36
|
import type { ValueSetPromise } from '../../interfaces/valueSet.interface';
|
|
37
37
|
import { getTerminologyServerUrl, getValueSetPromise } from '../valueSet';
|
|
@@ -21,7 +21,7 @@ import type {
|
|
|
21
21
|
QuestionnaireResponse,
|
|
22
22
|
QuestionnaireResponseItem
|
|
23
23
|
} from 'fhir/r4';
|
|
24
|
-
import type { EnableWhenExpressions, EnableWhenItems } from '../interfaces';
|
|
24
|
+
import type { EnableWhenExpressions, EnableWhenItems } from '../interfaces/enableWhen.interface';
|
|
25
25
|
import { isHiddenByEnableWhen } from './qItem';
|
|
26
26
|
|
|
27
27
|
interface removeEmptyAnswersParams {
|
|
@@ -7,6 +7,23 @@ import type {
|
|
|
7
7
|
import type { ItemToRepopulate } from './repopulateItems';
|
|
8
8
|
import { getQrItemsIndex, mapQItemsIndex } from './mapItem';
|
|
9
9
|
import { isSpecificItemControl } from './itemControl';
|
|
10
|
+
import { questionnaireResponseStore, questionnaireStore } from '../stores';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Re-populate checked items in the re-population dialog into the current QuestionnaireResponse
|
|
14
|
+
*
|
|
15
|
+
* @author Sean Fong
|
|
16
|
+
*/
|
|
17
|
+
export function repopulateResponse(checkedItemsToRepopulate: Record<string, ItemToRepopulate>) {
|
|
18
|
+
const sourceQuestionnaire = questionnaireStore.getState().sourceQuestionnaire;
|
|
19
|
+
const updatableResponse = questionnaireResponseStore.getState().updatableResponse;
|
|
20
|
+
|
|
21
|
+
return repopulateItemsIntoResponse(
|
|
22
|
+
sourceQuestionnaire,
|
|
23
|
+
updatableResponse,
|
|
24
|
+
checkedItemsToRepopulate
|
|
25
|
+
);
|
|
26
|
+
}
|
|
10
27
|
|
|
11
28
|
export function repopulateItemsIntoResponse(
|
|
12
29
|
questionnaire: Questionnaire,
|
|
@@ -26,9 +26,22 @@ import _isEqual from 'lodash/isEqual';
|
|
|
26
26
|
import { containsTabs, isTabContainer } from './tabs';
|
|
27
27
|
import { getShortText, isSpecificItemControl } from './itemControl';
|
|
28
28
|
import { getQrItemsIndex, mapQItemsIndex } from './mapItem';
|
|
29
|
-
import type { EnableWhenExpressions, EnableWhenItems } from '../interfaces';
|
|
29
|
+
import type { EnableWhenExpressions, EnableWhenItems } from '../interfaces/enableWhen.interface';
|
|
30
30
|
import { isHiddenByEnableWhen } from './qItem';
|
|
31
|
+
import { questionnaireResponseStore, questionnaireStore } from '../stores';
|
|
31
32
|
|
|
33
|
+
/**
|
|
34
|
+
* ItemToRepopulate interface
|
|
35
|
+
*
|
|
36
|
+
* @property qItem - The QuestionnaireItem to repopulate
|
|
37
|
+
* @property heading - The heading of the group to repopulate
|
|
38
|
+
* @property newQRItem - The new QuestionnaireResponseItem to replace the old one
|
|
39
|
+
* @property oldQRItem - The old QuestionnaireResponseItem to be replaced
|
|
40
|
+
* @property newQRItems - The new QuestionnaireResponseItems to replace the old ones
|
|
41
|
+
* @property oldQRItems - The old QuestionnaireResponseItems to be replaced
|
|
42
|
+
*
|
|
43
|
+
* @author Sean Fong
|
|
44
|
+
*/
|
|
32
45
|
export interface ItemToRepopulate {
|
|
33
46
|
qItem: QuestionnaireItem | null;
|
|
34
47
|
heading: string | null;
|
|
@@ -52,6 +65,30 @@ interface getItemsToRepopulateParams {
|
|
|
52
65
|
enableWhenExpressions: EnableWhenExpressions;
|
|
53
66
|
}
|
|
54
67
|
|
|
68
|
+
/**
|
|
69
|
+
* Compare latest data from the server with the current QuestionnaireResponse and decide items to re-populate
|
|
70
|
+
*
|
|
71
|
+
* @author Sean Fong
|
|
72
|
+
*/
|
|
73
|
+
export function generateItemsToRepopulate(populatedResponse: QuestionnaireResponse) {
|
|
74
|
+
const sourceQuestionnaire = questionnaireStore.getState().sourceQuestionnaire;
|
|
75
|
+
const tabs = questionnaireStore.getState().tabs;
|
|
76
|
+
const updatableResponse = questionnaireResponseStore.getState().updatableResponse;
|
|
77
|
+
const enableWhenIsActivated = questionnaireStore.getState().enableWhenIsActivated;
|
|
78
|
+
const enableWhenItems = questionnaireStore.getState().enableWhenItems;
|
|
79
|
+
const enableWhenExpressions = questionnaireStore.getState().enableWhenExpressions;
|
|
80
|
+
|
|
81
|
+
return getItemsToRepopulate({
|
|
82
|
+
sourceQuestionnaire,
|
|
83
|
+
tabs,
|
|
84
|
+
populatedResponse,
|
|
85
|
+
updatableResponse,
|
|
86
|
+
enableWhenIsActivated,
|
|
87
|
+
enableWhenItems,
|
|
88
|
+
enableWhenExpressions
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
|
|
55
92
|
export function getItemsToRepopulate(
|
|
56
93
|
params: getItemsToRepopulateParams
|
|
57
94
|
): Record<string, ItemToRepopulate> {
|
package/src/utils/tabs.ts
CHANGED
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
*/
|
|
17
17
|
|
|
18
18
|
import type { Tabs } from '../interfaces/tab.interface';
|
|
19
|
-
import type { EnableWhenExpressions, EnableWhenItems } from '../interfaces';
|
|
19
|
+
import type { EnableWhenExpressions, EnableWhenItems } from '../interfaces/enableWhen.interface';
|
|
20
20
|
import type { Coding, QuestionnaireItem } from 'fhir/r4';
|
|
21
21
|
import { isSpecificItemControl } from './itemControl';
|
|
22
22
|
import { isHiddenByEnableWhen } from './qItem';
|
|
@@ -106,7 +106,7 @@ export function isTab(item: QuestionnaireItem) {
|
|
|
106
106
|
}
|
|
107
107
|
|
|
108
108
|
/**
|
|
109
|
-
* Create a <linkId, {isComplete: boolean}
|
|
109
|
+
* Create a `Record<linkId, {isComplete: boolean}>` key-value pair for all tabbed items in a qItem array
|
|
110
110
|
*
|
|
111
111
|
* @author Sean Fong
|
|
112
112
|
*/
|
|
@@ -25,7 +25,7 @@ import type {
|
|
|
25
25
|
QuestionnaireResponseItemAnswer
|
|
26
26
|
} from 'fhir/r4';
|
|
27
27
|
import { getQrItemsIndex, mapQItemsIndex } from './mapItem';
|
|
28
|
-
import type { EnableWhenExpressions, EnableWhenItems } from '../interfaces';
|
|
28
|
+
import type { EnableWhenExpressions, EnableWhenItems } from '../interfaces/enableWhen.interface';
|
|
29
29
|
import { isHiddenByEnableWhen } from './qItem';
|
|
30
30
|
import {
|
|
31
31
|
getDecimalPrecision,
|
|
@@ -39,6 +39,7 @@ import { structuredDataCapture } from 'fhir-sdc-helpers';
|
|
|
39
39
|
import type { RegexValidation } from '../interfaces/regex.interface';
|
|
40
40
|
import { parseDecimalStringToFloat } from './parseInputs';
|
|
41
41
|
import dayjs from 'dayjs';
|
|
42
|
+
import { questionnaireStore } from '../stores';
|
|
42
43
|
|
|
43
44
|
export enum ValidationResult {
|
|
44
45
|
unknown = 'unknown', // Unknown validation result
|
|
@@ -85,9 +86,6 @@ export enum ValidationResult {
|
|
|
85
86
|
interface ValidateQuestionnaireParams {
|
|
86
87
|
questionnaire: Questionnaire;
|
|
87
88
|
questionnaireResponse: QuestionnaireResponse;
|
|
88
|
-
enableWhenIsActivated: boolean;
|
|
89
|
-
enableWhenItems: EnableWhenItems;
|
|
90
|
-
enableWhenExpressions: EnableWhenExpressions;
|
|
91
89
|
}
|
|
92
90
|
|
|
93
91
|
/**
|
|
@@ -99,23 +97,20 @@ interface ValidateQuestionnaireParams {
|
|
|
99
97
|
export function validateQuestionnaire(
|
|
100
98
|
params: ValidateQuestionnaireParams
|
|
101
99
|
): Record<string, OperationOutcome> {
|
|
102
|
-
const {
|
|
103
|
-
questionnaire,
|
|
104
|
-
questionnaireResponse,
|
|
105
|
-
enableWhenIsActivated,
|
|
106
|
-
enableWhenItems,
|
|
107
|
-
enableWhenExpressions
|
|
108
|
-
} = params;
|
|
100
|
+
const { questionnaire, questionnaireResponse } = params;
|
|
109
101
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
) {
|
|
102
|
+
const enableWhenIsActivated = questionnaireStore.getState().enableWhenIsActivated;
|
|
103
|
+
const enableWhenItems = questionnaireStore.getState().enableWhenItems;
|
|
104
|
+
const enableWhenExpressions = questionnaireStore.getState().enableWhenExpressions;
|
|
105
|
+
|
|
106
|
+
if (!questionnaire.item || questionnaire.item.length === 0) {
|
|
116
107
|
return {};
|
|
117
108
|
}
|
|
118
109
|
|
|
110
|
+
if (!questionnaireResponse.item || questionnaireResponse.item.length === 0) {
|
|
111
|
+
questionnaireResponse.item = [];
|
|
112
|
+
}
|
|
113
|
+
|
|
119
114
|
const qItemsIndexMap = mapQItemsIndex(questionnaire);
|
|
120
115
|
const topLevelQRItemsByIndex = getQrItemsIndex(
|
|
121
116
|
questionnaire.item,
|
package/vite.config.ts
CHANGED
|
@@ -1,114 +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 { Questionnaire, QuestionnaireResponse } from 'fhir/r4';
|
|
19
|
-
import { useLayoutEffect, useState } from 'react';
|
|
20
|
-
import { initialiseQuestionnaireResponse } from '../utils';
|
|
21
|
-
import type Client from 'fhirclient/lib/Client';
|
|
22
|
-
import { readEncounter, readPatient, readUser } from '../api/smartClient';
|
|
23
|
-
import {
|
|
24
|
-
useQuestionnaireResponseStore,
|
|
25
|
-
useQuestionnaireStore,
|
|
26
|
-
useSmartConfigStore,
|
|
27
|
-
useTerminologyServerStore
|
|
28
|
-
} from '../stores';
|
|
29
|
-
|
|
30
|
-
function useInitialiseRenderer(
|
|
31
|
-
questionnaire: Questionnaire,
|
|
32
|
-
questionnaireResponse?: QuestionnaireResponse,
|
|
33
|
-
additionalVariables?: Record<string, object>,
|
|
34
|
-
terminologyServerUrl?: string,
|
|
35
|
-
fhirClient?: Client,
|
|
36
|
-
readOnly?: boolean
|
|
37
|
-
): boolean {
|
|
38
|
-
const buildSourceQuestionnaire = useQuestionnaireStore.use.buildSourceQuestionnaire();
|
|
39
|
-
const updatePopulatedProperties = useQuestionnaireStore.use.updatePopulatedProperties();
|
|
40
|
-
const buildSourceResponse = useQuestionnaireResponseStore.use.buildSourceResponse();
|
|
41
|
-
const setUpdatableResponseAsPopulated =
|
|
42
|
-
useQuestionnaireResponseStore.use.setUpdatableResponseAsPopulated();
|
|
43
|
-
|
|
44
|
-
const setTerminologyServerUrl = useTerminologyServerStore.use.setUrl();
|
|
45
|
-
const resetTerminologyServerUrl = useTerminologyServerStore.use.resetUrl();
|
|
46
|
-
const setSmartClient = useSmartConfigStore.use.setClient();
|
|
47
|
-
const setPatient = useSmartConfigStore.use.setPatient();
|
|
48
|
-
const setUser = useSmartConfigStore.use.setUser();
|
|
49
|
-
const setEncounter = useSmartConfigStore.use.setEncounter();
|
|
50
|
-
|
|
51
|
-
const [loading, setLoading] = useState(true);
|
|
52
|
-
|
|
53
|
-
useLayoutEffect(() => {
|
|
54
|
-
setLoading(true);
|
|
55
|
-
// set fhirClient if provided
|
|
56
|
-
if (fhirClient) {
|
|
57
|
-
setSmartClient(fhirClient);
|
|
58
|
-
readPatient(fhirClient).then((patient) => {
|
|
59
|
-
setPatient(patient);
|
|
60
|
-
});
|
|
61
|
-
readUser(fhirClient).then((user) => {
|
|
62
|
-
setUser(user);
|
|
63
|
-
});
|
|
64
|
-
readEncounter(fhirClient).then((encounter) => {
|
|
65
|
-
setEncounter(encounter);
|
|
66
|
-
});
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
// set terminology server url if provided, otherwise reset it back to ontoserver
|
|
70
|
-
if (terminologyServerUrl) {
|
|
71
|
-
setTerminologyServerUrl(terminologyServerUrl);
|
|
72
|
-
} else {
|
|
73
|
-
resetTerminologyServerUrl();
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
// initialise form including enableWhen, enableWhenExpressions, calculatedExpressions, initialExpressions, answerExpressions, cache answerValueSets
|
|
77
|
-
buildSourceQuestionnaire(
|
|
78
|
-
questionnaire,
|
|
79
|
-
questionnaireResponse,
|
|
80
|
-
additionalVariables,
|
|
81
|
-
terminologyServerUrl,
|
|
82
|
-
readOnly
|
|
83
|
-
).then(() => {
|
|
84
|
-
buildSourceResponse(initialiseQuestionnaireResponse(questionnaire));
|
|
85
|
-
|
|
86
|
-
if (questionnaireResponse) {
|
|
87
|
-
const updatedResponse = updatePopulatedProperties(questionnaireResponse);
|
|
88
|
-
setUpdatableResponseAsPopulated(updatedResponse);
|
|
89
|
-
}
|
|
90
|
-
setLoading(false);
|
|
91
|
-
});
|
|
92
|
-
}, [
|
|
93
|
-
questionnaire,
|
|
94
|
-
questionnaireResponse,
|
|
95
|
-
buildSourceQuestionnaire,
|
|
96
|
-
buildSourceResponse,
|
|
97
|
-
setUpdatableResponseAsPopulated,
|
|
98
|
-
updatePopulatedProperties,
|
|
99
|
-
additionalVariables,
|
|
100
|
-
fhirClient,
|
|
101
|
-
setSmartClient,
|
|
102
|
-
setPatient,
|
|
103
|
-
setUser,
|
|
104
|
-
setEncounter,
|
|
105
|
-
terminologyServerUrl,
|
|
106
|
-
setTerminologyServerUrl,
|
|
107
|
-
resetTerminologyServerUrl,
|
|
108
|
-
readOnly
|
|
109
|
-
]);
|
|
110
|
-
|
|
111
|
-
return loading;
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
export default useInitialiseRenderer;
|