df-ae-forms-package 1.0.98 → 1.0.99
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.css +1 -1
- package/dist/index.css.map +1 -1
- package/dist/index.d.ts +5 -16
- package/dist/index.esm.js +213 -63
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +211 -61
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -716,38 +716,27 @@ declare const DfFormSection: React.FC<DfFormSectionProps>;
|
|
|
716
716
|
interface DfFormDataGridProps {
|
|
717
717
|
id: string;
|
|
718
718
|
properties: IDataGridComponent;
|
|
719
|
-
validationErrors?: Record<string, any>;
|
|
720
|
-
formValue?: any;
|
|
721
|
-
formData?: Record<string, any>;
|
|
722
|
-
readonly?: boolean;
|
|
723
|
-
disabled?: boolean;
|
|
724
|
-
touchedFields?: Record<string, boolean>;
|
|
725
|
-
formSubmitted?: boolean;
|
|
726
719
|
mode?: 'edit' | 'preview' | 'test';
|
|
720
|
+
formData?: any;
|
|
727
721
|
onValueChange?: (change: IFormControlChange) => void;
|
|
728
|
-
onBlur?: () => void;
|
|
729
|
-
onFocus?: () => void;
|
|
730
722
|
onSelect?: () => void;
|
|
731
723
|
isSelected?: boolean;
|
|
732
724
|
className?: string;
|
|
733
|
-
onDataGridSelect?: (
|
|
734
|
-
onDataGridDelete?: (dataGridId: string) => void;
|
|
735
|
-
onEntryChange?: (entryIndex: number, components: FormComponentType[]) => void;
|
|
725
|
+
onDataGridSelect?: (component: IDataGridComponent) => void;
|
|
736
726
|
onComponentSelect?: (component: FormComponentType) => void;
|
|
737
727
|
onComponentDelete?: (component: FormComponentType, event: React.MouseEvent) => void;
|
|
738
728
|
onComponentEdit?: (component: FormComponentType) => void;
|
|
739
729
|
onComponentUpdate?: (componentId: string, updates: Partial<FormComponentType>) => void;
|
|
740
730
|
selectedComponent?: FormComponentType | null;
|
|
741
|
-
renderFormComponent?: (
|
|
742
|
-
onDataGridUpdate?: (dataGridId: string, updates: Partial<IDataGridComponent>) => void;
|
|
731
|
+
renderFormComponent?: (component: FormComponentType, hideLabel?: boolean) => React.ReactNode;
|
|
743
732
|
onEntryAdd?: () => void;
|
|
744
|
-
onEntryRemove?: (
|
|
733
|
+
onEntryRemove?: (index: number) => void;
|
|
745
734
|
formTemplateId?: string;
|
|
746
735
|
onThresholdActionCompletion?: (conditionId: string, action: 'notes' | 'attachments' | 'email', completed: boolean) => void;
|
|
747
736
|
onThresholdIssueRaised?: (conditionId: string) => void;
|
|
748
737
|
onNotesChange?: (componentId: string, notes: string) => void;
|
|
749
738
|
onAttachmentChange?: (componentId: string, attachments: File[] | null) => void;
|
|
750
|
-
shouldShowComponent?: (
|
|
739
|
+
shouldShowComponent?: (componentId: string) => boolean;
|
|
751
740
|
}
|
|
752
741
|
declare const DfFormDataGrid: React.FC<DfFormDataGridProps>;
|
|
753
742
|
|
package/dist/index.esm.js
CHANGED
|
@@ -2,8 +2,8 @@ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
|
2
2
|
import React, { useState, useEffect, useCallback, useRef, useMemo } from 'react';
|
|
3
3
|
import { AlertTriangle, X as X$1, User, Calendar, MessageSquare, UploadCloud, Paperclip, Loader2, Navigation, MapPin, Bold, Italic, List, ListOrdered, Image as Image$1, Check, Mail, AlertCircle, ChevronUp, ChevronDown, ChevronRight, Grid, GripVertical, Edit, Trash2, Table } from 'lucide-react';
|
|
4
4
|
import require$$0, { createPortal } from 'react-dom';
|
|
5
|
-
import { useDroppable } from '@dnd-kit/core';
|
|
6
|
-
import { SortableContext, horizontalListSortingStrategy, useSortable
|
|
5
|
+
import { useDroppable, useSensors, useSensor, PointerSensor, KeyboardSensor, DndContext } from '@dnd-kit/core';
|
|
6
|
+
import { sortableKeyboardCoordinates, SortableContext, verticalListSortingStrategy, horizontalListSortingStrategy, useSortable } from '@dnd-kit/sortable';
|
|
7
7
|
import { CSS } from '@dnd-kit/utilities';
|
|
8
8
|
import { v4 } from 'uuid';
|
|
9
9
|
|
|
@@ -4332,20 +4332,57 @@ const DraggableGridComponent = ({ component, selectedComponent, mode, onComponen
|
|
|
4332
4332
|
e.currentTarget.style.backgroundColor = '#ef4444';
|
|
4333
4333
|
}, children: jsx(Trash2, { size: 12 }) })] }))] }));
|
|
4334
4334
|
};
|
|
4335
|
-
|
|
4335
|
+
// Sub-component for the drop zone within the grid
|
|
4336
|
+
const GridDropZone = ({ gridComponents, mode, onComponentSelect, onComponentDelete, onComponentEdit, onComponentUpdate, selectedComponent, renderFormComponent, gridId, formData, formTemplateId, onThresholdActionCompletion, onThresholdIssueRaised, onNotesChange, onAttachmentChange, columnView, shouldShowComponent }) => {
|
|
4336
4337
|
const { setNodeRef, isOver } = useDroppable({
|
|
4337
4338
|
id: `grid-drop-zone-${gridId}`,
|
|
4338
|
-
disabled: mode !== 'edit'
|
|
4339
|
+
disabled: mode !== 'edit',
|
|
4340
|
+
data: {
|
|
4341
|
+
isGridDropZone: true,
|
|
4342
|
+
gridId: gridId
|
|
4343
|
+
}
|
|
4344
|
+
});
|
|
4345
|
+
// Sensors for drag and drop
|
|
4346
|
+
const sensors = useSensors(useSensor(PointerSensor, {
|
|
4347
|
+
activationConstraint: {
|
|
4348
|
+
distance: 8,
|
|
4349
|
+
},
|
|
4350
|
+
}), useSensor(KeyboardSensor, {
|
|
4351
|
+
coordinateGetter: sortableKeyboardCoordinates,
|
|
4352
|
+
}));
|
|
4353
|
+
const handleDragEnd = ((event) => {
|
|
4354
|
+
const { active, over } = event;
|
|
4355
|
+
if (over && active.id !== over.id) {
|
|
4356
|
+
gridComponents.findIndex((item) => item.id === active.id);
|
|
4357
|
+
gridComponents.findIndex((item) => item.id === over.id);
|
|
4358
|
+
}
|
|
4339
4359
|
});
|
|
4340
|
-
return (jsx("div", { ref: setNodeRef, className:
|
|
4341
|
-
border: isOver ? '2px dashed #3b82f6' : '
|
|
4360
|
+
return (jsx("div", { ref: setNodeRef, className: `grid-drop-zone ${gridComponents.length === 0 ? 'empty' : ''}`, style: {
|
|
4361
|
+
border: isOver ? '2px dashed #3b82f6' : '1px dashed #d1d5db',
|
|
4342
4362
|
borderRadius: '8px',
|
|
4343
4363
|
padding: '16px',
|
|
4344
|
-
backgroundColor: isOver ? 'var(--df-color-primary-light)' : '
|
|
4345
|
-
minHeight: '
|
|
4346
|
-
transition: 'all 0.2s ease'
|
|
4347
|
-
|
|
4348
|
-
|
|
4364
|
+
backgroundColor: isOver ? 'var(--df-color-primary-light)' : '#f9fafb',
|
|
4365
|
+
minHeight: '100px',
|
|
4366
|
+
transition: 'all 0.2s ease'
|
|
4367
|
+
}, children: gridComponents.length === 0 ? (jsxs("div", { style: {
|
|
4368
|
+
textAlign: 'center',
|
|
4369
|
+
color: 'var(--df-color-text-light)',
|
|
4370
|
+
fontSize: '14px',
|
|
4371
|
+
padding: '40px 20px',
|
|
4372
|
+
display: 'flex',
|
|
4373
|
+
flexDirection: 'column',
|
|
4374
|
+
alignItems: 'center',
|
|
4375
|
+
gap: '8px',
|
|
4376
|
+
backgroundColor: 'var(--df-color-fb-container)',
|
|
4377
|
+
border: '1px dashed var(--df-color-fb-border)',
|
|
4378
|
+
borderRadius: '8px'
|
|
4379
|
+
}, children: [jsx("div", { style: {
|
|
4380
|
+
fontWeight: '500',
|
|
4381
|
+
color: isOver ? 'var(--df-color-primary)' : 'var(--df-color-text-dark)'
|
|
4382
|
+
}, children: isOver ? 'Drop components here' : 'Empty DataGrid' }), jsx("div", { style: {
|
|
4383
|
+
fontSize: '12px',
|
|
4384
|
+
color: '#9ca3af'
|
|
4385
|
+
}, children: "Drag and drop components here to create your grid" })] })) : (jsxs(DndContext, { sensors: sensors, onDragEnd: handleDragEnd, children: [jsx(SortableContext, { items: gridComponents.map(c => c.id), strategy: columnView ? verticalListSortingStrategy : horizontalListSortingStrategy, children: jsx("div", { style: {
|
|
4349
4386
|
display: 'flex',
|
|
4350
4387
|
flexDirection: columnView ? 'column' : 'row',
|
|
4351
4388
|
flexWrap: 'nowrap',
|
|
@@ -4370,28 +4407,14 @@ const GridDropZone = ({ gridComponents, mode, onComponentSelect, onComponentDele
|
|
|
4370
4407
|
minHeight: '40px',
|
|
4371
4408
|
display: 'flex',
|
|
4372
4409
|
alignItems: 'center',
|
|
4373
|
-
justifyContent: 'center'
|
|
4374
|
-
|
|
4375
|
-
|
|
4376
|
-
color: 'var(--df-color-text-light)',
|
|
4377
|
-
fontSize: '14px',
|
|
4378
|
-
padding: '40px 20px',
|
|
4379
|
-
display: 'flex',
|
|
4380
|
-
flexDirection: 'column',
|
|
4381
|
-
alignItems: 'center',
|
|
4382
|
-
gap: '8px',
|
|
4383
|
-
backgroundColor: 'var(--df-color-fb-container)',
|
|
4384
|
-
border: '1px dashed var(--df-color-fb-border)',
|
|
4385
|
-
borderRadius: '8px'
|
|
4386
|
-
}, children: [jsx("div", { style: {
|
|
4387
|
-
fontWeight: '500',
|
|
4388
|
-
color: isOver ? 'var(--df-color-primary)' : 'var(--df-color-text-dark)'
|
|
4389
|
-
}, children: isOver ? 'Drop components here' : 'Empty DataGrid' }), jsx("div", { style: {
|
|
4390
|
-
fontSize: '12px',
|
|
4391
|
-
color: '#9ca3af'
|
|
4392
|
-
}, children: "Drag and drop components here to create your grid" })] })) }));
|
|
4410
|
+
justifyContent: 'center',
|
|
4411
|
+
marginTop: '12px'
|
|
4412
|
+
}, children: isOver ? (jsx("span", { style: { color: '#3b82f6', fontWeight: '500' }, children: "Drop component here to add to grid" })) : (jsx("span", { children: "+ Drop more components here" })) })] })) }));
|
|
4393
4413
|
};
|
|
4394
|
-
|
|
4414
|
+
// Sub-component for displaying entries (TableView)
|
|
4415
|
+
const TableView = ({ templateComponents, dataEntries, renderFormComponent, mode, allowAddRemoveEntries, addAnotherText, removeText, maxEntries, minEntries, displayAsGrid = true, onAddEntry, onRemoveEntry, formData, // Use current formData to render values
|
|
4416
|
+
formTemplateId, onThresholdActionCompletion, onThresholdIssueRaised, onNotesChange, onAttachmentChange, columnView, shouldShowComponent }) => {
|
|
4417
|
+
const _formData = formData || {};
|
|
4395
4418
|
const visibleTemplateComponents = React.useMemo(() => {
|
|
4396
4419
|
if (!shouldShowComponent)
|
|
4397
4420
|
return templateComponents;
|
|
@@ -4453,16 +4476,18 @@ const TableView = ({ templateComponents, dataEntries, renderFormComponent, mode
|
|
|
4453
4476
|
whiteSpace: 'nowrap',
|
|
4454
4477
|
overflow: 'hidden',
|
|
4455
4478
|
textOverflow: 'ellipsis'
|
|
4456
|
-
}, children: component.basic?.label || `Column ${index + 1}` }, `header-${component.id}`))) })), dataEntries.length > 0 ? (dataEntries.map((entry, entryIndex) => (jsxs("div", { className: "table-row", style: {
|
|
4457
|
-
|
|
4458
|
-
|
|
4459
|
-
|
|
4460
|
-
|
|
4461
|
-
|
|
4479
|
+
}, children: component.basic?.label || `Column ${index + 1}` }, `header-${component.id || index}`))) })), dataEntries.length > 0 ? (dataEntries.map((entry, entryIndex) => (jsxs("div", { className: "table-row", style: {
|
|
4480
|
+
// Use flex column for column view, grid for row view
|
|
4481
|
+
display: columnView ? 'flex' : 'grid',
|
|
4482
|
+
flexDirection: columnView ? 'column' : 'row',
|
|
4483
|
+
gridTemplateColumns: !columnView
|
|
4484
|
+
? `repeat(${visibleTemplateComponents.length}, minmax(150px, 1fr))`
|
|
4485
|
+
: undefined,
|
|
4462
4486
|
borderBottom: entryIndex < dataEntries.length - 1 ? '1px solid var(--df-color-fb-border)' : 'none',
|
|
4463
4487
|
backgroundColor: entryIndex % 2 === 0 ? 'var(--df-color-fb-container)' : 'var(--df-color-fb-bg)',
|
|
4464
4488
|
position: 'relative',
|
|
4465
|
-
minWidth: columnView ? '100%' : `${visibleTemplateComponents.length * 150}px
|
|
4489
|
+
minWidth: columnView ? '100%' : `${visibleTemplateComponents.length * 150}px`,
|
|
4490
|
+
padding: columnView ? '16px' : '0'
|
|
4466
4491
|
}, children: [visibleTemplateComponents.map((templateComponent, componentIndex) => {
|
|
4467
4492
|
let entryComponent = entry.components?.[componentIndex];
|
|
4468
4493
|
if (!entryComponent) {
|
|
@@ -4488,21 +4513,24 @@ const TableView = ({ templateComponents, dataEntries, renderFormComponent, mode
|
|
|
4488
4513
|
};
|
|
4489
4514
|
}
|
|
4490
4515
|
return (jsx("div", { style: {
|
|
4491
|
-
padding: '12px 16px',
|
|
4516
|
+
padding: columnView ? '12px 0' : '12px 16px',
|
|
4492
4517
|
borderRight: !columnView && componentIndex < visibleTemplateComponents.length - 1 ? '1px solid var(--df-color-fb-border)' : 'none',
|
|
4493
4518
|
// Add bottom border for fields in column view except the last one
|
|
4494
4519
|
borderBottom: columnView && componentIndex < visibleTemplateComponents.length - 1 ? '1px dashed var(--df-color-fb-border)' : 'none',
|
|
4495
|
-
minHeight: '60px',
|
|
4520
|
+
minHeight: columnView ? 'auto' : '60px',
|
|
4496
4521
|
minWidth: columnView ? '100%' : '150px',
|
|
4522
|
+
width: columnView ? '100%' : 'auto',
|
|
4497
4523
|
display: 'flex',
|
|
4498
|
-
|
|
4499
|
-
|
|
4524
|
+
flexDirection: columnView ? 'column' : 'row',
|
|
4525
|
+
alignItems: columnView ? 'stretch' : 'center',
|
|
4526
|
+
overflow: 'hidden',
|
|
4527
|
+
gap: columnView ? '8px' : '0'
|
|
4500
4528
|
}, children: jsx("div", { style: {
|
|
4501
4529
|
width: '100%',
|
|
4502
|
-
minWidth: '120px',
|
|
4530
|
+
minWidth: columnView ? '100%' : '120px',
|
|
4503
4531
|
overflow: 'hidden'
|
|
4504
4532
|
}, children: renderFormComponent(entryComponent, !columnView) }) }, `${entry.id}-${componentIndex}`));
|
|
4505
|
-
}), mode === 'test' && allowAddRemoveEntries && dataEntries.length > minEntries && (jsx("button", { onClick: () => onRemoveEntry
|
|
4533
|
+
}), mode === 'test' && allowAddRemoveEntries && dataEntries.length > minEntries && (jsx("button", { onClick: () => onRemoveEntry(entryIndex), disabled: dataEntries.length <= minEntries, style: {
|
|
4506
4534
|
position: 'absolute',
|
|
4507
4535
|
top: '8px',
|
|
4508
4536
|
right: '8px',
|
|
@@ -4536,7 +4564,7 @@ const TableView = ({ templateComponents, dataEntries, renderFormComponent, mode
|
|
|
4536
4564
|
position: 'sticky',
|
|
4537
4565
|
bottom: 0,
|
|
4538
4566
|
zIndex: 5
|
|
4539
|
-
}, children: jsxs("button", { onClick: onAddEntry, disabled: dataEntries.length >= maxEntries, style: {
|
|
4567
|
+
}, children: jsxs("button", { onClick: () => { console.log('[TableView] Add Entry button clicked (grid view)', 'entries:', dataEntries.length, 'max:', maxEntries); onAddEntry(); }, disabled: dataEntries.length >= maxEntries, style: {
|
|
4540
4568
|
padding: '8px 16px',
|
|
4541
4569
|
backgroundColor: dataEntries.length >= maxEntries ? '#f3f4f6' : '#10b981',
|
|
4542
4570
|
color: dataEntries.length >= maxEntries ? '#9ca3af' : '#ffffff',
|
|
@@ -4574,7 +4602,7 @@ const TableView = ({ templateComponents, dataEntries, renderFormComponent, mode
|
|
|
4574
4602
|
fontWeight: '600',
|
|
4575
4603
|
color: 'var(--df-color-text-dark)',
|
|
4576
4604
|
fontSize: '14px'
|
|
4577
|
-
}, children: ["Entry #", entryIndex + 1] }), mode === 'test' && allowAddRemoveEntries && dataEntries.length > 1 && (jsx("button", { onClick: () => onRemoveEntry
|
|
4605
|
+
}, children: ["Entry #", entryIndex + 1] }), mode === 'test' && allowAddRemoveEntries && dataEntries.length > 1 && (jsx("button", { onClick: () => onRemoveEntry(entryIndex), disabled: dataEntries.length <= minEntries, style: {
|
|
4578
4606
|
padding: '4px 8px',
|
|
4579
4607
|
backgroundColor: dataEntries.length <= minEntries ? '#f3f4f6' : '#ef4444',
|
|
4580
4608
|
color: dataEntries.length <= minEntries ? '#9ca3af' : '#ffffff',
|
|
@@ -4590,40 +4618,39 @@ const TableView = ({ templateComponents, dataEntries, renderFormComponent, mode
|
|
|
4590
4618
|
height: '24px',
|
|
4591
4619
|
justifyContent: 'center'
|
|
4592
4620
|
}, title: removeText, children: jsx("span", { style: { fontSize: '14px' }, children: "\u00D7" }) }))] }), jsx("div", { style: {
|
|
4593
|
-
display: 'grid',
|
|
4594
|
-
|
|
4621
|
+
display: columnView ? 'flex' : 'grid',
|
|
4622
|
+
flexDirection: columnView ? 'column' : 'row',
|
|
4623
|
+
gridTemplateColumns: !columnView ? 'repeat(auto-fit, minmax(200px, 1fr))' : undefined,
|
|
4595
4624
|
gap: '16px'
|
|
4596
4625
|
}, children: visibleTemplateComponents.map((templateComponent, componentIndex) => {
|
|
4597
|
-
// Find the corresponding component in this entry by index first, then by name+label
|
|
4598
4626
|
let entryComponent = entry.components?.[componentIndex];
|
|
4599
|
-
// If no component at this index, try to find by name+label
|
|
4600
4627
|
if (!entryComponent) {
|
|
4601
4628
|
entryComponent = entry.components?.find((comp) => comp.name === templateComponent.name &&
|
|
4602
4629
|
comp.basic?.label === templateComponent.basic?.label);
|
|
4603
4630
|
}
|
|
4604
4631
|
if (!entryComponent) {
|
|
4605
|
-
// Use entry.id (which is unique) instead of entryIndex
|
|
4606
4632
|
const uniqueId = `${templateComponent.id}-${entry.id}-${componentIndex}`;
|
|
4607
4633
|
entryComponent = {
|
|
4608
4634
|
...templateComponent,
|
|
4609
4635
|
id: uniqueId,
|
|
4610
4636
|
basic: {
|
|
4611
4637
|
...templateComponent.basic,
|
|
4612
|
-
showLabel:
|
|
4638
|
+
showLabel: columnView // Show label in column view, hide in grid view
|
|
4613
4639
|
}
|
|
4614
4640
|
};
|
|
4615
4641
|
}
|
|
4616
4642
|
else {
|
|
4617
|
-
// Preserve the original ID to maintain form value connections
|
|
4618
4643
|
entryComponent = {
|
|
4619
4644
|
...entryComponent,
|
|
4620
|
-
id: entryComponent.id,
|
|
4645
|
+
id: entryComponent.id,
|
|
4621
4646
|
basic: {
|
|
4622
4647
|
...entryComponent.basic,
|
|
4623
|
-
showLabel:
|
|
4648
|
+
showLabel: columnView // Show label in column view, hide in grid view
|
|
4624
4649
|
}
|
|
4625
4650
|
};
|
|
4626
4651
|
}
|
|
4652
|
+
if (!entryComponent)
|
|
4653
|
+
return null;
|
|
4627
4654
|
return (jsxs("div", { style: {
|
|
4628
4655
|
display: 'flex',
|
|
4629
4656
|
flexDirection: 'column',
|
|
@@ -4659,7 +4686,7 @@ const TableView = ({ templateComponents, dataEntries, renderFormComponent, mode
|
|
|
4659
4686
|
borderRadius: '8px',
|
|
4660
4687
|
display: 'flex',
|
|
4661
4688
|
justifyContent: 'center'
|
|
4662
|
-
}, children: jsxs("button", { onClick: onAddEntry, disabled: dataEntries.length >= maxEntries, style: {
|
|
4689
|
+
}, children: jsxs("button", { onClick: () => { console.log('[TableView] Add Entry button clicked (list view)', 'entries:', dataEntries.length, 'max:', maxEntries); onAddEntry(); }, disabled: dataEntries.length >= maxEntries, style: {
|
|
4663
4690
|
padding: '8px 16px',
|
|
4664
4691
|
backgroundColor: dataEntries.length >= maxEntries ? '#f3f4f6' : '#10b981',
|
|
4665
4692
|
color: dataEntries.length >= maxEntries ? '#9ca3af' : '#ffffff',
|
|
@@ -4672,6 +4699,12 @@ const TableView = ({ templateComponents, dataEntries, renderFormComponent, mode
|
|
|
4672
4699
|
alignItems: 'center',
|
|
4673
4700
|
gap: '8px',
|
|
4674
4701
|
transition: 'all 0.2s ease'
|
|
4702
|
+
}, onMouseEnter: (e) => {
|
|
4703
|
+
if (dataEntries.length < maxEntries) {
|
|
4704
|
+
e.currentTarget.style.backgroundColor = '#059669';
|
|
4705
|
+
}
|
|
4706
|
+
}, onMouseLeave: (e) => {
|
|
4707
|
+
e.currentTarget.style.backgroundColor = '#10b981';
|
|
4675
4708
|
}, children: [jsx("span", { children: "+" }), addAnotherText] }) }))] }));
|
|
4676
4709
|
};
|
|
4677
4710
|
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 }) => {
|
|
@@ -4903,6 +4936,10 @@ const DfFormDataGrid = ({ id, properties, mode = 'edit', formData = {}, onValueC
|
|
|
4903
4936
|
// In edit/preview modes, don't handle value changes as components are read-only
|
|
4904
4937
|
}, [mode, onValueChange]);
|
|
4905
4938
|
const handleAddEntry = useCallback(() => {
|
|
4939
|
+
console.log('[DfFormDataGrid] handleAddEntry called');
|
|
4940
|
+
console.log('[DfFormDataGrid] gridComponents:', gridComponents.length, gridComponents.map(c => c.id));
|
|
4941
|
+
console.log('[DfFormDataGrid] current entries:', properties.entries?.length);
|
|
4942
|
+
console.log('[DfFormDataGrid] onValueChange exists:', !!onValueChange);
|
|
4906
4943
|
// Use timestamp and random string to ensure uniqueness even if entries are deleted
|
|
4907
4944
|
const uniqueSuffix = `${Date.now()}-${Math.random().toString(36).substr(2, 5)}`;
|
|
4908
4945
|
const newEntryId = `entry-${uniqueSuffix}`;
|
|
@@ -4924,13 +4961,19 @@ const DfFormDataGrid = ({ id, properties, mode = 'edit', formData = {}, onValueC
|
|
|
4924
4961
|
}),
|
|
4925
4962
|
styles: {}
|
|
4926
4963
|
};
|
|
4964
|
+
console.log('[DfFormDataGrid] newEntry created:', newEntry.id, 'with', newEntry.components.length, 'components');
|
|
4927
4965
|
const updatedEntries = [...properties.entries, newEntry];
|
|
4966
|
+
console.log('[DfFormDataGrid] updatedEntries count:', updatedEntries.length);
|
|
4928
4967
|
if (onValueChange) {
|
|
4968
|
+
console.log('[DfFormDataGrid] calling onValueChange with updated entries');
|
|
4929
4969
|
onValueChange({
|
|
4930
4970
|
id,
|
|
4931
4971
|
value: { ...properties, entries: updatedEntries }
|
|
4932
4972
|
});
|
|
4933
4973
|
}
|
|
4974
|
+
else {
|
|
4975
|
+
console.log('[DfFormDataGrid] WARNING: onValueChange is not defined!');
|
|
4976
|
+
}
|
|
4934
4977
|
onEntryAdd?.();
|
|
4935
4978
|
}, [properties, onValueChange, id, onEntryAdd, gridComponents]);
|
|
4936
4979
|
const handleRemoveEntry = useCallback((entryIndex) => {
|
|
@@ -5027,7 +5070,7 @@ const DfFormDataGrid = ({ id, properties, mode = 'edit', formData = {}, onValueC
|
|
|
5027
5070
|
, {
|
|
5028
5071
|
// Cast to FormComponentType[] to satisfy TableView typing; gridComponents
|
|
5029
5072
|
// are always child form components of the datagrid.
|
|
5030
|
-
templateComponents: gridComponents, dataEntries: dataEntries, renderFormComponent: renderFormComponent || renderComponent, mode: mode, allowAddRemoveEntries: properties.datagrid?.allowAddRemoveEntries ?? true, addAnotherText: properties.datagrid?.addAnotherText ?? 'Add Entry', removeText: properties.datagrid?.removeText ?? 'Remove', maxEntries: properties.datagrid?.maxEntries ?? 10, minEntries: properties.datagrid?.minEntries ?? 1, displayAsGrid: properties.datagrid?.displayAsGrid ?? true, onAddEntry:
|
|
5073
|
+
templateComponents: gridComponents, dataEntries: dataEntries, renderFormComponent: renderFormComponent || renderComponent, mode: mode, allowAddRemoveEntries: properties.datagrid?.allowAddRemoveEntries ?? true, addAnotherText: properties.datagrid?.addAnotherText ?? 'Add Entry', removeText: properties.datagrid?.removeText ?? 'Remove', maxEntries: properties.datagrid?.maxEntries ?? 10, minEntries: properties.datagrid?.minEntries ?? 1, displayAsGrid: properties.datagrid?.displayAsGrid ?? true, onAddEntry: handleAddEntry, onRemoveEntry: handleRemoveEntry, formData: formData, formTemplateId: formTemplateId, onThresholdActionCompletion: onThresholdActionCompletion, onThresholdIssueRaised: onThresholdIssueRaised, onNotesChange: onNotesChange, onAttachmentChange: onAttachmentChange, columnView: properties.datagrid?.columnView, shouldShowComponent: shouldShowComponent })) }))] }));
|
|
5031
5074
|
};
|
|
5032
5075
|
|
|
5033
5076
|
const DraggableChild = ({ child, selectedChild, mode, onChildSelect, onChildDelete, renderFormComponent, isOverlay = false, isChildrenEditMode = false, formData = {}, formTemplateId, onThresholdActionCompletion, onThresholdIssueRaised, onNotesChange, onAttachmentChange, workOrderNumber, assetNumber, user, onCreateIssue, onUpdateIssue }) => {
|
|
@@ -6450,12 +6493,9 @@ onComponentSelect, onComponentDelete, onComponentEdit, onComponentUpdate, select
|
|
|
6450
6493
|
onFormDataChange?.(updatedComponents);
|
|
6451
6494
|
} }) }));
|
|
6452
6495
|
case 'datagrid':
|
|
6453
|
-
// Align package datagrid wiring with main app behaviour:
|
|
6454
|
-
// - Let DfFormDataGrid manage entry structure via onValueChange
|
|
6455
|
-
// - Use the shared onFormValueChange handler for nested field values
|
|
6456
|
-
// - Keep notes/attachments wiring as before
|
|
6457
6496
|
return (jsx(DfFormDataGrid, { ...commonProps, properties: component, formData: formValues, formTemplateId: formTemplateId, mode: commonProps.mode, onThresholdActionCompletion: handleThresholdActionCompletion, onThresholdIssueRaised: handleThresholdIssueRaised, onNotesChange: (componentId, notes) => {
|
|
6458
6497
|
handleComponentNotesChange(componentId, notes);
|
|
6498
|
+
// Handle notes change for datagrid entry components
|
|
6459
6499
|
const updatedComponents = localFormComponents.map(comp => {
|
|
6460
6500
|
if (comp.id === component.id && comp.entries) {
|
|
6461
6501
|
const updatedEntries = comp.entries.map((entry) => {
|
|
@@ -6483,6 +6523,7 @@ onComponentSelect, onComponentDelete, onComponentEdit, onComponentUpdate, select
|
|
|
6483
6523
|
onFormDataChange?.(updatedComponents);
|
|
6484
6524
|
}, onAttachmentChange: (componentId, attachments) => {
|
|
6485
6525
|
handleComponentAttachmentChange(componentId, attachments);
|
|
6526
|
+
// Handle attachment change for datagrid entry components
|
|
6486
6527
|
const updatedComponents = localFormComponents.map(comp => {
|
|
6487
6528
|
if (comp.id === component.id && comp.entries) {
|
|
6488
6529
|
const updatedEntries = comp.entries.map((entry) => {
|
|
@@ -6508,7 +6549,116 @@ onComponentSelect, onComponentDelete, onComponentEdit, onComponentUpdate, select
|
|
|
6508
6549
|
return comp;
|
|
6509
6550
|
});
|
|
6510
6551
|
onFormDataChange?.(updatedComponents);
|
|
6511
|
-
}, onValueChange:
|
|
6552
|
+
}, onValueChange: (change) => {
|
|
6553
|
+
console.log('[DfFormPreview] datagrid onValueChange received:', change.id, 'hasEntries:', change.value && typeof change.value === 'object' && 'entries' in change.value);
|
|
6554
|
+
// Handle datagrid value changes (entries updates)
|
|
6555
|
+
if (change.id === component.id && change.value && typeof change.value === 'object' && 'entries' in change.value) {
|
|
6556
|
+
console.log('[DfFormPreview] datagrid entries update - entries count:', change.value.entries?.length);
|
|
6557
|
+
// Update localFormComponents with new entries structure
|
|
6558
|
+
const updatedComponents = localFormComponents.map(comp => {
|
|
6559
|
+
if (comp.id === component.id) {
|
|
6560
|
+
return {
|
|
6561
|
+
...comp,
|
|
6562
|
+
...change.value
|
|
6563
|
+
};
|
|
6564
|
+
}
|
|
6565
|
+
return comp;
|
|
6566
|
+
});
|
|
6567
|
+
// CRITICAL: Update local state immediately so new entries render without Angular round-trip
|
|
6568
|
+
setLocalFormComponents(updatedComponents);
|
|
6569
|
+
onFormDataChange?.(updatedComponents);
|
|
6570
|
+
// Also update formValues for nested components
|
|
6571
|
+
if (change.value.entries && Array.isArray(change.value.entries)) {
|
|
6572
|
+
change.value.entries.forEach((entry) => {
|
|
6573
|
+
if (entry.components && Array.isArray(entry.components)) {
|
|
6574
|
+
entry.components.forEach((nestedComp) => {
|
|
6575
|
+
const nestedValue = formValues[nestedComp.id];
|
|
6576
|
+
if (nestedValue !== undefined) ;
|
|
6577
|
+
else {
|
|
6578
|
+
// Initialize with defaultValue if available
|
|
6579
|
+
const defaultValue = nestedComp.basic?.defaultValue;
|
|
6580
|
+
if (defaultValue !== undefined) {
|
|
6581
|
+
setFormValues(prev => ({
|
|
6582
|
+
...prev,
|
|
6583
|
+
[nestedComp.id]: defaultValue
|
|
6584
|
+
}));
|
|
6585
|
+
}
|
|
6586
|
+
}
|
|
6587
|
+
});
|
|
6588
|
+
}
|
|
6589
|
+
});
|
|
6590
|
+
}
|
|
6591
|
+
}
|
|
6592
|
+
else {
|
|
6593
|
+
// For nested component value changes, use the regular handler
|
|
6594
|
+
onFormValueChange(change);
|
|
6595
|
+
}
|
|
6596
|
+
}, onEntryAdd: () => {
|
|
6597
|
+
// CRITICAL: Entry has already been added via onValueChange in DfFormDataGrid
|
|
6598
|
+
// Get the updated component from localFormComponents (which should have been updated by onValueChange)
|
|
6599
|
+
const currentComponent = localFormComponents.find(comp => comp.id === component.id);
|
|
6600
|
+
if (currentComponent && currentComponent.entries) {
|
|
6601
|
+
// Entry should already be in the component via onValueChange
|
|
6602
|
+
// Just ensure localFormComponents is in sync (no-op if already synced)
|
|
6603
|
+
const updatedComponents = localFormComponents.map(comp => {
|
|
6604
|
+
if (comp.id === component.id) {
|
|
6605
|
+
// Ensure entries are properly structured
|
|
6606
|
+
return {
|
|
6607
|
+
...comp,
|
|
6608
|
+
entries: comp.entries || []
|
|
6609
|
+
};
|
|
6610
|
+
}
|
|
6611
|
+
return comp;
|
|
6612
|
+
});
|
|
6613
|
+
onFormDataChange?.(updatedComponents);
|
|
6614
|
+
}
|
|
6615
|
+
else {
|
|
6616
|
+
// Fallback: If component doesn't have entries yet, try to get from formValues
|
|
6617
|
+
setTimeout(() => {
|
|
6618
|
+
const datagridValue = formValues[component.id];
|
|
6619
|
+
if (datagridValue && typeof datagridValue === 'object' && 'entries' in datagridValue) {
|
|
6620
|
+
const updatedComponents = localFormComponents.map(comp => {
|
|
6621
|
+
if (comp.id === component.id) {
|
|
6622
|
+
return {
|
|
6623
|
+
...comp,
|
|
6624
|
+
entries: datagridValue.entries
|
|
6625
|
+
};
|
|
6626
|
+
}
|
|
6627
|
+
return comp;
|
|
6628
|
+
});
|
|
6629
|
+
onFormDataChange?.(updatedComponents);
|
|
6630
|
+
}
|
|
6631
|
+
}, 100);
|
|
6632
|
+
}
|
|
6633
|
+
}, onEntryRemove: (entryIndex) => {
|
|
6634
|
+
// Handle entry remove - update form components
|
|
6635
|
+
const updatedComponents = localFormComponents.map(comp => {
|
|
6636
|
+
if (comp.id === component.id && comp.entries) {
|
|
6637
|
+
const currentEntries = comp.entries || [];
|
|
6638
|
+
const updatedEntries = currentEntries
|
|
6639
|
+
.filter((_, index) => index !== entryIndex)
|
|
6640
|
+
.map((entry, index) => ({
|
|
6641
|
+
...entry,
|
|
6642
|
+
index,
|
|
6643
|
+
id: `entry-${comp.id}-${index}`,
|
|
6644
|
+
components: entry.components?.map((comp, compIndex) => {
|
|
6645
|
+
const templateComp = (comp.templateComponents || [])[compIndex];
|
|
6646
|
+
return {
|
|
6647
|
+
...comp,
|
|
6648
|
+
id: templateComp ? `${templateComp.id}-entry-${index}-${compIndex}` : comp.id
|
|
6649
|
+
};
|
|
6650
|
+
}) || []
|
|
6651
|
+
}));
|
|
6652
|
+
return {
|
|
6653
|
+
...comp,
|
|
6654
|
+
entries: updatedEntries
|
|
6655
|
+
};
|
|
6656
|
+
}
|
|
6657
|
+
return comp;
|
|
6658
|
+
});
|
|
6659
|
+
onFormDataChange?.(updatedComponents);
|
|
6660
|
+
}, renderFormComponent: (field) => {
|
|
6661
|
+
// Ensure the nested component gets the proper form value
|
|
6512
6662
|
return renderFormComponent(field);
|
|
6513
6663
|
} }));
|
|
6514
6664
|
case 'file':
|