@openmrs/esm-form-engine-lib 3.0.0-pre.1636 → 3.0.0-pre.1637
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/061e32979240d73f/061e32979240d73f.gz +0 -0
- package/1f09c0a0fe19adb9/1f09c0a0fe19adb9.gz +0 -0
- package/3ccbe3e56feebb71/3ccbe3e56feebb71.gz +0 -0
- package/__mocks__/forms/rfe-forms/obs-group-test_form.json +188 -124
- package/d85de193c6bc805e/d85de193c6bc805e.gz +0 -0
- package/package.json +1 -1
- package/src/components/group/obs-group.component.tsx +5 -5
- package/src/form-engine.test.tsx +44 -0
Binary file
|
Binary file
|
Binary file
|
@@ -1,137 +1,201 @@
|
|
1
1
|
{
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
"
|
20
|
-
"
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
2
|
+
"name": "ObsGroup Test Form",
|
3
|
+
"version": "1",
|
4
|
+
"published": true,
|
5
|
+
"retired": false,
|
6
|
+
"pages": [
|
7
|
+
{
|
8
|
+
"label": "Obs Group Page",
|
9
|
+
"sections": [
|
10
|
+
{
|
11
|
+
"label": "Group Section",
|
12
|
+
"isExpanded": "true",
|
13
|
+
"questions": [
|
14
|
+
{
|
15
|
+
"id": "myGroup",
|
16
|
+
"label": "My Group",
|
17
|
+
"type": "obsGroup",
|
18
|
+
"questionOptions": {
|
19
|
+
"rendering": "repeating",
|
20
|
+
"concept": "1c70c490-cafa-4c95-9fdd-a30b62bb78b8"
|
21
|
+
},
|
22
|
+
"behaviours": [
|
23
|
+
{
|
24
|
+
"intent": "*",
|
25
|
+
"required": "false",
|
26
|
+
"unspecified": "false",
|
27
|
+
"hide": {
|
28
|
+
"hideWhenExpression": ""
|
29
|
+
},
|
30
|
+
"validators": []
|
31
|
+
}
|
32
|
+
],
|
33
|
+
"questions": [
|
34
|
+
{
|
35
|
+
"label": "Sex",
|
36
|
+
"type": "obs",
|
37
|
+
"required": "true",
|
38
|
+
"questionOptions": {
|
39
|
+
"rendering": "radio",
|
40
|
+
"concept": "1587AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
|
41
|
+
"answers": [
|
42
|
+
{
|
43
|
+
"concept": "1535AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
|
44
|
+
"label": "Female"
|
45
|
+
},
|
46
|
+
{
|
47
|
+
"concept": "1534AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
|
48
|
+
"label": "Male"
|
49
|
+
}
|
50
|
+
]
|
51
|
+
},
|
52
|
+
"id": "childSex",
|
53
|
+
"behaviours": [
|
54
|
+
{
|
55
|
+
"intent": "*",
|
56
|
+
"required": "true",
|
57
|
+
"unspecified": "true",
|
58
|
+
"hide": {
|
59
|
+
"hideWhenExpression": "false"
|
60
|
+
},
|
61
|
+
"validators": []
|
62
|
+
}
|
63
|
+
]
|
42
64
|
},
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
"
|
48
|
-
"
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
"
|
61
|
-
"concept":"1587AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
|
62
|
-
"answers":[
|
65
|
+
{
|
66
|
+
"label": "Date of Birth",
|
67
|
+
"type": "obs",
|
68
|
+
"questionOptions": {
|
69
|
+
"rendering": "date",
|
70
|
+
"concept": "164802AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
|
71
|
+
"weeksList": ""
|
72
|
+
},
|
73
|
+
"id": "birthDate",
|
74
|
+
"behaviours": [
|
75
|
+
{
|
76
|
+
"intent": "*",
|
77
|
+
"required": "true",
|
78
|
+
"unspecified": "true",
|
79
|
+
"hide": {
|
80
|
+
"hideWhenExpression": "false"
|
81
|
+
},
|
82
|
+
"validators": [
|
63
83
|
{
|
64
|
-
"
|
65
|
-
"
|
84
|
+
"type": "date",
|
85
|
+
"allowFutureDates": "false"
|
66
86
|
},
|
67
87
|
{
|
68
|
-
"
|
69
|
-
"
|
88
|
+
"type": "js_expression",
|
89
|
+
"failsWhenExpression": "!isDateEqualTo(myValue, useFieldValue('visit_date'))",
|
90
|
+
"message": "Child birth date should be the same as the visit date!"
|
70
91
|
}
|
71
92
|
]
|
72
|
-
}
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
93
|
+
}
|
94
|
+
]
|
95
|
+
}
|
96
|
+
]
|
97
|
+
}
|
98
|
+
]
|
99
|
+
},
|
100
|
+
{
|
101
|
+
"label": "Screening Section",
|
102
|
+
"questions": [
|
103
|
+
{
|
104
|
+
"label": "Do you have dependents?",
|
105
|
+
"id": "hasDependents",
|
106
|
+
"type": "obs",
|
107
|
+
"questionOptions": {
|
108
|
+
"rendering": "radio",
|
109
|
+
"concept": "a89e3f94-1350-11df-a1f1-0026b9348837",
|
110
|
+
"answers": [
|
111
|
+
{
|
112
|
+
"concept": "a89ce50e-1350-11df-a1f1-0026b9348839",
|
113
|
+
"label": "Yes"
|
85
114
|
},
|
86
115
|
{
|
87
|
-
"
|
88
|
-
"
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
116
|
+
"concept": "a89ce50e-1350-11df-a1f1-0026b9348838",
|
117
|
+
"label": "No"
|
118
|
+
}
|
119
|
+
]
|
120
|
+
}
|
121
|
+
}
|
122
|
+
]
|
123
|
+
},
|
124
|
+
{
|
125
|
+
"label": "Groups with Hide logic",
|
126
|
+
"questions": [
|
127
|
+
{
|
128
|
+
"type": "obsGroup",
|
129
|
+
"label": "Dependents Group",
|
130
|
+
"id": "dependentGroup",
|
131
|
+
"questionOptions": {
|
132
|
+
"concept": "3665d0ef-3718-47b2-9091-8b685bda412d",
|
133
|
+
"rendering": "group"
|
134
|
+
},
|
135
|
+
"questions": [
|
136
|
+
{
|
137
|
+
"label": "Dependent Type",
|
138
|
+
"id": "dependentType",
|
139
|
+
"type": "obs",
|
140
|
+
"questionOptions": {
|
141
|
+
"rendering": "radio",
|
142
|
+
"concept": "a89e3f94-1350-11df-a1f1-0026b9348838",
|
143
|
+
"answers": [
|
96
144
|
{
|
97
|
-
"
|
98
|
-
"
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
"validators": [
|
104
|
-
{
|
105
|
-
"type": "date",
|
106
|
-
"allowFutureDates": "false"
|
107
|
-
},
|
108
|
-
{
|
109
|
-
"type": "js_expression",
|
110
|
-
"failsWhenExpression": "!isDateEqualTo(myValue, useFieldValue('visit_date'))",
|
111
|
-
"message": "Child birth date should be the same as the visit date!"
|
112
|
-
}
|
113
|
-
]
|
145
|
+
"concept": "6daff4ce-bce7-41f5-9141-17e694155180",
|
146
|
+
"label": "Child"
|
147
|
+
},
|
148
|
+
{
|
149
|
+
"concept": "a89ce50e-1350-11df-a1f1-0026b9348838",
|
150
|
+
"label": "Spouse"
|
114
151
|
}
|
115
152
|
]
|
153
|
+
},
|
154
|
+
"hide": {
|
155
|
+
"hideWhenExpression": "hasDependents !== 'a89ce50e-1350-11df-a1f1-0026b9348839'"
|
116
156
|
}
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
157
|
+
},
|
158
|
+
{
|
159
|
+
"label": "Dependent Name",
|
160
|
+
"id": "dependentName",
|
161
|
+
"type": "obs",
|
162
|
+
"questionOptions": {
|
163
|
+
"rendering": "text",
|
164
|
+
"concept": "a8a06fc6-1350-11df-a1f1-0026b9348838"
|
165
|
+
},
|
166
|
+
"hide": {
|
167
|
+
"hideWhenExpression": "isEmpty(dependentType)"
|
168
|
+
}
|
169
|
+
},
|
170
|
+
{
|
171
|
+
"label": "Dependent Age",
|
172
|
+
"id": "dependentAge",
|
173
|
+
"type": "obs",
|
174
|
+
"questionOptions": {
|
175
|
+
"rendering": "number",
|
176
|
+
"concept": "a8a06fc6-1350-11df-a1f1-0026b9348839"
|
177
|
+
},
|
178
|
+
"hide": {
|
179
|
+
"hideWhenExpression": "dependentType !== '6daff4ce-bce7-41f5-9141-17e694155180'"
|
180
|
+
}
|
181
|
+
}
|
182
|
+
]
|
183
|
+
}
|
184
|
+
]
|
185
|
+
}
|
186
|
+
]
|
187
|
+
}
|
188
|
+
],
|
189
|
+
"availableIntents": [
|
190
|
+
{
|
191
|
+
"intent": "*",
|
192
|
+
"display": "ObsGroup Test Form"
|
193
|
+
}
|
194
|
+
],
|
195
|
+
"processor": "EncounterFormProcessor",
|
196
|
+
"uuid": "8f713e0e-94a0-3c57-9024-69520933802a",
|
197
|
+
"referencedForms": [],
|
198
|
+
"encounterType": "7e54cd64-f9c3-11eb-8e6a-57478ce139b0",
|
199
|
+
"encounter": "Obs Group Test",
|
200
|
+
"allowUnspecifiedAll": true
|
201
|
+
}
|
Binary file
|
package/package.json
CHANGED
@@ -9,13 +9,13 @@ import { useTranslation } from 'react-i18next';
|
|
9
9
|
|
10
10
|
export const ObsGroup: React.FC<FormFieldInputProps> = ({ field, ...restProps }) => {
|
11
11
|
const { t } = useTranslation();
|
12
|
-
const { formFieldAdapters } = useFormProviderContext();
|
13
|
-
const showLabel = useMemo(() => field.questions?.length > 1, [field]);
|
12
|
+
const { formFieldAdapters, formFields } = useFormProviderContext();
|
14
13
|
|
15
14
|
const content = useMemo(
|
16
15
|
() =>
|
17
16
|
field.questions
|
18
|
-
|
17
|
+
.map((child) => formFields.find((field) => field.id === child.id))
|
18
|
+
.filter((child) => !child.isHidden)
|
19
19
|
.map((child, index) => {
|
20
20
|
const key = `${child.id}_${index}`;
|
21
21
|
|
@@ -35,12 +35,12 @@ export const ObsGroup: React.FC<FormFieldInputProps> = ({ field, ...restProps })
|
|
35
35
|
);
|
36
36
|
}
|
37
37
|
}),
|
38
|
-
[field],
|
38
|
+
[field, formFields],
|
39
39
|
);
|
40
40
|
|
41
41
|
return (
|
42
42
|
<div className={styles.groupContainer}>
|
43
|
-
{
|
43
|
+
{content.length > 1 ? (
|
44
44
|
<FormGroup legendText={t(field.label)} className={styles.boldLegend}>
|
45
45
|
{content}
|
46
46
|
</FormGroup>
|
package/src/form-engine.test.tsx
CHANGED
@@ -876,6 +876,50 @@ describe('Form engine component', () => {
|
|
876
876
|
});
|
877
877
|
|
878
878
|
describe('Obs group', () => {
|
879
|
+
it('should not render empty obs group', async () => {
|
880
|
+
await act(async () => {
|
881
|
+
renderForm(null, obsGroupTestForm);
|
882
|
+
});
|
883
|
+
|
884
|
+
// Check that only one obs group is initially rendered
|
885
|
+
const initialGroups = screen.getAllByRole('group', { name: /My Group|Dependents Group/i });
|
886
|
+
expect(initialGroups.length).toBe(1);
|
887
|
+
const dependentTypeRadios = screen.queryAllByRole('radio', { name: /child|spouse/i });
|
888
|
+
expect(dependentTypeRadios.length).toBe(0);
|
889
|
+
|
890
|
+
// Select "Yes" for having dependents
|
891
|
+
const yesRadio = screen.getByRole('radio', { name: /yes/i });
|
892
|
+
await user.click(yesRadio);
|
893
|
+
|
894
|
+
// Now the dependent type radios should be visible
|
895
|
+
const visibleDependentTypeRadios = screen.getAllByRole('radio', { name: /child|spouse/i });
|
896
|
+
expect(visibleDependentTypeRadios.length).toBe(2);
|
897
|
+
|
898
|
+
// Check that the group label is still hidden since it only has one visible field
|
899
|
+
const dependentsGroupResults = screen.queryAllByRole('group', { name: /Dependents Group/i });
|
900
|
+
expect(dependentsGroupResults.length).toBe(0);
|
901
|
+
|
902
|
+
// Check that dependent name and age are still hidden
|
903
|
+
const hiddenDependentNameInput = screen.queryByRole('textbox', { name: /dependent name/i });
|
904
|
+
const hiddenDependentAgeInput = screen.queryByRole('spinbutton', { name: /dependent age/i });
|
905
|
+
expect(hiddenDependentNameInput).toBeNull();
|
906
|
+
expect(hiddenDependentAgeInput).toBeNull();
|
907
|
+
|
908
|
+
// Select "Child" as dependent type
|
909
|
+
await user.click(visibleDependentTypeRadios[0]);
|
910
|
+
|
911
|
+
// Check the visibility of the group label
|
912
|
+
const dependentsGroup = screen.getAllByRole('group', { name: /Dependents Group/i })[0];
|
913
|
+
expect(dependentsGroup).toBeInTheDocument();
|
914
|
+
|
915
|
+
// Check that dependent name and age are now visible
|
916
|
+
const dependentNameInput = screen.getByRole('textbox', { name: /dependent name/i });
|
917
|
+
const dependentAgeInput = screen.getByRole('spinbutton', { name: /dependent age/i });
|
918
|
+
|
919
|
+
expect(dependentNameInput).toBeInTheDocument();
|
920
|
+
expect(dependentAgeInput).toBeInTheDocument();
|
921
|
+
});
|
922
|
+
|
879
923
|
it('should save obs group on form submission', async () => {
|
880
924
|
const saveEncounterMock = jest.spyOn(api, 'saveEncounter');
|
881
925
|
await act(async () => {
|