@rsuci/shared-form-components 1.0.84 → 1.0.86

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;AA0xBD;;;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
@@ -1 +1 @@
1
- {"version":3,"file":"GeographicCascadeInput.d.ts","sourceRoot":"","sources":["../../../src/components/inputs/GeographicCascadeInput.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAA4D,MAAM,OAAO,CAAC;AAWjF;;GAEG;AACH,UAAU,SAAS;IACjB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;CACrB;AAWD,UAAU,2BAA2B;IACnC,QAAQ,EAAE,GAAG,CAAC;IACd,KAAK,EAAE,GAAG,CAAC;IACX,QAAQ,EAAE,CAAC,KAAK,EAAE,SAAS,GAAG,IAAI,KAAK,IAAI,CAAC;IAC5C,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC9B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAC9B;AAED,eAAO,MAAM,sBAAsB,EAAE,KAAK,CAAC,EAAE,CAAC,2BAA2B,CAkPxE,CAAC;AAEF,eAAe,sBAAsB,CAAC"}
1
+ {"version":3,"file":"GeographicCascadeInput.d.ts","sourceRoot":"","sources":["../../../src/components/inputs/GeographicCascadeInput.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAA4D,MAAM,OAAO,CAAC;AAWjF;;GAEG;AACH,UAAU,SAAS;IACjB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;CACrB;AAWD,UAAU,2BAA2B;IACnC,QAAQ,EAAE,GAAG,CAAC;IACd,KAAK,EAAE,GAAG,CAAC;IACX,QAAQ,EAAE,CAAC,KAAK,EAAE,SAAS,GAAG,IAAI,KAAK,IAAI,CAAC;IAC5C,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC9B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAC9B;AAED,eAAO,MAAM,sBAAsB,EAAE,KAAK,CAAC,EAAE,CAAC,2BAA2B,CAwPxE,CAAC;AAEF,eAAe,sBAAsB,CAAC"}
@@ -15,6 +15,10 @@ export const GeographicCascadeInput = ({ variable, value, onChange, reponses, di
15
15
  const [error, setError] = useState(null);
16
16
  // 1. Déterminer si ce type nécessite un parent
17
17
  const needsParent = requiresParent(variable.typeCode);
18
+ // 1b. Vérifier si un parent est CONFIGURÉ dans la variable (valeur non vide)
19
+ const hasParentConfigured = !!extractVariableCode(variable);
20
+ // Le champ a besoin d'un parent SEULEMENT si le type le requiert ET qu'un parent est configuré
21
+ const effectiveNeedsParent = needsParent && hasParentConfigured;
18
22
  // 2. Résoudre la valeur du parent depuis les réponses
19
23
  const parentValue = resolveParentValue(variable, reponses);
20
24
  // Debug temporaire - À SUPPRIMER après validation
@@ -34,11 +38,11 @@ export const GeographicCascadeInput = ({ variable, value, onChange, reponses, di
34
38
  ? (variable.valeur || 'CIV')
35
39
  : undefined;
36
40
  // 4. Déterminer l'endpoint API à appeler
37
- const apiEndpoint = getApiEndpoint(variable.typeCode, parentValue, countryCode);
41
+ const apiEndpoint = getApiEndpoint(variable.typeCode, parentValue, countryCode, hasParentConfigured);
38
42
  // 4. Fonction pour charger les données
39
43
  const fetchData = useCallback(async () => {
40
- // Si un parent est requis mais absent, ne rien charger
41
- if (needsParent && !parentValue) {
44
+ // Si un parent est requis (configuré) mais absent, ne rien charger
45
+ if (effectiveNeedsParent && !parentValue) {
42
46
  setItems([]);
43
47
  setLoading(false);
44
48
  setError(null);
@@ -90,7 +94,7 @@ export const GeographicCascadeInput = ({ variable, value, onChange, reponses, di
90
94
  finally {
91
95
  setLoading(false);
92
96
  }
93
- }, [apiEndpoint, needsParent, parentValue, variable.type, variable.libelle]);
97
+ }, [apiEndpoint, effectiveNeedsParent, parentValue, variable.type, variable.libelle]);
94
98
  // 5. Charger les données quand l'endpoint ou le parent change
95
99
  useEffect(() => {
96
100
  fetchData();
@@ -98,8 +102,8 @@ export const GeographicCascadeInput = ({ variable, value, onChange, reponses, di
98
102
  // 6. Réinitialiser la valeur si le parent change
99
103
  const previousParentRef = useRef(undefined);
100
104
  useEffect(() => {
101
- // Si un parent est requis et que la valeur du parent a changé
102
- if (needsParent) {
105
+ // Si un parent est requis (configuré) et que la valeur du parent a changé
106
+ if (effectiveNeedsParent) {
103
107
  // Premier rendu : initialiser la référence sans réinitialiser
104
108
  if (previousParentRef.current === undefined) {
105
109
  previousParentRef.current = parentValue;
@@ -111,7 +115,7 @@ export const GeographicCascadeInput = ({ variable, value, onChange, reponses, di
111
115
  }
112
116
  previousParentRef.current = parentValue;
113
117
  }
114
- }, [parentValue, needsParent, value, onChange]);
118
+ }, [parentValue, effectiveNeedsParent, value, onChange]);
115
119
  // 7. Gérer le changement de valeur
116
120
  const handleChange = (option) => {
117
121
  if (!option) {
@@ -128,12 +132,12 @@ export const GeographicCascadeInput = ({ variable, value, onChange, reponses, di
128
132
  };
129
133
  // 8. Déterminer si le champ est désactivé (select ne supporte pas readonly, on utilise disabled)
130
134
  const isReadonly = isComponentReadonly(variable, isConsultationMode);
131
- const isDisabled = disabled || isReadonly || loading || (needsParent && !parentValue);
135
+ const isDisabled = disabled || isReadonly || loading || (effectiveNeedsParent && !parentValue);
132
136
  // 9. Déterminer le message du placeholder
133
137
  const getPlaceholder = () => {
134
138
  if (loading)
135
139
  return 'Chargement...';
136
- if (needsParent && !parentValue) {
140
+ if (effectiveNeedsParent && !parentValue) {
137
141
  return `Sélectionnez d'abord ${getParentLabel(variable.typeCode)}`;
138
142
  }
139
143
  if (items.length === 0 && !loading) {
@@ -176,11 +180,11 @@ export const GeographicCascadeInput = ({ variable, value, onChange, reponses, di
176
180
  designation: parsedValue.designation
177
181
  } : null;
178
182
  // 13. Rendu du composant
179
- return (_jsxs("div", { className: "w-full", children: [_jsx(SearchableSelect, { options: options, value: currentValue, onChange: handleChange, placeholder: getPlaceholder(), searchPlaceholder: "Rechercher...", disabled: isDisabled, required: required, loading: loading, error: error || undefined, className: className, noOptionsMessage: needsParent && !parentValue
183
+ return (_jsxs("div", { className: "w-full", children: [_jsx(SearchableSelect, { options: options, value: currentValue, onChange: handleChange, placeholder: getPlaceholder(), searchPlaceholder: "Rechercher...", disabled: isDisabled, required: required, loading: loading, error: error || undefined, className: className, noOptionsMessage: effectiveNeedsParent && !parentValue
180
184
  ? `Veuillez d'abord sélectionner ${getParentLabel(variable.typeCode)}`
181
185
  : `Aucun(e) ${variable.designation?.toLowerCase() || 'élément'} disponible`, formatOptionLabel: (option) => {
182
186
  // Afficher uniquement la désignation
183
187
  return option.designation;
184
- } }), needsParent && !parentValue && !loading && !error && (_jsxs("p", { className: "mt-1 text-sm text-gray-500 flex items-center", children: [_jsx("svg", { className: "w-4 h-4 mr-1", fill: "currentColor", viewBox: "0 0 20 20", children: _jsx("path", { fillRule: "evenodd", d: "M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a1 1 0 000 2v3a1 1 0 001 1h1a1 1 0 100-2v-3a1 1 0 00-1-1H9z", clipRule: "evenodd" }) }), "Veuillez d'abord s\u00E9lectionner ", getParentLabel(variable.typeCode)] })), loading && (_jsxs("p", { className: "mt-1 text-sm text-blue-600 flex items-center", children: [_jsxs("svg", { className: "animate-spin h-4 w-4 mr-1", fill: "none", viewBox: "0 0 24 24", children: [_jsx("circle", { className: "opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4" }), _jsx("path", { className: "opacity-75", fill: "currentColor", d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z" })] }), "Chargement des donn\u00E9es..."] }))] }));
188
+ } }), effectiveNeedsParent && !parentValue && !loading && !error && (_jsxs("p", { className: "mt-1 text-sm text-gray-500 flex items-center", children: [_jsx("svg", { className: "w-4 h-4 mr-1", fill: "currentColor", viewBox: "0 0 20 20", children: _jsx("path", { fillRule: "evenodd", d: "M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a1 1 0 000 2v3a1 1 0 001 1h1a1 1 0 100-2v-3a1 1 0 00-1-1H9z", clipRule: "evenodd" }) }), "Veuillez d'abord s\u00E9lectionner ", getParentLabel(variable.typeCode)] })), loading && (_jsxs("p", { className: "mt-1 text-sm text-blue-600 flex items-center", children: [_jsxs("svg", { className: "animate-spin h-4 w-4 mr-1", fill: "none", viewBox: "0 0 24 24", children: [_jsx("circle", { className: "opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4" }), _jsx("path", { className: "opacity-75", fill: "currentColor", d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z" })] }), "Chargement des donn\u00E9es..."] }))] }));
185
189
  };
186
190
  export default GeographicCascadeInput;
@@ -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"', () => {
@@ -21,7 +21,7 @@ export declare function calculateDateDiff(date1: Date | null | undefined, date2:
21
21
  export declare function calculateDateAdd(date: Date | null | undefined, value: number, unit: DateUnit): Date | null;
22
22
  /**
23
23
  * Parse une chaîne de date en objet Date
24
- * Supporte les formats: ISO 8601, timestamp
24
+ * Supporte les formats: DD/MM/YYYY, DD/MM/YYYY HH:mm, ISO 8601, timestamp
25
25
  * @param value - Chaîne à parser
26
26
  * @returns Date ou null si invalide
27
27
  */
@@ -1 +1 @@
1
- {"version":3,"file":"date-functions.d.ts","sourceRoot":"","sources":["../../../src/lib/utils/date-functions.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,MAAM,QAAQ,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;AAEvC;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,IAAI,GAAG,IAAI,GAAG,SAAS,EAC9B,KAAK,EAAE,IAAI,GAAG,IAAI,GAAG,SAAS,EAC9B,IAAI,EAAE,QAAQ,GACb,MAAM,GAAG,IAAI,CA2Cf;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,IAAI,GAAG,IAAI,GAAG,SAAS,EAC7B,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,QAAQ,GACb,IAAI,GAAG,IAAI,CA6Bb;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAiB1D;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,IAAI,QAAQ,CAE9D"}
1
+ {"version":3,"file":"date-functions.d.ts","sourceRoot":"","sources":["../../../src/lib/utils/date-functions.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,MAAM,QAAQ,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;AAEvC;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,IAAI,GAAG,IAAI,GAAG,SAAS,EAC9B,KAAK,EAAE,IAAI,GAAG,IAAI,GAAG,SAAS,EAC9B,IAAI,EAAE,QAAQ,GACb,MAAM,GAAG,IAAI,CA2Cf;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,IAAI,GAAG,IAAI,GAAG,SAAS,EAC7B,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,QAAQ,GACb,IAAI,GAAG,IAAI,CA6Bb;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAkD1D;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,IAAI,QAAQ,CAE9D"}
@@ -78,7 +78,7 @@ export function calculateDateAdd(date, value, unit) {
78
78
  }
79
79
  /**
80
80
  * Parse une chaîne de date en objet Date
81
- * Supporte les formats: ISO 8601, timestamp
81
+ * Supporte les formats: DD/MM/YYYY, DD/MM/YYYY HH:mm, ISO 8601, timestamp
82
82
  * @param value - Chaîne à parser
83
83
  * @returns Date ou null si invalide
84
84
  */
@@ -93,6 +93,37 @@ export function parseDateString(value) {
93
93
  const date = new Date(timestamp);
94
94
  return isNaN(date.getTime()) ? null : date;
95
95
  }
96
+ // Format DD/MM/YYYY ou D/M/YYYY (locale française)
97
+ const ddmmyyyy = trimmed.match(/^(\d{1,2})\/(\d{1,2})\/(\d{4})$/);
98
+ if (ddmmyyyy) {
99
+ const day = parseInt(ddmmyyyy[1], 10);
100
+ const month = parseInt(ddmmyyyy[2], 10);
101
+ const year = parseInt(ddmmyyyy[3], 10);
102
+ if (month >= 1 && month <= 12 && day >= 1 && day <= 31) {
103
+ const date = new Date(year, month - 1, day);
104
+ // Vérifier que les composants correspondent (attrape les dates invalides comme 31/02)
105
+ if (date.getFullYear() === year && date.getMonth() === month - 1 && date.getDate() === day) {
106
+ return date;
107
+ }
108
+ }
109
+ return null;
110
+ }
111
+ // Format DD/MM/YYYY HH:mm (pour variables DATEHEURE)
112
+ const ddmmyyyyHHmm = trimmed.match(/^(\d{1,2})\/(\d{1,2})\/(\d{4})\s+(\d{1,2}):(\d{2})$/);
113
+ if (ddmmyyyyHHmm) {
114
+ const day = parseInt(ddmmyyyyHHmm[1], 10);
115
+ const month = parseInt(ddmmyyyyHHmm[2], 10);
116
+ const year = parseInt(ddmmyyyyHHmm[3], 10);
117
+ const hours = parseInt(ddmmyyyyHHmm[4], 10);
118
+ const minutes = parseInt(ddmmyyyyHHmm[5], 10);
119
+ if (month >= 1 && month <= 12 && day >= 1 && day <= 31 && hours >= 0 && hours <= 23 && minutes >= 0 && minutes <= 59) {
120
+ const date = new Date(year, month - 1, day, hours, minutes);
121
+ if (date.getFullYear() === year && date.getMonth() === month - 1 && date.getDate() === day) {
122
+ return date;
123
+ }
124
+ }
125
+ return null;
126
+ }
96
127
  // Parser comme date ISO ou autre format
97
128
  const date = new Date(trimmed);
98
129
  return isNaN(date.getTime()) ? null : date;
@@ -40,7 +40,7 @@ export declare function resolveParentValue(variable: any, reponses: Record<strin
40
40
  * getApiEndpoint('REGION', 1) // Returns: '/api/v1/Regions/1/select'
41
41
  * getApiEndpoint('REGION') // Returns: null (parent requis mais absent)
42
42
  */
43
- export declare function getApiEndpoint(variableType: string, parentId?: number | null, defaultCountryCode?: string): string | null;
43
+ export declare function getApiEndpoint(variableType: string, parentId?: number | null, defaultCountryCode?: string, hasParentConfigured?: boolean): string | null;
44
44
  /**
45
45
  * Détermine le libellé du parent selon le type de variable
46
46
  * @param variableType - Type de la variable
@@ -1 +1 @@
1
- {"version":3,"file":"variableDependencyResolver.d.ts","sourceRoot":"","sources":["../../src/utils/variableDependencyResolver.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;;;;;;;;;GAYG;AACH,wBAAgB,mBAAmB,CAAC,gBAAgB,EAAE,MAAM,GAAG,GAAG,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,CAmCpG;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,GAAG,EACb,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAC5B,MAAM,GAAG,IAAI,CA+Cf;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,cAAc,CAC5B,YAAY,EAAE,MAAM,EACpB,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,EACxB,kBAAkB,GAAE,MAAc,GACjC,MAAM,GAAG,IAAI,CA2Bf;AAED;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAa3D;AAED;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAW5D;AAED;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAY9D"}
1
+ {"version":3,"file":"variableDependencyResolver.d.ts","sourceRoot":"","sources":["../../src/utils/variableDependencyResolver.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;;;;;;;;;GAYG;AACH,wBAAgB,mBAAmB,CAAC,gBAAgB,EAAE,MAAM,GAAG,GAAG,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,CAmCpG;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,GAAG,EACb,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAC5B,MAAM,GAAG,IAAI,CA+Cf;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,cAAc,CAC5B,YAAY,EAAE,MAAM,EACpB,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,EACxB,kBAAkB,GAAE,MAAc,EAClC,mBAAmB,GAAE,OAAc,GAClC,MAAM,GAAG,IAAI,CA+Bf;AAED;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAa3D;AAED;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAW5D;AAED;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAY9D"}
@@ -114,23 +114,32 @@ export function resolveParentValue(variable, reponses) {
114
114
  * getApiEndpoint('REGION', 1) // Returns: '/api/v1/Regions/1/select'
115
115
  * getApiEndpoint('REGION') // Returns: null (parent requis mais absent)
116
116
  */
117
- export function getApiEndpoint(variableType, parentId, defaultCountryCode = 'CIV') {
117
+ export function getApiEndpoint(variableType, parentId, defaultCountryCode = 'CIV', hasParentConfigured = true) {
118
118
  const type = variableType?.toUpperCase();
119
119
  switch (type) {
120
120
  case 'DISTRICT':
121
- // Pour DISTRICT, pas besoin de code pays dans l'URL
122
121
  return `/api/v1/Districts/select`;
123
122
  case 'REGION':
124
- return parentId ? `/api/v1/Regions/${parentId}/select` : null;
123
+ if (parentId)
124
+ return `/api/v1/Regions/${parentId}/select`;
125
+ return hasParentConfigured ? null : `/api/v1/Regions/select`;
125
126
  case 'DEPARTEMENT':
126
- return parentId ? `/api/v1/Departements/${parentId}/select` : null;
127
+ if (parentId)
128
+ return `/api/v1/Departements/${parentId}/select`;
129
+ return hasParentConfigured ? null : `/api/v1/Departements/select`;
127
130
  case 'SOUS_PREFECTURE':
128
131
  case 'SOUSPREFECTURE':
129
- return parentId ? `/api/v1/SousPrefectures/${parentId}/select` : null;
132
+ if (parentId)
133
+ return `/api/v1/SousPrefectures/${parentId}/select`;
134
+ return hasParentConfigured ? null : `/api/v1/SousPrefectures/select`;
130
135
  case 'QUARTIER':
131
- return parentId ? `/api/v1/Quartiers/${parentId}/select` : null;
136
+ if (parentId)
137
+ return `/api/v1/Quartiers/${parentId}/select`;
138
+ return hasParentConfigured ? null : `/api/v1/Quartiers/select`;
132
139
  case 'VILLAGE':
133
- return parentId ? `/api/v1/Villages/${parentId}/select` : null;
140
+ if (parentId)
141
+ return `/api/v1/Villages/${parentId}/select`;
142
+ return hasParentConfigured ? null : `/api/v1/Villages/select`;
134
143
  default:
135
144
  return null;
136
145
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rsuci/shared-form-components",
3
- "version": "1.0.84",
3
+ "version": "1.0.86",
4
4
  "description": "Composants partagés de rendu de formulaires RSU v2 - Package local pour frontend Admin et Public",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",