@aehrc/smart-forms-renderer 0.20.0 → 0.21.1
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/lib/interfaces/enableWhen.interface.d.ts +11 -3
- package/lib/interfaces/index.d.ts +1 -1
- package/lib/interfaces/questionnaireStore.interface.d.ts +2 -2
- package/lib/setup-jest.js +1 -0
- package/lib/stores/questionnaireStore.d.ts +3 -3
- package/lib/stores/questionnaireStore.js +20 -5
- package/lib/stores/questionnaireStore.js.map +1 -1
- package/lib/stories/MedicalHistoryTable.stories.js +45 -0
- package/lib/stories/SmartFormsRenderer.stories.js +117 -0
- package/lib/utils/enableWhenExpression.d.ts +22 -5
- package/lib/utils/enableWhenExpression.js +106 -55
- package/lib/utils/enableWhenExpression.js.map +1 -1
- package/lib/utils/fhirpath.d.ts +3 -3
- package/lib/utils/initialise.d.ts +3 -3
- package/lib/utils/qItem.d.ts +2 -2
- package/lib/utils/qItem.js +8 -8
- package/lib/utils/qItem.js.map +1 -1
- package/lib/utils/questionnaireStoreUtils/createQuestionaireModel.js +1 -1
- package/lib/utils/questionnaireStoreUtils/createQuestionaireModel.js.map +1 -1
- package/lib/utils/questionnaireStoreUtils/extractOtherExtensions.d.ts +5 -5
- package/lib/utils/questionnaireStoreUtils/extractOtherExtensions.js +98 -34
- package/lib/utils/questionnaireStoreUtils/extractOtherExtensions.js.map +1 -1
- package/lib/utils/removeEmptyAnswers.d.ts +2 -2
- package/lib/utils/removeEmptyAnswers.js.map +1 -1
- package/lib/utils/repopulateItems.d.ts +2 -2
- package/lib/utils/tabs.d.ts +6 -6
- package/lib/utils/tabs.js +3 -18
- package/lib/utils/tabs.js.map +1 -1
- package/lib/utils/validateQuestionnaire.d.ts +2 -2
- package/lib/utils/validateQuestionnaire.js +0 -7
- package/lib/utils/validateQuestionnaire.js.map +1 -1
- package/package.json +5 -5
- package/src/interfaces/enableWhen.interface.ts +13 -3
- package/src/interfaces/index.ts +4 -2
- package/src/interfaces/questionnaireStore.interface.ts +2 -2
- package/src/stores/questionnaireStore.ts +23 -7
- package/src/utils/enableWhenExpression.ts +221 -83
- package/src/utils/fhirpath.ts +3 -3
- package/src/utils/initialise.ts +3 -3
- package/src/utils/qItem.ts +11 -11
- package/src/utils/questionnaireStoreUtils/createQuestionaireModel.ts +1 -1
- package/src/utils/questionnaireStoreUtils/extractOtherExtensions.ts +158 -39
- package/src/utils/removeEmptyAnswers.ts +4 -4
- package/src/utils/repopulateItems.ts +4 -4
- package/src/utils/tabs.ts +9 -24
- package/src/utils/validateQuestionnaire.ts +3 -11
|
@@ -1,8 +1,16 @@
|
|
|
1
1
|
import type { QuestionnaireItem, QuestionnaireItemEnableWhen, QuestionnaireResponseItemAnswer } from 'fhir/r4';
|
|
2
|
-
export interface
|
|
2
|
+
export interface EnableWhenExpressions {
|
|
3
|
+
singleExpressions: Record<string, EnableWhenSingleExpression>;
|
|
4
|
+
repeatExpressions: Record<string, EnableWhenRepeatExpression>;
|
|
5
|
+
}
|
|
6
|
+
export interface EnableWhenSingleExpression {
|
|
7
|
+
expression: string;
|
|
8
|
+
isEnabled?: boolean;
|
|
9
|
+
}
|
|
10
|
+
export interface EnableWhenRepeatExpression {
|
|
3
11
|
expression: string;
|
|
4
|
-
|
|
5
|
-
|
|
12
|
+
parentLinkId: string;
|
|
13
|
+
enabledIndexes: boolean[];
|
|
6
14
|
}
|
|
7
15
|
export interface EnableWhenItems {
|
|
8
16
|
singleItems: Record<string, EnableWhenSingleItemProperties>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { EnableWhenItems, EnableWhenSingleItemProperties, EnableWhenRepeatItemProperties, EnableWhenSingleLinkedItem, EnableWhenRepeatLinkedItem, EnableWhenExpressions, EnableWhenSingleExpression, EnableWhenRepeatExpression } from './enableWhen.interface';
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { Tabs } from './tab.interface';
|
|
2
2
|
import type { Variables } from './variables.interface';
|
|
3
3
|
import type { LaunchContext } from './populate.interface';
|
|
4
|
-
import type {
|
|
4
|
+
import type { EnableWhenExpressions, EnableWhenItems } from './enableWhen.interface';
|
|
5
5
|
import type { CalculatedExpression } from './calculatedExpression.interface';
|
|
6
6
|
import type { AnswerExpression } from './answerExpression.interface';
|
|
7
7
|
import type { Coding } from 'fhir/r4';
|
|
@@ -11,7 +11,7 @@ export interface QuestionnaireModel {
|
|
|
11
11
|
variables: Variables;
|
|
12
12
|
launchContexts: Record<string, LaunchContext>;
|
|
13
13
|
enableWhenItems: EnableWhenItems;
|
|
14
|
-
enableWhenExpressions:
|
|
14
|
+
enableWhenExpressions: EnableWhenExpressions;
|
|
15
15
|
calculatedExpressions: Record<string, CalculatedExpression>;
|
|
16
16
|
answerExpressions: Record<string, AnswerExpression>;
|
|
17
17
|
processedValueSetCodings: Record<string, Coding[]>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import '@testing-library/jest-dom';
|
|
@@ -2,7 +2,7 @@ import type { Coding, Questionnaire, QuestionnaireResponse, QuestionnaireRespons
|
|
|
2
2
|
import type { Variables } from '../interfaces/variables.interface';
|
|
3
3
|
import type { LaunchContext } from '../interfaces/populate.interface';
|
|
4
4
|
import type { CalculatedExpression } from '../interfaces/calculatedExpression.interface';
|
|
5
|
-
import type {
|
|
5
|
+
import type { EnableWhenExpressions, EnableWhenItems } from '../interfaces';
|
|
6
6
|
import type { AnswerExpression } from '../interfaces/answerExpression.interface';
|
|
7
7
|
import type { Tabs } from '../interfaces/tab.interface';
|
|
8
8
|
interface QuestionnaireStoreType {
|
|
@@ -15,7 +15,7 @@ interface QuestionnaireStoreType {
|
|
|
15
15
|
enableWhenItems: EnableWhenItems;
|
|
16
16
|
enableWhenLinkedQuestions: Record<string, string[]>;
|
|
17
17
|
enableWhenIsActivated: boolean;
|
|
18
|
-
enableWhenExpressions:
|
|
18
|
+
enableWhenExpressions: EnableWhenExpressions;
|
|
19
19
|
calculatedExpressions: Record<string, CalculatedExpression>;
|
|
20
20
|
answerExpressions: Record<string, AnswerExpression>;
|
|
21
21
|
processedValueSetCodings: Record<string, Coding[]>;
|
|
@@ -48,7 +48,7 @@ export declare const useQuestionnaireStore: import("zustand/vanilla").StoreApi<Q
|
|
|
48
48
|
enableWhenItems: () => EnableWhenItems;
|
|
49
49
|
enableWhenLinkedQuestions: () => Record<string, string[]>;
|
|
50
50
|
enableWhenIsActivated: () => boolean;
|
|
51
|
-
enableWhenExpressions: () =>
|
|
51
|
+
enableWhenExpressions: () => EnableWhenExpressions;
|
|
52
52
|
calculatedExpressions: () => Record<string, CalculatedExpression>;
|
|
53
53
|
answerExpressions: () => Record<string, AnswerExpression>;
|
|
54
54
|
processedValueSetCodings: () => Record<string, Coding[]>;
|
|
@@ -33,6 +33,8 @@ import { emptyQuestionnaire, emptyResponse } from '../utils/emptyResource';
|
|
|
33
33
|
import cloneDeep from 'lodash.clonedeep';
|
|
34
34
|
import { terminologyServerStore } from './terminologyServerStore';
|
|
35
35
|
import { createSelectors } from './selector';
|
|
36
|
+
import { mutateRepeatEnableWhenExpressionInstances } from '../utils/enableWhenExpression';
|
|
37
|
+
import { questionnaireResponseStore } from './questionnaireResponseStore';
|
|
36
38
|
export const questionnaireStore = createStore()((set, get) => ({
|
|
37
39
|
sourceQuestionnaire: cloneDeep(emptyQuestionnaire),
|
|
38
40
|
itemTypes: {},
|
|
@@ -41,7 +43,7 @@ export const questionnaireStore = createStore()((set, get) => ({
|
|
|
41
43
|
variables: { fhirPathVariables: {}, xFhirQueryVariables: {} },
|
|
42
44
|
launchContexts: {},
|
|
43
45
|
calculatedExpressions: {},
|
|
44
|
-
enableWhenExpressions: {},
|
|
46
|
+
enableWhenExpressions: { singleExpressions: {}, repeatExpressions: {} },
|
|
45
47
|
answerExpressions: {},
|
|
46
48
|
enableWhenItems: { singleItems: {}, repeatItems: {} },
|
|
47
49
|
enableWhenLinkedQuestions: {},
|
|
@@ -90,7 +92,7 @@ export const questionnaireStore = createStore()((set, get) => ({
|
|
|
90
92
|
launchContexts: {},
|
|
91
93
|
enableWhenItems: { singleItems: {}, repeatItems: {} },
|
|
92
94
|
enableWhenLinkedQuestions: {},
|
|
93
|
-
enableWhenExpressions: {},
|
|
95
|
+
enableWhenExpressions: { singleExpressions: {}, repeatExpressions: {} },
|
|
94
96
|
calculatedExpressions: {},
|
|
95
97
|
answerExpressions: {},
|
|
96
98
|
processedValueSetCodings: {},
|
|
@@ -118,10 +120,23 @@ export const questionnaireStore = createStore()((set, get) => ({
|
|
|
118
120
|
},
|
|
119
121
|
mutateRepeatEnableWhenItems: (parentRepeatGroupLinkId, parentRepeatGroupIndex, actionType) => {
|
|
120
122
|
const enableWhenItems = get().enableWhenItems;
|
|
123
|
+
const enableWhenExpressions = get().enableWhenExpressions;
|
|
121
124
|
const updatedEnableWhenItems = mutateRepeatEnableWhenItemInstances(Object.assign({}, enableWhenItems), parentRepeatGroupLinkId, parentRepeatGroupIndex, actionType);
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
+
const { updatedEnableWhenExpressions, isUpdated } = mutateRepeatEnableWhenExpressionInstances({
|
|
126
|
+
questionnaireResponse: questionnaireResponseStore.getState().updatableResponse,
|
|
127
|
+
variablesFhirPath: get().variables.fhirPathVariables,
|
|
128
|
+
existingFhirPathContext: get().fhirPathContext,
|
|
129
|
+
enableWhenExpressions: enableWhenExpressions,
|
|
130
|
+
parentRepeatGroupLinkId,
|
|
131
|
+
parentRepeatGroupIndex,
|
|
132
|
+
actionType
|
|
133
|
+
});
|
|
134
|
+
if (isUpdated) {
|
|
135
|
+
set(() => ({
|
|
136
|
+
enableWhenItems: updatedEnableWhenItems,
|
|
137
|
+
enableWhenExpressions: updatedEnableWhenExpressions
|
|
138
|
+
}));
|
|
139
|
+
}
|
|
125
140
|
},
|
|
126
141
|
toggleEnableWhenActivation: (isActivated) => set(() => ({ enableWhenIsActivated: isActivated })),
|
|
127
142
|
updateExpressions: (updatedResponse) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"questionnaireStore.js","sourceRoot":"","sources":["../../src/stores/questionnaireStore.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;;;;;;;;;;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAa9C,OAAO,EACL,mCAAmC,EACnC,0BAA0B,EAC3B,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,0BAA0B,EAAE,MAAM,mBAAmB,CAAC;AAC/D,OAAO,EACL,oCAAoC,EACpC,oCAAoC,EACrC,MAAM,+BAA+B,CAAC;AACvC,OAAO,EAAE,wBAAwB,EAAE,MAAM,0DAA0D,CAAC;AACpG,OAAO,EAAE,0BAA0B,EAAE,MAAM,qBAAqB,CAAC;AACjE,OAAO,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAC3E,OAAO,SAAS,MAAM,kBAAkB,CAAC;AACzC,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAClE,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"questionnaireStore.js","sourceRoot":"","sources":["../../src/stores/questionnaireStore.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,45 @@
|
|
|
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
|
+
*/ import ThemeProvider from '../theme/Theme';
|
|
17
|
+
import { GroupTable } from '../components';
|
|
18
|
+
import GTableMedicalHistoryItemJson from './assets/QItems-and-QRItems/Q_GTableMedicalHistory.json';
|
|
19
|
+
import GTableMedicalHistoryAnswersJson from './assets/QItems-and-QRItems/QR_GTableMedicalHistory.json';
|
|
20
|
+
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
|
21
|
+
// More on how to set up stories at: https://storybook.js.org/docs/react/writing-stories/introduction#default-export
|
|
22
|
+
const meta = {
|
|
23
|
+
title: 'Component/GroupTable',
|
|
24
|
+
component: GroupTable,
|
|
25
|
+
// This component will have an automatically generated Autodocs entry: https://storybook.js.org/docs/react/writing-docs/autodocs
|
|
26
|
+
tags: [],
|
|
27
|
+
decorators: [
|
|
28
|
+
(Story)=>/*#__PURE__*/ React.createElement(ThemeProvider, null, /*#__PURE__*/ React.createElement(QueryClientProvider, {
|
|
29
|
+
client: new QueryClient()
|
|
30
|
+
}, Story()))
|
|
31
|
+
]
|
|
32
|
+
};
|
|
33
|
+
const GTableMedicalHistoryItem = GTableMedicalHistoryItemJson;
|
|
34
|
+
const GTableMedicalHistoryAnswers = GTableMedicalHistoryAnswersJson;
|
|
35
|
+
export default meta;
|
|
36
|
+
// More on writing stories with args: https://storybook.js.org/docs/react/writing-stories/args
|
|
37
|
+
export const MedicalHistoryTable = {
|
|
38
|
+
args: {
|
|
39
|
+
qItem: GTableMedicalHistoryItem,
|
|
40
|
+
qrItems: GTableMedicalHistoryAnswers,
|
|
41
|
+
groupCardElevation: 1,
|
|
42
|
+
parentIsReadOnly: false,
|
|
43
|
+
onQrRepeatGroupChange: ()=>{}
|
|
44
|
+
}
|
|
45
|
+
};
|
|
@@ -0,0 +1,117 @@
|
|
|
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
|
+
*/ import { SmartFormsRenderer } from '../components';
|
|
17
|
+
import Q715Json from './assets/Qs-and-QRs/Q715.json';
|
|
18
|
+
import R715Json from './assets/Qs-and-QRs/R715.json';
|
|
19
|
+
import QTestGridJson from './assets/Qs-and-QRs/QTestGrid.json';
|
|
20
|
+
import RTestGridJson from './assets/Qs-and-QRs/RTestGrid.json';
|
|
21
|
+
import QDev715Json from './assets/Qs-and-QRs/QDev715.json';
|
|
22
|
+
// More on how to set up stories at: https://storybook.js.org/docs/react/writing-stories/introduction#default-export
|
|
23
|
+
const meta = {
|
|
24
|
+
title: 'Component/SmartFormsRenderer',
|
|
25
|
+
component: SmartFormsRenderer,
|
|
26
|
+
// This component will have an automatically generated Autodocs entry: https://storybook.js.org/docs/react/writing-docs/autodocs
|
|
27
|
+
tags: []
|
|
28
|
+
};
|
|
29
|
+
const Q715 = Q715Json;
|
|
30
|
+
const R715 = R715Json;
|
|
31
|
+
const QTestGrid = QTestGridJson;
|
|
32
|
+
const RTestGrid = RTestGridJson;
|
|
33
|
+
const QDev715 = QDev715Json;
|
|
34
|
+
export default meta;
|
|
35
|
+
// More on writing stories with args: https://storybook.js.org/docs/react/writing-stories/args
|
|
36
|
+
export const Form715 = {
|
|
37
|
+
args: {
|
|
38
|
+
questionnaire: Q715
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
export const Form715WithResponse = {
|
|
42
|
+
args: {
|
|
43
|
+
questionnaire: Q715,
|
|
44
|
+
questionnaireResponse: R715
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
export const FormDev715 = {
|
|
48
|
+
args: {
|
|
49
|
+
questionnaire: QDev715
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
export const FormTestGrid = {
|
|
53
|
+
args: {
|
|
54
|
+
questionnaire: QTestGrid
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
export const FormTestGridWithResponse = {
|
|
58
|
+
args: {
|
|
59
|
+
questionnaire: QTestGrid,
|
|
60
|
+
questionnaireResponse: RTestGrid,
|
|
61
|
+
additionalVariables: {}
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
export const QTestGridWithResponseAddFhirPath = {
|
|
65
|
+
args: {
|
|
66
|
+
questionnaire: QTestGrid,
|
|
67
|
+
questionnaireResponse: RTestGrid,
|
|
68
|
+
additionalVariables: {
|
|
69
|
+
addVar1: {
|
|
70
|
+
url: 'http://hl7.org/fhir/StructureDefinition/variable',
|
|
71
|
+
valueExpression: {
|
|
72
|
+
name: 'addVar1',
|
|
73
|
+
language: 'text/fhirpath',
|
|
74
|
+
expression: "%resource.item.where(linkId='grid').item.where(linkId='1').item.where(linkId='1.1').item.where(linkId='1.1.1').answer.value"
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
export const QTestGridWithResponseAddXFhirQuery = {
|
|
81
|
+
args: {
|
|
82
|
+
questionnaire: QTestGrid,
|
|
83
|
+
questionnaireResponse: RTestGrid,
|
|
84
|
+
additionalVariables: {
|
|
85
|
+
addVar1: {
|
|
86
|
+
url: 'http://hl7.org/fhir/StructureDefinition/variable',
|
|
87
|
+
valueExpression: {
|
|
88
|
+
name: 'addVar1',
|
|
89
|
+
language: 'text/fhirpath',
|
|
90
|
+
expression: "%resource.item.where(linkId='grid').item.where(linkId='1').item.where(linkId='1.1').item.where(linkId='1.1.1').answer.value"
|
|
91
|
+
}
|
|
92
|
+
},
|
|
93
|
+
addVar2: {
|
|
94
|
+
url: 'http://hl7.org/fhir/StructureDefinition/variable',
|
|
95
|
+
valueExpression: {
|
|
96
|
+
name: 'addVar2',
|
|
97
|
+
language: 'application/x-fhir-query',
|
|
98
|
+
expression: 'Condition?patient={{%patient.id}}'
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
export const QTestGridWithResponseReadOnly = {
|
|
105
|
+
args: {
|
|
106
|
+
questionnaire: QTestGrid,
|
|
107
|
+
questionnaireResponse: RTestGrid,
|
|
108
|
+
readOnly: true
|
|
109
|
+
}
|
|
110
|
+
};
|
|
111
|
+
export const Form715WithResponseReadOnly = {
|
|
112
|
+
args: {
|
|
113
|
+
questionnaire: Q715,
|
|
114
|
+
questionnaireResponse: R715,
|
|
115
|
+
readOnly: true
|
|
116
|
+
}
|
|
117
|
+
};
|
|
@@ -1,17 +1,34 @@
|
|
|
1
|
-
import type { EnableWhenExpression } from '../interfaces';
|
|
2
1
|
import type { Expression, QuestionnaireResponse } from 'fhir/r4';
|
|
2
|
+
import type { EnableWhenExpressions, EnableWhenRepeatExpression } from '../interfaces';
|
|
3
3
|
interface EvaluateInitialEnableWhenExpressionsParams {
|
|
4
4
|
initialResponse: QuestionnaireResponse;
|
|
5
|
-
enableWhenExpressions:
|
|
5
|
+
enableWhenExpressions: EnableWhenExpressions;
|
|
6
6
|
variablesFhirPath: Record<string, Expression[]>;
|
|
7
7
|
existingFhirPathContext: Record<string, any>;
|
|
8
8
|
}
|
|
9
9
|
export declare function evaluateInitialEnableWhenExpressions(params: EvaluateInitialEnableWhenExpressionsParams): {
|
|
10
|
-
initialEnableWhenExpressions:
|
|
10
|
+
initialEnableWhenExpressions: EnableWhenExpressions;
|
|
11
11
|
updatedFhirPathContext: Record<string, any>;
|
|
12
12
|
};
|
|
13
|
-
export declare function
|
|
13
|
+
export declare function evaluateEnableWhenRepeatExpressionInstance(linkId: string, fhirPathContext: Record<string, any>, enableWhenRepeatExpression: EnableWhenRepeatExpression, lastLinkIdIndex: number, instanceIndex: number): {
|
|
14
|
+
isEnabled: boolean | null;
|
|
15
|
+
isUpdated: boolean;
|
|
16
|
+
};
|
|
17
|
+
export declare function evaluateEnableWhenExpressions(fhirPathContext: Record<string, any>, enableWhenExpressions: EnableWhenExpressions): {
|
|
14
18
|
enableWhenExpsIsUpdated: boolean;
|
|
15
|
-
updatedEnableWhenExpressions:
|
|
19
|
+
updatedEnableWhenExpressions: EnableWhenExpressions;
|
|
20
|
+
};
|
|
21
|
+
interface MutateRepeatEnableWhenExpressionInstancesParams {
|
|
22
|
+
questionnaireResponse: QuestionnaireResponse;
|
|
23
|
+
variablesFhirPath: Record<string, Expression[]>;
|
|
24
|
+
existingFhirPathContext: Record<string, any>;
|
|
25
|
+
enableWhenExpressions: EnableWhenExpressions;
|
|
26
|
+
parentRepeatGroupLinkId: string;
|
|
27
|
+
parentRepeatGroupIndex: number;
|
|
28
|
+
actionType: 'add' | 'remove';
|
|
29
|
+
}
|
|
30
|
+
export declare function mutateRepeatEnableWhenExpressionInstances(params: MutateRepeatEnableWhenExpressionInstancesParams): {
|
|
31
|
+
updatedEnableWhenExpressions: EnableWhenExpressions;
|
|
32
|
+
isUpdated: boolean;
|
|
16
33
|
};
|
|
17
34
|
export {};
|
|
@@ -17,84 +17,135 @@
|
|
|
17
17
|
import { createFhirPathContext } from './fhirpath';
|
|
18
18
|
import fhirpath from 'fhirpath';
|
|
19
19
|
import fhirpath_r4_model from 'fhirpath/fhir-context/r4';
|
|
20
|
-
import _isEqual from 'lodash/isEqual';
|
|
21
|
-
import { emptyResponse } from './emptyResource';
|
|
22
|
-
import cloneDeep from 'lodash.clonedeep';
|
|
23
20
|
export function evaluateInitialEnableWhenExpressions(params) {
|
|
24
21
|
const { initialResponse, enableWhenExpressions, variablesFhirPath, existingFhirPathContext } = params;
|
|
25
|
-
// Return early if initialResponse is empty or there are no enableWhen expressions to evaluate
|
|
26
|
-
if (_isEqual(initialResponse, cloneDeep(emptyResponse)) ||
|
|
27
|
-
Object.keys(enableWhenExpressions).length === 0) {
|
|
28
|
-
return {
|
|
29
|
-
initialEnableWhenExpressions: enableWhenExpressions,
|
|
30
|
-
updatedFhirPathContext: existingFhirPathContext
|
|
31
|
-
};
|
|
32
|
-
}
|
|
33
22
|
const initialEnableWhenExpressions = Object.assign({}, enableWhenExpressions);
|
|
34
23
|
const updatedFhirPathContext = createFhirPathContext(initialResponse, variablesFhirPath, existingFhirPathContext);
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
const result = fhirpath.evaluate(initialResponse, enableWhenExpressions[linkId].expression, updatedFhirPathContext, fhirpath_r4_model);
|
|
38
|
-
// Update enableWhenExpressions if length of result array > 0
|
|
39
|
-
if (result.length > 0) {
|
|
40
|
-
updateEnableWhenExpressionStatus(initialEnableWhenExpressions, linkId, result);
|
|
41
|
-
}
|
|
42
|
-
// handle intersect edge case - evaluate() returns empty array if result is false
|
|
43
|
-
if (enableWhenExpressions[linkId].expression.includes('intersect') && result.length === 0) {
|
|
44
|
-
initialEnableWhenExpressions[linkId].isEnabledSingle = false;
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
catch (e) {
|
|
48
|
-
console.warn(e.message, `LinkId: ${linkId}\nExpression: ${enableWhenExpressions[linkId].expression}`);
|
|
49
|
-
}
|
|
50
|
-
}
|
|
24
|
+
const initialEnableWhenSingleExpressions = evaluateEnableWhenSingleExpressions(initialEnableWhenExpressions.singleExpressions, updatedFhirPathContext);
|
|
25
|
+
const initialEnableWhenRepeatExpressions = evaluateEnableWhenRepeatExpressions(initialEnableWhenExpressions.repeatExpressions, updatedFhirPathContext);
|
|
51
26
|
return {
|
|
52
|
-
initialEnableWhenExpressions
|
|
27
|
+
initialEnableWhenExpressions: {
|
|
28
|
+
singleExpressions: initialEnableWhenSingleExpressions.updatedExpressions,
|
|
29
|
+
repeatExpressions: initialEnableWhenRepeatExpressions.updatedExpressions
|
|
30
|
+
},
|
|
53
31
|
updatedFhirPathContext
|
|
54
32
|
};
|
|
55
33
|
}
|
|
56
|
-
|
|
57
|
-
const updatedEnableWhenExpressions = Object.assign({}, enableWhenExpressions);
|
|
34
|
+
function evaluateEnableWhenSingleExpressions(enableWhenSingleExpressions, updatedFhirPathContext) {
|
|
58
35
|
let isUpdated = false;
|
|
59
|
-
for (const linkId in
|
|
36
|
+
for (const linkId in enableWhenSingleExpressions) {
|
|
37
|
+
const initialValue = enableWhenSingleExpressions[linkId].isEnabled;
|
|
38
|
+
const expression = enableWhenSingleExpressions[linkId].expression;
|
|
60
39
|
try {
|
|
61
|
-
const result = fhirpath.evaluate('',
|
|
40
|
+
const result = fhirpath.evaluate('', expression, updatedFhirPathContext, fhirpath_r4_model);
|
|
62
41
|
// Update enableWhenExpressions if length of result array > 0
|
|
63
|
-
|
|
64
|
-
|
|
42
|
+
// Only update when current isEnabled value is different from the result, otherwise it will result in am infinite loop as per #733
|
|
43
|
+
if (result.length > 0 && initialValue !== result[0] && typeof result[0] === 'boolean') {
|
|
44
|
+
enableWhenSingleExpressions[linkId].isEnabled = result[0];
|
|
45
|
+
isUpdated = true;
|
|
65
46
|
}
|
|
66
47
|
// handle intersect edge case - evaluate() returns empty array if result is false
|
|
67
|
-
if (
|
|
68
|
-
|
|
48
|
+
if (enableWhenSingleExpressions[linkId].expression.includes('intersect') &&
|
|
49
|
+
result.length === 0 &&
|
|
50
|
+
initialValue !== false) {
|
|
51
|
+
enableWhenSingleExpressions[linkId].isEnabled = false;
|
|
52
|
+
isUpdated = true;
|
|
69
53
|
}
|
|
70
54
|
}
|
|
71
55
|
catch (e) {
|
|
72
|
-
console.warn(e.message, `LinkId: ${linkId}\nExpression: ${
|
|
56
|
+
console.warn(e.message, `LinkId: ${linkId}\nExpression: ${enableWhenSingleExpressions[linkId].expression}`);
|
|
73
57
|
}
|
|
74
58
|
}
|
|
59
|
+
return { updatedExpressions: enableWhenSingleExpressions, isUpdated };
|
|
60
|
+
}
|
|
61
|
+
function getNumOfEnableWhenExpressionItemInstances(enableWhenExpression, fhirPathContext) {
|
|
62
|
+
const result = fhirpath.evaluate('', `%resource.descendants().where(linkId = '${enableWhenExpression.parentLinkId}').count()`, fhirPathContext, fhirpath_r4_model);
|
|
63
|
+
return typeof result[0] === 'number' ? result[0] : null;
|
|
64
|
+
}
|
|
65
|
+
function evaluateEnableWhenRepeatExpressions(enableWhenRepeatExpressions, fhirPathContext) {
|
|
66
|
+
let aggregatedUpdated = false;
|
|
67
|
+
for (const linkId in enableWhenRepeatExpressions) {
|
|
68
|
+
// Get number of repeat group instances in the QR
|
|
69
|
+
const enableWhenExpression = enableWhenRepeatExpressions[linkId];
|
|
70
|
+
const numOfInstances = getNumOfEnableWhenExpressionItemInstances(enableWhenExpression, fhirPathContext);
|
|
71
|
+
if (!numOfInstances) {
|
|
72
|
+
continue;
|
|
73
|
+
}
|
|
74
|
+
const lastLinkIdIndex = enableWhenExpression.expression.lastIndexOf('.where(linkId');
|
|
75
|
+
if (lastLinkIdIndex === -1) {
|
|
76
|
+
continue;
|
|
77
|
+
}
|
|
78
|
+
for (let i = 0; i < numOfInstances; i++) {
|
|
79
|
+
const { isEnabled, isUpdated } = evaluateEnableWhenRepeatExpressionInstance(linkId, fhirPathContext, enableWhenExpression, lastLinkIdIndex, i);
|
|
80
|
+
if (typeof isEnabled === 'boolean') {
|
|
81
|
+
enableWhenRepeatExpressions[linkId].enabledIndexes[i] = isEnabled;
|
|
82
|
+
}
|
|
83
|
+
aggregatedUpdated = aggregatedUpdated || isUpdated;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
return { updatedExpressions: enableWhenRepeatExpressions, isUpdated: aggregatedUpdated };
|
|
87
|
+
}
|
|
88
|
+
export function evaluateEnableWhenRepeatExpressionInstance(linkId, fhirPathContext, enableWhenRepeatExpression, lastLinkIdIndex, instanceIndex) {
|
|
89
|
+
const expression = enableWhenRepeatExpression.expression;
|
|
90
|
+
const parentLinkId = enableWhenRepeatExpression.parentLinkId;
|
|
91
|
+
const initialValue = enableWhenRepeatExpression.enabledIndexes[instanceIndex];
|
|
92
|
+
const modifiedExpression = expression.slice(0, lastLinkIdIndex) +
|
|
93
|
+
`.where(linkId='${parentLinkId}').item[${instanceIndex}]` +
|
|
94
|
+
expression.slice(lastLinkIdIndex);
|
|
95
|
+
let isEnabled = null;
|
|
96
|
+
let isUpdated = false;
|
|
97
|
+
try {
|
|
98
|
+
const result = fhirpath.evaluate('', modifiedExpression, fhirPathContext, fhirpath_r4_model);
|
|
99
|
+
// Update enableWhenExpressions if length of result array > 0
|
|
100
|
+
// Only update when current isEnabled value is different from the result, otherwise it will result in am infinite loop as per #733
|
|
101
|
+
if (result.length > 0 && initialValue !== result[0] && typeof result[0] === 'boolean') {
|
|
102
|
+
isEnabled = result[0];
|
|
103
|
+
isUpdated = true;
|
|
104
|
+
}
|
|
105
|
+
// handle intersect edge case - evaluate() returns empty array if result is false
|
|
106
|
+
if (expression.includes('intersect') && result.length === 0 && initialValue !== result[0]) {
|
|
107
|
+
isEnabled = false;
|
|
108
|
+
isUpdated = true;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
catch (e) {
|
|
112
|
+
console.warn(e.message, `LinkId: ${linkId}\nExpression: ${expression}`);
|
|
113
|
+
}
|
|
114
|
+
return { isEnabled, isUpdated };
|
|
115
|
+
}
|
|
116
|
+
export function evaluateEnableWhenExpressions(fhirPathContext, enableWhenExpressions) {
|
|
117
|
+
const updatedEnableWhenExpressions = Object.assign({}, enableWhenExpressions);
|
|
118
|
+
const updatedEnableWhenSingleExpressions = evaluateEnableWhenSingleExpressions(updatedEnableWhenExpressions.singleExpressions, fhirPathContext);
|
|
119
|
+
const updatedEnableWhenRepeatExpressions = evaluateEnableWhenRepeatExpressions(updatedEnableWhenExpressions.repeatExpressions, fhirPathContext);
|
|
120
|
+
const isUpdated = updatedEnableWhenSingleExpressions.isUpdated || updatedEnableWhenRepeatExpressions.isUpdated;
|
|
75
121
|
return {
|
|
76
122
|
enableWhenExpsIsUpdated: isUpdated,
|
|
77
|
-
updatedEnableWhenExpressions:
|
|
123
|
+
updatedEnableWhenExpressions: {
|
|
124
|
+
singleExpressions: updatedEnableWhenSingleExpressions.updatedExpressions,
|
|
125
|
+
repeatExpressions: updatedEnableWhenRepeatExpressions.updatedExpressions
|
|
126
|
+
}
|
|
78
127
|
};
|
|
79
128
|
}
|
|
80
|
-
function
|
|
81
|
-
|
|
82
|
-
const
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
if (enableWhenExpressions[linkId].isEnabledMultiple !== result) {
|
|
89
|
-
enableWhenExpressions[linkId].isEnabledMultiple = result;
|
|
90
|
-
return true;
|
|
129
|
+
export function mutateRepeatEnableWhenExpressionInstances(params) {
|
|
130
|
+
const { questionnaireResponse, variablesFhirPath, existingFhirPathContext, enableWhenExpressions, parentRepeatGroupLinkId, parentRepeatGroupIndex, actionType } = params;
|
|
131
|
+
const { repeatExpressions } = enableWhenExpressions;
|
|
132
|
+
const updatedFhirPathContext = createFhirPathContext(questionnaireResponse, variablesFhirPath, existingFhirPathContext);
|
|
133
|
+
let isUpdated = false;
|
|
134
|
+
for (const linkId in repeatExpressions) {
|
|
135
|
+
if (repeatExpressions[linkId].parentLinkId !== parentRepeatGroupLinkId) {
|
|
136
|
+
continue;
|
|
91
137
|
}
|
|
138
|
+
if (actionType === 'add') {
|
|
139
|
+
const { isEnabled } = evaluateEnableWhenRepeatExpressionInstance(linkId, updatedFhirPathContext, repeatExpressions[linkId], repeatExpressions[linkId].expression.lastIndexOf('.where(linkId'), parentRepeatGroupIndex);
|
|
140
|
+
if (typeof isEnabled === 'boolean') {
|
|
141
|
+
repeatExpressions[linkId].enabledIndexes[parentRepeatGroupIndex] = isEnabled;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
else if (actionType === 'remove') {
|
|
145
|
+
repeatExpressions[linkId].enabledIndexes.splice(parentRepeatGroupIndex, 1);
|
|
146
|
+
}
|
|
147
|
+
isUpdated = true;
|
|
92
148
|
}
|
|
93
|
-
|
|
94
|
-
if (enableWhenExpressions[linkId].isEnabledSingle !== result[0]) {
|
|
95
|
-
enableWhenExpressions[linkId].isEnabledSingle = result[0];
|
|
96
|
-
return true;
|
|
97
|
-
}
|
|
98
|
-
return false;
|
|
149
|
+
return { updatedEnableWhenExpressions: enableWhenExpressions, isUpdated };
|
|
99
150
|
}
|
|
100
151
|
//# sourceMappingURL=enableWhenExpression.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"enableWhenExpression.js","sourceRoot":"","sources":["../../src/utils/enableWhenExpression.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;
|
|
1
|
+
{"version":3,"file":"enableWhenExpression.js","sourceRoot":"","sources":["../../src/utils/enableWhenExpression.ts"],"names":[],"mappings":"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"}
|
package/lib/utils/fhirpath.d.ts
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
import type { Expression, QuestionnaireResponse, QuestionnaireResponseItem } from 'fhir/r4';
|
|
2
2
|
import type { CalculatedExpression } from '../interfaces/calculatedExpression.interface';
|
|
3
|
-
import type {
|
|
3
|
+
import type { EnableWhenExpressions } from '../interfaces';
|
|
4
4
|
interface EvaluateUpdatedExpressionsParams {
|
|
5
5
|
updatedResponse: QuestionnaireResponse;
|
|
6
6
|
calculatedExpressions: Record<string, CalculatedExpression>;
|
|
7
|
-
enableWhenExpressions:
|
|
7
|
+
enableWhenExpressions: EnableWhenExpressions;
|
|
8
8
|
variablesFhirPath: Record<string, Expression[]>;
|
|
9
9
|
existingFhirPathContext: Record<string, any>;
|
|
10
10
|
}
|
|
11
11
|
export declare function evaluateUpdatedExpressions(params: EvaluateUpdatedExpressionsParams): {
|
|
12
12
|
isUpdated: boolean;
|
|
13
|
-
updatedEnableWhenExpressions:
|
|
13
|
+
updatedEnableWhenExpressions: EnableWhenExpressions;
|
|
14
14
|
updatedCalculatedExpressions: Record<string, CalculatedExpression>;
|
|
15
15
|
updatedFhirPathContext: Record<string, any>;
|
|
16
16
|
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Expression, Questionnaire, QuestionnaireResponse } from 'fhir/r4';
|
|
2
|
-
import type {
|
|
2
|
+
import type { EnableWhenExpressions, EnableWhenItems } from '../interfaces';
|
|
3
3
|
import type { Tabs } from '../interfaces/tab.interface';
|
|
4
4
|
import type { CalculatedExpression } from '../interfaces/calculatedExpression.interface';
|
|
5
5
|
/**
|
|
@@ -12,7 +12,7 @@ export declare function initialiseQuestionnaireResponse(questionnaire: Questionn
|
|
|
12
12
|
export interface initialFormFromResponseParams {
|
|
13
13
|
questionnaireResponse: QuestionnaireResponse;
|
|
14
14
|
enableWhenItems: EnableWhenItems;
|
|
15
|
-
enableWhenExpressions:
|
|
15
|
+
enableWhenExpressions: EnableWhenExpressions;
|
|
16
16
|
calculatedExpressions: Record<string, CalculatedExpression>;
|
|
17
17
|
variablesFhirPath: Record<string, Expression[]>;
|
|
18
18
|
tabs: Tabs;
|
|
@@ -21,7 +21,7 @@ export interface initialFormFromResponseParams {
|
|
|
21
21
|
export declare function initialiseFormFromResponse(params: initialFormFromResponseParams): {
|
|
22
22
|
initialEnableWhenItems: EnableWhenItems;
|
|
23
23
|
initialEnableWhenLinkedQuestions: Record<string, string[]>;
|
|
24
|
-
initialEnableWhenExpressions:
|
|
24
|
+
initialEnableWhenExpressions: EnableWhenExpressions;
|
|
25
25
|
initialCalculatedExpressions: Record<string, CalculatedExpression>;
|
|
26
26
|
firstVisibleTab: number;
|
|
27
27
|
updatedFhirPathContext: Record<string, any>;
|