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