@rsuci/shared-form-components 1.0.96 → 1.0.98

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;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;AAi2BD;;;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;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 l'instance courante avec FormTree (gestion des jumps par instance)
253
- if (currentGroup.estMultiple && currentInstance?.numeroInstance) {
254
- const { isValid } = validateGroupForInstance(currentGroup.code, currentInstance.numeroInstance);
255
- return isValid;
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);
@@ -275,7 +286,7 @@ const FormRendererInner = () => {
275
286
  const responseKey = currentGroup.estMultiple && currentInstance?.numeroInstance
276
287
  ? `${variable.code}_${currentInstance.numeroInstance}`
277
288
  : variable.code;
278
- const response = responses[responseKey];
289
+ const response = responses[responseKey] || (!currentGroup.estMultiple ? responsesByVariableCode.get(variable.code) : undefined);
279
290
  const optionsSource = (variable.proprietes?.valeur || variable.valeurDefaut);
280
291
  const hasValue = response && VariableValueConverter.hasRequiredValue(variable.typeCode, response.valeur, optionsSource);
281
292
  if (!hasValue) {
@@ -283,7 +294,7 @@ const FormRendererInner = () => {
283
294
  }
284
295
  }
285
296
  return true;
286
- }, [currentGroup, currentInstance, responses, isVariableVisible, isVariableFilteredByMode, validateGroupForInstance, mode]);
297
+ }, [currentGroup, currentInstance, responses, isVariableVisible, isVariableFilteredByMode, validateGroupForInstance, responsesByVariableCode, mode]);
287
298
  // Mode consultation (pas de validation, navigation libre)
288
299
  const isConsultationMode = features?.consultationMode || false;
289
300
  // En mode consultation, navigation libre sans validation des champs obligatoires
@@ -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)
@@ -311,7 +325,7 @@ const FormRendererInner = () => {
311
325
  continue;
312
326
  if (!visibleCodes.has(variable.code))
313
327
  continue;
314
- const response = responses[variable.code];
328
+ const response = responses[variable.code] || responsesByVariableCode.get(variable.code);
315
329
  const optionsSource = (variable.proprietes?.valeur || variable.valeurDefaut);
316
330
  const hasValue = response && VariableValueConverter.hasRequiredValue(variable.typeCode, response.valeur, optionsSource);
317
331
  if (!hasValue)
@@ -319,7 +333,7 @@ const FormRendererInner = () => {
319
333
  }
320
334
  }
321
335
  return true;
322
- }, [groupes, responses, getVisibleVariables, validateGroupForInstance, isVariableFilteredByMode]);
336
+ }, [groupes, responses, getVisibleVariables, validateGroupForInstance, isVariableFilteredByMode, responsesByVariableCode]);
323
337
  const handleNext = () => {
324
338
  // En mode consultation, navigation libre
325
339
  if (isConsultationMode) {
@@ -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
  });
@@ -384,7 +406,7 @@ const FormRendererInner = () => {
384
406
  continue;
385
407
  if (!visibleCodes.has(variable.code))
386
408
  continue;
387
- const response = responses[variable.code];
409
+ const response = responses[variable.code] || responsesByVariableCode.get(variable.code);
388
410
  const optionsSource = (variable.proprietes?.valeur || variable.valeurDefaut);
389
411
  const hasValue = response && VariableValueConverter.hasRequiredValue(variable.typeCode, response.valeur, optionsSource);
390
412
  if (!hasValue) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rsuci/shared-form-components",
3
- "version": "1.0.96",
3
+ "version": "1.0.98",
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",