df-ae-forms-package 1.0.89 → 1.0.91
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.esm.js +115 -73
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +115 -73
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.esm.js
CHANGED
|
@@ -5301,9 +5301,27 @@ const DfFormSection = ({ id, properties, mode = 'edit', formData = {}, onValueCh
|
|
|
5301
5301
|
|
|
5302
5302
|
// Dynamic imports to avoid circular dependencies
|
|
5303
5303
|
const DfFormTable$1 = React.lazy(() => Promise.resolve().then(function () { return dfFormTable; }));
|
|
5304
|
+
// Normalize a table row from API format (object with numeric keys) into a proper array.
|
|
5305
|
+
// The API may return cells as [{"0": {cell}, "1": {cell}}, ...] instead of [[cell, cell], ...].
|
|
5306
|
+
const normalizeTableRow = (row) => {
|
|
5307
|
+
if (Array.isArray(row))
|
|
5308
|
+
return row;
|
|
5309
|
+
if (row && typeof row === 'object') {
|
|
5310
|
+
const keys = Object.keys(row).filter(k => !isNaN(Number(k))).sort((a, b) => Number(a) - Number(b));
|
|
5311
|
+
if (keys.length > 0)
|
|
5312
|
+
return keys.map(k => row[k]);
|
|
5313
|
+
}
|
|
5314
|
+
return [];
|
|
5315
|
+
};
|
|
5304
5316
|
const DfFormPreview = ({ formComponents = [], currentDevice = 'desktop', isPreviewMode = false, initialFormData = [], onSubmit, onFormDataChange, formTitle, formDescription, formTemplateId,
|
|
5305
5317
|
// Add component management props for edit mode
|
|
5306
5318
|
onComponentSelect, onComponentDelete, onComponentEdit, onComponentUpdate, selectedComponent, workOrderNumber, assetNumber, isStandalone, user, onCreateIssue, onUpdateIssue }) => {
|
|
5319
|
+
// Local copy of formComponents so structure updates (e.g. table cell init) are reflected immediately
|
|
5320
|
+
const [localFormComponents, setLocalFormComponents] = useState(formComponents);
|
|
5321
|
+
// Sync local state when the prop changes from the parent
|
|
5322
|
+
useEffect(() => {
|
|
5323
|
+
setLocalFormComponents(formComponents);
|
|
5324
|
+
}, [formComponents]);
|
|
5307
5325
|
// Form state
|
|
5308
5326
|
const [formValues, setFormValues] = useState({});
|
|
5309
5327
|
const [validationErrors, setValidationErrors] = useState({});
|
|
@@ -5324,7 +5342,7 @@ onComponentSelect, onComponentDelete, onComponentEdit, onComponentUpdate, select
|
|
|
5324
5342
|
// Initialize form state
|
|
5325
5343
|
useEffect(() => {
|
|
5326
5344
|
initializeFormState();
|
|
5327
|
-
}, [
|
|
5345
|
+
}, [localFormComponents, initialFormData]);
|
|
5328
5346
|
// Recursive function to initialize values from nested components
|
|
5329
5347
|
const initializeComponentValues = (components, values) => {
|
|
5330
5348
|
components.forEach(component => {
|
|
@@ -5353,13 +5371,11 @@ onComponentSelect, onComponentDelete, onComponentEdit, onComponentUpdate, select
|
|
|
5353
5371
|
// Handle nested components in table cells
|
|
5354
5372
|
if (component.cells && Array.isArray(component.cells)) {
|
|
5355
5373
|
component.cells.forEach((row, _rowIndex) => {
|
|
5356
|
-
|
|
5357
|
-
|
|
5358
|
-
|
|
5359
|
-
|
|
5360
|
-
|
|
5361
|
-
});
|
|
5362
|
-
}
|
|
5374
|
+
normalizeTableRow(row).forEach((cell, _cellIndex) => {
|
|
5375
|
+
if (cell && cell.components && Array.isArray(cell.components)) {
|
|
5376
|
+
initializeComponentValues(cell.components, values);
|
|
5377
|
+
}
|
|
5378
|
+
});
|
|
5363
5379
|
});
|
|
5364
5380
|
}
|
|
5365
5381
|
// Handle nested components in datagrid entries
|
|
@@ -5422,11 +5438,10 @@ onComponentSelect, onComponentDelete, onComponentEdit, onComponentUpdate, select
|
|
|
5422
5438
|
extractNotesAndAttachments(comp.children);
|
|
5423
5439
|
if (comp.cells && Array.isArray(comp.cells))
|
|
5424
5440
|
comp.cells.forEach((row) => {
|
|
5425
|
-
|
|
5426
|
-
|
|
5427
|
-
|
|
5428
|
-
|
|
5429
|
-
});
|
|
5441
|
+
normalizeTableRow(row).forEach((cell) => {
|
|
5442
|
+
if (cell && cell.components)
|
|
5443
|
+
extractNotesAndAttachments(cell.components);
|
|
5444
|
+
});
|
|
5430
5445
|
});
|
|
5431
5446
|
if (comp.entries)
|
|
5432
5447
|
comp.entries.forEach((entry) => {
|
|
@@ -5465,8 +5480,9 @@ onComponentSelect, onComponentDelete, onComponentEdit, onComponentUpdate, select
|
|
|
5465
5480
|
}
|
|
5466
5481
|
if (validatedComponent.cells && Array.isArray(validatedComponent.cells)) {
|
|
5467
5482
|
validatedComponent.cells = validatedComponent.cells.map((row) => {
|
|
5468
|
-
|
|
5469
|
-
|
|
5483
|
+
const normalizedRow = normalizeTableRow(row);
|
|
5484
|
+
if (normalizedRow.length > 0) {
|
|
5485
|
+
return normalizedRow.map((cell) => {
|
|
5470
5486
|
if (cell && cell.components && Array.isArray(cell.components)) {
|
|
5471
5487
|
return {
|
|
5472
5488
|
...cell,
|
|
@@ -5494,11 +5510,11 @@ onComponentSelect, onComponentDelete, onComponentEdit, onComponentUpdate, select
|
|
|
5494
5510
|
});
|
|
5495
5511
|
};
|
|
5496
5512
|
// Initialize validated components
|
|
5497
|
-
let validatedFormComponents =
|
|
5498
|
-
if (
|
|
5499
|
-
validatedFormComponents = getValidatedComponents(
|
|
5513
|
+
let validatedFormComponents = localFormComponents;
|
|
5514
|
+
if (localFormComponents && localFormComponents.length > 0) {
|
|
5515
|
+
validatedFormComponents = getValidatedComponents(localFormComponents);
|
|
5500
5516
|
// Notifying parent of changed components if they were mutated (IDs added/fixed)
|
|
5501
|
-
if (JSON.stringify(validatedFormComponents) !== JSON.stringify(
|
|
5517
|
+
if (JSON.stringify(validatedFormComponents) !== JSON.stringify(localFormComponents)) {
|
|
5502
5518
|
onFormDataChange?.(validatedFormComponents);
|
|
5503
5519
|
}
|
|
5504
5520
|
}
|
|
@@ -5526,7 +5542,7 @@ onComponentSelect, onComponentDelete, onComponentEdit, onComponentUpdate, select
|
|
|
5526
5542
|
setComponentAttachments(prev => ({ ...initialAttachments, ...prev }));
|
|
5527
5543
|
// Conditional logic evaluation disabled temporarily to fix table issues
|
|
5528
5544
|
// evaluateConditionalLogic()
|
|
5529
|
-
}, [initialFormData,
|
|
5545
|
+
}, [initialFormData, localFormComponents]);
|
|
5530
5546
|
// Conditional logic disabled temporarily - all components are always visible
|
|
5531
5547
|
const shouldShowComponent = useCallback((_componentId) => {
|
|
5532
5548
|
return true;
|
|
@@ -5539,7 +5555,7 @@ onComponentSelect, onComponentDelete, onComponentEdit, onComponentUpdate, select
|
|
|
5539
5555
|
return;
|
|
5540
5556
|
}
|
|
5541
5557
|
// CRITICAL: Check if multiple components share this ID (ID collision detection)
|
|
5542
|
-
const componentsWithSameId =
|
|
5558
|
+
const componentsWithSameId = localFormComponents.filter(comp => comp.id === change.id);
|
|
5543
5559
|
if (componentsWithSameId.length > 1) {
|
|
5544
5560
|
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 })));
|
|
5545
5561
|
// Don't update - this would cause all components with this ID to get the same value
|
|
@@ -5560,7 +5576,7 @@ onComponentSelect, onComponentDelete, onComponentEdit, onComponentUpdate, select
|
|
|
5560
5576
|
}
|
|
5561
5577
|
// Clear raised issues for this component when value changes
|
|
5562
5578
|
// This ensures that if threshold condition changes, user must raise issue again
|
|
5563
|
-
const component =
|
|
5579
|
+
const component = localFormComponents.find(comp => comp.id === change.id);
|
|
5564
5580
|
if (component) {
|
|
5565
5581
|
const threshold = component?.threshold;
|
|
5566
5582
|
if (threshold && threshold.conditions && threshold.conditions.length > 0) {
|
|
@@ -5613,13 +5629,13 @@ onComponentSelect, onComponentDelete, onComponentEdit, onComponentUpdate, select
|
|
|
5613
5629
|
if (component.name === 'table' && component.cells) {
|
|
5614
5630
|
return {
|
|
5615
5631
|
...component,
|
|
5616
|
-
cells: component.cells.map((row) =>
|
|
5632
|
+
cells: component.cells.map((row) => normalizeTableRow(row).map((cell) => {
|
|
5617
5633
|
const updatedCell = { ...cell };
|
|
5618
5634
|
if (updatedCell.components) {
|
|
5619
5635
|
updatedCell.components = updateComponentValue(updatedCell.components);
|
|
5620
5636
|
}
|
|
5621
5637
|
return updatedCell;
|
|
5622
|
-
})
|
|
5638
|
+
}))
|
|
5623
5639
|
};
|
|
5624
5640
|
}
|
|
5625
5641
|
if (component.name === 'datagrid' && component.entries) {
|
|
@@ -5638,7 +5654,10 @@ onComponentSelect, onComponentDelete, onComponentEdit, onComponentUpdate, select
|
|
|
5638
5654
|
});
|
|
5639
5655
|
};
|
|
5640
5656
|
// Update form components
|
|
5641
|
-
const updatedComponents = updateComponentValue(
|
|
5657
|
+
const updatedComponents = updateComponentValue(localFormComponents);
|
|
5658
|
+
// CRITICAL: Update local state immediately so structure changes (e.g. table cell init)
|
|
5659
|
+
// are reflected without waiting for Angular parent round-trip
|
|
5660
|
+
setLocalFormComponents(updatedComponents);
|
|
5642
5661
|
onFormDataChange?.(updatedComponents);
|
|
5643
5662
|
// Clear validation errors when user starts typing and re-validate
|
|
5644
5663
|
if (validationErrors[change.id]) {
|
|
@@ -5675,7 +5694,7 @@ onComponentSelect, onComponentDelete, onComponentEdit, onComponentUpdate, select
|
|
|
5675
5694
|
}
|
|
5676
5695
|
// Conditional logic evaluation disabled temporarily
|
|
5677
5696
|
// evaluateConditionalLogic(newFormValues, updatedComponents)
|
|
5678
|
-
}, [
|
|
5697
|
+
}, [localFormComponents, formValues, validationErrors, onFormDataChange]);
|
|
5679
5698
|
// Recursive function to find a component by ID in nested structures
|
|
5680
5699
|
const findComponentById = useCallback((components, fieldId) => {
|
|
5681
5700
|
for (const comp of components) {
|
|
@@ -5719,7 +5738,7 @@ onComponentSelect, onComponentDelete, onComponentEdit, onComponentUpdate, select
|
|
|
5719
5738
|
if (isPreviewMode)
|
|
5720
5739
|
return;
|
|
5721
5740
|
// Find component recursively (handles nested components)
|
|
5722
|
-
const component = findComponentById(
|
|
5741
|
+
const component = findComponentById(localFormComponents, fieldId);
|
|
5723
5742
|
if (!component)
|
|
5724
5743
|
return;
|
|
5725
5744
|
// Get current value from form values (real-time input)
|
|
@@ -5814,7 +5833,7 @@ onComponentSelect, onComponentDelete, onComponentEdit, onComponentUpdate, select
|
|
|
5814
5833
|
...prev,
|
|
5815
5834
|
[fieldId]: errorMessage
|
|
5816
5835
|
}));
|
|
5817
|
-
}, [
|
|
5836
|
+
}, [localFormComponents, isPreviewMode, formValues, findComponentById]);
|
|
5818
5837
|
// Handle form control blur
|
|
5819
5838
|
const onFormControlBlur = useCallback((fieldId) => {
|
|
5820
5839
|
setTouchedFields(prev => ({
|
|
@@ -5844,11 +5863,11 @@ onComponentSelect, onComponentDelete, onComponentEdit, onComponentUpdate, select
|
|
|
5844
5863
|
// useEffect(() => {
|
|
5845
5864
|
// if (!isPreviewMode && Object.keys(formValues).length > 0) {
|
|
5846
5865
|
// // Validate all form components when form values change (but not on initial load)
|
|
5847
|
-
//
|
|
5866
|
+
// localFormComponents.forEach(component => {
|
|
5848
5867
|
// validateField(component.id)
|
|
5849
5868
|
// })
|
|
5850
5869
|
// }
|
|
5851
|
-
// }, [formValues, validateField, isPreviewMode,
|
|
5870
|
+
// }, [formValues, validateField, isPreviewMode, localFormComponents])
|
|
5852
5871
|
// Enhanced form validity check
|
|
5853
5872
|
const isFormValid = useCallback(() => {
|
|
5854
5873
|
// Check if there are any validation errors
|
|
@@ -5857,7 +5876,7 @@ onComponentSelect, onComponentDelete, onComponentEdit, onComponentUpdate, select
|
|
|
5857
5876
|
return false;
|
|
5858
5877
|
}
|
|
5859
5878
|
// Check required fields
|
|
5860
|
-
return
|
|
5879
|
+
return localFormComponents.every(component => {
|
|
5861
5880
|
// Use real-time form values instead of component values
|
|
5862
5881
|
const currentValue = formValues[component.id] || '';
|
|
5863
5882
|
// Check if field has a value
|
|
@@ -5903,7 +5922,7 @@ onComponentSelect, onComponentDelete, onComponentEdit, onComponentUpdate, select
|
|
|
5903
5922
|
}
|
|
5904
5923
|
return true;
|
|
5905
5924
|
});
|
|
5906
|
-
}, [
|
|
5925
|
+
}, [localFormComponents, formValues, validationErrors]);
|
|
5907
5926
|
// Evaluate threshold condition (handles both numeric and string values)
|
|
5908
5927
|
const evaluateThresholdCondition = useCallback((condition, currentVal) => {
|
|
5909
5928
|
// Handle array values (for checkbox)
|
|
@@ -5957,7 +5976,7 @@ onComponentSelect, onComponentDelete, onComponentEdit, onComponentUpdate, select
|
|
|
5957
5976
|
if (isPreviewMode)
|
|
5958
5977
|
return [];
|
|
5959
5978
|
const metConditions = [];
|
|
5960
|
-
|
|
5979
|
+
localFormComponents.forEach(component => {
|
|
5961
5980
|
const condition = component?.condition;
|
|
5962
5981
|
if (!condition || !condition.conditions || condition.conditions.length === 0) {
|
|
5963
5982
|
return;
|
|
@@ -5983,7 +6002,7 @@ onComponentSelect, onComponentDelete, onComponentEdit, onComponentUpdate, select
|
|
|
5983
6002
|
});
|
|
5984
6003
|
});
|
|
5985
6004
|
return metConditions;
|
|
5986
|
-
}, [
|
|
6005
|
+
}, [localFormComponents, formValues, isPreviewMode, evaluateThresholdCondition]);
|
|
5987
6006
|
// Validate threshold conditions - check if all met conditions have all mandatory actions completed
|
|
5988
6007
|
const validateThresholdConditions = useCallback(() => {
|
|
5989
6008
|
if (isPreviewMode)
|
|
@@ -6068,7 +6087,7 @@ onComponentSelect, onComponentDelete, onComponentEdit, onComponentUpdate, select
|
|
|
6068
6087
|
let isValid = true;
|
|
6069
6088
|
setFormSubmitted(true);
|
|
6070
6089
|
const errors = {};
|
|
6071
|
-
|
|
6090
|
+
localFormComponents.forEach(component => {
|
|
6072
6091
|
// Use real-time form values instead of component values
|
|
6073
6092
|
const currentValue = formValues[component.id] || '';
|
|
6074
6093
|
// Check if field has a value
|
|
@@ -6135,13 +6154,13 @@ onComponentSelect, onComponentDelete, onComponentEdit, onComponentUpdate, select
|
|
|
6135
6154
|
});
|
|
6136
6155
|
setValidationErrors(errors);
|
|
6137
6156
|
return isValid;
|
|
6138
|
-
}, [
|
|
6157
|
+
}, [localFormComponents, isPreviewMode, formValues]);
|
|
6139
6158
|
// Handle form submission
|
|
6140
6159
|
const handleSubmit = useCallback((status = 'Submitted') => {
|
|
6141
6160
|
setFormSubmitted(true);
|
|
6142
6161
|
if (!validateAllFields()) {
|
|
6143
6162
|
// Focus on the first invalid field
|
|
6144
|
-
const firstErrorField =
|
|
6163
|
+
const firstErrorField = localFormComponents.find(comp => {
|
|
6145
6164
|
const currentValue = formValues[comp.id] || '';
|
|
6146
6165
|
// Check if field has a value
|
|
6147
6166
|
let hasValue = false;
|
|
@@ -6223,13 +6242,13 @@ onComponentSelect, onComponentDelete, onComponentEdit, onComponentUpdate, select
|
|
|
6223
6242
|
updatedComponent.children = updateComponentValues(updatedComponent.children);
|
|
6224
6243
|
}
|
|
6225
6244
|
if (updatedComponent.name === 'table' && updatedComponent.cells) {
|
|
6226
|
-
updatedComponent.cells = updatedComponent.cells.map((row) =>
|
|
6245
|
+
updatedComponent.cells = updatedComponent.cells.map((row) => normalizeTableRow(row).map((cell) => {
|
|
6227
6246
|
const updatedCell = { ...cell };
|
|
6228
6247
|
if (updatedCell.components) {
|
|
6229
6248
|
updatedCell.components = updateComponentValues(updatedCell.components);
|
|
6230
6249
|
}
|
|
6231
6250
|
return updatedCell;
|
|
6232
|
-
})
|
|
6251
|
+
}));
|
|
6233
6252
|
}
|
|
6234
6253
|
if (updatedComponent.name === 'datagrid' && updatedComponent.entries) {
|
|
6235
6254
|
updatedComponent.entries = updatedComponent.entries.map((entry) => {
|
|
@@ -6244,12 +6263,12 @@ onComponentSelect, onComponentDelete, onComponentEdit, onComponentUpdate, select
|
|
|
6244
6263
|
});
|
|
6245
6264
|
};
|
|
6246
6265
|
// Prepare final form data
|
|
6247
|
-
const finalFormData = updateComponentValues(
|
|
6266
|
+
const finalFormData = updateComponentValues(localFormComponents);
|
|
6248
6267
|
// Also prepare a clean key-value payload
|
|
6249
6268
|
const payloadValues = { ...formValues, status };
|
|
6250
6269
|
// Pass both the updated component tree and the flat values object
|
|
6251
6270
|
onSubmit?.(finalFormData, payloadValues);
|
|
6252
|
-
}, [
|
|
6271
|
+
}, [localFormComponents, formValues, validateAllFields, onSubmit, componentNotes, componentAttachments]);
|
|
6253
6272
|
// Get preview classes
|
|
6254
6273
|
const getPreviewClasses = useCallback(() => {
|
|
6255
6274
|
return {
|
|
@@ -6311,7 +6330,7 @@ onComponentSelect, onComponentDelete, onComponentEdit, onComponentUpdate, select
|
|
|
6311
6330
|
// Debug: Log if formValue is being shared incorrectly
|
|
6312
6331
|
if (formValue !== undefined) {
|
|
6313
6332
|
// Check if this value is being used by multiple components
|
|
6314
|
-
const componentsWithSameValue =
|
|
6333
|
+
const componentsWithSameValue = localFormComponents.filter(comp => comp.id !== componentId && formValues[comp.id] === formValue);
|
|
6315
6334
|
if (componentsWithSameValue.length > 0) {
|
|
6316
6335
|
console.warn(`[DfFormPreview] Component ${componentId} shares form value with other components:`, componentsWithSameValue.map(c => c.id));
|
|
6317
6336
|
}
|
|
@@ -6410,9 +6429,9 @@ onComponentSelect, onComponentDelete, onComponentEdit, onComponentUpdate, select
|
|
|
6410
6429
|
return renderFormComponent(field);
|
|
6411
6430
|
}, onNotesChange: (componentId, notes) => {
|
|
6412
6431
|
// Handle notes change for table cell components
|
|
6413
|
-
const updatedComponents =
|
|
6432
|
+
const updatedComponents = localFormComponents.map(comp => {
|
|
6414
6433
|
if (comp.id === component.id && comp.cells) {
|
|
6415
|
-
const updatedCells = comp.cells.map((row) =>
|
|
6434
|
+
const updatedCells = comp.cells.map((row) => normalizeTableRow(row).map((cell) => {
|
|
6416
6435
|
if (cell.components) {
|
|
6417
6436
|
const updatedCellComponents = cell.components.map((cellComp) => {
|
|
6418
6437
|
if (cellComp.id === componentId) {
|
|
@@ -6429,7 +6448,7 @@ onComponentSelect, onComponentDelete, onComponentEdit, onComponentUpdate, select
|
|
|
6429
6448
|
return { ...cell, components: updatedCellComponents };
|
|
6430
6449
|
}
|
|
6431
6450
|
return cell;
|
|
6432
|
-
})
|
|
6451
|
+
}));
|
|
6433
6452
|
return { ...comp, cells: updatedCells };
|
|
6434
6453
|
}
|
|
6435
6454
|
return comp;
|
|
@@ -6437,9 +6456,9 @@ onComponentSelect, onComponentDelete, onComponentEdit, onComponentUpdate, select
|
|
|
6437
6456
|
onFormDataChange?.(updatedComponents);
|
|
6438
6457
|
}, onAttachmentChange: (componentId, attachments) => {
|
|
6439
6458
|
// Handle attachment change for table cell components
|
|
6440
|
-
const updatedComponents =
|
|
6459
|
+
const updatedComponents = localFormComponents.map(comp => {
|
|
6441
6460
|
if (comp.id === component.id && comp.cells) {
|
|
6442
|
-
const updatedCells = comp.cells.map((row) =>
|
|
6461
|
+
const updatedCells = comp.cells.map((row) => normalizeTableRow(row).map((cell) => {
|
|
6443
6462
|
if (cell.components) {
|
|
6444
6463
|
const updatedCellComponents = cell.components.map((cellComp) => {
|
|
6445
6464
|
if (cellComp.id === componentId) {
|
|
@@ -6456,7 +6475,7 @@ onComponentSelect, onComponentDelete, onComponentEdit, onComponentUpdate, select
|
|
|
6456
6475
|
return { ...cell, components: updatedCellComponents };
|
|
6457
6476
|
}
|
|
6458
6477
|
return cell;
|
|
6459
|
-
})
|
|
6478
|
+
}));
|
|
6460
6479
|
return { ...comp, cells: updatedCells };
|
|
6461
6480
|
}
|
|
6462
6481
|
return comp;
|
|
@@ -6467,7 +6486,7 @@ onComponentSelect, onComponentDelete, onComponentEdit, onComponentUpdate, select
|
|
|
6467
6486
|
return (jsx(DfFormDataGrid, { ...commonProps, properties: component, formData: formValues, formTemplateId: formTemplateId, mode: commonProps.mode, onThresholdActionCompletion: handleThresholdActionCompletion, onThresholdIssueRaised: handleThresholdIssueRaised, onNotesChange: (componentId, notes) => {
|
|
6468
6487
|
handleComponentNotesChange(componentId, notes);
|
|
6469
6488
|
// Handle notes change for datagrid entry components
|
|
6470
|
-
const updatedComponents =
|
|
6489
|
+
const updatedComponents = localFormComponents.map(comp => {
|
|
6471
6490
|
if (comp.id === component.id && comp.entries) {
|
|
6472
6491
|
const updatedEntries = comp.entries.map((entry) => {
|
|
6473
6492
|
if (entry.components) {
|
|
@@ -6495,7 +6514,7 @@ onComponentSelect, onComponentDelete, onComponentEdit, onComponentUpdate, select
|
|
|
6495
6514
|
}, onAttachmentChange: (componentId, attachments) => {
|
|
6496
6515
|
handleComponentAttachmentChange(componentId, attachments);
|
|
6497
6516
|
// Handle attachment change for datagrid entry components
|
|
6498
|
-
const updatedComponents =
|
|
6517
|
+
const updatedComponents = localFormComponents.map(comp => {
|
|
6499
6518
|
if (comp.id === component.id && comp.entries) {
|
|
6500
6519
|
const updatedEntries = comp.entries.map((entry) => {
|
|
6501
6520
|
if (entry.components) {
|
|
@@ -6523,8 +6542,8 @@ onComponentSelect, onComponentDelete, onComponentEdit, onComponentUpdate, select
|
|
|
6523
6542
|
}, onValueChange: (change) => {
|
|
6524
6543
|
// Handle datagrid value changes (entries updates)
|
|
6525
6544
|
if (change.id === component.id && change.value && typeof change.value === 'object' && 'entries' in change.value) {
|
|
6526
|
-
// Update
|
|
6527
|
-
const updatedComponents =
|
|
6545
|
+
// Update localFormComponents with new entries structure
|
|
6546
|
+
const updatedComponents = localFormComponents.map(comp => {
|
|
6528
6547
|
if (comp.id === component.id) {
|
|
6529
6548
|
return {
|
|
6530
6549
|
...comp,
|
|
@@ -6562,12 +6581,12 @@ onComponentSelect, onComponentDelete, onComponentEdit, onComponentUpdate, select
|
|
|
6562
6581
|
}
|
|
6563
6582
|
}, onEntryAdd: () => {
|
|
6564
6583
|
// CRITICAL: Entry has already been added via onValueChange in DfFormDataGrid
|
|
6565
|
-
// Get the updated component from
|
|
6566
|
-
const currentComponent =
|
|
6584
|
+
// Get the updated component from localFormComponents (which should have been updated by onValueChange)
|
|
6585
|
+
const currentComponent = localFormComponents.find(comp => comp.id === component.id);
|
|
6567
6586
|
if (currentComponent && currentComponent.entries) {
|
|
6568
6587
|
// Entry should already be in the component via onValueChange
|
|
6569
|
-
// Just ensure
|
|
6570
|
-
const updatedComponents =
|
|
6588
|
+
// Just ensure localFormComponents is in sync (no-op if already synced)
|
|
6589
|
+
const updatedComponents = localFormComponents.map(comp => {
|
|
6571
6590
|
if (comp.id === component.id) {
|
|
6572
6591
|
// Ensure entries are properly structured
|
|
6573
6592
|
return {
|
|
@@ -6584,7 +6603,7 @@ onComponentSelect, onComponentDelete, onComponentEdit, onComponentUpdate, select
|
|
|
6584
6603
|
setTimeout(() => {
|
|
6585
6604
|
const datagridValue = formValues[component.id];
|
|
6586
6605
|
if (datagridValue && typeof datagridValue === 'object' && 'entries' in datagridValue) {
|
|
6587
|
-
const updatedComponents =
|
|
6606
|
+
const updatedComponents = localFormComponents.map(comp => {
|
|
6588
6607
|
if (comp.id === component.id) {
|
|
6589
6608
|
return {
|
|
6590
6609
|
...comp,
|
|
@@ -6599,7 +6618,7 @@ onComponentSelect, onComponentDelete, onComponentEdit, onComponentUpdate, select
|
|
|
6599
6618
|
}
|
|
6600
6619
|
}, onEntryRemove: (entryIndex) => {
|
|
6601
6620
|
// Handle entry remove - update form components
|
|
6602
|
-
const updatedComponents =
|
|
6621
|
+
const updatedComponents = localFormComponents.map(comp => {
|
|
6603
6622
|
if (comp.id === component.id && comp.entries) {
|
|
6604
6623
|
const currentEntries = comp.entries || [];
|
|
6605
6624
|
const updatedEntries = currentEntries
|
|
@@ -6641,7 +6660,7 @@ onComponentSelect, onComponentDelete, onComponentEdit, onComponentUpdate, select
|
|
|
6641
6660
|
return (jsx("div", { className: "form-group", children: jsxs("div", { className: "form-group-label", children: ["Unsupported Component: ", component.name] }) }));
|
|
6642
6661
|
}
|
|
6643
6662
|
};
|
|
6644
|
-
return (jsx("div", { className: "form-preview-container", children: jsx("div", { className: "form-preview-wrapper", children: jsxs("div", { className: `form-preview ${Object.entries(getPreviewClasses()).map(([key, value]) => value ? key : '').join(' ')}`, children: [jsx("div", { className: "form-canvas-header" }),
|
|
6663
|
+
return (jsx("div", { className: "form-preview-container", children: jsx("div", { className: "form-preview-wrapper", children: jsxs("div", { className: `form-preview ${Object.entries(getPreviewClasses()).map(([key, value]) => value ? key : '').join(' ')}`, children: [jsx("div", { className: "form-canvas-header" }), localFormComponents.length === 0 ? (jsx("div", { className: "empty-state", children: jsx("div", { className: "empty-state-card", children: jsx("div", { className: "empty-state-preview-area", children: jsx("span", { className: "empty-state-placeholder", children: "Add components to see the form preview" }) }) }) })) : (jsxs("form", { className: "form-preview-form", onSubmit: (e) => { e.preventDefault(); handleSubmit(); }, children: [(formTitle || formDescription) && (jsxs("div", { className: "form-header", children: [formTitle && (jsx("h1", { className: "form-title", children: formTitle })), formDescription && (jsx("p", { className: "form-description", children: formDescription }))] })), localFormComponents.map((component) => {
|
|
6645
6664
|
const basic = component.basic;
|
|
6646
6665
|
const formValue = formValues[component.id];
|
|
6647
6666
|
const isOptionBased = ['select', 'radio', 'checkbox', 'segment'].includes(component.name || '');
|
|
@@ -6693,7 +6712,7 @@ onComponentSelect, onComponentDelete, onComponentEdit, onComponentUpdate, select
|
|
|
6693
6712
|
// Update local state immediately
|
|
6694
6713
|
setComponentNotes(prev => ({ ...prev, [component.id]: notes }));
|
|
6695
6714
|
// Handle notes change for regular components - update component.basic.notes
|
|
6696
|
-
const updatedComponents =
|
|
6715
|
+
const updatedComponents = localFormComponents.map(comp => {
|
|
6697
6716
|
if (comp.id === component.id) {
|
|
6698
6717
|
return {
|
|
6699
6718
|
...comp,
|
|
@@ -6710,7 +6729,7 @@ onComponentSelect, onComponentDelete, onComponentEdit, onComponentUpdate, select
|
|
|
6710
6729
|
// Update local state immediately
|
|
6711
6730
|
setComponentAttachments(prev => ({ ...prev, [component.id]: attachments || [] }));
|
|
6712
6731
|
// Handle attachment change for regular components - update component.basic.attachments
|
|
6713
|
-
const updatedComponents =
|
|
6732
|
+
const updatedComponents = localFormComponents.map(comp => {
|
|
6714
6733
|
if (comp.id === component.id) {
|
|
6715
6734
|
return {
|
|
6716
6735
|
...comp,
|
|
@@ -6762,6 +6781,26 @@ const DfFormComments = ({ comment = '', onSave, placeholder = 'Enter your reason
|
|
|
6762
6781
|
return (jsxs("div", { className: `df-form-comments ${className}`, children: [jsxs("div", { className: "df-form-comments__header", children: [jsx("h3", { className: "df-form-comments__title", children: "Comments" }), jsx("button", { className: "df-form-comments__toggle", type: "button", onClick: toggleComments, "aria-expanded": isExpanded, "aria-label": "Toggle comments section", disabled: disabled, children: isExpanded ? (jsx("span", { className: "df-form-comments__toggle-icon", children: "\u25BC" })) : (jsx("span", { className: "df-form-comments__toggle-icon", children: "\u25B6" })) })] }), jsx("div", { className: `df-form-comments__content ${isExpanded ? 'df-form-comments__content--expanded' : ''}`, children: jsx("div", { className: "df-form-comments__input-container", children: jsx("div", { className: "df-form-comments__input-line", children: jsx("input", { type: "text", id: "comment-input", className: "df-form-comments__input", value: currentComment, onChange: handleInputChange, onBlur: handleInputBlur, onFocus: handleInputFocus, placeholder: placeholder, disabled: disabled }) }) }) })] }));
|
|
6763
6782
|
};
|
|
6764
6783
|
|
|
6784
|
+
// Normalize a row from the API format (object with numeric keys) into a proper TableCell array.
|
|
6785
|
+
// The API may return cells as [{"0": {cell}, "1": {cell}}, ...] instead of [[cell, cell], ...].
|
|
6786
|
+
const normalizeRow = (row) => {
|
|
6787
|
+
if (Array.isArray(row))
|
|
6788
|
+
return row;
|
|
6789
|
+
if (row && typeof row === 'object') {
|
|
6790
|
+
// Convert object with numeric keys to array, sorted by key
|
|
6791
|
+
const keys = Object.keys(row).filter(k => !isNaN(Number(k))).sort((a, b) => Number(a) - Number(b));
|
|
6792
|
+
if (keys.length > 0) {
|
|
6793
|
+
return keys.map(k => row[k]);
|
|
6794
|
+
}
|
|
6795
|
+
}
|
|
6796
|
+
return [];
|
|
6797
|
+
};
|
|
6798
|
+
// Normalize the entire cells structure from API format to TableCell[][]
|
|
6799
|
+
const normalizeCells = (cells) => {
|
|
6800
|
+
if (!cells || !Array.isArray(cells))
|
|
6801
|
+
return [];
|
|
6802
|
+
return cells.map(normalizeRow);
|
|
6803
|
+
};
|
|
6765
6804
|
// Function to ensure table cell components have proper IDs
|
|
6766
6805
|
const ensureComponentHasId = (component) => {
|
|
6767
6806
|
if (!component.id) {
|
|
@@ -6846,19 +6885,22 @@ const TableCellComponent = ({ cell, mode, onComponentSelect, onComponentDelete,
|
|
|
6846
6885
|
};
|
|
6847
6886
|
const DfFormTable = ({ id, properties, mode = 'edit', formData = {}, validationErrors = {}, touchedFields = {}, formSubmitted = false, onValueChange, onSelect, isSelected = false, className = '', onTableSelect, onComponentSelect, onComponentDelete, onComponentEdit, selectedComponent, renderFormComponent, formTemplateId, onThresholdActionCompletion, onThresholdIssueRaised, onNotesChange, onAttachmentChange, workOrderNumber, assetNumber, user, onCreateIssue, onUpdateIssue }) => {
|
|
6848
6887
|
const [isCollapsed, setIsCollapsed] = useState(false); // Always start expanded to show drop zones
|
|
6888
|
+
// CRITICAL: Normalize cells from API format (object with numeric keys) to proper 2D array
|
|
6889
|
+
// The API may return cells as [{"0": {cell}, "1": {cell}}, ...] instead of [[cell, cell], ...]
|
|
6890
|
+
const normalizedCells = useMemo(() => normalizeCells(properties.cells), [properties.cells]);
|
|
6849
6891
|
// Check if table has any components in any cells
|
|
6850
|
-
const hasAnyComponents =
|
|
6892
|
+
const hasAnyComponents = normalizedCells.some((row) => row.some((cell) => cell.components && cell.components.length > 0)) || false;
|
|
6851
6893
|
// Initialize and update table cells when rows/columns change
|
|
6852
6894
|
// Only trigger when cells are truly missing or structure doesn't match rows/columns
|
|
6853
6895
|
useEffect(() => {
|
|
6854
6896
|
// Get rows and columns from table properties (where they're actually stored)
|
|
6855
6897
|
const currentRows = Number(properties.table?.rows || properties.basic?.rows || 3);
|
|
6856
6898
|
const currentColumns = Number(properties.table?.columns || properties.basic?.columns || 3);
|
|
6857
|
-
const currentCells =
|
|
6899
|
+
const currentCells = normalizedCells;
|
|
6858
6900
|
// Check if we need to update the table structure
|
|
6859
6901
|
const needsUpdate = currentCells.length === 0 ||
|
|
6860
6902
|
currentCells.length !== currentRows ||
|
|
6861
|
-
(currentCells.length > 0 &&
|
|
6903
|
+
(currentCells.length > 0 && currentCells[0].length !== currentColumns);
|
|
6862
6904
|
if (needsUpdate) {
|
|
6863
6905
|
const newCells = [];
|
|
6864
6906
|
for (let row = 0; row < currentRows; row++) {
|
|
@@ -6867,7 +6909,7 @@ const DfFormTable = ({ id, properties, mode = 'edit', formData = {}, validationE
|
|
|
6867
6909
|
const cellId = `cell-${row}-${col}`;
|
|
6868
6910
|
// Try to preserve existing components if the cell exists
|
|
6869
6911
|
let existingComponents = [];
|
|
6870
|
-
if (
|
|
6912
|
+
if (currentCells[row] && currentCells[row][col]) {
|
|
6871
6913
|
existingComponents = (currentCells[row][col].components || []).map(ensureComponentHasId);
|
|
6872
6914
|
}
|
|
6873
6915
|
rowCells.push({
|
|
@@ -6885,7 +6927,7 @@ const DfFormTable = ({ id, properties, mode = 'edit', formData = {}, validationE
|
|
|
6885
6927
|
value: { ...properties, cells: newCells }
|
|
6886
6928
|
});
|
|
6887
6929
|
}
|
|
6888
|
-
}, [properties.table?.rows, properties.table?.columns, properties.basic?.rows, properties.basic?.columns,
|
|
6930
|
+
}, [properties.table?.rows, properties.table?.columns, properties.basic?.rows, properties.basic?.columns, normalizedCells, id, onValueChange]);
|
|
6889
6931
|
const handleTableClick = useCallback((event) => {
|
|
6890
6932
|
event.stopPropagation();
|
|
6891
6933
|
onSelect?.();
|
|
@@ -6902,7 +6944,7 @@ const DfFormTable = ({ id, properties, mode = 'edit', formData = {}, validationE
|
|
|
6902
6944
|
const handleComponentDelete = useCallback((component, event) => {
|
|
6903
6945
|
event.stopPropagation();
|
|
6904
6946
|
// Find and remove the component from the table cell
|
|
6905
|
-
const updatedCells =
|
|
6947
|
+
const updatedCells = normalizedCells.map((row) => row.map((cell) => {
|
|
6906
6948
|
if (cell.components && cell.components.some((comp) => comp.id === component.id)) {
|
|
6907
6949
|
const filteredComponents = cell.components.filter((comp) => comp.id !== component.id);
|
|
6908
6950
|
return {
|
|
@@ -6911,7 +6953,7 @@ const DfFormTable = ({ id, properties, mode = 'edit', formData = {}, validationE
|
|
|
6911
6953
|
};
|
|
6912
6954
|
}
|
|
6913
6955
|
return cell;
|
|
6914
|
-
})
|
|
6956
|
+
}));
|
|
6915
6957
|
// Update the table with the modified cells
|
|
6916
6958
|
if (onValueChange) {
|
|
6917
6959
|
onValueChange({
|
|
@@ -6921,13 +6963,13 @@ const DfFormTable = ({ id, properties, mode = 'edit', formData = {}, validationE
|
|
|
6921
6963
|
}
|
|
6922
6964
|
// Don't call parent delete handler for table cell components
|
|
6923
6965
|
// The parent delete handler is for deleting entire fields, not components within table cells
|
|
6924
|
-
}, [onComponentDelete, properties, onValueChange, id]);
|
|
6966
|
+
}, [onComponentDelete, normalizedCells, properties, onValueChange, id]);
|
|
6925
6967
|
// CRITICAL FIX: Ensure all table cell components have proper IDs with table and cell position
|
|
6926
6968
|
// Use useMemo to prevent ID regeneration on every render
|
|
6927
6969
|
const cellsWithIds = useMemo(() => {
|
|
6928
|
-
if (
|
|
6970
|
+
if (normalizedCells.length === 0)
|
|
6929
6971
|
return [];
|
|
6930
|
-
return
|
|
6972
|
+
return normalizedCells.map((row, rowIndex) => row.map((cell, cellIndex) => ({
|
|
6931
6973
|
...cell,
|
|
6932
6974
|
components: (cell.components && Array.isArray(cell.components))
|
|
6933
6975
|
? cell.components.map((comp, compIndex) => {
|
|
@@ -6946,8 +6988,8 @@ const DfFormTable = ({ id, properties, mode = 'edit', formData = {}, validationE
|
|
|
6946
6988
|
};
|
|
6947
6989
|
})
|
|
6948
6990
|
: []
|
|
6949
|
-
}))
|
|
6950
|
-
}, [
|
|
6991
|
+
})));
|
|
6992
|
+
}, [normalizedCells, id]); // Only recalculate if cells or table ID changes
|
|
6951
6993
|
// CRITICAL FIX: Update the parent component with the cells that have proper IDs
|
|
6952
6994
|
// Skip this in package to prevent flickering - cells are managed by parent
|
|
6953
6995
|
// useEffect(() => {
|