df-ae-forms-package 1.0.88 → 1.0.90

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/index.js CHANGED
@@ -5306,6 +5306,12 @@ const DfFormTable$1 = React.lazy(() => Promise.resolve().then(function () { retu
5306
5306
  const DfFormPreview = ({ formComponents = [], currentDevice = 'desktop', isPreviewMode = false, initialFormData = [], onSubmit, onFormDataChange, formTitle, formDescription, formTemplateId,
5307
5307
  // Add component management props for edit mode
5308
5308
  onComponentSelect, onComponentDelete, onComponentEdit, onComponentUpdate, selectedComponent, workOrderNumber, assetNumber, isStandalone, user, onCreateIssue, onUpdateIssue }) => {
5309
+ // Local copy of formComponents so structure updates (e.g. table cell init) are reflected immediately
5310
+ const [localFormComponents, setLocalFormComponents] = React.useState(formComponents);
5311
+ // Sync local state when the prop changes from the parent
5312
+ React.useEffect(() => {
5313
+ setLocalFormComponents(formComponents);
5314
+ }, [formComponents]);
5309
5315
  // Form state
5310
5316
  const [formValues, setFormValues] = React.useState({});
5311
5317
  const [validationErrors, setValidationErrors] = React.useState({});
@@ -5326,7 +5332,7 @@ onComponentSelect, onComponentDelete, onComponentEdit, onComponentUpdate, select
5326
5332
  // Initialize form state
5327
5333
  React.useEffect(() => {
5328
5334
  initializeFormState();
5329
- }, [formComponents, initialFormData]);
5335
+ }, [localFormComponents, initialFormData]);
5330
5336
  // Recursive function to initialize values from nested components
5331
5337
  const initializeComponentValues = (components, values) => {
5332
5338
  components.forEach(component => {
@@ -5496,11 +5502,11 @@ onComponentSelect, onComponentDelete, onComponentEdit, onComponentUpdate, select
5496
5502
  });
5497
5503
  };
5498
5504
  // Initialize validated components
5499
- let validatedFormComponents = formComponents;
5500
- if (formComponents && formComponents.length > 0) {
5501
- validatedFormComponents = getValidatedComponents(formComponents);
5505
+ let validatedFormComponents = localFormComponents;
5506
+ if (localFormComponents && localFormComponents.length > 0) {
5507
+ validatedFormComponents = getValidatedComponents(localFormComponents);
5502
5508
  // Notifying parent of changed components if they were mutated (IDs added/fixed)
5503
- if (JSON.stringify(validatedFormComponents) !== JSON.stringify(formComponents)) {
5509
+ if (JSON.stringify(validatedFormComponents) !== JSON.stringify(localFormComponents)) {
5504
5510
  onFormDataChange?.(validatedFormComponents);
5505
5511
  }
5506
5512
  }
@@ -5528,7 +5534,7 @@ onComponentSelect, onComponentDelete, onComponentEdit, onComponentUpdate, select
5528
5534
  setComponentAttachments(prev => ({ ...initialAttachments, ...prev }));
5529
5535
  // Conditional logic evaluation disabled temporarily to fix table issues
5530
5536
  // evaluateConditionalLogic()
5531
- }, [initialFormData, formComponents]);
5537
+ }, [initialFormData, localFormComponents]);
5532
5538
  // Conditional logic disabled temporarily - all components are always visible
5533
5539
  const shouldShowComponent = React.useCallback((_componentId) => {
5534
5540
  return true;
@@ -5541,7 +5547,7 @@ onComponentSelect, onComponentDelete, onComponentEdit, onComponentUpdate, select
5541
5547
  return;
5542
5548
  }
5543
5549
  // CRITICAL: Check if multiple components share this ID (ID collision detection)
5544
- const componentsWithSameId = formComponents.filter(comp => comp.id === change.id);
5550
+ const componentsWithSameId = localFormComponents.filter(comp => comp.id === change.id);
5545
5551
  if (componentsWithSameId.length > 1) {
5546
5552
  console.error(`[DfFormPreview] ID COLLISION DETECTED! Multiple components share ID "${change.id}":`, componentsWithSameId.map(c => ({ id: c.id, name: c.name, label: c.basic?.label })));
5547
5553
  // Don't update - this would cause all components with this ID to get the same value
@@ -5562,7 +5568,7 @@ onComponentSelect, onComponentDelete, onComponentEdit, onComponentUpdate, select
5562
5568
  }
5563
5569
  // Clear raised issues for this component when value changes
5564
5570
  // This ensures that if threshold condition changes, user must raise issue again
5565
- const component = formComponents.find(comp => comp.id === change.id);
5571
+ const component = localFormComponents.find(comp => comp.id === change.id);
5566
5572
  if (component) {
5567
5573
  const threshold = component?.threshold;
5568
5574
  if (threshold && threshold.conditions && threshold.conditions.length > 0) {
@@ -5640,7 +5646,10 @@ onComponentSelect, onComponentDelete, onComponentEdit, onComponentUpdate, select
5640
5646
  });
5641
5647
  };
