@inseefr/lunatic 0.3.0-experimental → 0.3.4-experimental
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/index.js +218 -260
- package/lib/index.js.map +1 -1
- package/package.json +2 -2
- package/src/components/component-wrapper/controls/validators/datepicker.js +25 -14
- package/src/components/component-wrapper/missing/component.js +37 -17
- package/src/components/datepicker/component.js +8 -12
- package/src/components/declarations/wrappers/input-declarations-wrapper.js +31 -9
- package/src/components/dropdown/commons/components/dropdown.js +21 -0
- package/src/components/dropdown/dropdown-edit/dropdown-edit.js +4 -1
- package/src/components/dropdown/dropdown-simple/dropdown.js +3 -1
- package/src/components/input/input-number.js +2 -1
- package/src/components/loop-constructor/block/index.js +1 -1
- package/src/components/loop-constructor/index.js +1 -1
- package/src/components/loop-constructor/roster/index.js +1 -1
- package/src/components/loop-constructor/wrapper/body-component.js +3 -0
- package/src/components/loop-constructor/wrapper/build-components.js +33 -33
- package/src/components/loop-constructor/wrapper/index.js +1 -1
- package/src/components/suggester/components/panel/option-container.js +1 -1
- package/src/components/suggester/components/suggester-content.js +42 -42
- package/src/components/suggester/components/suggester.js +43 -3
- package/src/components/suggester/idb-suggester.js +7 -1
- package/src/components/suggester/lunatic-suggester.js +1 -0
- package/src/components/suggester/suggester-wrapper.js +9 -3
- package/src/components/table/table.js +3 -1
- package/src/stories/loop-constructor/README.md +27 -27
- package/src/stories/loop-constructor/data-input-forced.json +64 -64
- package/src/stories/loop-constructor/data-input.json +100 -100
- package/src/stories/loop-constructor/data-loop-forced.json +66 -66
- package/src/stories/loop-constructor/data-loop-static-forced.json +66 -66
- package/src/stories/loop-constructor/data-loop-static.json +81 -81
- package/src/stories/loop-constructor/data-loop.json +81 -81
- package/src/stories/loop-constructor/data-roster-forced.json +68 -68
- package/src/stories/loop-constructor/data-roster.json +83 -83
- package/src/stories/loop-constructor/loop-constructor.stories.js +180 -180
- package/src/stories/questionnaire/arithmetic-management.json +47 -0
- package/src/stories/questionnaire/logement-queen.json +23389 -22705
- package/src/stories/questionnaire/logement-s2.json +46027 -44536
- package/src/stories/questionnaire/questionnaire.stories.js +46 -13
- package/src/stories/questionnaire/update-external/data.json +1 -0
- package/src/stories/questionnaire/update-external/questionnaire.json +75 -0
- package/src/stories/suggester/data.json +4 -1
- package/src/stories/suggester/suggester-workers.stories.js +4 -1
- package/src/stories/utils/orchestrator-split.js +119 -0
- package/src/stories/utils/orchestrator.js +12 -3
- package/src/tests/utils/to-expose/handler/results/res-input-edited.json +158 -158
- package/src/tests/utils/to-expose/state/state.spec.js +59 -59
- package/src/utils/lib/index.js +1 -0
- package/src/utils/lib/pagination/navigation/shared.js +5 -5
- package/src/utils/lib/splitting.js +142 -0
- package/src/utils/suggester-workers/commons-tokenizer/create-entity-tokenizer.js +4 -2
- package/src/utils/suggester-workers/commons-tokenizer/filters/{filter-accents-to-lower.js → filter-accents.js} +2 -2
- package/src/utils/suggester-workers/commons-tokenizer/filters/{filter-accents-to-lower.spec.js → filter-accents.spec.js} +1 -1
- package/src/utils/suggester-workers/commons-tokenizer/filters/filter-synonyms.js +27 -1
- package/src/utils/suggester-workers/commons-tokenizer/filters/filter-to-lower.js +10 -0
- package/src/utils/suggester-workers/commons-tokenizer/filters/filter-to-lower.spec.js +12 -0
- package/src/utils/suggester-workers/commons-tokenizer/index.js +1 -1
- package/src/utils/to-expose/handler.js +67 -28
- package/src/utils/to-expose/hooks/filter-components.js +106 -106
- package/src/utils/to-expose/hooks/index.js +2 -1
- package/src/utils/to-expose/hooks/lunatic-split.js +421 -0
- package/src/utils/to-expose/hooks/lunatic.js +39 -7
- package/src/utils/to-expose/index.js +11 -11
- package/src/utils/to-expose/state.js +23 -15
|
@@ -0,0 +1,421 @@
|
|
|
1
|
+
import { useState, useEffect, useCallback, useMemo } from 'react';
|
|
2
|
+
import { mergeQuestionnaireAndData } from '../init-questionnaire';
|
|
3
|
+
import { getBindings } from '../state';
|
|
4
|
+
import { updateQuestionnaire, updateExternals } from '../handler';
|
|
5
|
+
import {
|
|
6
|
+
getPage,
|
|
7
|
+
FLOW_NEXT,
|
|
8
|
+
FLOW_PREVIOUS,
|
|
9
|
+
getControls,
|
|
10
|
+
isDev,
|
|
11
|
+
getSplitQuestionnaireSource,
|
|
12
|
+
mergeStateData,
|
|
13
|
+
getRootPageInSources,
|
|
14
|
+
} from '../../lib';
|
|
15
|
+
import { COLLECTED } from '../../../constants';
|
|
16
|
+
import { useFilterComponents } from './filter-components';
|
|
17
|
+
import { loadSuggesters } from '../../store-tools/auto-load';
|
|
18
|
+
import { getCollectedStateByValueType, getState } from '..';
|
|
19
|
+
|
|
20
|
+
const defaultData = {};
|
|
21
|
+
const defaultPreferences = [COLLECTED];
|
|
22
|
+
const defaultFeatures = ['VTL'];
|
|
23
|
+
|
|
24
|
+
const useLunaticSplit = (
|
|
25
|
+
source,
|
|
26
|
+
data = defaultData,
|
|
27
|
+
{
|
|
28
|
+
savingType = COLLECTED,
|
|
29
|
+
preferences = defaultPreferences,
|
|
30
|
+
features = defaultFeatures,
|
|
31
|
+
management = false,
|
|
32
|
+
pagination = false,
|
|
33
|
+
modalForControls = false,
|
|
34
|
+
initialPage = null,
|
|
35
|
+
logFunction = null,
|
|
36
|
+
autoSuggesterLoading = false,
|
|
37
|
+
suggesterFetcher,
|
|
38
|
+
suggesters,
|
|
39
|
+
}
|
|
40
|
+
) => {
|
|
41
|
+
if (isDev) {
|
|
42
|
+
console.log('useLunaticSplit');
|
|
43
|
+
var start = new Date().getTime();
|
|
44
|
+
}
|
|
45
|
+
const fullQuestionnaire = useMemo(
|
|
46
|
+
() => mergeQuestionnaireAndData(source)(data),
|
|
47
|
+
[source, data]
|
|
48
|
+
);
|
|
49
|
+
const sources = useMemo(() => getSplitQuestionnaireSource(source), [source]);
|
|
50
|
+
const allData = useMemo(
|
|
51
|
+
() => getState(fullQuestionnaire),
|
|
52
|
+
[fullQuestionnaire]
|
|
53
|
+
);
|
|
54
|
+
const [allBindings, setAllBindings] = useState(() =>
|
|
55
|
+
getBindings(fullQuestionnaire)
|
|
56
|
+
);
|
|
57
|
+
|
|
58
|
+
const rootPagesOfSource = useMemo(
|
|
59
|
+
() => getRootPageInSources(sources),
|
|
60
|
+
[sources]
|
|
61
|
+
);
|
|
62
|
+
|
|
63
|
+
const [sourceIndex, setSourceIndex] = useState(0);
|
|
64
|
+
const [lunaticData, setLunaticData] = useState(allData);
|
|
65
|
+
|
|
66
|
+
const [initPage, setInitPage] = useState(false);
|
|
67
|
+
const featuresWithoutMD = features.filter((f) => f !== 'MD');
|
|
68
|
+
|
|
69
|
+
const [questionnaire, setQuestionnaire] = useState(() =>
|
|
70
|
+
mergeQuestionnaireAndData(sources[sourceIndex])(lunaticData)
|
|
71
|
+
);
|
|
72
|
+
const [bindings, setBindings] = useState(() => getBindings(questionnaire));
|
|
73
|
+
|
|
74
|
+
const [wantedPage, setWantedPage] = useState(null);
|
|
75
|
+
|
|
76
|
+
// updating current source
|
|
77
|
+
useEffect(() => {
|
|
78
|
+
setInitPage(false);
|
|
79
|
+
const newQ = mergeQuestionnaireAndData(sources[sourceIndex])(lunaticData);
|
|
80
|
+
setQuestionnaire(newQ);
|
|
81
|
+
const bind = getBindings(newQ);
|
|
82
|
+
setBindings(bind);
|
|
83
|
+
setAllBindings({ ...allBindings, ...bind });
|
|
84
|
+
|
|
85
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
86
|
+
}, [sources, sourceIndex]);
|
|
87
|
+
|
|
88
|
+
const getBindingsSplit = (quest) => {
|
|
89
|
+
const bind = getBindings(quest);
|
|
90
|
+
return { ...allBindings, ...bind };
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
function getStateSplit(quest) {
|
|
94
|
+
const lastState = getState(quest);
|
|
95
|
+
return mergeStateData(lunaticData, lastState);
|
|
96
|
+
}
|
|
97
|
+
const getCollectedStateSplit = (quest) => {
|
|
98
|
+
const lastState = getStateSplit(quest);
|
|
99
|
+
return lastState[COLLECTED];
|
|
100
|
+
};
|
|
101
|
+
const getCollectedStateByValueTypeSplit =
|
|
102
|
+
(quest) => (valueType, displayNull) => {
|
|
103
|
+
return getCollectedStateByValueType(null, getCollectedStateSplit(quest))(
|
|
104
|
+
valueType,
|
|
105
|
+
displayNull
|
|
106
|
+
);
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
const [page, setPage] = useState(questionnaire.firstPage);
|
|
110
|
+
|
|
111
|
+
const [todo, setTodo] = useState({});
|
|
112
|
+
const [todoExternals, setTodoExternals] = useState({});
|
|
113
|
+
const [modalContent, setModalContent] = useState(null);
|
|
114
|
+
|
|
115
|
+
const components = useFilterComponents({
|
|
116
|
+
questionnaire,
|
|
117
|
+
management,
|
|
118
|
+
bindings,
|
|
119
|
+
features: featuresWithoutMD,
|
|
120
|
+
page,
|
|
121
|
+
pagination,
|
|
122
|
+
todo: { ...todo, ...todoExternals },
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
const { suggesters: suggestersToLoad } = source;
|
|
126
|
+
|
|
127
|
+
useEffect(() => {
|
|
128
|
+
const init = async () => {
|
|
129
|
+
if (
|
|
130
|
+
autoSuggesterLoading &&
|
|
131
|
+
typeof suggesters === 'object' &&
|
|
132
|
+
Object.values(suggesters).length > 0
|
|
133
|
+
) {
|
|
134
|
+
const s = suggestersToLoad.reduce(function (current, storeInfo) {
|
|
135
|
+
const { name } = storeInfo;
|
|
136
|
+
if (!suggesters[name]) return current;
|
|
137
|
+
return {
|
|
138
|
+
...current,
|
|
139
|
+
[name]: {
|
|
140
|
+
...storeInfo,
|
|
141
|
+
url: suggesters[name].url,
|
|
142
|
+
stopWords: suggesters[name].stopWords,
|
|
143
|
+
},
|
|
144
|
+
};
|
|
145
|
+
}, {});
|
|
146
|
+
loadSuggesters(suggesterFetcher)(s);
|
|
147
|
+
}
|
|
148
|
+
};
|
|
149
|
+
init();
|
|
150
|
+
}, [autoSuggesterLoading, suggesterFetcher, suggesters, suggestersToLoad]);
|
|
151
|
+
|
|
152
|
+
const [flow, setFlow] = useState(null);
|
|
153
|
+
|
|
154
|
+
// TODO: dynamic because of filters (kind of last accessible page)
|
|
155
|
+
const { firstPage, maxPage } = questionnaire;
|
|
156
|
+
|
|
157
|
+
const isFirstPage = page === firstPage;
|
|
158
|
+
const isLastPage = page === maxPage;
|
|
159
|
+
const isFirstSource = sourceIndex === 0;
|
|
160
|
+
const isLastSource = sourceIndex === sources.length - 1;
|
|
161
|
+
|
|
162
|
+
const goSplitNext = () => {
|
|
163
|
+
if (!isLastSource) {
|
|
164
|
+
const stateData = getState(questionnaire);
|
|
165
|
+
setLunaticData(mergeStateData(lunaticData, stateData));
|
|
166
|
+
setSourceIndex(sourceIndex + 1);
|
|
167
|
+
}
|
|
168
|
+
};
|
|
169
|
+
|
|
170
|
+
// First param is the onClick event, useless for us but we have to keep it safe into
|
|
171
|
+
// function signature to avoid confusing with customBindings
|
|
172
|
+
const goNext = (_, customBindings) => {
|
|
173
|
+
if (!(isLastPage && isLastSource)) {
|
|
174
|
+
if (flow !== FLOW_NEXT) {
|
|
175
|
+
setFlow(FLOW_NEXT);
|
|
176
|
+
}
|
|
177
|
+
const nextPage = getPage({
|
|
178
|
+
components: questionnaire.components,
|
|
179
|
+
bindings: customBindings || bindings,
|
|
180
|
+
currentPage: page,
|
|
181
|
+
featuresWithoutMD,
|
|
182
|
+
flow: FLOW_NEXT,
|
|
183
|
+
management,
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
const nextFunction = nextPage ? () => setPage(nextPage) : goSplitNext;
|
|
187
|
+
|
|
188
|
+
if (modalForControls) {
|
|
189
|
+
const controls = getControls({
|
|
190
|
+
page,
|
|
191
|
+
features: featuresWithoutMD,
|
|
192
|
+
components,
|
|
193
|
+
bindings,
|
|
194
|
+
preferences,
|
|
195
|
+
});
|
|
196
|
+
if (controls.length > 0)
|
|
197
|
+
setModalContent({ confirm: nextFunction, controls });
|
|
198
|
+
else nextFunction();
|
|
199
|
+
} else nextFunction();
|
|
200
|
+
}
|
|
201
|
+
};
|
|
202
|
+
|
|
203
|
+
const goSplitPrevious = () => {
|
|
204
|
+
if (!isFirstSource) {
|
|
205
|
+
const stateData = getState(questionnaire);
|
|
206
|
+
setLunaticData(mergeStateData(lunaticData, stateData));
|
|
207
|
+
setSourceIndex(sourceIndex - 1);
|
|
208
|
+
}
|
|
209
|
+
};
|
|
210
|
+
|
|
211
|
+
const goPrevious = () => {
|
|
212
|
+
if (!(isFirstPage && isFirstSource)) {
|
|
213
|
+
if (flow !== FLOW_PREVIOUS) {
|
|
214
|
+
setFlow(FLOW_PREVIOUS);
|
|
215
|
+
}
|
|
216
|
+
const previousPage = getPage({
|
|
217
|
+
components: questionnaire.components,
|
|
218
|
+
bindings,
|
|
219
|
+
currentPage: page,
|
|
220
|
+
featuresWithoutMD,
|
|
221
|
+
flow: FLOW_PREVIOUS,
|
|
222
|
+
management,
|
|
223
|
+
});
|
|
224
|
+
|
|
225
|
+
const previousFunction = previousPage
|
|
226
|
+
? () => setPage(previousPage)
|
|
227
|
+
: goSplitPrevious;
|
|
228
|
+
|
|
229
|
+
if (modalForControls) {
|
|
230
|
+
const controls = getControls({
|
|
231
|
+
page,
|
|
232
|
+
features: featuresWithoutMD,
|
|
233
|
+
components,
|
|
234
|
+
bindings,
|
|
235
|
+
preferences,
|
|
236
|
+
});
|
|
237
|
+
if (controls.length > 0)
|
|
238
|
+
setModalContent({
|
|
239
|
+
confirm: previousFunction,
|
|
240
|
+
controls,
|
|
241
|
+
});
|
|
242
|
+
else previousFunction();
|
|
243
|
+
} else previousFunction();
|
|
244
|
+
}
|
|
245
|
+
};
|
|
246
|
+
|
|
247
|
+
const exportedSetPage = useCallback(
|
|
248
|
+
(newPage) => {
|
|
249
|
+
const p = newPage?.split('.')[0];
|
|
250
|
+
const index = rootPagesOfSource.findIndex((pages) => pages.includes(p));
|
|
251
|
+
if (index === sourceIndex) {
|
|
252
|
+
setPage(newPage);
|
|
253
|
+
setWantedPage(null);
|
|
254
|
+
} else {
|
|
255
|
+
// change source
|
|
256
|
+
setWantedPage(newPage);
|
|
257
|
+
const stateData = getState(questionnaire);
|
|
258
|
+
setLunaticData(mergeStateData(lunaticData, stateData));
|
|
259
|
+
setSourceIndex(index);
|
|
260
|
+
}
|
|
261
|
+
},
|
|
262
|
+
[lunaticData, questionnaire, rootPagesOfSource, sourceIndex]
|
|
263
|
+
);
|
|
264
|
+
|
|
265
|
+
useEffect(() => {
|
|
266
|
+
if (!initPage) {
|
|
267
|
+
if (wantedPage) {
|
|
268
|
+
setPage(wantedPage);
|
|
269
|
+
setWantedPage(null);
|
|
270
|
+
} else {
|
|
271
|
+
const getNewInitPage = () => {
|
|
272
|
+
if (flow === FLOW_NEXT) {
|
|
273
|
+
const tempPage =
|
|
274
|
+
sourceIndex - 1 > 0
|
|
275
|
+
? sources[sourceIndex - 1].maxPage
|
|
276
|
+
: sources[0].maxPage;
|
|
277
|
+
return getPage({
|
|
278
|
+
components: questionnaire.components,
|
|
279
|
+
bindings: bindings,
|
|
280
|
+
currentPage: tempPage,
|
|
281
|
+
featuresWithoutMD,
|
|
282
|
+
flow: FLOW_NEXT,
|
|
283
|
+
management,
|
|
284
|
+
});
|
|
285
|
+
} else if (flow === FLOW_PREVIOUS) {
|
|
286
|
+
const tempPage =
|
|
287
|
+
sourceIndex + 1 < sources.length - 1
|
|
288
|
+
? sources[sourceIndex + 1].firstPage
|
|
289
|
+
: sources[sources.length - 1].firstPage;
|
|
290
|
+
return getPage({
|
|
291
|
+
components: questionnaire.components,
|
|
292
|
+
bindings: bindings,
|
|
293
|
+
currentPage: tempPage,
|
|
294
|
+
featuresWithoutMD,
|
|
295
|
+
flow: flow,
|
|
296
|
+
management,
|
|
297
|
+
});
|
|
298
|
+
}
|
|
299
|
+
return null;
|
|
300
|
+
};
|
|
301
|
+
|
|
302
|
+
if (!flow) exportedSetPage(initialPage || sources[0].firstPage);
|
|
303
|
+
else {
|
|
304
|
+
const newPage = getNewInitPage();
|
|
305
|
+
if (!newPage) {
|
|
306
|
+
if (flow === FLOW_NEXT) setSourceIndex(sourceIndex + 1);
|
|
307
|
+
else setSourceIndex(sourceIndex - 1);
|
|
308
|
+
} else setPage(newPage);
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
setInitPage(true);
|
|
312
|
+
}
|
|
313
|
+
}, [
|
|
314
|
+
initPage,
|
|
315
|
+
isFirstSource,
|
|
316
|
+
components,
|
|
317
|
+
questionnaire.components,
|
|
318
|
+
bindings,
|
|
319
|
+
page,
|
|
320
|
+
featuresWithoutMD,
|
|
321
|
+
management,
|
|
322
|
+
sourceIndex,
|
|
323
|
+
sources,
|
|
324
|
+
flow,
|
|
325
|
+
wantedPage,
|
|
326
|
+
exportedSetPage,
|
|
327
|
+
initialPage,
|
|
328
|
+
]);
|
|
329
|
+
|
|
330
|
+
const handleChange = useCallback((updatedValue) => {
|
|
331
|
+
setTodo((t) => ({ ...t, ...updatedValue }));
|
|
332
|
+
}, []);
|
|
333
|
+
|
|
334
|
+
const handleExternals = useCallback((externals) => {
|
|
335
|
+
setTodoExternals((t) => ({ ...t, ...externals }));
|
|
336
|
+
}, []);
|
|
337
|
+
|
|
338
|
+
useEffect(() => {
|
|
339
|
+
if (Object.keys(todo).length !== 0) {
|
|
340
|
+
const newQ = updateQuestionnaire(savingType)(questionnaire)(
|
|
341
|
+
preferences,
|
|
342
|
+
logFunction
|
|
343
|
+
)(todo);
|
|
344
|
+
|
|
345
|
+
const bind = getBindings(newQ);
|
|
346
|
+
setBindings(bind);
|
|
347
|
+
setAllBindings({ ...allBindings, ...bind });
|
|
348
|
+
setQuestionnaire(newQ);
|
|
349
|
+
setTodo({});
|
|
350
|
+
}
|
|
351
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
352
|
+
}, [
|
|
353
|
+
todo,
|
|
354
|
+
preferences,
|
|
355
|
+
logFunction,
|
|
356
|
+
questionnaire,
|
|
357
|
+
savingType,
|
|
358
|
+
features,
|
|
359
|
+
management,
|
|
360
|
+
]);
|
|
361
|
+
|
|
362
|
+
useEffect(() => {
|
|
363
|
+
if (Object.keys(todoExternals).length !== 0) {
|
|
364
|
+
const newQ = updateExternals(questionnaire)(logFunction)(todoExternals);
|
|
365
|
+
setQuestionnaire(newQ);
|
|
366
|
+
setTodoExternals({});
|
|
367
|
+
}
|
|
368
|
+
}, [todoExternals, logFunction, questionnaire]);
|
|
369
|
+
|
|
370
|
+
const cancelModal = () => {
|
|
371
|
+
setModalContent(null);
|
|
372
|
+
};
|
|
373
|
+
|
|
374
|
+
const validateModal = () => {
|
|
375
|
+
const { confirm } = modalContent;
|
|
376
|
+
if (confirm) confirm();
|
|
377
|
+
setModalContent(null);
|
|
378
|
+
};
|
|
379
|
+
|
|
380
|
+
const componentsToDiplay =
|
|
381
|
+
pagination && modalContent
|
|
382
|
+
? [
|
|
383
|
+
{
|
|
384
|
+
componentType: 'Modal',
|
|
385
|
+
controls: modalContent.controls,
|
|
386
|
+
validateModal,
|
|
387
|
+
cancelModal,
|
|
388
|
+
},
|
|
389
|
+
...components,
|
|
390
|
+
]
|
|
391
|
+
: components;
|
|
392
|
+
|
|
393
|
+
if (isDev)
|
|
394
|
+
console.log(`End useLunaticSplit: ${new Date().getTime() - start} ms`);
|
|
395
|
+
|
|
396
|
+
return {
|
|
397
|
+
questionnaire,
|
|
398
|
+
handleChange,
|
|
399
|
+
handleExternals,
|
|
400
|
+
components: componentsToDiplay,
|
|
401
|
+
bindings,
|
|
402
|
+
allBindings,
|
|
403
|
+
state: {
|
|
404
|
+
getState: getStateSplit,
|
|
405
|
+
getCollectedState: getCollectedStateSplit,
|
|
406
|
+
getCollectedStateByValueType: getCollectedStateByValueTypeSplit,
|
|
407
|
+
getBindings: getBindingsSplit,
|
|
408
|
+
},
|
|
409
|
+
pagination: {
|
|
410
|
+
page: page,
|
|
411
|
+
maxPage: sources[sources.length - 1].maxPage,
|
|
412
|
+
goNext,
|
|
413
|
+
goPrevious,
|
|
414
|
+
isFirstPage: isFirstPage && isFirstSource,
|
|
415
|
+
isLastPage: isLastPage && isLastSource,
|
|
416
|
+
setPage: exportedSetPage,
|
|
417
|
+
},
|
|
418
|
+
};
|
|
419
|
+
};
|
|
420
|
+
|
|
421
|
+
export default useLunaticSplit;
|
|
@@ -1,19 +1,29 @@
|
|
|
1
1
|
import { useState, useEffect, useCallback } from 'react';
|
|
2
2
|
import { mergeQuestionnaireAndData } from '../init-questionnaire';
|
|
3
3
|
import { getBindings } from '../state';
|
|
4
|
-
import { updateQuestionnaire } from '../handler';
|
|
5
|
-
import {
|
|
4
|
+
import { updateQuestionnaire, updateExternals } from '../handler';
|
|
5
|
+
import {
|
|
6
|
+
getPage,
|
|
7
|
+
FLOW_NEXT,
|
|
8
|
+
FLOW_PREVIOUS,
|
|
9
|
+
getControls,
|
|
10
|
+
isDev,
|
|
11
|
+
} from '../../lib';
|
|
6
12
|
import { COLLECTED } from '../../../constants';
|
|
7
13
|
import { useFilterComponents } from './filter-components';
|
|
8
14
|
import { loadSuggesters } from '../../store-tools/auto-load';
|
|
9
15
|
|
|
16
|
+
const defaultData = {};
|
|
17
|
+
const defaultPreferences = [COLLECTED];
|
|
18
|
+
const defaultFeatures = ['VTL'];
|
|
19
|
+
|
|
10
20
|
const useLunatic = (
|
|
11
21
|
source,
|
|
12
|
-
data,
|
|
22
|
+
data = defaultData,
|
|
13
23
|
{
|
|
14
24
|
savingType = COLLECTED,
|
|
15
|
-
preferences =
|
|
16
|
-
features =
|
|
25
|
+
preferences = defaultPreferences,
|
|
26
|
+
features = defaultFeatures,
|
|
17
27
|
management = false,
|
|
18
28
|
pagination = false,
|
|
19
29
|
modalForControls = false,
|
|
@@ -24,15 +34,21 @@ const useLunatic = (
|
|
|
24
34
|
suggesters,
|
|
25
35
|
}
|
|
26
36
|
) => {
|
|
37
|
+
if (isDev) {
|
|
38
|
+
console.log('useLunatic');
|
|
39
|
+
var start = new Date().getTime();
|
|
40
|
+
}
|
|
27
41
|
const [initPage, setInitPage] = useState(false);
|
|
28
42
|
const featuresWithoutMD = features.filter((f) => f !== 'MD');
|
|
29
43
|
const [questionnaire, setQuestionnaire] = useState(() =>
|
|
30
44
|
mergeQuestionnaireAndData(source)(data || {})
|
|
31
45
|
);
|
|
32
|
-
const bindings = getBindings(questionnaire);
|
|
46
|
+
const [bindings, setBindings] = useState(() => getBindings(questionnaire));
|
|
47
|
+
|
|
33
48
|
const [page, setPage] = useState(initialPage);
|
|
34
49
|
|
|
35
50
|
const [todo, setTodo] = useState({});
|
|
51
|
+
const [todoExternals, setTodoExternals] = useState({});
|
|
36
52
|
|
|
37
53
|
const [modalContent, setModalContent] = useState(null);
|
|
38
54
|
|
|
@@ -43,7 +59,7 @@ const useLunatic = (
|
|
|
43
59
|
features: featuresWithoutMD,
|
|
44
60
|
page,
|
|
45
61
|
pagination,
|
|
46
|
-
todo,
|
|
62
|
+
todo: { ...todo, ...todoExternals },
|
|
47
63
|
});
|
|
48
64
|
|
|
49
65
|
const { suggesters: suggestersToLoad } = source;
|
|
@@ -168,6 +184,10 @@ const useLunatic = (
|
|
|
168
184
|
setTodo((t) => ({ ...t, ...updatedValue }));
|
|
169
185
|
}, []);
|
|
170
186
|
|
|
187
|
+
const handleExternals = useCallback((externals) => {
|
|
188
|
+
setTodoExternals((t) => ({ ...t, ...externals }));
|
|
189
|
+
}, []);
|
|
190
|
+
|
|
171
191
|
// Assume we only want to handle source update
|
|
172
192
|
useEffect(() => {
|
|
173
193
|
setQuestionnaire(mergeQuestionnaireAndData(source)(data));
|
|
@@ -180,6 +200,7 @@ const useLunatic = (
|
|
|
180
200
|
preferences,
|
|
181
201
|
logFunction
|
|
182
202
|
)(todo);
|
|
203
|
+
setBindings(getBindings(newQ));
|
|
183
204
|
setQuestionnaire(newQ);
|
|
184
205
|
setTodo({});
|
|
185
206
|
}
|
|
@@ -193,6 +214,14 @@ const useLunatic = (
|
|
|
193
214
|
management,
|
|
194
215
|
]);
|
|
195
216
|
|
|
217
|
+
useEffect(() => {
|
|
218
|
+
if (Object.keys(todoExternals).length !== 0) {
|
|
219
|
+
const newQ = updateExternals(questionnaire)(logFunction)(todoExternals);
|
|
220
|
+
setQuestionnaire(newQ);
|
|
221
|
+
setTodoExternals({});
|
|
222
|
+
}
|
|
223
|
+
}, [todoExternals, logFunction, questionnaire]);
|
|
224
|
+
|
|
196
225
|
const cancelModal = () => {
|
|
197
226
|
setModalContent(null);
|
|
198
227
|
};
|
|
@@ -215,9 +244,12 @@ const useLunatic = (
|
|
|
215
244
|
]
|
|
216
245
|
: components;
|
|
217
246
|
|
|
247
|
+
if (isDev) console.log(`End useLunatic: ${new Date().getTime() - start} ms`);
|
|
248
|
+
|
|
218
249
|
return {
|
|
219
250
|
questionnaire,
|
|
220
251
|
handleChange,
|
|
252
|
+
handleExternals,
|
|
221
253
|
components: componentsToDiplay,
|
|
222
254
|
bindings,
|
|
223
255
|
pagination: {
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
// updateQuestionnaire is useless since 2.0 optimization efforts
|
|
2
|
-
// export { updateQuestionnaire } from './handler';
|
|
3
|
-
export { mergeQuestionnaireAndData } from './init-questionnaire';
|
|
4
|
-
export {
|
|
5
|
-
getState,
|
|
6
|
-
getCollectedState,
|
|
7
|
-
getCollectedStateByValueType,
|
|
8
|
-
getBindings,
|
|
9
|
-
} from './state';
|
|
10
|
-
export { interpret } from './interpret';
|
|
11
|
-
export {
|
|
1
|
+
// updateQuestionnaire is useless since 2.0 optimization efforts
|
|
2
|
+
// export { updateQuestionnaire } from './handler';
|
|
3
|
+
export { mergeQuestionnaireAndData } from './init-questionnaire';
|
|
4
|
+
export {
|
|
5
|
+
getState,
|
|
6
|
+
getCollectedState,
|
|
7
|
+
getCollectedStateByValueType,
|
|
8
|
+
getBindings,
|
|
9
|
+
} from './state';
|
|
10
|
+
export { interpret } from './interpret';
|
|
11
|
+
export { useLunatic, useLunaticSplit } from './hooks';
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import * as C from '../../constants';
|
|
2
|
+
import { isDev } from '../lib';
|
|
2
3
|
|
|
3
4
|
export const getState = (questionnaire) => {
|
|
4
5
|
const { variables } = questionnaire;
|
|
@@ -33,26 +34,33 @@ const getCalculatedFromVariables = (variables) =>
|
|
|
33
34
|
const getExternalFromVariables = (variables) =>
|
|
34
35
|
(variables && variables[C.EXTERNAL]) || {};
|
|
35
36
|
|
|
36
|
-
export const getCollectedStateByValueType =
|
|
37
|
-
valueType,
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
37
|
+
export const getCollectedStateByValueType =
|
|
38
|
+
(questionnaire, collectedState) => (valueType, displayNull) =>
|
|
39
|
+
['PREVIOUS', 'COLLECTED', 'FORCED', 'EDITED', 'INPUTED'].includes(valueType)
|
|
40
|
+
? Object.entries(
|
|
41
|
+
collectedState || getCollectedState(questionnaire)
|
|
42
|
+
).reduce((_, v) => {
|
|
43
|
+
if (displayNull || v[1][valueType] !== null)
|
|
44
|
+
return {
|
|
45
|
+
..._,
|
|
46
|
+
[v[0]]: v[1][valueType],
|
|
47
|
+
};
|
|
48
|
+
return _;
|
|
49
|
+
}, {})
|
|
50
|
+
: {};
|
|
50
51
|
|
|
51
52
|
export const getBindings = (questionnaire) => {
|
|
53
|
+
if (isDev) {
|
|
54
|
+
console.log('Get bindings');
|
|
55
|
+
var start = new Date().getTime();
|
|
56
|
+
}
|
|
52
57
|
const { variables } = questionnaire;
|
|
53
|
-
|
|
58
|
+
const bindings = {
|
|
54
59
|
...getCollectedStateByValueType(questionnaire)('COLLECTED', true),
|
|
55
60
|
...getCalculatedFromVariables(variables),
|
|
56
61
|
...getExternalFromVariables(variables),
|
|
57
62
|
};
|
|
63
|
+
if (isDev)
|
|
64
|
+
console.log(`End get bindings: ${new Date().getTime() - start} ms`);
|
|
65
|
+
return bindings;
|
|
58
66
|
};
|