df-ae-forms-package 1.0.96 → 1.0.97
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 +89 -122
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +89 -122
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -4712,8 +4712,6 @@ formTemplateId, onThresholdActionCompletion, onThresholdIssueRaised, onNotesChan
|
|
|
4712
4712
|
const DfFormDataGrid = ({ id, properties, mode = 'edit', formData = {}, onValueChange, onSelect, isSelected = false, className = '', onDataGridSelect, onComponentSelect, onComponentDelete, onComponentEdit, onComponentUpdate, selectedComponent, renderFormComponent, onEntryAdd, onEntryRemove, formTemplateId, onThresholdActionCompletion, onThresholdIssueRaised, onNotesChange, onAttachmentChange, shouldShowComponent }) => {
|
|
4713
4713
|
const [isCollapsed, setIsCollapsed] = React.useState(false);
|
|
4714
4714
|
const hasInitialized = React.useRef(false);
|
|
4715
|
-
// Track local form values for entry components to prevent value loss during parent round-trip
|
|
4716
|
-
const localFormValuesRef = React.useRef({});
|
|
4717
4715
|
// Get all components in the grid and sanitize them to ensure no data leaks into templates
|
|
4718
4716
|
let gridComponents = (properties.templateComponents || []).map(comp => ({
|
|
4719
4717
|
...comp,
|
|
@@ -4791,6 +4789,87 @@ const DfFormDataGrid = ({ id, properties, mode = 'edit', formData = {}, onValueC
|
|
|
4791
4789
|
}
|
|
4792
4790
|
}
|
|
4793
4791
|
}
|
|
4792
|
+
else {
|
|
4793
|
+
// Update existing entries to include all template components and sync their properties
|
|
4794
|
+
const needsUpdate = dataEntries.some(entry => {
|
|
4795
|
+
// Check if entry is missing any template components or if existing components need updates
|
|
4796
|
+
return gridComponents.some((templateComp, componentIndex) => {
|
|
4797
|
+
const existingComponent = entry.components?.[componentIndex];
|
|
4798
|
+
if (!existingComponent) {
|
|
4799
|
+
return true; // Missing component at this index
|
|
4800
|
+
}
|
|
4801
|
+
// We don't check for ID matches here anymore
|
|
4802
|
+
// const expectedId = `${templateComp.id}-entry-${entry.index}-${componentIndex}`
|
|
4803
|
+
// const hasProperId = existingComponent.id === expectedId
|
|
4804
|
+
// Check if existing component needs to be updated with new template properties
|
|
4805
|
+
// Compare key properties that should be synced
|
|
4806
|
+
const needsPropertyUpdate = JSON.stringify(existingComponent.basic?.options) !== JSON.stringify(templateComp.basic?.options) ||
|
|
4807
|
+
existingComponent.basic?.placeholder !== templateComp.basic?.placeholder ||
|
|
4808
|
+
existingComponent.basic?.defaultValue !== templateComp.basic?.defaultValue ||
|
|
4809
|
+
existingComponent.basic?.label !== templateComp.basic?.label ||
|
|
4810
|
+
existingComponent.validation?.required !== templateComp.validation?.required;
|
|
4811
|
+
// We do not check for ID mismatch anymore as we want to preserve unique IDs
|
|
4812
|
+
return needsPropertyUpdate;
|
|
4813
|
+
});
|
|
4814
|
+
});
|
|
4815
|
+
if (needsUpdate && onValueChange) {
|
|
4816
|
+
const updatedEntries = dataEntries.map(entry => {
|
|
4817
|
+
// Use index-based matching to ensure each template component maps to the correct entry component
|
|
4818
|
+
const updatedComponents = gridComponents.map((templateComp, componentIndex) => {
|
|
4819
|
+
// Find existing component by index first
|
|
4820
|
+
let existingComponent = entry.components?.[componentIndex];
|
|
4821
|
+
// If no component at this index, try to find by name+label (for backward compatibility)
|
|
4822
|
+
if (!existingComponent) {
|
|
4823
|
+
existingComponent = entry.components?.find((comp) => comp.name === templateComp.name &&
|
|
4824
|
+
comp.basic?.label === templateComp.basic?.label);
|
|
4825
|
+
}
|
|
4826
|
+
// Always ensure a valid ID exists, but respect existing one if possible
|
|
4827
|
+
// const uniqueId = `${templateComp.id}-entry-${entry.index}-${componentIndex}`
|
|
4828
|
+
if (existingComponent) {
|
|
4829
|
+
// Update existing component with new template properties while ensuring unique ID and preserving form values
|
|
4830
|
+
const updatedComponent = {
|
|
4831
|
+
...templateComp,
|
|
4832
|
+
id: existingComponent.id, // Preserve existing ID !!
|
|
4833
|
+
basic: {
|
|
4834
|
+
...templateComp.basic,
|
|
4835
|
+
showLabel: false, // Hide label in datagrid cells
|
|
4836
|
+
// Preserve any user-entered values
|
|
4837
|
+
value: existingComponent.basic?.value || templateComp.basic?.defaultValue || ''
|
|
4838
|
+
}
|
|
4839
|
+
};
|
|
4840
|
+
return updatedComponent;
|
|
4841
|
+
}
|
|
4842
|
+
else {
|
|
4843
|
+
// Create new component based on template
|
|
4844
|
+
// Only for NEW components in existing entries (e.g. column added) do we generate a new ID
|
|
4845
|
+
const uniqueSuffix = `${Date.now()}-${Math.random().toString(36).substr(2, 5)}`;
|
|
4846
|
+
const newId = `${templateComp.id}-${uniqueSuffix}-${componentIndex}`;
|
|
4847
|
+
const newComponent = {
|
|
4848
|
+
...templateComp,
|
|
4849
|
+
id: newId,
|
|
4850
|
+
basic: {
|
|
4851
|
+
...templateComp.basic,
|
|
4852
|
+
showLabel: false // Hide label in datagrid cells
|
|
4853
|
+
}
|
|
4854
|
+
};
|
|
4855
|
+
return newComponent;
|
|
4856
|
+
}
|
|
4857
|
+
});
|
|
4858
|
+
return {
|
|
4859
|
+
...entry,
|
|
4860
|
+
components: updatedComponents
|
|
4861
|
+
};
|
|
4862
|
+
});
|
|
4863
|
+
const newValue = { ...properties, entries: updatedEntries };
|
|
4864
|
+
// Only call onValueChange if the data actually changed
|
|
4865
|
+
if (JSON.stringify(newValue) !== JSON.stringify(properties)) {
|
|
4866
|
+
onValueChange({
|
|
4867
|
+
id,
|
|
4868
|
+
value: newValue
|
|
4869
|
+
});
|
|
4870
|
+
}
|
|
4871
|
+
}
|
|
4872
|
+
}
|
|
4794
4873
|
}
|
|
4795
4874
|
}, [gridComponents, dataEntries, id, onValueChange, properties, mode, properties.templateComponents]);
|
|
4796
4875
|
const handleDataGridClick = React.useCallback((event) => {
|
|
@@ -4847,9 +4926,8 @@ const DfFormDataGrid = ({ id, properties, mode = 'edit', formData = {}, onValueC
|
|
|
4847
4926
|
// Handle component value change for form data updates (test mode)
|
|
4848
4927
|
const handleComponentValueChange = React.useCallback((change) => {
|
|
4849
4928
|
if (mode === 'test') {
|
|
4850
|
-
//
|
|
4851
|
-
|
|
4852
|
-
// Also propagate up to parent for persistence
|
|
4929
|
+
// In test mode, update form data through the parent's onValueChange
|
|
4930
|
+
// This allows the form data to be updated for interactive components
|
|
4853
4931
|
if (onValueChange) {
|
|
4854
4932
|
onValueChange({
|
|
4855
4933
|
id: change.id,
|
|
@@ -4913,11 +4991,7 @@ const DfFormDataGrid = ({ id, properties, mode = 'edit', formData = {}, onValueC
|
|
|
4913
4991
|
}, [properties, onValueChange, id, onEntryRemove]);
|
|
4914
4992
|
// Use our own render function to ensure proper onComponentUpdate handling
|
|
4915
4993
|
const renderComponent = React.useCallback((field, hideLabel = false) => {
|
|
4916
|
-
|
|
4917
|
-
// This ensures typed values in entry 2+ persist immediately
|
|
4918
|
-
const formValue = mode === 'test'
|
|
4919
|
-
? (localFormValuesRef.current[field.id] ?? formData[field.id] ?? field.basic?.value ?? ('defaultValue' in field.basic ? field.basic.defaultValue || '' : ''))
|
|
4920
|
-
: ('defaultValue' in field.basic ? field.basic.defaultValue || '' : '');
|
|
4994
|
+
const formValue = mode === 'test' ? (formData[field.id] || ('defaultValue' in field.basic ? field.basic.defaultValue || '' : '')) : ('defaultValue' in field.basic ? field.basic.defaultValue || '' : '');
|
|
4921
4995
|
const commonProps = {
|
|
4922
4996
|
id: field.id,
|
|
4923
4997
|
properties: field,
|
|
@@ -6421,9 +6495,12 @@ onComponentSelect, onComponentDelete, onComponentEdit, onComponentUpdate, select
|
|
|
6421
6495
|
onFormDataChange?.(updatedComponents);
|
|
6422
6496
|
} }) }));
|
|
6423
6497
|
case 'datagrid':
|
|
6498
|
+
// Align package datagrid wiring with main app behaviour:
|
|
6499
|
+
// - Let DfFormDataGrid manage entry structure via onValueChange
|
|
6500
|
+
// - Use the shared onFormValueChange handler for nested field values
|
|
6501
|
+
// - Keep notes/attachments wiring as before
|
|
6424
6502
|
return (jsxRuntime.jsx(DfFormDataGrid, { ...commonProps, properties: component, formData: formValues, formTemplateId: formTemplateId, mode: commonProps.mode, onThresholdActionCompletion: handleThresholdActionCompletion, onThresholdIssueRaised: handleThresholdIssueRaised, onNotesChange: (componentId, notes) => {
|
|
6425
6503
|
handleComponentNotesChange(componentId, notes);
|
|
6426
|
-
// Handle notes change for datagrid entry components
|
|
6427
6504
|
const updatedComponents = localFormComponents.map(comp => {
|
|
6428
6505
|
if (comp.id === component.id && comp.entries) {
|
|
6429
6506
|
const updatedEntries = comp.entries.map((entry) => {
|
|
@@ -6451,7 +6528,6 @@ onComponentSelect, onComponentDelete, onComponentEdit, onComponentUpdate, select
|
|
|
6451
6528
|
onFormDataChange?.(updatedComponents);
|
|
6452
6529
|
}, onAttachmentChange: (componentId, attachments) => {
|
|
6453
6530
|
handleComponentAttachmentChange(componentId, attachments);
|
|
6454
|
-
// Handle attachment change for datagrid entry components
|
|
6455
6531
|
const updatedComponents = localFormComponents.map(comp => {
|
|
6456
6532
|
if (comp.id === component.id && comp.entries) {
|
|
6457
6533
|
const updatedEntries = comp.entries.map((entry) => {
|
|
@@ -6477,116 +6553,7 @@ onComponentSelect, onComponentDelete, onComponentEdit, onComponentUpdate, select
|
|
|
6477
6553
|
return comp;
|
|
6478
6554
|
});
|
|
6479
6555
|
onFormDataChange?.(updatedComponents);
|
|
6480
|
-
}, onValueChange: (
|
|
6481
|
-
console.log('[DfFormPreview] datagrid onValueChange received:', change.id, 'hasEntries:', change.value && typeof change.value === 'object' && 'entries' in change.value);
|
|
6482
|
-
// Handle datagrid value changes (entries updates)
|
|
6483
|
-
if (change.id === component.id && change.value && typeof change.value === 'object' && 'entries' in change.value) {
|
|
6484
|
-
console.log('[DfFormPreview] datagrid entries update - entries count:', change.value.entries?.length);
|
|
6485
|
-
// Update localFormComponents with new entries structure
|
|
6486
|
-
const updatedComponents = localFormComponents.map(comp => {
|
|
6487
|
-
if (comp.id === component.id) {
|
|
6488
|
-
return {
|
|
6489
|
-
...comp,
|
|
6490
|
-
...change.value
|
|
6491
|
-
};
|
|
6492
|
-
}
|
|
6493
|
-
return comp;
|
|
6494
|
-
});
|
|
6495
|
-
// CRITICAL: Update local state immediately so new entries render without Angular round-trip
|
|
6496
|
-
setLocalFormComponents(updatedComponents);
|
|
6497
|
-
onFormDataChange?.(updatedComponents);
|
|
6498
|
-
// Also update formValues for nested components
|
|
6499
|
-
if (change.value.entries && Array.isArray(change.value.entries)) {
|
|
6500
|
-
change.value.entries.forEach((entry) => {
|
|
6501
|
-
if (entry.components && Array.isArray(entry.components)) {
|
|
6502
|
-
entry.components.forEach((nestedComp) => {
|
|
6503
|
-
const nestedValue = formValues[nestedComp.id];
|
|
6504
|
-
if (nestedValue !== undefined) ;
|
|
6505
|
-
else {
|
|
6506
|
-
// Initialize with defaultValue if available
|
|
6507
|
-
const defaultValue = nestedComp.basic?.defaultValue;
|
|
6508
|
-
if (defaultValue !== undefined) {
|
|
6509
|
-
setFormValues(prev => ({
|
|
6510
|
-
...prev,
|
|
6511
|
-
[nestedComp.id]: defaultValue
|
|
6512
|
-
}));
|
|
6513
|
-
}
|
|
6514
|
-
}
|
|
6515
|
-
});
|
|
6516
|
-
}
|
|
6517
|
-
});
|
|
6518
|
-
}
|
|
6519
|
-
}
|
|
6520
|
-
else {
|
|
6521
|
-
// For nested component value changes, use the regular handler
|
|
6522
|
-
onFormValueChange(change);
|
|
6523
|
-
}
|
|
6524
|
-
}, onEntryAdd: () => {
|
|
6525
|
-
// CRITICAL: Entry has already been added via onValueChange in DfFormDataGrid
|
|
6526
|
-
// Get the updated component from localFormComponents (which should have been updated by onValueChange)
|
|
6527
|
-
const currentComponent = localFormComponents.find(comp => comp.id === component.id);
|
|
6528
|
-
if (currentComponent && currentComponent.entries) {
|
|
6529
|
-
// Entry should already be in the component via onValueChange
|
|
6530
|
-
// Just ensure localFormComponents is in sync (no-op if already synced)
|
|
6531
|
-
const updatedComponents = localFormComponents.map(comp => {
|
|
6532
|
-
if (comp.id === component.id) {
|
|
6533
|
-
// Ensure entries are properly structured
|
|
6534
|
-
return {
|
|
6535
|
-
...comp,
|
|
6536
|
-
entries: comp.entries || []
|
|
6537
|
-
};
|
|
6538
|
-
}
|
|
6539
|
-
return comp;
|
|
6540
|
-
});
|
|
6541
|
-
onFormDataChange?.(updatedComponents);
|
|
6542
|
-
}
|
|
6543
|
-
else {
|
|
6544
|
-
// Fallback: If component doesn't have entries yet, try to get from formValues
|
|
6545
|
-
setTimeout(() => {
|
|
6546
|
-
const datagridValue = formValues[component.id];
|
|
6547
|
-
if (datagridValue && typeof datagridValue === 'object' && 'entries' in datagridValue) {
|
|
6548
|
-
const updatedComponents = localFormComponents.map(comp => {
|
|
6549
|
-
if (comp.id === component.id) {
|
|
6550
|
-
return {
|
|
6551
|
-
...comp,
|
|
6552
|
-
entries: datagridValue.entries
|
|
6553
|
-
};
|
|
6554
|
-
}
|
|
6555
|
-
return comp;
|
|
6556
|
-
});
|
|
6557
|
-
onFormDataChange?.(updatedComponents);
|
|
6558
|
-
}
|
|
6559
|
-
}, 100);
|
|
6560
|
-
}
|
|
6561
|
-
}, onEntryRemove: (entryIndex) => {
|
|
6562
|
-
// Handle entry remove - update form components
|
|
6563
|
-
const updatedComponents = localFormComponents.map(comp => {
|
|
6564
|
-
if (comp.id === component.id && comp.entries) {
|
|
6565
|
-
const currentEntries = comp.entries || [];
|
|
6566
|
-
const updatedEntries = currentEntries
|
|
6567
|
-
.filter((_, index) => index !== entryIndex)
|
|
6568
|
-
.map((entry, index) => ({
|
|
6569
|
-
...entry,
|
|
6570
|
-
index,
|
|
6571
|
-
id: `entry-${comp.id}-${index}`,
|
|
6572
|
-
components: entry.components?.map((comp, compIndex) => {
|
|
6573
|
-
const templateComp = (comp.templateComponents || [])[compIndex];
|
|
6574
|
-
return {
|
|
6575
|
-
...comp,
|
|
6576
|
-
id: templateComp ? `${templateComp.id}-entry-${index}-${compIndex}` : comp.id
|
|
6577
|
-
};
|
|
6578
|
-
}) || []
|
|
6579
|
-
}));
|
|
6580
|
-
return {
|
|
6581
|
-
...comp,
|
|
6582
|
-
entries: updatedEntries
|
|
6583
|
-
};
|
|
6584
|
-
}
|
|
6585
|
-
return comp;
|
|
6586
|
-
});
|
|
6587
|
-
onFormDataChange?.(updatedComponents);
|
|
6588
|
-
}, renderFormComponent: (field) => {
|
|
6589
|
-
// Ensure the nested component gets the proper form value
|
|
6556
|
+
}, onValueChange: onFormValueChange, renderFormComponent: (field) => {
|
|
6590
6557
|
return renderFormComponent(field);
|
|
6591
6558
|
} }));
|
|
6592
6559
|
case 'file':
|