5642
5648
  // Update form components
5643
- const updatedComponents = updateComponentValue(formComponents);
5649
+ const updatedComponents = updateComponentValue(localFormComponents);
5650
+ // CRITICAL: Update local state immediately so structure changes (e.g. table cell init)
5651
+ // are reflected without waiting for Angular parent round-trip
5652
+ setLocalFormComponents(updatedComponents);
5644
5653
  onFormDataChange?.(updatedComponents);
5645
5654
  // Clear validation errors when user starts typing and re-validate
5646
5655
  if (validationErrors[change.id]) {
@@ -5677,7 +5686,7 @@ onComponentSelect, onComponentDelete, onComponentEdit, onComponentUpdate, select
5677
5686
  }
5678
5687
  // Conditional logic evaluation disabled temporarily
5679
5688
  // evaluateConditionalLogic(newFormValues, updatedComponents)
5680
- }, [formComponents, formValues, validationErrors, onFormDataChange]);
5689
+ }, [localFormComponents, formValues, validationErrors, onFormDataChange]);
5681
5690
  // Recursive function to find a component by ID in nested structures
5682
5691
  const findComponentById = React.useCallback((components, fieldId) => {
5683
5692
  for (const comp of components) {
@@ -5721,7 +5730,7 @@ onComponentSelect, onComponentDelete, onComponentEdit, onComponentUpdate, select
5721
5730
  if (isPreviewMode)
5722
5731
  return;
5723
5732
  // Find component recursively (handles nested components)
5724
- const component = findComponentById(formComponents, fieldId);
5733
+ const component = findComponentById(localFormComponents, fieldId);
5725
5734
  if (!component)
5726
5735
  return;
5727
5736
  // Get current value from form values (real-time input)
@@ -5816,7 +5825,7 @@ onComponentSelect, onComponentDelete, onComponentEdit, onComponentUpdate, select
5816
5825
  ...prev,
5817
5826
  [fieldId]: errorMessage
5818
5827
  }));
5819
- }, [formComponents, isPreviewMode, formValues, findComponentById]);
5828
+ }, [localFormComponents, isPreviewMode, formValues, findComponentById]);
5820
5829
  // Handle form control blur
