@inseefr/lunatic 3.6.5 → 3.6.7
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 +25 -0
- package/components/CheckboxGroup/CustomCheckboxGroup.d.ts +1 -1
- package/components/CheckboxGroup/CustomCheckboxGroup.js.map +1 -1
- package/components/Loop/Loop.d.ts +1 -1
- package/components/Loop/Loop.js +5 -27
- package/components/Loop/Loop.js.map +1 -1
- package/components/Loop/utils.d.ts +8 -0
- package/components/Loop/utils.js +65 -0
- package/components/Loop/utils.js.map +1 -0
- package/components/RosterForLoop/RosterForLoop.js +4 -27
- package/components/RosterForLoop/RosterForLoop.js.map +1 -1
- package/components/Roundabout/CustomRoundabout.js +2 -2
- package/components/Roundabout/CustomRoundabout.js.map +1 -1
- package/components/Roundabout/roundabout.spec.js +22 -0
- package/components/Roundabout/roundabout.spec.js.map +1 -1
- package/components/shared/Checkbox/CheckboxOption.d.ts +4 -2
- package/components/shared/Checkbox/CheckboxOption.js.map +1 -1
- package/components/shared/Radio/RadioGroup.d.ts +1 -1
- package/components/shared/Radio/RadioGroup.js.map +1 -1
- package/esm/components/CheckboxGroup/CustomCheckboxGroup.d.ts +1 -1
- package/esm/components/CheckboxGroup/CustomCheckboxGroup.js.map +1 -1
- package/esm/components/Loop/Loop.d.ts +1 -1
- package/esm/components/Loop/Loop.js +5 -28
- package/esm/components/Loop/Loop.js.map +1 -1
- package/esm/components/Loop/utils.d.ts +8 -0
- package/esm/components/Loop/utils.js +62 -0
- package/esm/components/Loop/utils.js.map +1 -0
- package/esm/components/RosterForLoop/RosterForLoop.js +5 -29
- package/esm/components/RosterForLoop/RosterForLoop.js.map +1 -1
- package/esm/components/Roundabout/CustomRoundabout.js +2 -2
- package/esm/components/Roundabout/CustomRoundabout.js.map +1 -1
- package/esm/components/Roundabout/roundabout.spec.js +22 -0
- package/esm/components/Roundabout/roundabout.spec.js.map +1 -1
- package/esm/components/shared/Checkbox/CheckboxOption.d.ts +4 -2
- package/esm/components/shared/Checkbox/CheckboxOption.js.map +1 -1
- package/esm/components/shared/Radio/RadioGroup.d.ts +1 -1
- package/esm/components/shared/Radio/RadioGroup.js.map +1 -1
- package/esm/use-lunatic/commons/compile-controls.js +33 -7
- package/esm/use-lunatic/commons/compile-controls.js.map +1 -1
- package/esm/use-lunatic/props/propIterations.js +12 -1
- package/esm/use-lunatic/props/propIterations.js.map +1 -1
- package/esm/use-lunatic/reducer/controls/check-base-control.js.map +1 -1
- package/package.json +16 -3
- package/src/components/CheckboxGroup/CustomCheckboxGroup.tsx +1 -0
- package/src/components/Loop/Loop.tsx +6 -35
- package/src/components/Loop/utils.test.ts +39 -0
- package/src/components/Loop/utils.ts +73 -0
- package/src/components/RosterForLoop/RosterForLoop.tsx +3 -33
- package/src/components/Roundabout/CustomRoundabout.tsx +11 -1
- package/src/components/Roundabout/roundabout.spec.tsx +38 -0
- package/src/components/shared/Checkbox/CheckboxOption.tsx +3 -2
- package/src/components/shared/Radio/RadioGroup.tsx +1 -0
- package/src/stories/behaviour/controls/controls.stories.tsx +12 -3
- package/src/stories/behaviour/controls/data-standalone-loop.json +17 -0
- package/src/stories/behaviour/controls/source-standalone-loop.json +5503 -0
- package/src/stories/loop/source-paginated.json +1 -1
- package/src/stories/roundabout/roundabout.stories.tsx +13 -0
- package/src/stories/roundabout/sourceWithControl.json +613 -0
- package/src/use-lunatic/commons/compile-controls.ts +60 -11
- package/src/use-lunatic/props/propIterations.ts +30 -15
- package/src/use-lunatic/reducer/controls/check-base-control.ts +0 -1
- package/src/use-lunatic/use-lunatic-bug.test.ts +42 -0
- package/tsconfig.build.tsbuildinfo +1 -1
- package/use-lunatic/commons/compile-controls.js +31 -7
- package/use-lunatic/commons/compile-controls.js.map +1 -1
- package/use-lunatic/props/propIterations.js +12 -1
- package/use-lunatic/props/propIterations.js.map +1 -1
- package/use-lunatic/reducer/controls/check-base-control.js.map +1 -1
- /package/src/stories/behaviour/controls/{source-loop.json → source-roster-for-loop.json} +0 -0
|
@@ -24,13 +24,28 @@ type InterpretedLoopComponent = DeepTranslateExpression<
|
|
|
24
24
|
componentType: 'Loop' | 'RosterForLoop';
|
|
25
25
|
}
|
|
26
26
|
>;
|
|
27
|
+
type InterpretedRoundaboutComponent = DeepTranslateExpression<
|
|
28
|
+
ComponentDefinition & {
|
|
29
|
+
componentType: 'Roundabout';
|
|
30
|
+
}
|
|
31
|
+
>;
|
|
27
32
|
|
|
33
|
+
/**
|
|
34
|
+
* Check if the component is a Loop or a RosterForLoop
|
|
35
|
+
*/
|
|
28
36
|
const isLoopComponent = (
|
|
29
37
|
component: ComponentDefinition | InterpretedComponent
|
|
30
38
|
): component is InterpretedLoopComponent => {
|
|
31
|
-
return ['Loop', 'RosterForLoop'
|
|
32
|
-
|
|
33
|
-
|
|
39
|
+
return ['Loop', 'RosterForLoop'].includes(component.componentType);
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Check if the component is a Roundabout
|
|
44
|
+
*/
|
|
45
|
+
const isRoundaboutComponent = (
|
|
46
|
+
component: ComponentDefinition | InterpretedComponent
|
|
47
|
+
): component is InterpretedRoundaboutComponent => {
|
|
48
|
+
return component.componentType === 'Roundabout';
|
|
34
49
|
};
|
|
35
50
|
|
|
36
51
|
const isQuestionComponent = (
|
|
@@ -63,7 +78,11 @@ function checkComponents(
|
|
|
63
78
|
}
|
|
64
79
|
}
|
|
65
80
|
|
|
66
|
-
// For
|
|
81
|
+
// For Loop and RosterForLoop, inspect iterations for row controls
|
|
82
|
+
if (isRoundaboutComponent(component))
|
|
83
|
+
errors = checkRoundabout(state, component, errors);
|
|
84
|
+
|
|
85
|
+
// For Loop and RosterForLoop, inspect children
|
|
67
86
|
if (isLoopComponent(component))
|
|
68
87
|
errors = checkLoop(state, component, errors);
|
|
69
88
|
|
|
@@ -75,6 +94,22 @@ function checkComponents(
|
|
|
75
94
|
return errors;
|
|
76
95
|
}
|
|
77
96
|
|
|
97
|
+
function checkRoundabout(
|
|
98
|
+
state: StateForControls,
|
|
99
|
+
component: InterpretedRoundaboutComponent,
|
|
100
|
+
errors: Record<string, LunaticError[]>
|
|
101
|
+
) {
|
|
102
|
+
const rowControls = component.controls?.filter((c) => c.type === 'ROW');
|
|
103
|
+
if (rowControls?.length) {
|
|
104
|
+
errors = checkComponentInLoop(
|
|
105
|
+
state,
|
|
106
|
+
{ ...component, controls: rowControls },
|
|
107
|
+
errors
|
|
108
|
+
);
|
|
109
|
+
}
|
|
110
|
+
return errors;
|
|
111
|
+
}
|
|
112
|
+
|
|
78
113
|
function checkLoop(
|
|
79
114
|
state: StateForControls,
|
|
80
115
|
component: InterpretedLoopComponent,
|
|
@@ -101,14 +136,12 @@ function checkControls(
|
|
|
101
136
|
): LunaticError[] {
|
|
102
137
|
return controls
|
|
103
138
|
.map((control) => {
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
return checkRoundaboutControl(control, executeExpression);
|
|
107
|
-
default:
|
|
108
|
-
return checkBaseControl(control, executeExpression, pager);
|
|
139
|
+
if (control.type === 'roundabout') {
|
|
140
|
+
return checkRoundaboutControl(control, executeExpression);
|
|
109
141
|
}
|
|
142
|
+
return checkBaseControl(control, executeExpression, pager);
|
|
110
143
|
})
|
|
111
|
-
.filter((error) => error !== undefined)
|
|
144
|
+
.filter((error) => error !== undefined);
|
|
112
145
|
}
|
|
113
146
|
|
|
114
147
|
/**
|
|
@@ -152,7 +185,10 @@ function computeIterations(
|
|
|
152
185
|
*/
|
|
153
186
|
function checkComponentInLoop(
|
|
154
187
|
state: StateForControls,
|
|
155
|
-
component:
|
|
188
|
+
component:
|
|
189
|
+
| ComponentDefinition
|
|
190
|
+
| InterpretedLoopComponent
|
|
191
|
+
| InterpretedRoundaboutComponent,
|
|
156
192
|
errors: Record<string, LunaticError[]>
|
|
157
193
|
): Record<string, LunaticError[]> {
|
|
158
194
|
// For Question, loop over children
|
|
@@ -181,6 +217,19 @@ function checkComponentInLoop(
|
|
|
181
217
|
if (!('controls' in component) || !component.controls) {
|
|
182
218
|
continue;
|
|
183
219
|
}
|
|
220
|
+
|
|
221
|
+
// For Roundabout, we don't check controls for iterations that are disabled
|
|
222
|
+
if (component.componentType === 'Roundabout' && component.item.disabled) {
|
|
223
|
+
const isIterationDisabled = state.executeExpression(
|
|
224
|
+
{ value: component.item.disabled?.value, type: 'VTL' },
|
|
225
|
+
iterationPager
|
|
226
|
+
);
|
|
227
|
+
|
|
228
|
+
if (isIterationDisabled) {
|
|
229
|
+
continue;
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
|
|
184
233
|
// The component is filtered on this iteration, skip it
|
|
185
234
|
if (
|
|
186
235
|
// conditionFilter can be the interpreted expression, or the object representing the expression
|
|
@@ -32,20 +32,35 @@ export function getIterationsProp(
|
|
|
32
32
|
|
|
33
33
|
// Iterations expression is not present on the component definition
|
|
34
34
|
// infer it from the value of child components
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
return acc;
|
|
39
|
-
}
|
|
40
|
-
const value = state.variables.get(
|
|
41
|
-
component.response.name,
|
|
42
|
-
isNumber(state.pager.iteration) ? [state.pager.iteration] : undefined
|
|
43
|
-
);
|
|
44
|
-
if (Array.isArray(value) && value.length > acc) {
|
|
45
|
-
return value.length;
|
|
46
|
-
}
|
|
35
|
+
|
|
36
|
+
return getFlatComponentsInLoop(definition).reduce((acc, component) => {
|
|
37
|
+
if (!hasResponse(component)) {
|
|
47
38
|
return acc;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
|
|
39
|
+
}
|
|
40
|
+
const value = state.variables.get(
|
|
41
|
+
component.response.name,
|
|
42
|
+
isNumber(state.pager.iteration) ? [state.pager.iteration] : undefined
|
|
43
|
+
);
|
|
44
|
+
if (Array.isArray(value) && value.length > acc) {
|
|
45
|
+
return value.length;
|
|
46
|
+
}
|
|
47
|
+
return acc;
|
|
48
|
+
}, 0);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function getFlatComponentsInLoop(
|
|
52
|
+
definition: LunaticComponentDefinition
|
|
53
|
+
): LunaticComponentDefinition[] {
|
|
54
|
+
if (
|
|
55
|
+
definition.componentType !== 'RosterForLoop' &&
|
|
56
|
+
definition.componentType !== 'Loop'
|
|
57
|
+
) {
|
|
58
|
+
return [definition];
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
return definition.components.reduce((acc, component) => {
|
|
62
|
+
if (component.componentType === 'Question')
|
|
63
|
+
return [...acc, ...component.components];
|
|
64
|
+
return [...acc, component];
|
|
65
|
+
}, [] as LunaticComponentDefinition[]);
|
|
51
66
|
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { act, renderHook } from '@testing-library/react';
|
|
2
|
+
import { describe, expect, it } from 'vitest';
|
|
3
|
+
|
|
4
|
+
import loopControlSource from '../stories/behaviour/controls/source-standalone-loop.json';
|
|
5
|
+
import surveyUnit from '../stories/behaviour/controls/data-standalone-loop.json';
|
|
6
|
+
import { useLunatic } from './use-lunatic';
|
|
7
|
+
|
|
8
|
+
describe('use-lunatic()', () => {
|
|
9
|
+
/**
|
|
10
|
+
* This test should be succeded after make some improvment
|
|
11
|
+
* See: comment above useEffect of src/components/Loop/utils.ts > useLoopUtils
|
|
12
|
+
*/
|
|
13
|
+
it.skip('should compile errors correctly', () => {
|
|
14
|
+
const { result } = renderHook(() =>
|
|
15
|
+
useLunatic(loopControlSource, surveyUnit.data)
|
|
16
|
+
);
|
|
17
|
+
act(() => {
|
|
18
|
+
result.current.goToPage({ page: '3' });
|
|
19
|
+
});
|
|
20
|
+
const { currentErrors } = result.current.compileControls();
|
|
21
|
+
expect(currentErrors).not.toBeUndefined();
|
|
22
|
+
expect(Object.keys(currentErrors!).length).toEqual(6);
|
|
23
|
+
});
|
|
24
|
+
it('should compile errors correctly 2', () => {
|
|
25
|
+
const { result } = renderHook(() =>
|
|
26
|
+
useLunatic(loopControlSource, {
|
|
27
|
+
COLLECTED: {
|
|
28
|
+
PRES_SAL: { COLLECTED: ['1', null, '2', null, null, null] },
|
|
29
|
+
},
|
|
30
|
+
...surveyUnit.data,
|
|
31
|
+
})
|
|
32
|
+
);
|
|
33
|
+
act(() => {
|
|
34
|
+
result.current.goToPage({ page: '3' });
|
|
35
|
+
});
|
|
36
|
+
act(() => {
|
|
37
|
+
const { currentErrors } = result.current.compileControls();
|
|
38
|
+
expect(currentErrors).not.toBeUndefined();
|
|
39
|
+
expect(Object.keys(currentErrors!).length).toEqual(4);
|
|
40
|
+
});
|
|
41
|
+
});
|
|
42
|
+
});
|