df-ae-forms-package 1.1.4 → 1.1.5
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 +112 -40
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +112 -40
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.esm.js
CHANGED
|
@@ -2402,6 +2402,7 @@ const DfFormFileUpload = ({ id, properties, validationErrors = {}, formValue = n
|
|
|
2402
2402
|
const [isDragOver, setIsDragOver] = useState(false);
|
|
2403
2403
|
const [isTouched, setIsTouched] = useState(false);
|
|
2404
2404
|
const fileInputRef = useRef(null);
|
|
2405
|
+
const lastFormValueRef = useRef(null); // Track the last formValue to prevent unnecessary resets
|
|
2405
2406
|
// Convert FileList or File[] to IFilePreview[]
|
|
2406
2407
|
const convertToFilePreviews = useCallback((fileList, startIndex = 0) => {
|
|
2407
2408
|
if (!fileList)
|
|
@@ -2494,12 +2495,20 @@ const DfFormFileUpload = ({ id, properties, validationErrors = {}, formValue = n
|
|
|
2494
2495
|
if (fileObject.url || fileObject.path) {
|
|
2495
2496
|
preview = fileObject.url || fileObject.path;
|
|
2496
2497
|
}
|
|
2497
|
-
else if (
|
|
2498
|
-
// Handle base64 data
|
|
2498
|
+
else if (fileObject.data) {
|
|
2499
|
+
// Handle base64 data - works for all file types with data
|
|
2500
|
+
const resolvedType = fileType || 'application/octet-stream';
|
|
2499
2501
|
const fileData = fileObject.data;
|
|
2500
|
-
|
|
2501
|
-
|
|
2502
|
-
|
|
2502
|
+
if (typeof fileData === 'string') {
|
|
2503
|
+
if (fileData.startsWith('data:')) {
|
|
2504
|
+
// Already a full data URI
|
|
2505
|
+
preview = fileData;
|
|
2506
|
+
}
|
|
2507
|
+
else {
|
|
2508
|
+
// Raw base64 - construct data URI
|
|
2509
|
+
preview = `data:${resolvedType};base64,${fileData}`;
|
|
2510
|
+
}
|
|
2511
|
+
}
|
|
2503
2512
|
}
|
|
2504
2513
|
// Use the original object to preserve data
|
|
2505
2514
|
fileObj = fileObject;
|
|
@@ -2684,10 +2693,35 @@ const DfFormFileUpload = ({ id, properties, validationErrors = {}, formValue = n
|
|
|
2684
2693
|
}
|
|
2685
2694
|
}, [mode]);
|
|
2686
2695
|
// Update value when formValue prop changes or on mount
|
|
2696
|
+
// CRITICAL: Use a stable reference check to prevent unnecessary resets
|
|
2687
2697
|
useEffect(() => {
|
|
2688
|
-
//
|
|
2698
|
+
// Skip if formValue is null/undefined (no data)
|
|
2699
|
+
if (formValue === null || formValue === undefined || (typeof formValue === 'string' && formValue === '')) {
|
|
2700
|
+
// Only clear files if we previously had files from formValue
|
|
2701
|
+
// Don't clear files that were added by user interaction
|
|
2702
|
+
if (lastFormValueRef.current !== null && lastFormValueRef.current !== undefined && lastFormValueRef.current !== '') {
|
|
2703
|
+
setFiles([]);
|
|
2704
|
+
lastFormValueRef.current = null;
|
|
2705
|
+
}
|
|
2706
|
+
return;
|
|
2707
|
+
}
|
|
2708
|
+
// Check if formValue actually changed (deep comparison for arrays)
|
|
2709
|
+
try {
|
|
2710
|
+
const currentStr = JSON.stringify(formValue);
|
|
2711
|
+
const prevStr = JSON.stringify(lastFormValueRef.current);
|
|
2712
|
+
if (currentStr === prevStr) {
|
|
2713
|
+
return; // No change, skip
|
|
2714
|
+
}
|
|
2715
|
+
}
|
|
2716
|
+
catch {
|
|
2717
|
+
// If stringify fails, proceed with update
|
|
2718
|
+
}
|
|
2719
|
+
// Convert and set new files
|
|
2689
2720
|
const newFiles = convertToFilePreviews(formValue);
|
|
2690
|
-
|
|
2721
|
+
if (newFiles.length > 0) {
|
|
2722
|
+
setFiles(newFiles);
|
|
2723
|
+
lastFormValueRef.current = formValue;
|
|
2724
|
+
}
|
|
2691
2725
|
}, [formValue, convertToFilePreviews]);
|
|
2692
2726
|
// Mark as touched when form is submitted
|
|
2693
2727
|
useEffect(() => {
|
|
@@ -5431,7 +5465,38 @@ onComponentSelect, onComponentDelete, onComponentEdit, onComponentUpdate, select
|
|
|
5431
5465
|
const initializeComponentValues = (components, values) => {
|
|
5432
5466
|
components.forEach(component => {
|
|
5433
5467
|
const componentId = ensureStringId$1(component.id);
|
|
5434
|
-
if (componentId)
|
|
5468
|
+
if (!componentId)
|
|
5469
|
+
return; // Skip components without valid IDs
|
|
5470
|
+
// CRITICAL: Handle file component FIRST — file data is an array, not a simple string
|
|
5471
|
+
// The general handler below would misinterpret an empty file array
|
|
5472
|
+
if (component.name === 'file' && component.basic) {
|
|
5473
|
+
// Don't overwrite if already initialized
|
|
5474
|
+
if (values[componentId] !== undefined && values[componentId] !== '' && values[componentId] !== null) ;
|
|
5475
|
+
else {
|
|
5476
|
+
// Check all possible locations where file data could be stored
|
|
5477
|
+
const fileData = component.basic.value ||
|
|
5478
|
+
component.basic.files ||
|
|
5479
|
+
component.basic.attachments;
|
|
5480
|
+
if (fileData && (Array.isArray(fileData) ? fileData.length > 0 : true)) {
|
|
5481
|
+
values[componentId] = fileData;
|
|
5482
|
+
}
|
|
5483
|
+
else {
|
|
5484
|
+
values[componentId] = null; // Use null, not empty string, for file components
|
|
5485
|
+
}
|
|
5486
|
+
}
|
|
5487
|
+
}
|
|
5488
|
+
// Handle instructions component
|
|
5489
|
+
else if (component.name === 'instructions' && component.basic) {
|
|
5490
|
+
if (!component.basic.instructions) {
|
|
5491
|
+
component.basic.instructions = [];
|
|
5492
|
+
}
|
|
5493
|
+
const instructionValue = component.basic.value || component.basic.instructions;
|
|
5494
|
+
if (instructionValue) {
|
|
5495
|
+
values[componentId] = instructionValue;
|
|
5496
|
+
}
|
|
5497
|
+
}
|
|
5498
|
+
// General handler for all other components
|
|
5499
|
+
else {
|
|
5435
5500
|
// ALWAYS prioritize existing form state (values param) if it exists
|
|
5436
5501
|
if (values[componentId] !== undefined) ;
|
|
5437
5502
|
// Then use captured value in basic.value
|
|
@@ -5446,10 +5511,10 @@ onComponentSelect, onComponentDelete, onComponentEdit, onComponentUpdate, select
|
|
|
5446
5511
|
else {
|
|
5447
5512
|
// For checkbox and multi-select, empty array
|
|
5448
5513
|
if (component.name === 'checkbox' || component.name === 'select') {
|
|
5449
|
-
values[
|
|
5514
|
+
values[componentId] = [];
|
|
5450
5515
|
}
|
|
5451
5516
|
else {
|
|
5452
|
-
values[
|
|
5517
|
+
values[componentId] = '';
|
|
5453
5518
|
}
|
|
5454
5519
|
}
|
|
5455
5520
|
}
|
|
@@ -5471,31 +5536,10 @@ onComponentSelect, onComponentDelete, onComponentEdit, onComponentUpdate, select
|
|
|
5471
5536
|
}
|
|
5472
5537
|
});
|
|
5473
5538
|
}
|
|
5474
|
-
// Handle file component - initialize with file data if present
|
|
5475
|
-
if (component.name === 'file' && component.basic) {
|
|
5476
|
-
const fileData = component.basic.files || component.basic.attachments || component.basic.value;
|
|
5477
|
-
if (fileData) {
|
|
5478
|
-
values[component.id] = fileData;
|
|
5479
|
-
}
|
|
5480
|
-
}
|
|
5481
5539
|
// Initialize notes and attachments
|
|
5482
|
-
if (
|
|
5540
|
+
if (componentId && component.basic) {
|
|
5483
5541
|
if (component.basic.notes) ;
|
|
5484
5542
|
}
|
|
5485
|
-
// Handle instructions component - ensure instructions array exists and initialize formValue
|
|
5486
|
-
if (component.name === 'instructions' && component.basic) {
|
|
5487
|
-
if (!component.basic.instructions) {
|
|
5488
|
-
// Initialize empty instructions array if not present
|
|
5489
|
-
component.basic.instructions = [];
|
|
5490
|
-
}
|
|
5491
|
-
// CRITICAL: Initialize formValue for instructions from API data
|
|
5492
|
-
// Check if component has value from API (could be in basic.value, basic.instructions, or formData)
|
|
5493
|
-
const instructionValue = component.basic.value || component.basic.instructions;
|
|
5494
|
-
if (instructionValue) {
|
|
5495
|
-
// Store instruction data in formValues so it can be passed to DfFormInstruction
|
|
5496
|
-
values[component.id] = instructionValue;
|
|
5497
|
-
}
|
|
5498
|
-
}
|
|
5499
5543
|
// Handle nested components in section children
|
|
5500
5544
|
if (component.children && Array.isArray(component.children)) {
|
|
5501
5545
|
initializeComponentValues(component.children, values);
|
|
@@ -5655,8 +5699,34 @@ onComponentSelect, onComponentDelete, onComponentEdit, onComponentUpdate, select
|
|
|
5655
5699
|
}
|
|
5656
5700
|
// Set the state
|
|
5657
5701
|
setFormValues(prev => {
|
|
5658
|
-
//
|
|
5659
|
-
|
|
5702
|
+
// Smart merge: initial values should win over empty/stale prev values
|
|
5703
|
+
// but user-entered values in prev should win over initial defaults
|
|
5704
|
+
const merged = { ...initialValues };
|
|
5705
|
+
Object.keys(prev).forEach(key => {
|
|
5706
|
+
const prevVal = prev[key];
|
|
5707
|
+
const initVal = initialValues[key];
|
|
5708
|
+
// If prev has a meaningful value (not empty/null/undefined), keep it
|
|
5709
|
+
if (prevVal !== undefined && prevVal !== null && prevVal !== '') {
|
|
5710
|
+
// But if initVal is an array (like file data) and prevVal is a simple empty value,
|
|
5711
|
+
// prefer the initialValue
|
|
5712
|
+
if (Array.isArray(initVal) && initVal.length > 0 && !Array.isArray(prevVal)) {
|
|
5713
|
+
// initialValue is a populated array but prev is not — keep initial
|
|
5714
|
+
merged[key] = initVal;
|
|
5715
|
+
}
|
|
5716
|
+
else {
|
|
5717
|
+
merged[key] = prevVal;
|
|
5718
|
+
}
|
|
5719
|
+
}
|
|
5720
|
+
// If prev has empty string but initial has actual data, use initial
|
|
5721
|
+
else if (initVal !== undefined && initVal !== null && initVal !== '') {
|
|
5722
|
+
merged[key] = initVal;
|
|
5723
|
+
}
|
|
5724
|
+
// Otherwise keep prev (even if empty — preserves user clearing a field)
|
|
5725
|
+
else {
|
|
5726
|
+
merged[key] = prevVal;
|
|
5727
|
+
}
|
|
5728
|
+
});
|
|
5729
|
+
return merged;
|
|
5660
5730
|
});
|
|
5661
5731
|
// Initialize notes and attachments state
|
|
5662
5732
|
setComponentNotes(prev => ({ ...initialNotes, ...prev }));
|
|
@@ -6815,12 +6885,14 @@ onComponentSelect, onComponentDelete, onComponentEdit, onComponentUpdate, select
|
|
|
6815
6885
|
} }));
|
|
6816
6886
|
case 'file':
|
|
6817
6887
|
// Get file value from formValues, or from component basic properties
|
|
6818
|
-
// CRITICAL:
|
|
6819
|
-
const
|
|
6820
|
-
|
|
6821
|
-
|
|
6822
|
-
component.basic?.
|
|
6823
|
-
|
|
6888
|
+
// CRITICAL: formValue could be '' (empty string) which is falsy — check explicitly
|
|
6889
|
+
const hasFormValue = formValue !== undefined && formValue !== null && formValue !== '';
|
|
6890
|
+
const fileFormValue = hasFormValue
|
|
6891
|
+
? formValue
|
|
6892
|
+
: (component.basic?.value ||
|
|
6893
|
+
component.basic?.files ||
|
|
6894
|
+
component.basic?.attachments ||
|
|
6895
|
+
null);
|
|
6824
6896
|
return (jsx(DfFormFileUpload, { ...commonProps, properties: component, formValue: fileFormValue }));
|
|
6825
6897
|
default:
|
|
6826
6898
|
return (jsx("div", { className: "form-group", children: jsxs("div", { className: "form-group-label", children: ["Unsupported Component: ", component.name] }) }));
|