5821
5830
  const onFormControlBlur = React.useCallback((fieldId) => {
5822
5831
  setTouchedFields(prev => ({
@@ -5846,11 +5855,11 @@ onComponentSelect, onComponentDelete, onComponentEdit, onComponentUpdate, select
5846
5855
  // useEffect(() => {
5847
5856
  // if (!isPreviewMode && Object.keys(formValues).length > 0) {
5848
5857
  // // Validate all form components when form values change (but not on initial load)
5849
- // formComponents.forEach(component => {
5858
+ // localFormComponents.forEach(component => {
5850
5859
  // validateField(component.id)
5851
5860
  // })
5852
5861
  // }
5853
- // }, [formValues, validateField, isPreviewMode, formComponents])
5862
+ // }, [formValues, validateField, isPreviewMode, localFormComponents])
5854
5863
  // Enhanced form validity check
5855
5864
  const isFormValid = React.useCallback(() => {
5856
5865
  // Check if there are any validation errors
@@ -5859,7 +5868,7 @@ onComponentSelect, onComponentDelete, onComponentEdit, onComponentUpdate, select
5859
5868
  return false;
5860
5869
  }
5861
5870
  // Check required fields
5862
- return formComponents.every(component => {
5871
+ return localFormComponents.every(component => {
5863
5872
  // Use real-time form values instead of component values
5864
5873
  const currentValue = formValues[component.id] || '';
5865
5874
  // Check if field has a value
@@ -5905,7 +5914,7 @@ onComponentSelect, onComponentDelete, onComponentEdit, onComponentUpdate, select
5905
5914
  }
5906
5915
  return true;
5907
5916
  });
5908
- }, [formComponents, formValues, validationErrors]);
5917
+ }, [localFormComponents, formValues, validationErrors]);
5909
5918
  // Evaluate threshold condition (handles both numeric and string values)
5910
5919
  const evaluateThresholdCondition = React.useCallback((condition, currentVal) => {
5911
5920
  // Handle array values (for checkbox)
@@ -5959,7 +5968,7 @@ onComponentSelect, onComponentDelete, onComponentEdit, onComponentUpdate, select
5959
5968
  if (isPreviewMode)
5960
5969
  return [];
5961
5970
  const metConditions = [];
5962
- formComponents.forEach(component => {
5971
+ localFormComponents.forEach(component => {
5963
5972
  const condition = component?.condition;
5964
5973
  if (!condition || !condition.conditions || condition.conditions.length === 0) {
5965
5974
  return;
@@ -5985,7 +5994,7 @@ onComponentSelect, onComponentDelete, onComponentEdit, onComponentUpdate, select
5985
5994
  });
5986
5995
  });
5987
5996
  return metConditions;
5988
- }, [formComponents, formValues, isPreviewMode, evaluateThresholdCondition]);
5997
+ }, [localFormComponents, formValues, isPreviewMode, evaluateThresholdCondition]);
5989
5998
  // Validate threshold conditions - check if all met conditions have all mandatory actions completed
5990
5999
  const validateThresholdConditions = React.useCallback(() => {
5991
6000
  if (isPreviewMode)
@@ -6070,7 +6079,7 @@ onComponentSelect, onComponentDelete, onComponentEdit, onComponentUpdate, select
6070
6079
  let isValid = true;
6071
6080
  setFormSubmitted(true);
6072
6081
  const errors = {};
6073
- formComponents.forEach(component => {
6082
+ localFormComponents.forEach(component => {
6074
6083
  // Use real-time form values instead of component values
6075
6084
  const currentValue = formValues[component.id] || '';
6076
6085
  // Check if field has a value
@@ -6137,13 +6146,13 @@ onComponentSelect, onComponentDelete, onComponentEdit, onComponentUpdate, select
6137
6146
  });
6138
6147
  setValidationErrors(errors);
6139
6148
  return isValid;
6140
- }, [formComponents, isPreviewMode, formValues]);
6149
+ }, [localFormComponents, isPreviewMode, formValues]);
6141
6150
  // Handle form submission
6142
6151
  const handleSubmit = React.useCallback((status = 'Submitted') => {
6143
6152
  setFormSubmitted(true);
6144
6153
  if (!validateAllFields()) {
6145
6154
  // Focus on the first invalid field
6146
- const firstErrorField = formComponents.find(comp => {
6155
+ const firstErrorField = localFormComponents.find(comp => {
6147
6156
  const currentValue = formValues[comp.id] || '';
6148
6157
  // Check if field has a value
6149
6158
  let hasValue = false;
@@ -6246,12 +6255,12 @@ onComponentSelect, onComponentDelete, onComponentEdit, onComponentUpdate, select
6246
6255
  });
6247
6256
  };
6248
6257
  // Prepare final form data
6249
- const finalFormData = updateComponentValues(formComponents);
6258
+ const finalFormData = updateComponentValues(localFormComponents);
6250
6259
  // Also prepare a clean key-value payload
6251
6260
  const payloadValues = { ...formValues, status };
6252
6261
  // Pass both the updated component tree and the flat values object
6253
6262
  onSubmit?.(finalFormData, payloadValues);
6254
- }, [formComponents, formValues, validateAllFields, onSubmit, componentNotes, componentAttachments]);
6263
+ }, [localFormComponents, formValues, validateAllFields, onSubmit, componentNotes, componentAttachments]);
6255
6264
  // Get preview classes
6256
6265
  const getPreviewClasses = React.useCallback(() => {
6257
6266
  return {
@@ -6313,7 +6322,7 @@ onComponentSelect, onComponentDelete, onComponentEdit, onComponentUpdate, select
6313
6322
  // Debug: Log if formValue is being shared incorrectly
6314
6323
  if (formValue !== undefined) {
6315
6324
  // Check if this value is being used by multiple components
6316
- const componentsWithSameValue = formComponents.filter(comp => comp.id !== componentId && formValues[comp.id] === formValue);
6325
+ const componentsWithSameValue = localFormComponents.filter(comp => comp.id !== componentId && formValues[comp.id] === formValue);
6317
6326
  if (componentsWithSameValue.length > 0) {
6318
6327
  console.warn(`[DfFormPreview] Component ${componentId} shares form value with other components:`, componentsWithSameValue.map(c => c.id));
6319
6328
  }
@@ -6408,9 +6417,11 @@ onComponentSelect, onComponentDelete, onComponentEdit, onComponentUpdate, select
6408
6417
  return renderFormComponent(field);
6409
6418
  } }));
6410
6419
  case 'table':
6411
- return (jsxRuntime.jsx(React.Suspense, { fallback: jsxRuntime.jsx("div", { children: "Loading table..." }), children: jsxRuntime.jsx(DfFormTable$1, { ...commonProps, properties: component, formData: formValues, formTemplateId: formTemplateId, mode: commonProps.mode, validationErrors: validationErrors, touchedFields: touchedFields, formSubmitted: formSubmitted, onThresholdActionCompletion: handleThresholdActionCompletion, onThresholdIssueRaised: handleThresholdIssueRaised, workOrderNumber: workOrderNumber, assetNumber: assetNumber, onCreateIssue: onCreateIssue, onUpdateIssue: onUpdateIssue, onNotesChange: (componentId, notes) => {
6420
+ return (jsxRuntime.jsx(React.Suspense, { fallback: jsxRuntime.jsx("div", { children: "Loading table..." }), children: jsxRuntime.jsx(DfFormTable$1, { ...commonProps, properties: component, formData: formValues, formTemplateId: formTemplateId, mode: commonProps.mode, validationErrors: validationErrors, touchedFields: touchedFields, formSubmitted: formSubmitted, onThresholdActionCompletion: handleThresholdActionCompletion, onThresholdIssueRaised: handleThresholdIssueRaised, workOrderNumber: workOrderNumber, assetNumber: assetNumber, onCreateIssue: onCreateIssue, onUpdateIssue: onUpdateIssue, renderFormComponent: (field) => {
6421
+ return renderFormComponent(field);
6422
+ }, onNotesChange: (componentId, notes) => {
6412
6423
  // Handle notes change for table cell components
6413
- const updatedComponents = formComponents.map(comp => {
6424
+ const updatedComponents = localFormComponents.map(comp => {
6414
6425
  if (comp.id === component.id && comp.cells) {
6415
6426
  const updatedCells = comp.cells.map((row) => Array.isArray(row) ? row.map((cell) => {
6416
6427
  if (cell.components) {
@@ -6437,7 +6448,7 @@ onComponentSelect, onComponentDelete, onComponentEdit, onComponentUpdate, select
6437
6448
  onFormDataChange?.(updatedComponents);
6438
6449
  }, onAttachmentChange: (componentId, attachments) => {
6439
6450
  // Handle attachment change for table cell components
6440
- const updatedComponents = formComponents.map(comp => {
6451
+ const updatedComponents = localFormComponents.map(comp => {
6441
6452
  if (comp.id === component.id && comp.cells) {
6442
6453
  const updatedCells = comp.cells.map((row) => Array.isArray(row) ? row.map((cell) => {
6443
6454
  if (cell.components) {
@@ -6462,16 +6473,12 @@ onComponentSelect, onComponentDelete, onComponentEdit, onComponentUpdate, select
6462
6473
  return comp;
6463
6474
  });
6464
6475
  onFormDataChange?.(updatedComponents);
6465
- }, renderFormComponent: (field) => {
6466
- // CRITICAL: Pass the field to renderFormComponent which has access to latest formValues
6467
- // renderFormComponent uses formValues[field.id] internally, so it will get the correct value
6468
- return renderFormComponent(field);
6469
6476
  } }) }));
6470
6477
  case 'datagrid':
6471
6478
  return (jsxRuntime.jsx(DfFormDataGrid, { ...commonProps, properties: component, formData: formValues, formTemplateId: formTemplateId, mode: commonProps.mode, onThresholdActionCompletion: handleThresholdActionCompletion, onThresholdIssueRaised: handleThresholdIssueRaised, onNotesChange: (componentId, notes) => {
6472
6479
  handleComponentNotesChange(componentId, notes);
6473
6480
  // Handle notes change for datagrid entry components
6474
- const updatedComponents = formComponents.map(comp => {
6481
+ const updatedComponents = localFormComponents.map(comp => {
6475
6482
  if (comp.id === component.id && comp.entries) {
6476
6483
  const updatedEntries = comp.entries.map((entry) => {
6477
6484
  if (entry.components) {
@@ -6499,7 +6506,7 @@ onComponentSelect, onComponentDelete, onComponentEdit, onComponentUpdate, select
6499
6506
  }, onAttachmentChange: (componentId, attachments) => {
6500
6507
  handleComponentAttachmentChange(componentId, attachments);
6501
6508
  // Handle attachment change for datagrid entry components
6502
- const updatedComponents = formComponents.map(comp => {
6509
+ const updatedComponents = localFormComponents.map(comp => {
6503
6510
  if (comp.id === component.id && comp.entries) {
6504
6511
  const updatedEntries = comp.entries.map((entry) => {
6505
6512
  if (entry.components) {
@@ -6527,8 +6534,8 @@ onComponentSelect, onComponentDelete, onComponentEdit, onComponentUpdate, select
6527
6534
  }, onValueChange: (change) => {
6528
6535
  // Handle datagrid value changes (entries updates)
6529
6536
  if (change.id === component.id && change.value && typeof change.value === 'object' && 'entries' in change.value) {
6530
- // Update formComponents with new entries structure
6531
- const updatedComponents = formComponents.map(comp => {
6537
+ // Update localFormComponents with new entries structure
6538
+ const updatedComponents = localFormComponents.map(comp => {
6532
6539
  if (comp.id === component.id) {
6533
6540
  return {
6534
6541
  ...comp,
@@ -6566,12 +6573,12 @@ onComponentSelect, onComponentDelete, onComponentEdit, onComponentUpdate, select
6566
6573
  }
6567
6574
  }, onEntryAdd: () => {
6568
6575
  // CRITICAL: Entry has already been added via onValueChange in DfFormDataGrid
6569
- // Get the updated component from formComponents (which should have been updated by onValueChange)
6570
- const currentComponent = formComponents.find(comp => comp.id === component.id);
6576
+ // Get the updated component from localFormComponents (which should have been updated by onValueChange)
6577
+ const currentComponent = localFormComponents.find(comp => comp.id === component.id);
6571
6578
  if (currentComponent && currentComponent.entries) {
6572
6579
  // Entry should already be in the component via onValueChange
6573
- // Just ensure formComponents is in sync (no-op if already synced)
6574
- const updatedComponents = formComponents.map(comp => {
6580
+ // Just ensure localFormComponents is in sync (no-op if already synced)
6581
+ const updatedComponents = localFormComponents.map(comp => {
6575
6582
  if (comp.id === component.id) {
6576
6583
  // Ensure entries are properly structured
6577
6584
  return {
@@ -6588,7 +6595,7 @@ onComponentSelect, onComponentDelete, onComponentEdit, onComponentUpdate, select
6588
6595
  setTimeout(() => {
6589
6596
  const datagridValue = formValues[component.id];
6590
6597
  if (datagridValue && typeof datagridValue === 'object' && 'entries' in datagridValue) {
6591
- const updatedComponents = formComponents.map(comp => {
6598
+ const updatedComponents = localFormComponents.map(comp => {
6592
6599
  if (comp.id === component.id) {
6593
6600
  return {
6594
6601
  ...comp,
@@ -6603,7 +6610,7 @@ onComponentSelect, onComponentDelete, onComponentEdit, onComponentUpdate, select
6603
6610
  }
6604
6611
  }, onEntryRemove: (entryIndex) => {
6605
6612
  // Handle entry remove - update form components
6606
- const updatedComponents = formComponents.map(comp => {
6613
+ const updatedComponents = localFormComponents.map(comp => {
6607
6614
  if (comp.id === component.id && comp.entries) {
6608
6615
  const currentEntries = comp.entries || [];
6609
6616
  const updatedEntries = currentEntries
@@ -6645,7 +6652,7 @@ onComponentSelect, onComponentDelete, onComponentEdit, onComponentUpdate, select
6645
6652
  return (jsxRuntime.jsx("div", { className: "form-group", children: jsxRuntime.jsxs("div", { className: "form-group-label", children: ["Unsupported Component: ", component.name] }) }));
6646
6653
  }
6647
6654
  };
6648
- return (jsxRuntime.jsx("div", { className: "form-preview-container", children: jsxRuntime.jsx("div", { className: "form-preview-wrapper", children: jsxRuntime.jsxs("div", { className: `form-preview ${Object.entries(getPreviewClasses()).map(([key, value]) => value ? key : '').join(' ')}`, children: [jsxRuntime.jsx("div", { className: "form-canvas-header" }), formComponents.length === 0 ? (jsxRuntime.jsx("div", { className: "empty-state", children: jsxRuntime.jsx("div", { className: "empty-state-card", children: jsxRuntime.jsx("div", { className: "empty-state-preview-area", children: jsxRuntime.jsx("span", { className: "empty-state-placeholder", children: "Add components to see the form preview" }) }) }) })) : (jsxRuntime.jsxs("form", { className: "form-preview-form", onSubmit: (e) => { e.preventDefault(); handleSubmit(); }, children: [(formTitle || formDescription) && (jsxRuntime.jsxs("div", { className: "form-header", children: [formTitle && (jsxRuntime.jsx("h1", { className: "form-title", children: formTitle })), formDescription && (jsxRuntime.jsx("p", { className: "form-description", children: formDescription }))] })), formComponents.map((component) => {
6655
+ return (jsxRuntime.jsx("div", { className: "form-preview-container", children: jsxRuntime.jsx("div", { className: "form-preview-wrapper", children: jsxRuntime.jsxs("div", { className: `form-preview ${Object.entries(getPreviewClasses()).map(([key, value]) => value ? key : '').join(' ')}`, children: [jsxRuntime.jsx("div", { className: "form-canvas-header" }), localFormComponents.length === 0 ? (jsxRuntime.jsx("div", { className: "empty-state", children: jsxRuntime.jsx("div", { className: "empty-state-card", children: jsxRuntime.jsx("div", { className: "empty-state-preview-area", children: jsxRuntime.jsx("span", { className: "empty-state-placeholder", children: "Add components to see the form preview" }) }) }) })) : (jsxRuntime.jsxs("form", { className: "form-preview-form", onSubmit: (e) => { e.preventDefault(); handleSubmit(); }, children: [(formTitle || formDescription) && (jsxRuntime.jsxs("div", { className: "form-header", children: [formTitle && (jsxRuntime.jsx("h1", { className: "form-title", children: formTitle })), formDescription && (jsxRuntime.jsx("p", { className: "form-description", children: formDescription }))] })), localFormComponents.map((component) => {
6649
6656
  const basic = component.basic;
6650
6657
  const formValue = formValues[component.id];
6651
6658
  const isOptionBased = ['select', 'radio', 'checkbox', 'segment'].includes(component.name || '');
@@ -6697,7 +6704,7 @@ onComponentSelect, onComponentDelete, onComponentEdit, onComponentUpdate, select
6697
6704
  // Update local state immediately
6698
6705
  setComponentNotes(prev => ({ ...prev, [component.id]: notes }));
6699
6706
  // Handle notes change for regular components - update component.basic.notes
6700
- const updatedComponents = formComponents.map(comp => {
6707
+ const updatedComponents = localFormComponents.map(comp => {
6701
6708
  if (comp.id === component.id) {
6702
6709
  return {
6703
6710
  ...comp,
@@ -6714,7 +6721,7 @@ onComponentSelect, onComponentDelete, onComponentEdit, onComponentUpdate, select
6714
6721
  // Update local state immediately
6715
6722
  setComponentAttachments(prev => ({ ...prev, [component.id]: attachments || [] }));
6716
6723
  // Handle attachment change for regular components - update component.basic.attachments
6717
- const updatedComponents = formComponents.map(comp => {
6724
+ const updatedComponents = localFormComponents.map(comp => {
6718
6725
  if (comp.id === component.id) {
6719
6726
  return {
6720
6727
  ...comp,