@rsuci/shared-form-components 1.0.85 → 1.0.87

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.
@@ -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;AAsBlF;;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;AAuxBD;;;GAGG;AACH,eAAO,MAAM,YAAY,EAAE,KAAK,CAAC,EAAE,CAAC,iBAAiB,CAgBpD,CAAC;AAEF,eAAe,YAAY,CAAC"}
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;AAsBlF;;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;AAwyBD;;;GAGG;AACH,eAAO,MAAM,YAAY,EAAE,KAAK,CAAC,EAAE,CAAC,iBAAiB,CAgBpD,CAAC;AAEF,eAAe,YAAY,CAAC"}
@@ -99,7 +99,10 @@ const FormRendererInner = () => {
99
99
  }
100
100
  }
101
101
  });
102
- isApplyingAutoActions.current = false;
102
+ // Différer le reset après que React ait committé les state updates
103
+ requestAnimationFrame(() => {
104
+ isApplyingAutoActions.current = false;
105
+ });
103
106
  }
104
107
  }, [responses, currentGroup, currentInstance, evaluateAutoActionsForInstance, updateResponse]);
105
108
  // Vérifier si une variable est visible
@@ -203,16 +206,22 @@ const FormRendererInner = () => {
203
206
  navigation.changeInstance(instanceIndex);
204
207
  };
205
208
  // Handler pour l'ajout d'instance
