df-ae-forms-package 1.1.5 → 1.1.7
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.d.ts +1 -0
- package/dist/index.esm.js +246 -39
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +246 -39
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -334,7 +334,7 @@ const RaiseIssueModal = ({ isOpen, onClose, onSuccess, component, formTemplateId
|
|
|
334
334
|
'Maria Garcia',
|
|
335
335
|
'John Smith',
|
|
336
336
|
'Sarah Johnson'
|
|
337
|
-
], workOrderNumber: initialWorkOrderNumber, assetNumber: initialAssetNumber, isStandalone, isEdit }) => {
|
|
337
|
+
], workOrderNumber: initialWorkOrderNumber, assetNumber: initialAssetNumber, isStandalone, inEditMode = false, isEdit }) => {
|
|
338
338
|
// Determine if workflow actions should be enabled
|
|
339
339
|
// If explicitly provided, use that. Otherwise, default to isEdit (true if editing, false/undefined otherwise).
|
|
340
340
|
// Fallback to false if neither is provided.
|
|
@@ -350,6 +350,7 @@ const RaiseIssueModal = ({ isOpen, onClose, onSuccess, component, formTemplateId
|
|
|
350
350
|
// State to hold both File objects and existing attachments
|
|
351
351
|
const [localAttachments, setLocalAttachments] = React.useState(attachments || []);
|
|
352
352
|
const [isDragging, setIsDragging] = React.useState(false);
|
|
353
|
+
const [isViewMode, setIsViewMode] = React.useState(!!issue && !inEditMode);
|
|
353
354
|
const fileInputRef = React.useRef(null);
|
|
354
355
|
const isEditMode = isEdit !== undefined ? isEdit : !!issue;
|
|
355
356
|
React.useEffect(() => {
|
|
@@ -371,6 +372,11 @@ const RaiseIssueModal = ({ isOpen, onClose, onSuccess, component, formTemplateId
|
|
|
371
372
|
}
|
|
372
373
|
}
|
|
373
374
|
}, [isOpen, attachments, issue, isEditMode]);
|
|
375
|
+
React.useEffect(() => {
|
|
376
|
+
if (issue) {
|
|
377
|
+
setIsViewMode(!inEditMode);
|
|
378
|
+
}
|
|
379
|
+
}, [issue, inEditMode]);
|
|
374
380
|
const handleFileChange = (event) => {
|
|
375
381
|
if (event.target.files && event.target.files.length > 0) {
|
|
376
382
|
const newFiles = Array.from(event.target.files);
|
|
@@ -587,6 +593,7 @@ const RaiseIssueModal = ({ isOpen, onClose, onSuccess, component, formTemplateId
|
|
|
587
593
|
await onUpdateIssue(issue._id, updateData);
|
|
588
594
|
}
|
|
589
595
|
toastService.showSuccess('Issue updated successfully');
|
|
596
|
+
setIsViewMode(true);
|
|
590
597
|
if (onSuccess) {
|
|
591
598
|
onSuccess();
|
|
592
599
|
}
|
|
@@ -668,7 +675,7 @@ const RaiseIssueModal = ({ isOpen, onClose, onSuccess, component, formTemplateId
|
|
|
668
675
|
if (!isOpen) {
|
|
669
676
|
return null;
|
|
670
677
|
}
|
|
671
|
-
const modalContent = (jsxRuntime.jsx("div", { className: "raise-issue-modal-overlay", onClick: onClose, children: jsxRuntime.jsxs("div", { className: "raise-issue-modal", onClick: (e) => e.stopPropagation(), children: [jsxRuntime.jsxs("div", { className: "raise-issue-modal-header", children: [jsxRuntime.jsxs("div", { className: "raise-issue-modal-header-left", children: [jsxRuntime.jsx(lucideReact.AlertTriangle, { className: "raise-issue-modal-icon", size: 20 }), jsxRuntime.jsx("div", { className: "raise-issue-modal-header-text", children: jsxRuntime.jsx("div", { className: "raise-issue-modal-title-main", children: isEditMode ? 'Issue Details' : 'Create Issue' }) })] }), jsxRuntime.jsx("button", { className: "raise-issue-modal-close", onClick: onClose, "aria-label": "Close", children: jsxRuntime.jsx(lucideReact.X, { size: 18 }) })] }), jsxRuntime.jsx("div", { className: "raise-issue-modal-content", children: jsxRuntime.jsxs("div", { className: "raise-issue-fields-grid", children: [isEditMode && issue?.issueNumber && (jsxRuntime.jsxs("div", { className: "raise-issue-field", children: [jsxRuntime.jsx("label", { className: "raise-issue-field-label", children: "Issue ID" }), jsxRuntime.jsx("input", { type: "text", className: "raise-issue-field-input raise-issue-field-readonly", value: issue.issueNumber, readOnly: true })] })), jsxRuntime.jsxs("div", { className: "raise-issue-field", children: [jsxRuntime.jsx("label", { className: "raise-issue-field-label", children: "Task" }), jsxRuntime.jsx("input", { type: "text", className: "raise-issue-field-input raise-issue-field-readonly", value: isEditMode ? (issue?.component?.basic?.label || '') : (component?.basic?.label || ''), readOnly: true })] }), jsxRuntime.jsxs("div", { className: "raise-issue-field", children: [jsxRuntime.jsx("label", { className: "raise-issue-field-label", children: "Task Value" }), jsxRuntime.jsx("input", { type: "text", className: "raise-issue-field-input raise-issue-field-readonly", value: isEditMode ? (issue?.component?.basic?.value || '') : (component?.basic?.value || ''), readOnly: true })] }), jsxRuntime.jsxs("div", { className: "raise-issue-field", children: [jsxRuntime.jsxs("label", { className: "raise-issue-field-label", children: ["Title ", jsxRuntime.jsx("span", { className: "raise-issue-required", children: "*" })] }), jsxRuntime.jsx("input", { type: "text", className: `raise-issue-field-input ${isEditMode ? 'raise-issue-field-readonly' : ''}`, value: title, onChange: (e) => setTitle(e.target.value), placeholder: "Enter issue title", readOnly: isEditMode })] }), !isStandalone && (jsxRuntime.jsxs("div", { className: "raise-issue-field", children: [jsxRuntime.jsxs("label", { className: "raise-issue-field-label", children: ["Work Order ", jsxRuntime.jsx("span", { className: "raise-issue-required", children: "*" })] }), jsxRuntime.jsx("input", { type: "text", className: `raise-issue-field-input ${isEditMode ? 'raise-issue-field-readonly' : ''}`, value: workOrderNumber, onChange: (e) => setWorkOrderNumber(e.target.value), placeholder: "N/A", readOnly: isEditMode })] })), !isStandalone && (jsxRuntime.jsxs("div", { className: "raise-issue-field", children: [jsxRuntime.jsxs("label", { className: "raise-issue-field-label", children: ["Asset Number ", jsxRuntime.jsx("span", { className: "raise-issue-required", children: "*" })] }), jsxRuntime.jsx("input", { type: "text", className: `raise-issue-field-input ${isEditMode ? 'raise-issue-field-readonly' : ''}`, value: assetNumber, onChange: (e) => setAssetNumber(e.target.value), placeholder: "Enter asset number", readOnly: isEditMode })] })), jsxRuntime.jsxs("div", { className: "raise-issue-field", children: [jsxRuntime.jsxs("label", { className: "raise-issue-field-label", children: ["Raised By ", jsxRuntime.jsx("span", { className: "raise-issue-required", children: "*" })] }), jsxRuntime.jsxs("div", { className: "raise-issue-field-value-with-icon", children: [jsxRuntime.jsx(lucideReact.User, { size: 16 }), jsxRuntime.jsx("span", { children: user ? `${user.firstName || ''} ${user.lastName || ''}`.trim() || 'User' : 'User' })] })] }), jsxRuntime.jsxs("div", { className: "raise-issue-field", children: [jsxRuntime.jsx("label", { className: "raise-issue-field-label", children: "Created On" }), jsxRuntime.jsxs("div", { className: "raise-issue-field-value-with-icon", children: [jsxRuntime.jsx(lucideReact.Calendar, { size: 16 }), jsxRuntime.jsx("span", { children: isEditMode && issue?.createdAt
|
|
678
|
+
const modalContent = (jsxRuntime.jsx("div", { className: "raise-issue-modal-overlay", onClick: onClose, children: jsxRuntime.jsxs("div", { className: "raise-issue-modal", onClick: (e) => e.stopPropagation(), children: [jsxRuntime.jsxs("div", { className: "raise-issue-modal-header", children: [jsxRuntime.jsxs("div", { className: "raise-issue-modal-header-left", children: [jsxRuntime.jsx(lucideReact.AlertTriangle, { className: "raise-issue-modal-icon", size: 20 }), jsxRuntime.jsx("div", { className: "raise-issue-modal-header-text", children: jsxRuntime.jsx("div", { className: "raise-issue-modal-title-main", children: isEditMode ? 'Issue Details' : 'Create Issue' }) })] }), jsxRuntime.jsx("button", { className: "raise-issue-modal-close", onClick: onClose, "aria-label": "Close", children: jsxRuntime.jsx(lucideReact.X, { size: 18 }) })] }), jsxRuntime.jsx("div", { className: "raise-issue-modal-content", children: jsxRuntime.jsxs("div", { className: "raise-issue-fields-grid", children: [isEditMode && issue?.issueNumber && (jsxRuntime.jsxs("div", { className: "raise-issue-field", children: [jsxRuntime.jsx("label", { className: "raise-issue-field-label", children: "Issue ID" }), jsxRuntime.jsx("input", { type: "text", className: "raise-issue-field-input raise-issue-field-readonly", value: issue.issueNumber, readOnly: true })] })), jsxRuntime.jsxs("div", { className: "raise-issue-field", children: [jsxRuntime.jsx("label", { className: "raise-issue-field-label", children: "Task" }), jsxRuntime.jsx("input", { type: "text", className: "raise-issue-field-input raise-issue-field-readonly", value: isEditMode ? (issue?.component?.basic?.label || '') : (component?.basic?.label || ''), readOnly: true })] }), jsxRuntime.jsxs("div", { className: "raise-issue-field", children: [jsxRuntime.jsx("label", { className: "raise-issue-field-label", children: "Task Value" }), jsxRuntime.jsx("input", { type: "text", className: "raise-issue-field-input raise-issue-field-readonly", value: isEditMode ? (issue?.component?.basic?.value || '') : (component?.basic?.value || ''), readOnly: true })] }), jsxRuntime.jsxs("div", { className: "raise-issue-field", children: [jsxRuntime.jsxs("label", { className: "raise-issue-field-label", children: ["Title ", jsxRuntime.jsx("span", { className: "raise-issue-required", children: "*" })] }), jsxRuntime.jsx("input", { type: "text", className: `raise-issue-field-input ${isEditMode ? 'raise-issue-field-readonly' : ''}`, value: title, onChange: (e) => setTitle(e.target.value), placeholder: "Enter issue title", readOnly: isEditMode && isViewMode })] }), !isStandalone && (jsxRuntime.jsxs("div", { className: "raise-issue-field", children: [jsxRuntime.jsxs("label", { className: "raise-issue-field-label", children: ["Work Order ", jsxRuntime.jsx("span", { className: "raise-issue-required", children: "*" })] }), jsxRuntime.jsx("input", { type: "text", className: `raise-issue-field-input ${isEditMode ? 'raise-issue-field-readonly' : ''}`, value: workOrderNumber, onChange: (e) => setWorkOrderNumber(e.target.value), placeholder: "N/A", readOnly: isEditMode && isViewMode })] })), !isStandalone && (jsxRuntime.jsxs("div", { className: "raise-issue-field", children: [jsxRuntime.jsxs("label", { className: "raise-issue-field-label", children: ["Asset Number ", jsxRuntime.jsx("span", { className: "raise-issue-required", children: "*" })] }), jsxRuntime.jsx("input", { type: "text", className: `raise-issue-field-input ${isEditMode ? 'raise-issue-field-readonly' : ''}`, value: assetNumber, onChange: (e) => setAssetNumber(e.target.value), placeholder: "Enter asset number", readOnly: isEditMode && isViewMode })] })), jsxRuntime.jsxs("div", { className: "raise-issue-field", children: [jsxRuntime.jsxs("label", { className: "raise-issue-field-label", children: ["Raised By ", jsxRuntime.jsx("span", { className: "raise-issue-required", children: "*" })] }), jsxRuntime.jsxs("div", { className: "raise-issue-field-value-with-icon", children: [jsxRuntime.jsx(lucideReact.User, { size: 16 }), jsxRuntime.jsx("span", { children: user ? `${user.firstName || ''} ${user.lastName || ''}`.trim() || 'User' : 'User' })] })] }), jsxRuntime.jsxs("div", { className: "raise-issue-field", children: [jsxRuntime.jsx("label", { className: "raise-issue-field-label", children: "Created On" }), jsxRuntime.jsxs("div", { className: "raise-issue-field-value-with-icon", children: [jsxRuntime.jsx(lucideReact.Calendar, { size: 16 }), jsxRuntime.jsx("span", { children: isEditMode && issue?.createdAt
|
|
672
679
|
? (safeDate(issue.createdAt) || new Date()).toLocaleString('en-US', {
|
|
673
680
|
year: 'numeric',
|
|
674
681
|
month: 'short',
|
|
@@ -684,7 +691,7 @@ const RaiseIssueModal = ({ isOpen, onClose, onSuccess, component, formTemplateId
|
|
|
684
691
|
hour: '2-digit',
|
|
685
692
|
minute: '2-digit',
|
|
686
693
|
hour12: true
|
|
687
|
-
}) })] })] }), jsxRuntime.jsxs("div", { className: "raise-issue-field raise-issue-field-full-width", children: [jsxRuntime.jsxs("label", { className: "raise-issue-field-label", children: ["Description ", jsxRuntime.jsx("span", { className: "raise-issue-required", children: "*" })] }), jsxRuntime.jsx("textarea", { className: `raise-issue-field-textarea ${isEditMode ? 'raise-issue-field-readonly' : ''}`, value: description, onChange: (e) => setDescription(e.target.value), placeholder: "Enter issue description", rows: 4, readOnly: isEditMode })] }), jsxRuntime.jsxs("div", { className: "raise-issue-field", children: [jsxRuntime.jsxs("label", { className: "raise-issue-field-label", children: ["Status ", jsxRuntime.jsx("span", { className: "raise-issue-required", children: "*" })] }), jsxRuntime.
|
|
694
|
+
}) })] })] }), jsxRuntime.jsxs("div", { className: "raise-issue-field raise-issue-field-full-width", children: [jsxRuntime.jsxs("label", { className: "raise-issue-field-label", children: ["Description ", jsxRuntime.jsx("span", { className: "raise-issue-required", children: "*" })] }), jsxRuntime.jsx("textarea", { className: `raise-issue-field-textarea ${isEditMode ? 'raise-issue-field-readonly' : ''}`, value: description, onChange: (e) => setDescription(e.target.value), placeholder: "Enter issue description", rows: 4, readOnly: isEditMode && isViewMode })] }), jsxRuntime.jsxs("div", { className: "raise-issue-field", children: [jsxRuntime.jsxs("label", { className: "raise-issue-field-label", children: ["Status ", jsxRuntime.jsx("span", { className: "raise-issue-required", children: "*" })] }), jsxRuntime.jsx("input", { type: "text", className: "raise-issue-field-input raise-issue-field-readonly", value: status, readOnly: true })] }), jsxRuntime.jsxs("div", { className: "raise-issue-field", children: [jsxRuntime.jsxs("label", { className: "raise-issue-field-label", children: ["Assign to ", jsxRuntime.jsx("span", { className: "raise-issue-required", children: "*" })] }), jsxRuntime.jsxs("select", { className: "raise-issue-field-select", value: assignee, onChange: (e) => setAssignee(e.target.value), disabled: isEditMode && isViewMode, children: [jsxRuntime.jsx("option", { value: "", children: "Unassigned" }), availableUsers.map(userName => (jsxRuntime.jsx("option", { value: userName, children: userName }, userName)))] })] }), jsxRuntime.jsxs("div", { className: "raise-issue-field raise-issue-field-full-width", children: [jsxRuntime.jsxs("label", { className: "raise-issue-field-label", children: ["Priority ", jsxRuntime.jsx("span", { className: "raise-issue-required", children: "*" })] }), jsxRuntime.jsxs("div", { className: "raise-issue-priority-buttons", children: [jsxRuntime.jsx("button", { type: "button", className: `priority-button priority-low ${priority === 'Low' ? 'active' : ''}`, onClick: () => setPriority('Low'), disabled: isEditMode && isViewMode, children: "Low" }), jsxRuntime.jsx("button", { type: "button", className: `priority-button priority-medium ${priority === 'Medium' ? 'active' : ''}`, onClick: () => setPriority('Medium'), disabled: isEditMode && isViewMode, children: "Medium" }), jsxRuntime.jsx("button", { type: "button", className: `priority-button priority-high ${priority === 'High' ? 'active' : ''}`, onClick: () => setPriority('High'), disabled: isEditMode && isViewMode, children: "High" })] })] }), jsxRuntime.jsxs("div", { className: "raise-issue-field raise-issue-field-full-width", children: [jsxRuntime.jsxs("label", { className: "raise-issue-field-label-with-icon", children: [jsxRuntime.jsx(lucideReact.MessageSquare, { size: 16 }), jsxRuntime.jsx("span", { children: "Comments" })] }), !comments && (jsxRuntime.jsx("div", { className: "raise-issue-no-comments", children: "No comments yet" })), jsxRuntime.jsx("textarea", { className: `raise-issue-field-textarea raise-issue-comments-textarea ${isEditMode ? 'raise-issue-field-readonly' : ''}`, value: comments, onChange: (e) => setComments(e.target.value), placeholder: "Add a comment...", rows: 4, readOnly: isEditMode })] }), jsxRuntime.jsxs("div", { className: "raise-issue-field raise-issue-field-full-width", style: { marginTop: '1rem' }, children: [jsxRuntime.jsx("label", { className: "raise-issue-field-label", children: "Attachments" }), jsxRuntime.jsxs("div", { className: "raise-issue-attachments-container", children: [!isEditMode && (jsxRuntime.jsxs("div", { className: `raise-issue-dropzone ${isDragging ? 'dragging' : ''}`, onDragOver: handleDragOver, onDragLeave: handleDragLeave, onDrop: handleDrop, onClick: () => fileInputRef.current?.click(), children: [jsxRuntime.jsx("input", { type: "file", ref: fileInputRef, style: { display: 'none' }, onChange: handleFileChange, multiple: true }), jsxRuntime.jsx("div", { className: "raise-issue-dropzone-icon", children: jsxRuntime.jsx(lucideReact.UploadCloud, { size: 24 }) }), jsxRuntime.jsx("div", { className: "raise-issue-dropzone-text", children: "Click to upload or drag and drop" }), jsxRuntime.jsx("div", { className: "raise-issue-dropzone-hint", children: "PNG, JPG up to 10MB" })] })), localAttachments.length > 0 && (jsxRuntime.jsx("div", { className: "raise-issue-attachments-list", children: localAttachments.map((file, index) => (jsxRuntime.jsxs("div", { className: "raise-issue-attachment-item", children: [jsxRuntime.jsx("div", { className: "raise-issue-attachment-thumbnail", children: getAttachmentPreview(file) ? (jsxRuntime.jsx("img", { src: getAttachmentPreview(file), alt: "Thumbnail" })) : (jsxRuntime.jsx(lucideReact.Paperclip, { size: 20, color: "#9ca3af" })) }), jsxRuntime.jsxs("div", { className: "raise-issue-attachment-info", children: [jsxRuntime.jsx("span", { className: "attachment-name", title: getAttachmentName(file), children: getAttachmentName(file) }), file instanceof File && (jsxRuntime.jsxs("span", { className: "attachment-size", children: [(file.size / 1024).toFixed(1), " KB"] }))] }), !isEditMode && (jsxRuntime.jsx("button", { type: "button", className: "attachment-remove-btn", onClick: () => handleRemoveAttachment(index), title: "Remove", children: jsxRuntime.jsx(lucideReact.X, { size: 12 }) }))] }, index))) }))] })] })] }) }), jsxRuntime.jsx("div", { className: "raise-issue-modal-actions", children: jsxRuntime.jsxs("div", { className: "raise-issue-modal-actions-buttons", children: [isEditMode && issue && !isViewMode && (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [status === EIssueStatus.OPEN && (jsxRuntime.jsx("button", { className: "raise-issue-modal-button raise-issue-modal-button-accept", onClick: handleAccept, disabled: isSubmitting, children: isSubmitting ? 'Processing...' : 'Accept' })), status === EIssueStatus.IN_PROGRESS && (jsxRuntime.jsx("button", { className: "raise-issue-modal-button raise-issue-modal-button-resolve", onClick: handleResolve, disabled: isSubmitting, children: isSubmitting ? 'Processing...' : 'Resolve' })), (status === EIssueStatus.OPEN) && (jsxRuntime.jsx("button", { className: "raise-issue-modal-button raise-issue-modal-button-reject", onClick: handleReject, disabled: isSubmitting, children: isSubmitting ? 'Processing...' : 'Reject' }))] })), !isEditMode && (jsxRuntime.jsx("button", { className: `raise-issue-modal-button raise-issue-modal-button-save ${!isFormValid ? 'disabled' : ''}`, onClick: handleSubmit, disabled: isSubmitting || !isFormValid, children: isSubmitting ? 'Creating...' : 'Create Issue' }))] }) })] }) }));
|
|
688
695
|
// Render modal using portal to document body for full-page overlay
|
|
689
696
|
return require$$0.createPortal(modalContent, document.body);
|
|
690
697
|
};
|
|
@@ -820,7 +827,6 @@ const DfFormInput = ({ id, properties, validationErrors = {}, formValue = '', in
|
|
|
820
827
|
// Update ref if ID changes (shouldn't happen, but safety check)
|
|
821
828
|
React.useEffect(() => {
|
|
822
829
|
if (id !== componentIdRef.current) {
|
|
823
|
-
console.warn(`[DfFormInput] Component ID changed from ${componentIdRef.current} to ${id}`);
|
|
824
830
|
componentIdRef.current = id;
|
|
825
831
|
}
|
|
826
832
|
}, [id]);
|
|
@@ -2998,8 +3004,6 @@ const DfFormLocation = ({ id, properties, validationErrors = {}, formValue = nul
|
|
|
2998
3004
|
}
|
|
2999
3005
|
}
|
|
3000
3006
|
catch (error) {
|
|
3001
|
-
// Capacitor not properly initialized, fall through to web geolocation
|
|
3002
|
-
console.warn('Capacitor Geolocation not available, falling back to web geolocation');
|
|
3003
3007
|
}
|
|
3004
3008
|
}
|
|
3005
3009
|
// Fallback to standard web geolocation API (for browsers)
|
|
@@ -3713,7 +3717,6 @@ const AttachmentThumbnails = ({ attachments, onRemove }) => {
|
|
|
3713
3717
|
newUrls.set(index, url);
|
|
3714
3718
|
}
|
|
3715
3719
|
catch (e) {
|
|
3716
|
-
console.warn('Failed to create object URL for attachment:', e);
|
|
3717
3720
|
}
|
|
3718
3721
|
}
|
|
3719
3722
|
else if (file && file.url && file.type && file.type.startsWith('image/')) {
|
|
@@ -4624,7 +4627,6 @@ formTemplateId, onThresholdActionCompletion, onThresholdIssueRaised, onNotesChan
|
|
|
4624
4627
|
zIndex: 5
|
|
4625
4628
|
}, children: jsxRuntime.jsxs("button", { onClick: (e) => {
|
|
4626
4629
|
e.stopPropagation();
|
|
4627
|
-
console.log('[TableView] Add Entry button clicked (grid view)', 'entries:', dataEntries.length, 'max:', maxEntries);
|
|
4628
4630
|
onAddEntry();
|
|
4629
4631
|
}, disabled: dataEntries.length >= maxEntries, style: {
|
|
4630
4632
|
padding: '8px 16px',
|
|
@@ -4750,7 +4752,6 @@ formTemplateId, onThresholdActionCompletion, onThresholdIssueRaised, onNotesChan
|
|
|
4750
4752
|
justifyContent: 'center'
|
|
4751
4753
|
}, children: jsxRuntime.jsxs("button", { onClick: (e) => {
|
|
4752
4754
|
e.stopPropagation();
|
|
4753
|
-
console.log('[TableView] Add Entry button clicked (list view)', 'entries:', dataEntries.length, 'max:', maxEntries);
|
|
4754
4755
|
onAddEntry();
|
|
4755
4756
|
}, disabled: dataEntries.length >= maxEntries, style: {
|
|
4756
4757
|
padding: '8px 16px',
|
|
@@ -5003,12 +5004,8 @@ const DfFormDataGrid = ({ id, properties, mode = 'edit', formData = {}, onValueC
|
|
|
5003
5004
|
// In edit/preview modes, don't handle value changes as components are read-only
|
|
5004
5005
|
}, [mode, onValueChange]);
|
|
5005
5006
|
const handleAddEntry = React.useCallback(() => {
|
|
5006
|
-
console.log('[DfFormDataGrid] handleAddEntry called - Component ID:', id);
|
|
5007
5007
|
// Safety check: ensure we have entries array
|
|
5008
5008
|
const currentEntries = Array.isArray(properties.entries) ? properties.entries : [];
|
|
5009
|
-
console.log('[DfFormDataGrid] gridComponents:', gridComponents.length);
|
|
5010
|
-
console.log('[DfFormDataGrid] current entries count:', currentEntries.length);
|
|
5011
|
-
console.log('[DfFormDataGrid] onValueChange exists:', !!onValueChange);
|
|
5012
5009
|
// Use timestamp and random string to ensure uniqueness even if entries are deleted
|
|
5013
5010
|
const uniqueSuffix = `${Date.now()}-${Math.random().toString(36).substr(2, 5)}`;
|
|
5014
5011
|
const newEntryId = `entry-${uniqueSuffix}`;
|
|
@@ -5030,11 +5027,8 @@ const DfFormDataGrid = ({ id, properties, mode = 'edit', formData = {}, onValueC
|
|
|
5030
5027
|
}),
|
|
5031
5028
|
styles: {}
|
|
5032
5029
|
};
|
|
5033
|
-
console.log('[DfFormDataGrid] newEntry created:', newEntry.id, 'with', newEntry.components.length, 'components');
|
|
5034
5030
|
const updatedEntries = [...currentEntries, newEntry];
|
|
5035
|
-
console.log('[DfFormDataGrid] updatedEntries count:', updatedEntries.length);
|
|
5036
5031
|
if (onValueChange) {
|
|
5037
|
-
console.log('[DfFormDataGrid] calling onValueChange with updated datagrid structure - Entries:', updatedEntries.length);
|
|
5038
5032
|
onValueChange({
|
|
5039
5033
|
id: gridId, // Use sanitized gridId
|
|
5040
5034
|
value: {
|
|
@@ -5044,13 +5038,9 @@ const DfFormDataGrid = ({ id, properties, mode = 'edit', formData = {}, onValueC
|
|
|
5044
5038
|
});
|
|
5045
5039
|
// Notify parent if callback provided
|
|
5046
5040
|
if (onEntryAdd) {
|
|
5047
|
-
console.log('[DfFormDataGrid] calling onEntryAdd callback');
|
|
5048
5041
|
onEntryAdd();
|
|
5049
5042
|
}
|
|
5050
5043
|
}
|
|
5051
|
-
else {
|
|
5052
|
-
console.warn('[DfFormDataGrid] Cannot add entry: onValueChange is missing');
|
|
5053
|
-
}
|
|
5054
5044
|
}, [onValueChange, properties, gridId, gridComponents, onEntryAdd]);
|
|
5055
5045
|
const handleRemoveEntry = React.useCallback((entryIndex) => {
|
|
5056
5046
|
// Safety check: ensure we have entries array
|
|
@@ -5059,7 +5049,6 @@ const DfFormDataGrid = ({ id, properties, mode = 'edit', formData = {}, onValueC
|
|
|
5059
5049
|
.filter((_, index) => index !== entryIndex)
|
|
5060
5050
|
.map((entry, index) => ({ ...entry, index })); // Only update index, preserve unique ID
|
|
5061
5051
|
if (onValueChange) {
|
|
5062
|
-
console.log('[DfFormDataGrid] Removing entry at index:', entryIndex, 'New count:', updatedEntries.length);
|
|
5063
5052
|
onValueChange({
|
|
5064
5053
|
id: gridId, // Use sanitized gridId
|
|
5065
5054
|
value: { ...properties, entries: updatedEntries }
|
|
@@ -5447,8 +5436,8 @@ onComponentSelect, onComponentDelete, onComponentEdit, onComponentUpdate, select
|
|
|
5447
5436
|
const [validationErrors, setValidationErrors] = React.useState({});
|
|
5448
5437
|
const [formSubmitted, setFormSubmitted] = React.useState(false);
|
|
5449
5438
|
const [touchedFields, setTouchedFields] = React.useState({});
|
|
5450
|
-
//
|
|
5451
|
-
|
|
5439
|
+
// Component visibility state - driven by conditional logic evaluation
|
|
5440
|
+
const [componentVisibility, setComponentVisibility] = React.useState({});
|
|
5452
5441
|
// Track raised issues for threshold conditions (Set of condition IDs)
|
|
5453
5442
|
const [raisedThresholdIssues, setRaisedThresholdIssues] = React.useState(new Set());
|
|
5454
5443
|
// Track threshold action completions: Map<conditionId, { notesCompleted, attachmentsCompleted, emailSent }>
|
|
@@ -5546,6 +5535,11 @@ onComponentSelect, onComponentDelete, onComponentEdit, onComponentUpdate, select
|
|
|
5546
5535
|
if (component.children && Array.isArray(component.children)) {
|
|
5547
5536
|
initializeComponentValues(component.children, values);
|
|
5548
5537
|
}
|
|
5538
|
+
// CRITICAL for conditional logic: Also store value under the label key
|
|
5539
|
+
// so condition lookups by label (e.g. "Temperature") work during init
|
|
5540
|
+
if (component.basic?.label && componentId && values[componentId] !== undefined) {
|
|
5541
|
+
values[component.basic.label] = values[componentId];
|
|
5542
|
+
}
|
|
5549
5543
|
});
|
|
5550
5544
|
};
|
|
5551
5545
|
const initializeFormState = React.useCallback(() => {
|
|
@@ -5617,15 +5611,12 @@ onComponentSelect, onComponentDelete, onComponentEdit, onComponentUpdate, select
|
|
|
5617
5611
|
const labelPart = safeLabel ? `-${safeLabel}` : '';
|
|
5618
5612
|
validatedComponent.id = `${name}${labelPart}-${index}`;
|
|
5619
5613
|
}
|
|
5620
|
-
console.warn(`[DfFormPreview] Fixed missing/invalid ID: ${validatedComponent.id}`);
|
|
5621
5614
|
}
|
|
5622
5615
|
else {
|
|
5623
5616
|
// ID is a valid string, check for duplicates
|
|
5624
5617
|
if (seenIds.has(validatedComponent.id)) {
|
|
5625
|
-
console.error(`[DfFormPreview] Duplicate component ID detected: ${validatedComponent.id}`);
|
|
5626
5618
|
// Generate a unique ID for duplicate - using index to keep it somewhat stable
|
|
5627
5619
|
validatedComponent.id = `${validatedComponent.id}-dup-${index}`;
|
|
5628
|
-
console.warn(`[DfFormPreview] Generated new unique ID: ${validatedComponent.id}`);
|
|
5629
5620
|
}
|
|
5630
5621
|
}
|
|
5631
5622
|
seenIds.add(validatedComponent.id);
|
|
@@ -5680,7 +5671,6 @@ onComponentSelect, onComponentDelete, onComponentEdit, onComponentUpdate, select
|
|
|
5680
5671
|
validatedFormComponents = getValidatedComponents(localFormComponents);
|
|
5681
5672
|
// Synchronize local state if components were mutated (IDs added/fixed)
|
|
5682
5673
|
if (JSON.stringify(validatedFormComponents) !== JSON.stringify(localFormComponents)) {
|
|
5683
|
-
console.log('[DfFormPreview] Synchronizing local components after ID validation');
|
|
5684
5674
|
setLocalFormComponents(validatedFormComponents);
|
|
5685
5675
|
onFormDataChange?.(validatedFormComponents);
|
|
5686
5676
|
}
|
|
@@ -5733,13 +5723,229 @@ onComponentSelect, onComponentDelete, onComponentEdit, onComponentUpdate, select
|
|
|
5733
5723
|
// Initialize notes and attachments state
|
|
5734
5724
|
setComponentNotes(prev => ({ ...initialNotes, ...prev }));
|
|
5735
5725
|
setComponentAttachments(prev => ({ ...initialAttachments, ...prev }));
|
|
5736
|
-
//
|
|
5737
|
-
|
|
5726
|
+
// Evaluate conditional logic on initialization
|
|
5727
|
+
evaluateConditionalLogic(initialValues);
|
|
5738
5728
|
}, [initialFormData, localFormComponents]);
|
|
5739
|
-
//
|
|
5740
|
-
|
|
5741
|
-
|
|
5729
|
+
// ======================== CONDITIONAL LOGIC ENGINE ========================
|
|
5730
|
+
// This is a pure visibility layer. It NEVER modifies component data.
|
|
5731
|
+
// It computes a { [componentId]: boolean } map based on each component's
|
|
5732
|
+
// `logic` property and the current form values.
|
|
5733
|
+
// Helper: Flatten all components (including nested) into a flat list
|
|
5734
|
+
const flattenAllComponents = React.useCallback((components) => {
|
|
5735
|
+
const flat = [];
|
|
5736
|
+
const traverse = (items) => {
|
|
5737
|
+
if (!items || !Array.isArray(items))
|
|
5738
|
+
return;
|
|
5739
|
+
for (const item of items) {
|
|
5740
|
+
flat.push(item);
|
|
5741
|
+
if (item.children && Array.isArray(item.children))
|
|
5742
|
+
traverse(item.children);
|
|
5743
|
+
if (item.cells && Array.isArray(item.cells)) {
|
|
5744
|
+
for (const row of item.cells) {
|
|
5745
|
+
const normalizedRow = normalizeTableRow(row);
|
|
5746
|
+
for (const cell of normalizedRow) {
|
|
5747
|
+
if (cell.components)
|
|
5748
|
+
traverse(cell.components);
|
|
5749
|
+
}
|
|
5750
|
+
}
|
|
5751
|
+
}
|
|
5752
|
+
if (item.entries && Array.isArray(item.entries)) {
|
|
5753
|
+
for (const entry of item.entries) {
|
|
5754
|
+
if (entry.components)
|
|
5755
|
+
traverse(entry.components);
|
|
5756
|
+
}
|
|
5757
|
+
}
|
|
5758
|
+
if (item.templateComponents && Array.isArray(item.templateComponents)) {
|
|
5759
|
+
traverse(item.templateComponents);
|
|
5760
|
+
}
|
|
5761
|
+
}
|
|
5762
|
+
};
|
|
5763
|
+
traverse(components);
|
|
5764
|
+
return flat;
|
|
5765
|
+
}, []);
|
|
5766
|
+
// Helper: Get the value of a component referenced by a condition's `when` field.
|
|
5767
|
+
// The `when` field is typically a component LABEL (e.g. "Temperature"), not an ID.
|
|
5768
|
+
const getConditionComponentValue = React.useCallback((conditionWhen, allComponents, currentFormValues) => {
|
|
5769
|
+
// Try to find the component by label, id, or _id
|
|
5770
|
+
const comp = allComponents.find(c => c.basic?.label === conditionWhen ||
|
|
5771
|
+
ensureStringId$1(c.id) === conditionWhen ||
|
|
5772
|
+
ensureStringId$1(c._id) === conditionWhen);
|
|
5773
|
+
if (!comp)
|
|
5774
|
+
return undefined;
|
|
5775
|
+
const compId = ensureStringId$1(comp.id || comp._id);
|
|
5776
|
+
// Check formValues by ID first
|
|
5777
|
+
if (compId && currentFormValues[compId] !== undefined) {
|
|
5778
|
+
return currentFormValues[compId];
|
|
5779
|
+
}
|
|
5780
|
+
// Also check by label (main website stores values by label too)
|
|
5781
|
+
if (comp.basic?.label && currentFormValues[comp.basic.label] !== undefined) {
|
|
5782
|
+
return currentFormValues[comp.basic.label];
|
|
5783
|
+
}
|
|
5784
|
+
// Fall back to component's basic.value or defaultValue
|
|
5785
|
+
if (comp.basic?.value !== undefined && comp.basic?.value !== null && comp.basic?.value !== '') {
|
|
5786
|
+
return comp.basic.value;
|
|
5787
|
+
}
|
|
5788
|
+
if (comp.basic?.defaultValue !== undefined && comp.basic?.defaultValue !== null && comp.basic?.defaultValue !== '') {
|
|
5789
|
+
return comp.basic.defaultValue;
|
|
5790
|
+
}
|
|
5791
|
+
return undefined;
|
|
5792
|
+
}, []);
|
|
5793
|
+
// Helper: Evaluate a single condition
|
|
5794
|
+
const evaluateSingleCondition = React.useCallback((condition, componentValue) => {
|
|
5795
|
+
const { operator, value } = condition;
|
|
5796
|
+
// isEmpty / isNotEmpty
|
|
5797
|
+
if (operator === 'isEmpty') {
|
|
5798
|
+
if (componentValue == null)
|
|
5799
|
+
return true;
|
|
5800
|
+
if (typeof componentValue === 'string')
|
|
5801
|
+
return componentValue.trim() === '';
|
|
5802
|
+
if (Array.isArray(componentValue))
|
|
5803
|
+
return componentValue.length === 0;
|
|
5804
|
+
return false;
|
|
5805
|
+
}
|
|
5806
|
+
if (operator === 'isNotEmpty') {
|
|
5807
|
+
if (componentValue == null)
|
|
5808
|
+
return false;
|
|
5809
|
+
if (typeof componentValue === 'string')
|
|
5810
|
+
return componentValue.trim() !== '';
|
|
5811
|
+
if (Array.isArray(componentValue))
|
|
5812
|
+
return componentValue.length > 0;
|
|
5813
|
+
return true;
|
|
5814
|
+
}
|
|
5815
|
+
// checked / notChecked (for checkboxes)
|
|
5816
|
+
if (operator === 'checked' || operator === 'notChecked') {
|
|
5817
|
+
let isChecked = false;
|
|
5818
|
+
if (typeof componentValue === 'boolean')
|
|
5819
|
+
isChecked = componentValue;
|
|
5820
|
+
else if (typeof componentValue === 'string')
|
|
5821
|
+
isChecked = componentValue.toLowerCase() === 'true' || componentValue === '1' || componentValue.length > 0;
|
|
5822
|
+
else if (Array.isArray(componentValue))
|
|
5823
|
+
isChecked = componentValue.length > 0;
|
|
5824
|
+
else if (typeof componentValue === 'number')
|
|
5825
|
+
isChecked = componentValue > 0;
|
|
5826
|
+
return operator === 'checked' ? isChecked : !isChecked;
|
|
5827
|
+
}
|
|
5828
|
+
// equals / notEquals
|
|
5829
|
+
if (operator === 'equals' || operator === 'notEquals') {
|
|
5830
|
+
let isEqual = false;
|
|
5831
|
+
// Loose comparison
|
|
5832
|
+
if (componentValue == value)
|
|
5833
|
+
isEqual = true;
|
|
5834
|
+
// String comparison (case-insensitive, trimmed)
|
|
5835
|
+
if (!isEqual && componentValue != null && value != null) {
|
|
5836
|
+
const strA = String(componentValue).trim();
|
|
5837
|
+
const strB = String(value).trim();
|
|
5838
|
+
// Numeric comparison within strings
|
|
5839
|
+
if (strA !== '' && strB !== '' && !isNaN(Number(strA)) && !isNaN(Number(strB))) {
|
|
5840
|
+
isEqual = Number(strA) === Number(strB);
|
|
5841
|
+
}
|
|
5842
|
+
if (!isEqual) {
|
|
5843
|
+
isEqual = strA.toLowerCase() === strB.toLowerCase();
|
|
5844
|
+
}
|
|
5845
|
+
}
|
|
5846
|
+
// Array contains check (for multi-select)
|
|
5847
|
+
if (!isEqual && Array.isArray(componentValue)) {
|
|
5848
|
+
isEqual = componentValue.some(v => String(v).trim().toLowerCase() === String(value).trim().toLowerCase());
|
|
5849
|
+
}
|
|
5850
|
+
return operator === 'equals' ? isEqual : !isEqual;
|
|
5851
|
+
}
|
|
5852
|
+
// contains / notContains
|
|
5853
|
+
if (operator === 'contains' || operator === 'notContains') {
|
|
5854
|
+
let doesContain = false;
|
|
5855
|
+
if (typeof componentValue === 'string' && value != null) {
|
|
5856
|
+
doesContain = componentValue.trim().toLowerCase().includes(String(value).trim().toLowerCase());
|
|
5857
|
+
}
|
|
5858
|
+
else if (Array.isArray(componentValue) && value != null) {
|
|
5859
|
+
doesContain = componentValue.some(v => String(v).trim().toLowerCase() === String(value).trim().toLowerCase());
|
|
5860
|
+
}
|
|
5861
|
+
return operator === 'contains' ? doesContain : !doesContain;
|
|
5862
|
+
}
|
|
5863
|
+
// Numeric comparisons
|
|
5864
|
+
if (['greaterThan', 'lessThan', 'greaterThanOrEqual', 'lessThanOrEqual'].includes(operator)) {
|
|
5865
|
+
const numA = typeof componentValue === 'number' ? componentValue : parseFloat(String(componentValue));
|
|
5866
|
+
const numB = typeof value === 'number' ? value : parseFloat(String(value));
|
|
5867
|
+
if (isNaN(numA) || isNaN(numB))
|
|
5868
|
+
return false;
|
|
5869
|
+
switch (operator) {
|
|
5870
|
+
case 'greaterThan': return numA > numB;
|
|
5871
|
+
case 'lessThan': return numA < numB;
|
|
5872
|
+
case 'greaterThanOrEqual': return numA >= numB;
|
|
5873
|
+
case 'lessThanOrEqual': return numA <= numB;
|
|
5874
|
+
default: return false;
|
|
5875
|
+
}
|
|
5876
|
+
}
|
|
5877
|
+
return false;
|
|
5742
5878
|
}, []);
|
|
5879
|
+
// Main conditional logic evaluation function
|
|
5880
|
+
const evaluateConditionalLogic = React.useCallback((explicitValues) => {
|
|
5881
|
+
const currentComponents = localFormComponents;
|
|
5882
|
+
const currentValues = explicitValues || formValues;
|
|
5883
|
+
if (!currentComponents || currentComponents.length === 0)
|
|
5884
|
+
return;
|
|
5885
|
+
const allComponents = flattenAllComponents(currentComponents);
|
|
5886
|
+
const visibility = {};
|
|
5887
|
+
allComponents.forEach(component => {
|
|
5888
|
+
const compId = ensureStringId$1(component.id || component._id);
|
|
5889
|
+
if (!compId)
|
|
5890
|
+
return;
|
|
5891
|
+
// Container components are ALWAYS visible — their children handle their own logic
|
|
5892
|
+
if (['table', 'datagrid', 'section', 'heading', 'instructions'].includes(component.name)) {
|
|
5893
|
+
visibility[compId] = true;
|
|
5894
|
+
return;
|
|
5895
|
+
}
|
|
5896
|
+
// Get the logic property (API sends it as `logic`, builder uses `conditional`)
|
|
5897
|
+
const logic = component.logic || component.conditional;
|
|
5898
|
+
// No logic or action is 'always' → always show
|
|
5899
|
+
if (!logic || logic.action === 'always' || !logic.conditions || logic.conditions.length === 0) {
|
|
5900
|
+
visibility[compId] = true;
|
|
5901
|
+
return;
|
|
5902
|
+
}
|
|
5903
|
+
// Evaluate each condition
|
|
5904
|
+
const conditionResults = logic.conditions.map((condition) => {
|
|
5905
|
+
const componentValue = getConditionComponentValue(condition.when, allComponents, currentValues);
|
|
5906
|
+
return evaluateSingleCondition(condition, componentValue);
|
|
5907
|
+
});
|
|
5908
|
+
// Determine if conditions are met based on 'when' (all/any)
|
|
5909
|
+
let conditionsMet;
|
|
5910
|
+
if (logic.when === 'any') {
|
|
5911
|
+
conditionsMet = conditionResults.some((r) => r);
|
|
5912
|
+
}
|
|
5913
|
+
else {
|
|
5914
|
+
// Default to 'all'
|
|
5915
|
+
conditionsMet = conditionResults.every((r) => r);
|
|
5916
|
+
}
|
|
5917
|
+
// Apply action
|
|
5918
|
+
if (logic.action === 'show') {
|
|
5919
|
+
visibility[compId] = conditionsMet;
|
|
5920
|
+
}
|
|
5921
|
+
else if (logic.action === 'hide') {
|
|
5922
|
+
visibility[compId] = !conditionsMet;
|
|
5923
|
+
}
|
|
5924
|
+
else {
|
|
5925
|
+
visibility[compId] = true;
|
|
5926
|
+
}
|
|
5927
|
+
});
|
|
5928
|
+
// Only update state if visibility actually changed (prevent re-render loops)
|
|
5929
|
+
setComponentVisibility(prev => {
|
|
5930
|
+
const prevStr = JSON.stringify(prev);
|
|
5931
|
+
const newStr = JSON.stringify(visibility);
|
|
5932
|
+
if (prevStr === newStr)
|
|
5933
|
+
return prev;
|
|
5934
|
+
return visibility;
|
|
5935
|
+
});
|
|
5936
|
+
}, [localFormComponents, formValues, flattenAllComponents, getConditionComponentValue, evaluateSingleCondition]);
|
|
5937
|
+
// Re-evaluate conditional logic whenever form values change
|
|
5938
|
+
React.useEffect(() => {
|
|
5939
|
+
evaluateConditionalLogic();
|
|
5940
|
+
}, [formValues, evaluateConditionalLogic]);
|
|
5941
|
+
// Check if a component should be visible
|
|
5942
|
+
const shouldShowComponent = React.useCallback((componentId) => {
|
|
5943
|
+
// In preview mode (read-only submission view), always show everything
|
|
5944
|
+
if (isPreviewMode)
|
|
5945
|
+
return true;
|
|
5946
|
+
// Default to visible if not explicitly set to false
|
|
5947
|
+
return componentVisibility[componentId] !== false;
|
|
5948
|
+
}, [componentVisibility, isPreviewMode]);
|
|
5743
5949
|
// Handle form value changes and re-evaluate conditional logic
|
|
5744
5950
|
const onFormValueChange = React.useCallback((change) => {
|
|
5745
5951
|
// CRITICAL: Validate that change.id is valid and unique
|
|
@@ -5791,6 +5997,13 @@ onComponentSelect, onComponentDelete, onComponentEdit, onComponentUpdate, select
|
|
|
5791
5997
|
// Only update formValues for actual value changes, not structure updates
|
|
5792
5998
|
if (!isStructureUpdate) {
|
|
5793
5999
|
newFormValues[change.id] = change.value;
|
|
6000
|
+
// CRITICAL for conditional logic: Also store value under the component's label.
|
|
6001
|
+
// Conditions reference components by label (e.g. "Temperature"), not by ID.
|
|
6002
|
+
const allComponents = flattenAllComponents(localFormComponents);
|
|
6003
|
+
const targetComp = allComponents.find(c => ensureStringId$1(c.id || c._id) === change.id);
|
|
6004
|
+
if (targetComp?.basic?.label) {
|
|
6005
|
+
newFormValues[targetComp.basic.label] = change.value;
|
|
6006
|
+
}
|
|
5794
6007
|
setFormValues(newFormValues);
|
|
5795
6008
|
}
|
|
5796
6009
|
// Clear raised issues for this component when value changes
|
|
@@ -6531,7 +6744,6 @@ onComponentSelect, onComponentDelete, onComponentEdit, onComponentUpdate, select
|
|
|
6531
6744
|
componentCounterRef.current += 1;
|
|
6532
6745
|
cachedId = `generated-${name}-${componentCounterRef.current}-${Math.random().toString(36).substr(2, 9)}`;
|
|
6533
6746
|
componentIdCacheRef.current.set(cacheKey, cachedId);
|
|
6534
|
-
console.warn('[DfFormPreview] Generated and cached ID for component:', cachedId, 'key:', cacheKey);
|
|
6535
6747
|
}
|
|
6536
6748
|
finalComponentId = cachedId;
|
|
6537
6749
|
// Create a new component object with the cached ID (don't mutate original)
|
|
@@ -6547,9 +6759,7 @@ onComponentSelect, onComponentDelete, onComponentEdit, onComponentUpdate, select
|
|
|
6547
6759
|
if (formValue !== undefined) {
|
|
6548
6760
|
// Check if this value is being used by multiple components
|
|
6549
6761
|
const componentsWithSameValue = localFormComponents.filter(comp => comp.id !== componentId && formValues[comp.id] === formValue);
|
|
6550
|
-
if (componentsWithSameValue.length > 0)
|
|
6551
|
-
console.warn(`[DfFormPreview] Component ${componentId} shares form value with other components:`, componentsWithSameValue.map(c => c.id));
|
|
6552
|
-
}
|
|
6762
|
+
if (componentsWithSameValue.length > 0) ;
|
|
6553
6763
|
}
|
|
6554
6764
|
const commonProps = {
|
|
6555
6765
|
id: componentId, // Use the validated component ID
|
|
@@ -6762,10 +6972,8 @@ onComponentSelect, onComponentDelete, onComponentEdit, onComponentUpdate, select
|
|
|
6762
6972
|
}, onValueChange: (change) => {
|
|
6763
6973
|
const changeId = ensureStringId$1(change.id);
|
|
6764
6974
|
const componentId = ensureStringId$1(component.id);
|
|
6765
|
-
console.log(`[DfFormPreview] datagrid onValueChange - Target: ${changeId}, Component: ${componentId}`);
|
|
6766
6975
|
// Handle datagrid value changes (entries updates)
|
|
6767
6976
|
if (changeId === componentId && change.value && typeof change.value === 'object' && 'entries' in change.value) {
|
|
6768
|
-
console.log('[DfFormPreview] datagrid entries update - entries count:', change.value.entries?.length);
|
|
6769
6977
|
// Update localFormComponents with new entries structure
|
|
6770
6978
|
const updatedComponents = localFormComponents.map(comp => {
|
|
6771
6979
|
const currentCompId = ensureStringId$1(comp.id);
|
|
@@ -6808,7 +7016,6 @@ onComponentSelect, onComponentDelete, onComponentEdit, onComponentUpdate, select
|
|
|
6808
7016
|
}
|
|
6809
7017
|
});
|
|
6810
7018
|
if (valuesChanged) {
|
|
6811
|
-
console.log('[DfFormPreview] Initializing form values for new datagrid entries');
|
|
6812
7019
|
setFormValues(newValues);
|
|
6813
7020
|
}
|
|
6814
7021
|
}
|