@rsuci/shared-form-components 1.0.95 → 1.0.97
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/dist/components/form-renderer/FormRenderer.d.ts.map +1 -1
- package/dist/components/form-renderer/FormRenderer.js +28 -6
- package/dist/components/inputs/MobilePhoneInput.d.ts.map +1 -1
- package/dist/components/inputs/MobilePhoneInput.js +6 -2
- package/dist/components/inputs/PhoneInput.d.ts.map +1 -1
- package/dist/components/inputs/PhoneInput.js +6 -3
- package/dist/hooks/useFormInstances.d.ts.map +1 -1
- package/dist/hooks/useFormInstances.js +20 -10
- package/dist/hooks/useFormTree.d.ts.map +1 -1
- package/dist/hooks/useFormTree.js +15 -30
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FormRenderer.d.ts","sourceRoot":"","sources":["../../../src/components/form-renderer/FormRenderer.tsx"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,KAA4D,MAAM,OAAO,CAAC;AACjF,OAAO,EACL,iBAAiB,EACjB,eAAe,EACf,cAAc,EAIf,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,kBAAkB,EAClB,qBAAqB,EAEtB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAuBlF;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,6BAA6B;IAC7B,UAAU,EAAE,iBAAiB,CAAC;IAC9B,6DAA6D;IAC7D,OAAO,CAAC,EAAE,eAAe,CAAC;IAC1B,yBAAyB;IACzB,gBAAgB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IAClD,oCAAoC;IACpC,MAAM,EAAE,kBAAkB,CAAC;IAC3B,iCAAiC;IACjC,SAAS,EAAE,qBAAqB,CAAC;IACjC,wBAAwB;IACxB,QAAQ,CAAC,EAAE,oBAAoB,CAAC;IAChC,wCAAwC;IACxC,oBAAoB,CAAC,EAAE,oBAAoB,CAAC;IAC5C,iCAAiC;IACjC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,iCAAiC;IACjC,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;
|
|
1
|
+
{"version":3,"file":"FormRenderer.d.ts","sourceRoot":"","sources":["../../../src/components/form-renderer/FormRenderer.tsx"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,KAA4D,MAAM,OAAO,CAAC;AACjF,OAAO,EACL,iBAAiB,EACjB,eAAe,EACf,cAAc,EAIf,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,kBAAkB,EAClB,qBAAqB,EAEtB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAuBlF;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,6BAA6B;IAC7B,UAAU,EAAE,iBAAiB,CAAC;IAC9B,6DAA6D;IAC7D,OAAO,CAAC,EAAE,eAAe,CAAC;IAC1B,yBAAyB;IACzB,gBAAgB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IAClD,oCAAoC;IACpC,MAAM,EAAE,kBAAkB,CAAC;IAC3B,iCAAiC;IACjC,SAAS,EAAE,qBAAqB,CAAC;IACjC,wBAAwB;IACxB,QAAQ,CAAC,EAAE,oBAAoB,CAAC;IAChC,wCAAwC;IACxC,oBAAoB,CAAC,EAAE,oBAAoB,CAAC;IAC5C,iCAAiC;IACjC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,iCAAiC;IACjC,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAo3BD;;;GAGG;AACH,eAAO,MAAM,YAAY,EAAE,KAAK,CAAC,EAAE,CAAC,iBAAiB,CAgBpD,CAAC;AAEF,eAAe,YAAY,CAAC"}
|
|
@@ -20,6 +20,7 @@ import RosterListInput from '../roster/RosterListInput';
|
|
|
20
20
|
// Hooks et utilitaires
|
|
21
21
|
import { useFormTree } from '../../hooks/useFormTree';
|
|
22
22
|
import { useConditionValidation } from '../../hooks/useConditionValidation';
|
|
23
|
+
import { GroupeInstanceManager } from '../../lib/utils/groupeInstanceManager';
|
|
23
24
|
import { interpolateVariableLabel } from '../../lib/utils/interpolateVariableLabel';
|
|
24
25
|
import { VariableValueConverter } from '../../lib/utils/variableValueConverter';
|
|
25
26
|
/**
|
|
@@ -249,10 +250,20 @@ const FormRendererInner = () => {
|
|
|
249
250
|
const validateCurrentGroupWithVisibility = useCallback(() => {
|
|
250
251
|
if (!currentGroup || !currentGroup.variables)
|
|
251
252
|
return true;
|
|
252
|
-
// Pour les groupes multiples, valider
|
|
253
|
-
if (currentGroup.estMultiple &&
|
|
254
|
-
|
|
255
|
-
|
|
253
|
+
// Pour les groupes multiples, valider le nombre d'instances ET toutes les instances
|
|
254
|
+
if (currentGroup.estMultiple && currentGroup.instances) {
|
|
255
|
+
// Vérifier le nombre d'instances vs variable de contrôle
|
|
256
|
+
const maxInstances = GroupeInstanceManager.getMaxInstances(currentGroup, responses);
|
|
257
|
+
if (currentGroup.instances.length !== maxInstances) {
|
|
258
|
+
return false;
|
|
259
|
+
}
|
|
260
|
+
// Valider toutes les instances (champs obligatoires)
|
|
261
|
+
for (const instance of currentGroup.instances) {
|
|
262
|
+
const { isValid } = validateGroupForInstance(currentGroup.code, instance.numeroInstance);
|
|
263
|
+
if (!isValid)
|
|
264
|
+
return false;
|
|
265
|
+
}
|
|
266
|
+
return true;
|
|
256
267
|
}
|
|
257
268
|
// Pour les groupes normaux, valider uniquement les variables visibles et obligatoires
|
|
258
269
|
const requiredVariables = currentGroup.variables.filter(v => v.estObligatoire);
|
|
@@ -292,8 +303,11 @@ const FormRendererInner = () => {
|
|
|
292
303
|
for (const groupe of groupes) {
|
|
293
304
|
if (!groupe.variables)
|
|
294
305
|
continue;
|
|
295
|
-
// Groupes multiples : valider chaque instance via FormTree
|
|
306
|
+
// Groupes multiples : valider le nombre d'instances + chaque instance via FormTree
|
|
296
307
|
if (groupe.estMultiple && groupe.instances) {
|
|
308
|
+
const maxInstances = GroupeInstanceManager.getMaxInstances(groupe, responses);
|
|
309
|
+
if (groupe.instances.length !== maxInstances)
|
|
310
|
+
return false;
|
|
297
311
|
for (const instance of groupe.instances) {
|
|
298
312
|
const { isValid } = validateGroupForInstance(groupe.code, instance.numeroInstance);
|
|
299
313
|
if (!isValid)
|
|
@@ -362,13 +376,21 @@ const FormRendererInner = () => {
|
|
|
362
376
|
if (!groupe.variables)
|
|
363
377
|
continue;
|
|
364
378
|
if (groupe.estMultiple && groupe.instances) {
|
|
379
|
+
const maxInstances = GroupeInstanceManager.getMaxInstances(groupe, responses);
|
|
380
|
+
if (groupe.instances.length !== maxInstances) {
|
|
381
|
+
errors.push({
|
|
382
|
+
variableCode: groupe.codeVariable || groupe.code,
|
|
383
|
+
message: `Le groupe "${groupe.designation}" doit avoir ${maxInstances} instance(s) (actuellement ${groupe.instances.length})`,
|
|
384
|
+
type: 'required'
|
|
385
|
+
});
|
|
386
|
+
}
|
|
365
387
|
for (const instance of groupe.instances) {
|
|
366
388
|
const { errors: instanceErrors } = validateGroupForInstance(groupe.code, instance.numeroInstance);
|
|
367
389
|
instanceErrors.forEach(msg => {
|
|
368
390
|
const variable = groupe.variables?.find(v => msg.includes(v.designation));
|
|
369
391
|
errors.push({
|
|
370
392
|
variableCode: variable?.code || groupe.code,
|
|
371
|
-
message: msg
|
|
393
|
+
message: `Instance ${instance.numeroInstance} : ${msg}`,
|
|
372
394
|
type: 'required'
|
|
373
395
|
});
|
|
374
396
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MobilePhoneInput.d.ts","sourceRoot":"","sources":["../../../src/components/inputs/MobilePhoneInput.tsx"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,OAAO,KAAgC,MAAM,OAAO,CAAC;AACrD,OAAO,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAIxE,MAAM,WAAW,qBAAqB;IACpC,QAAQ,EAAE,kBAAkB,GAAG;QAAE,QAAQ,EAAE,aAAa,CAAA;KAAE,CAAC;IAC3D,KAAK,EAAE,aAAa,CAAC;IACrB,QAAQ,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC;IACzC,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAC9B;AAID,QAAA,MAAM,gBAAgB,EAAE,KAAK,CAAC,EAAE,CAAC,qBAAqB,
|
|
1
|
+
{"version":3,"file":"MobilePhoneInput.d.ts","sourceRoot":"","sources":["../../../src/components/inputs/MobilePhoneInput.tsx"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,OAAO,KAAgC,MAAM,OAAO,CAAC;AACrD,OAAO,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAIxE,MAAM,WAAW,qBAAqB;IACpC,QAAQ,EAAE,kBAAkB,GAAG;QAAE,QAAQ,EAAE,aAAa,CAAA;KAAE,CAAC;IAC3D,KAAK,EAAE,aAAa,CAAC;IACrB,QAAQ,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC;IACzC,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAC9B;AAID,QAAA,MAAM,gBAAgB,EAAE,KAAK,CAAC,EAAE,CAAC,qBAAqB,CA0FrD,CAAC;AAEF,eAAe,gBAAgB,CAAC"}
|
|
@@ -36,8 +36,12 @@ const MobilePhoneInput = ({ variable, value, onChange, onBlur, error, disabled,
|
|
|
36
36
|
}
|
|
37
37
|
if (val.length >= 2) {
|
|
38
38
|
const prefix2 = val.slice(0, 2);
|
|
39
|
-
|
|
40
|
-
|
|
39
|
+
// Si le numéro commence par 00, il doit être exactement 0000000000
|
|
40
|
+
if (prefix2 === '00' && val.length === 10 && val !== '0000000000') {
|
|
41
|
+
return 'Un numéro commençant par 00 doit être 00 00 00 00 00';
|
|
42
|
+
}
|
|
43
|
+
if (!['07', '05', '01', '00', '27'].includes(prefix2)) {
|
|
44
|
+
return 'Le numero doit commencer par 27, 07, 05, 01 ou 00';
|
|
41
45
|
}
|
|
42
46
|
}
|
|
43
47
|
return null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PhoneInput.d.ts","sourceRoot":"","sources":["../../../src/components/inputs/PhoneInput.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,KAAgC,MAAM,OAAO,CAAC;AACrD,OAAO,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAIxE,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,kBAAkB,GAAG;QAAE,QAAQ,EAAE,OAAO,CAAA;KAAE,CAAC;IACrD,KAAK,EAAE,aAAa,CAAC;IACrB,QAAQ,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC;IACzC,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAC9B;AAED,QAAA,MAAM,UAAU,EAAE,KAAK,CAAC,EAAE,CAAC,eAAe,
|
|
1
|
+
{"version":3,"file":"PhoneInput.d.ts","sourceRoot":"","sources":["../../../src/components/inputs/PhoneInput.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,KAAgC,MAAM,OAAO,CAAC;AACrD,OAAO,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAIxE,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,kBAAkB,GAAG;QAAE,QAAQ,EAAE,OAAO,CAAA;KAAE,CAAC;IACrD,KAAK,EAAE,aAAa,CAAC;IACrB,QAAQ,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC;IACzC,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAC9B;AAED,QAAA,MAAM,UAAU,EAAE,KAAK,CAAC,EAAE,CAAC,eAAe,CAiEzC,CAAC;AAEF,eAAe,UAAU,CAAC"}
|
|
@@ -20,9 +20,12 @@ const PhoneInput = ({ variable, value, onChange, onBlur, error, disabled, isCons
|
|
|
20
20
|
return 'Le numéro doit contenir exactement 10 chiffres';
|
|
21
21
|
}
|
|
22
22
|
const prefix2 = val.slice(0, 2);
|
|
23
|
-
|
|
24
|
-
if (
|
|
25
|
-
return '
|
|
23
|
+
// Si le numéro commence par 00, il doit être exactement 0000000000
|
|
24
|
+
if (prefix2 === '00' && val !== '0000000000') {
|
|
25
|
+
return 'Un numéro commençant par 00 doit être 00 00 00 00 00';
|
|
26
|
+
}
|
|
27
|
+
if (!['07', '05', '01', '00', '27'].includes(prefix2)) {
|
|
28
|
+
return 'Le numéro doit commencer par 27, 07, 05, 01 ou 00';
|
|
26
29
|
}
|
|
27
30
|
return null;
|
|
28
31
|
}, []);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useFormInstances.d.ts","sourceRoot":"","sources":["../../src/hooks/useFormInstances.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"useFormInstances.d.ts","sourceRoot":"","sources":["../../src/hooks/useFormInstances.ts"],"names":[],"mappings":"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"}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* Gère l'ajout, la suppression et la synchronisation des instances de groupes
|
|
4
4
|
* RSU v2 - Package Partagé
|
|
5
5
|
*/
|
|
6
|
-
import { useState, useCallback
|
|
6
|
+
import { useState, useCallback } from 'react';
|
|
7
7
|
import { GroupeInstanceManager } from '../lib/utils/groupeInstanceManager';
|
|
8
8
|
/**
|
|
9
9
|
* Hook pour gérer les instances multiples dans un formulaire d'enquête
|
|
@@ -28,8 +28,24 @@ import { GroupeInstanceManager } from '../lib/utils/groupeInstanceManager';
|
|
|
28
28
|
*/
|
|
29
29
|
export function useFormInstances(initialGroupes, initialResponses, options = {}) {
|
|
30
30
|
const { onInstanceAdded, onInstanceRemoved, onInstanceChange, onGroupesUpdated, debug = false } = options;
|
|
31
|
-
// État des groupes avec instances
|
|
32
|
-
|
|
31
|
+
// État des groupes avec instances — initialisé synchronement pour éviter un cycle de double rendu
|
|
32
|
+
// qui causerait un FormTree avec des données de visibilité obsolètes à la réouverture d'un brouillon
|
|
33
|
+
const [groupesWithInstances, setGroupesWithInstances] = useState(() => {
|
|
34
|
+
if (!initialGroupes?.length)
|
|
35
|
+
return [];
|
|
36
|
+
return initialGroupes.map(groupe => {
|
|
37
|
+
if (groupe.estMultiple) {
|
|
38
|
+
GroupeInstanceManager.updateGroupeProperties(groupe, initialResponses);
|
|
39
|
+
if (!groupe.instances || groupe.instances.length === 0) {
|
|
40
|
+
groupe.instances = [GroupeInstanceManager.createInstance(groupe, 1)];
|
|
41
|
+
}
|
|
42
|
+
groupe.instances.forEach((instance) => {
|
|
43
|
+
GroupeInstanceManager.syncInstanceResponses(instance, groupe, initialResponses);
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
return groupe;
|
|
47
|
+
});
|
|
48
|
+
});
|
|
33
49
|
// Index de l'instance active
|
|
34
50
|
const [currentInstanceIndex, setCurrentInstanceIndex] = useState(0);
|
|
35
51
|
// Fonction utilitaire pour logger en mode debug
|
|
@@ -69,13 +85,7 @@ export function useFormInstances(initialGroupes, initialResponses, options = {})
|
|
|
69
85
|
return groupe;
|
|
70
86
|
});
|
|
71
87
|
}, [log]);
|
|
72
|
-
//
|
|
73
|
-
useEffect(() => {
|
|
74
|
-
if (initialGroupes?.length) {
|
|
75
|
-
const initialized = initializeGroupesWithInstances(initialGroupes, initialResponses);
|
|
76
|
-
setGroupesWithInstances(initialized);
|
|
77
|
-
}
|
|
78
|
-
}, []);
|
|
88
|
+
// Note: l'initialisation est faite dans le useState initializer ci-dessus (synchrone)
|
|
79
89
|
/**
|
|
80
90
|
* Ajouter une instance à un groupe
|
|
81
91
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useFormTree.d.ts","sourceRoot":"","sources":["../../src/hooks/useFormTree.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACvG,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAE7F,MAAM,WAAW,kBAAkB;IACjC,8CAA8C;IAC9C,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,SAAS,KAAK,IAAI,CAAC;IACzC,kCAAkC;IAClC,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,kEAAkE;IAClE,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,iBAAiB;IAChC,2BAA2B;IAC3B,QAAQ,EAAE,QAAQ,CAAC;IAEnB,kDAAkD;IAClD,mBAAmB,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,kBAAkB,EAAE,CAAC;IAElE,mGAAmG;IACnG,8BAA8B,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,KAAK,kBAAkB,EAAE,CAAC;IAErG,8DAA8D;IAC9D,sBAAsB,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,GAAG,CAAC,MAAM,CAAC,CAAC;IAE5D,gGAAgG;IAChG,iCAAiC,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,KAAK,GAAG,CAAC,MAAM,CAAC,CAAC;IAE/F,+CAA+C;IAC/C,aAAa,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,MAAM,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;IAE9E,wEAAwE;IACxE,wBAAwB,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,KAAK;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,MAAM,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;IAEjH,uEAAuE;IACvE,yBAAyB,EAAE,MAAM,MAAM,EAAE,CAAC;IAE1C,qCAAqC;IACrC,gBAAgB,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,iBAAiB,GAAG,SAAS,CAAC;IAE1E,kCAAkC;IAClC,aAAa,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,cAAc,GAAG,SAAS,CAAC;IAElE,0CAA0C;IAC1C,UAAU,EAAE,SAAS,EAAE,CAAC;IAExB,6BAA6B;IAC7B,WAAW,EAAE,SAAS,EAAE,CAAC;IAEzB,6DAA6D;IAC7D,yBAAyB,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,KAAK,SAAS,EAAE,CAAC;IAEvF,sDAAsD;IACtD,aAAa,EAAE,MAAM,IAAI,CAAC;IAE1B,yDAAyD;IACzD,WAAW,EAAE,MAAM,CAAC;IAEpB,oEAAoE;IACpE,kBAAkB,EAAE,MAAM,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IAErD,+EAA+E;IAC/E,8BAA8B,EAAE,CAAC,UAAU,CAAC,EAAE,MAAM,EAAE,cAAc,CAAC,EAAE,MAAM,KAAK,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;CAC9G;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,WAAW,CACzB,OAAO,EAAE,gBAAgB,EAAE,EAC3B,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,EACzC,OAAO,GAAE,kBAAuB,GAC/B,iBAAiB,
|
|
1
|
+
{"version":3,"file":"useFormTree.d.ts","sourceRoot":"","sources":["../../src/hooks/useFormTree.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACvG,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAE7F,MAAM,WAAW,kBAAkB;IACjC,8CAA8C;IAC9C,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,SAAS,KAAK,IAAI,CAAC;IACzC,kCAAkC;IAClC,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,kEAAkE;IAClE,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,iBAAiB;IAChC,2BAA2B;IAC3B,QAAQ,EAAE,QAAQ,CAAC;IAEnB,kDAAkD;IAClD,mBAAmB,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,kBAAkB,EAAE,CAAC;IAElE,mGAAmG;IACnG,8BAA8B,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,KAAK,kBAAkB,EAAE,CAAC;IAErG,8DAA8D;IAC9D,sBAAsB,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,GAAG,CAAC,MAAM,CAAC,CAAC;IAE5D,gGAAgG;IAChG,iCAAiC,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,KAAK,GAAG,CAAC,MAAM,CAAC,CAAC;IAE/F,+CAA+C;IAC/C,aAAa,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,MAAM,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;IAE9E,wEAAwE;IACxE,wBAAwB,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,KAAK;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,MAAM,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;IAEjH,uEAAuE;IACvE,yBAAyB,EAAE,MAAM,MAAM,EAAE,CAAC;IAE1C,qCAAqC;IACrC,gBAAgB,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,iBAAiB,GAAG,SAAS,CAAC;IAE1E,kCAAkC;IAClC,aAAa,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,cAAc,GAAG,SAAS,CAAC;IAElE,0CAA0C;IAC1C,UAAU,EAAE,SAAS,EAAE,CAAC;IAExB,6BAA6B;IAC7B,WAAW,EAAE,SAAS,EAAE,CAAC;IAEzB,6DAA6D;IAC7D,yBAAyB,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,KAAK,SAAS,EAAE,CAAC;IAEvF,sDAAsD;IACtD,aAAa,EAAE,MAAM,IAAI,CAAC;IAE1B,yDAAyD;IACzD,WAAW,EAAE,MAAM,CAAC;IAEpB,oEAAoE;IACpE,kBAAkB,EAAE,MAAM,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IAErD,+EAA+E;IAC/E,8BAA8B,EAAE,CAAC,UAAU,CAAC,EAAE,MAAM,EAAE,cAAc,CAAC,EAAE,MAAM,KAAK,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;CAC9G;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,WAAW,CACzB,OAAO,EAAE,gBAAgB,EAAE,EAC3B,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,EACzC,OAAO,GAAE,kBAAuB,GAC/B,iBAAiB,CAwJnB;AAED,eAAe,WAAW,CAAC"}
|
|
@@ -39,6 +39,9 @@ export function useFormTree(groupes, responses, options = {}) {
|
|
|
39
39
|
optionsRef.current = options;
|
|
40
40
|
// Référence pour tracker les réponses précédentes
|
|
41
41
|
const previousResponsesRef = useRef(responses);
|
|
42
|
+
// Référence pour tracker la dernière synchronisation des réponses avec le FormTree
|
|
43
|
+
// Doit être déclarée AVANT le useMemo pour exister lors de la première exécution
|
|
44
|
+
const lastSyncedResponsesRef = useRef(responses);
|
|
42
45
|
// Créer l'instance FormTree (stable tant que groupes ne changent pas)
|
|
43
46
|
const formTree = useMemo(() => {
|
|
44
47
|
const tree = new FormTree(responses, {
|
|
@@ -46,43 +49,25 @@ export function useFormTree(groupes, responses, options = {}) {
|
|
|
46
49
|
onJumpError: optionsRef.current.onJumpError
|
|
47
50
|
});
|
|
48
51
|
tree.buildFromFormulaire(groupes);
|
|
52
|
+
lastSyncedResponsesRef.current = responses; // Marquer comme synchronisé
|
|
49
53
|
return tree;
|
|
50
54
|
}, [groupes]); // Reconstruire seulement si groupes changent
|
|
55
|
+
// Synchroniser le FormTree avec les réponses actuelles pendant le rendu (synchrone)
|
|
56
|
+
// Cela prévient le créneau où le useEffect n'a pas encore mis à jour le FormTree
|
|
57
|
+
// mais la validation a besoin des dernières données de visibilité
|
|
58
|
+
if (lastSyncedResponsesRef.current !== responses) {
|
|
59
|
+
formTree.updateResponses(responses);
|
|
60
|
+
lastSyncedResponsesRef.current = responses;
|
|
61
|
+
}
|
|
51
62
|
// Mettre à jour le callback d'erreur quand il change
|
|
52
63
|
useEffect(() => {
|
|
53
64
|
formTree.onJumpError = options.onJumpError;
|
|
54
65
|
}, [formTree, options.onJumpError]);
|
|
55
|
-
//
|
|
66
|
+
// Forcer un re-render quand le FormTree ou les réponses changent
|
|
67
|
+
// Le FormTree est déjà synchronisé pendant le rendu (voir ref sync ci-dessus)
|
|
68
|
+
// L'effect sert uniquement à incrémenter updateCount pour que les useCallback/useMemo
|
|
69
|
+
// qui en dépendent se mettent à jour
|
|
56
70
|
useEffect(() => {
|
|
57
|
-
const activeGroupCode = optionsRef.current.activeGroupCode;
|
|
58
|
-
// Si un groupe actif est spécifié, utiliser l'optimisation
|
|
59
|
-
if (activeGroupCode) {
|
|
60
|
-
// Identifier les variables qui ont changé
|
|
61
|
-
const changedVariableCodes = [];
|
|
62
|
-
const currentKeys = Object.keys(responses);
|
|
63
|
-
const previousKeys = Object.keys(previousResponsesRef.current);
|
|
64
|
-
// Vérifier les nouvelles variables et les valeurs modifiées
|
|
65
|
-
for (const key of currentKeys) {
|
|
66
|
-
const current = responses[key];
|
|
67
|
-
const previous = previousResponsesRef.current[key];
|
|
68
|
-
if (!previous || JSON.stringify(current.valeur) !== JSON.stringify(previous.valeur)) {
|
|
69
|
-
changedVariableCodes.push(current.variableCode);
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
// Vérifier les variables supprimées
|
|
73
|
-
for (const key of previousKeys) {
|
|
74
|
-
if (!responses[key]) {
|
|
75
|
-
changedVariableCodes.push(previousResponsesRef.current[key].variableCode);
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
// Utiliser la mise à jour optimisée par groupe
|
|
79
|
-
formTree.updateResponsesForGroup(responses, activeGroupCode, changedVariableCodes);
|
|
80
|
-
}
|
|
81
|
-
else {
|
|
82
|
-
// Sinon, utiliser la mise à jour complète
|
|
83
|
-
formTree.updateResponses(responses);
|
|
84
|
-
}
|
|
85
|
-
// Mettre à jour la référence
|
|
86
71
|
previousResponsesRef.current = responses;
|
|
87
72
|
setUpdateCount(c => c + 1);
|
|
88
73
|
}, [formTree, responses]);
|
package/package.json
CHANGED