206
- const handleInstanceAdded = (instance) => {
207
- navigation.updateTotalInstances(currentGroup?.instances?.length || 1);
209
+ const handleInstanceAdded = (instance, updatedGroupe) => {
210
+ // Mettre à jour le groupe via l'état React (pas de mutation directe)
211
+ instances.setGroupesWithInstances(prev => prev.map(g => g.code === updatedGroupe.code ? updatedGroupe : g));
212
+ navigation.updateTotalInstances(updatedGroupe.instances?.length || 1);
208
213
  // Naviguer vers la nouvelle instance
209
- if (currentGroup?.instances) {
210
- navigation.changeInstance(currentGroup.instances.length - 1);
214
+ if (updatedGroupe.instances) {
215
+ navigation.changeInstance(updatedGroupe.instances.length - 1);
211
216
  }
212
217
  };
213
218
  // Handler pour la suppression d'instance
214
- const handleInstanceRemoved = (instanceNumber) => {
215
- navigation.updateTotalInstances(currentGroup?.instances?.length || 1);
219
+ const handleInstanceRemoved = (instanceNumber, updatedGroupe, updatedResponses) => {
220
+ // CRITIQUE : mettre à jour les réponses via l'état React
221
+ context.setResponses(updatedResponses);
222
+ // Mettre à jour le groupe via l'état React
223
+ instances.setGroupesWithInstances(prev => prev.map(g => g.code === updatedGroupe.code ? updatedGroupe : g));
224
+ navigation.updateTotalInstances(updatedGroupe.instances?.length || 1);
216
225
  // Revenir à la première instance
217
226
  navigation.changeInstance(0);
218
227
  };
@@ -9,8 +9,8 @@ export interface GroupeInstanceTabsProps {
9
9
  currentInstanceIndex: number;
10
10
  responses: Record<string, EnqueteReponse>;
11
11
  onInstanceChange: (instanceIndex: number) => void;
12
- onInstanceAdded: (instance: GroupeInstance) => void;
13
- onInstanceRemoved: (instanceNumber: number) => void;
12
+ onInstanceAdded: (instance: GroupeInstance, updatedGroupe: GroupeFormulaire) => void;
13
+ onInstanceRemoved: (instanceNumber: number, updatedGroupe: GroupeFormulaire, updatedResponses: Record<string, EnqueteReponse>) => void;
14
14
  disabled?: boolean;
15
15
  }
16
16
  declare const GroupeInstanceTabs: React.FC<GroupeInstanceTabsProps>;
@@ -1 +1 @@
1
- {"version":3,"file":"GroupeInstanceTabs.d.ts","sourceRoot":"","sources":["../../../src/components/form-renderer/GroupeInstanceTabs.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,KAA8B,MAAM,OAAO,CAAC;AAEnD,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAIvF,MAAM,WAAW,uBAAuB;IACtC,MAAM,EAAE,gBAAgB,CAAC;IACzB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IAC1C,gBAAgB,EAAE,CAAC,aAAa,EAAE,MAAM,KAAK,IAAI,CAAC;IAClD,eAAe,EAAE,CAAC,QAAQ,EAAE,cAAc,KAAK,IAAI,CAAC;IACpD,iBAAiB,EAAE,CAAC,cAAc,EAAE,MAAM,KAAK,IAAI,CAAC;IACpD,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,QAAA,MAAM,kBAAkB,EAAE,KAAK,CAAC,EAAE,CAAC,uBAAuB,CA0RzD,CAAC;AAEF,eAAe,kBAAkB,CAAC"}
1
+ {"version":3,"file":"GroupeInstanceTabs.d.ts","sourceRoot":"","sources":["../../../src/components/form-renderer/GroupeInstanceTabs.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,KAA8B,MAAM,OAAO,CAAC;AAEnD,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAIvF,MAAM,WAAW,uBAAuB;IACtC,MAAM,EAAE,gBAAgB,CAAC;IACzB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IAC1C,gBAAgB,EAAE,CAAC,aAAa,EAAE,MAAM,KAAK,IAAI,CAAC;IAClD,eAAe,EAAE,CAAC,QAAQ,EAAE,cAAc,EAAE,aAAa,EAAE,gBAAgB,KAAK,IAAI,CAAC;IACrF,iBAAiB,EAAE,CAAC,cAAc,EAAE,MAAM,EAAE,aAAa,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,KAAK,IAAI,CAAC;IACvI,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,QAAA,MAAM,kBAAkB,EAAE,KAAK,CAAC,EAAE,CAAC,uBAAuB,CAuQzD,CAAC;AAEF,eAAe,kBAAkB,CAAC"}
@@ -26,12 +26,6 @@ const GroupeInstanceTabs = ({ groupe, currentInstanceIndex, responses, onInstanc
26
26
  useEffect(() => {
27
27
  const newMaxInstances = GroupeInstanceManager.getMaxInstances(groupe, responses);
28
28
  if (newMaxInstances !== maxInstances) {
29
- console.log('GroupeInstanceTabs - Changement de maxInstances détecté:', {
30
- groupeCode: groupe.code,
31
- oldMaxInstances: maxInstances,
32
- newMaxInstances,
33
- codeVariable: groupe.codeVariable
34
- });
35
29
  setForceUpdate(prev => prev + 1);
36
30
  }
37
31
  }, [responses, groupe.codeVariable, groupe.maxInstances]);
@@ -39,18 +33,6 @@ const GroupeInstanceTabs = ({ groupe, currentInstanceIndex, responses, onInstanc
39
33
  // Le nombre d'onglets affichés = Math.max(maxInstances, instances existantes)
40
34
  const minDisplayCount = Math.max(maxInstances, groupe.instances.length);
41
35
  const displayedInstances = groupe.instances.slice(0, minDisplayCount);
42
- console.log('GroupeInstanceTabs - Debug avec protection:', {
43
- groupeCode: groupe.code,
44
- codeVariable: groupe.codeVariable,
45
- maxInstances,
46
- totalInstances: groupe.instances.length,
47
- minDisplayCount,
48
- displayedInstances: displayedInstances.length,
49
- canAdd: canAdd.canProceed,
50
- canRemove: canRemove.canProceed,
51
- canAddMessage: canAdd.constraints[0]?.message,
52
- canRemoveMessage: canRemove.constraints[0]?.message
53
- });
54
36
  // Fonction pour déterminer l'état d'une instance
55
37
  const getInstanceState = (instance) => {
56
38
  const responseCount = Object.keys(instance.reponses).length;
@@ -109,8 +91,8 @@ const GroupeInstanceTabs = ({ groupe, currentInstanceIndex, responses, onInstanc
109
91
  setError(null);
110
92
  try {
111
93
  const result = GroupeInstanceManager.addInstance(groupe, responses);
112
- if (result.success && result.instance) {
113
- onInstanceAdded(result.instance);
94
+ if (result.success && result.instance && result.updatedGroupe) {
95
+ onInstanceAdded(result.instance, result.updatedGroupe);
114
96
  }
115
97
  else {
116
98
  setError(result.error || 'Erreur lors de l\'ajout de l\'instance');
@@ -143,8 +125,8 @@ const GroupeInstanceTabs = ({ groupe, currentInstanceIndex, responses, onInstanc
143
125
  return;
144
126
  }
145
127
  const result = GroupeInstanceManager.removeInstance(groupe, currentInstance.numeroInstance, responses);
146
- if (result.success) {
147
- onInstanceRemoved(currentInstance.numeroInstance);
128
+ if (result.success && result.updatedGroupe && result.updatedResponses) {
129
+ onInstanceRemoved(currentInstance.numeroInstance, result.updatedGroupe, result.updatedResponses);
148
130
  }
149
131
  else {
150
132
  setError(result.error || 'Erreur lors de la suppression de l\'instance');
@@ -81,16 +81,16 @@ export function useFormInstances(initialGroupes, initialResponses, options = {})
81
81
  */
82
82
  const addInstance = useCallback((groupe, responses) => {
83
83
  const result = GroupeInstanceManager.addInstance(groupe, responses);
84
- if (result.success && result.instance) {
84
+ if (result.success && result.instance && result.updatedGroupe) {
85
85
  log('Instance ajoutée:', {
86
86
  groupeCode: groupe.code,
87
87
  instanceNumber: result.instance.numeroInstance
88
88
  });
89
- // Mettre à jour les groupes
89
+ // Mettre à jour les groupes avec le nouveau groupe immutable
90
90
  setGroupesWithInstances(prev => {
91
91
  const updated = prev.map(g => {
92
- if (g.code === groupe.code) {
93
- return { ...groupe };
92
+ if (g.code === result.updatedGroupe.code) {
93
+ return result.updatedGroupe;
94
94
  }
95
95
  return g;
96
96
  });
@@ -110,16 +110,16 @@ export function useFormInstances(initialGroupes, initialResponses, options = {})
110
110
  */
111
111
  const removeInstance = useCallback((groupe, instanceNumber, responses) => {
112
112
  const result = GroupeInstanceManager.removeInstance(groupe, instanceNumber, responses);
113
- if (result.success) {
113
+ if (result.success && result.updatedGroupe) {
114
114
  log('Instance supprimée:', {
115
115
  groupeCode: groupe.code,
116
116
  instanceNumber
117
117
  });
118
- // Mettre à jour les groupes
118
+ // Mettre à jour les groupes avec le nouveau groupe immutable
119
119
  setGroupesWithInstances(prev => {
120
120
  const updated = prev.map(g => {
121
- if (g.code === groupe.code) {
122
- return { ...groupe };
121
+ if (g.code === result.updatedGroupe.code) {
122
+ return result.updatedGroupe;
123
123
  }
124
124
  return g;
125
125
  });
@@ -1 +1 @@
1
- {"version":3,"file":"useFormRenderer.d.ts","sourceRoot":"","sources":["../../src/hooks/useFormRenderer.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"useFormRenderer.d.ts","sourceRoot":"","sources":["../../src/hooks/useFormRenderer.ts"],"names":[],"mappings":"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"}
@@ -7,6 +7,7 @@ import { useState, useCallback, useEffect, useMemo } from 'react';
7
7
  import { useFormNavigation } from './useFormNavigation';
8
8
  import { useFormValidation } from './useFormValidation';
9
9
  import { useFormInstances } from './useFormInstances';
10
+ import { GroupeInstanceManager } from '../lib/utils/groupeInstanceManager';
10
11
  /**
11
12
  * Hook principal pour gérer un formulaire d'enquête
12
13
  *
@@ -94,6 +95,20 @@ export function useFormRenderer(formulaire, enquete, options = { config: { mode:
94
95
  // === Mise à jour des réponses ===
95
96
  const updateResponse = useCallback((variableCode, value, variable, numeroMembre) => {
96
97
  const responseKey = getResponseKey(variableCode, numeroMembre);
98
+ // Validation de la variable de contrôle : empêcher la réduction en-dessous des instances existantes
99
+ if (isControlVariable(variable) && value !== null && value !== '') {
100
+ const numericValue = typeof value === 'number' ? value : parseInt(String(value), 10);
101
+ if (!isNaN(numericValue)) {
102
+ const groupesMultiples = (instances.groupesWithInstances.length > 0
103
+ ? instances.groupesWithInstances
104
+ : formulaire?.groupes || []).filter(g => g.estMultiple);
105
+ const validation = GroupeInstanceManager.canModifyControlVariable(variableCode, numericValue, groupesMultiples, responses);
106
+ if (!validation.canProceed) {
107
+ console.warn('[FormRenderer] Variable de contrôle rejetée:', validation.constraints[0]?.message);
108
+ return; // Rejeter le changement - l'input revient à la valeur précédente
109
+ }
110
+ }
111
+ }
97
112
  const newResponse = {
98
113
  variableId: variable.id,
99
114
  variableCode: variableCode,
@@ -129,9 +144,11 @@ export function useFormRenderer(formulaire, enquete, options = { config: { mode:
129
144
  setHasUnsavedChanges(true);
130
145
  }, [
131
146
  getResponseKey,
147
+ isControlVariable,
132
148
  currentGroup,
133
149
  currentInstance,
134
150
  instances,
151
+ formulaire?.groupes,
135
152
  responses,
136
153
  onResponsesChange
137
154
  ]);
@@ -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,CAyKnB;AAED,eAAe,WAAW,CAAC"}
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,CA2KnB;AAED,eAAe,WAAW,CAAC"}
@@ -102,8 +102,10 @@ export function useFormTree(groupes, responses, options = {}) {
102
102
  setUpdateCount(c => c + 1);
103
103
  }, [formTree]);
104
104
  // Méthodes pour les autoactions
105
- const executeAutoActions = useCallback(() => formTree.executeAutoActions(), [formTree, updateCount]);
106
- const evaluateAutoActionsForInstance = useCallback((groupeCode, instanceNumber) => formTree.evaluateAutoActionsForInstance(groupeCode, instanceNumber), [formTree, updateCount]);
105
+ // Note: pas de dépendance sur updateCount car formTree est une instance mutable
106
+ // dont l'état interne est toujours à jour. Ces callbacks sont appelés impérativement.
107
+ const executeAutoActions = useCallback(() => formTree.executeAutoActions(), [formTree]);
108
+ const evaluateAutoActionsForInstance = useCallback((groupeCode, instanceNumber) => formTree.evaluateAutoActionsForInstance(groupeCode, instanceNumber), [formTree]);
107
109
  // Valeurs dérivées
108
110
  const jumpErrors = useMemo(() => formTree.getJumpErrors(), [formTree, updateCount]);
109
111
  const activeJumps = useMemo(() => formTree.getActiveJumps(), [formTree, updateCount]);
@@ -166,6 +166,38 @@ describe('date-functions', () => {
166
166
  it('devrait retourner null pour une date invalide', () => {
167
167
  expect(parseDateString('invalid')).toBe(null);
168
168
  });
169
+ it('devrait parser une date DD/MM/YYYY', () => {
170
+ const result = parseDateString('13/05/2006');
171
+ expect(result).not.toBe(null);
172
+ expect(result.getDate()).toBe(13);
173
+ expect(result.getMonth()).toBe(4); // 0-indexé
174
+ expect(result.getFullYear()).toBe(2006);
175
+ });
176
+ it('devrait parser une date D/M/YYYY (chiffres simples)', () => {
177
+ const result = parseDateString('1/5/2006');
178
+ expect(result).not.toBe(null);
179
+ expect(result.getDate()).toBe(1);
180
+ expect(result.getMonth()).toBe(4);
181
+ expect(result.getFullYear()).toBe(2006);
182
+ });
183
+ it('devrait rejeter un mois > 12 en DD/MM/YYYY', () => {
184
+ expect(parseDateString('13/13/2006')).toBe(null);
185
+ });
186
+ it('devrait rejeter un jour invalide (31 février)', () => {
187
+ expect(parseDateString('31/02/2006')).toBe(null);
188
+ });
189
+ it('devrait parser DD/MM/YYYY HH:mm', () => {
190
+ const result = parseDateString('13/05/2006 14:30');
191
+ expect(result).not.toBe(null);
192
+ expect(result.getDate()).toBe(13);
193
+ expect(result.getMonth()).toBe(4);
194
+ expect(result.getFullYear()).toBe(2006);
195
+ expect(result.getHours()).toBe(14);
196
+ expect(result.getMinutes()).toBe(30);
197
+ });
198
+ it('devrait rejeter DD/MM/YYYY HH:mm avec heure invalide', () => {
199
+ expect(parseDateString('13/05/2006 25:00')).toBe(null);
200
+ });
169
201
  });
170
202
  describe('isValidDateUnit', () => {
171
203
  it('devrait retourner true pour "d"', () => {
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Tests unitaires pour GroupeInstanceManager
3
+ * Couvre le comptage, l'ajout/suppression, la validation et les scénarios d'intégration
4
+ */
5
+ export {};
6
+ //# sourceMappingURL=groupeInstanceManager.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"groupeInstanceManager.test.d.ts","sourceRoot":"","sources":["../../../src/lib/__tests__/groupeInstanceManager.test.ts"],"names":[],"mappings":"AAAA;;;GAGG"}