@visns-studio/visns-components 5.14.14 → 5.14.15
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/package.json +1 -1
- package/src/components/DataGrid.jsx +166 -7
- package/src/components/Form.jsx +86 -43
package/package.json
CHANGED
|
@@ -89,7 +89,7 @@
|
|
|
89
89
|
"react-dom": "^17.0.0 || ^18.0.0"
|
|
90
90
|
},
|
|
91
91
|
"name": "@visns-studio/visns-components",
|
|
92
|
-
"version": "5.14.
|
|
92
|
+
"version": "5.14.15",
|
|
93
93
|
"description": "Various packages to assist in the development of our Custom Applications.",
|
|
94
94
|
"main": "src/index.js",
|
|
95
95
|
"files": [
|
|
@@ -24,6 +24,7 @@ import React, {
|
|
|
24
24
|
useCallback,
|
|
25
25
|
useEffect,
|
|
26
26
|
useImperativeHandle,
|
|
27
|
+
useMemo,
|
|
27
28
|
useRef,
|
|
28
29
|
useState,
|
|
29
30
|
} from 'react';
|
|
@@ -250,6 +251,28 @@ const DataGrid = forwardRef(
|
|
|
250
251
|
) => {
|
|
251
252
|
const navigate = useNavigate();
|
|
252
253
|
|
|
254
|
+
/**
|
|
255
|
+
* DEBUG: Settings Configuration Tracking
|
|
256
|
+
* Monitor changes to settings prop to identify config update issues
|
|
257
|
+
*/
|
|
258
|
+
useEffect(() => {
|
|
259
|
+
console.log('🔍 DataGrid settings prop changed:', {
|
|
260
|
+
settings: settings,
|
|
261
|
+
settingsLength: settings?.length || 0,
|
|
262
|
+
hasUpdateSetting: settings?.some(s => s.id === 'update') || false,
|
|
263
|
+
settingsIds: settings?.map(s => s.id) || [],
|
|
264
|
+
timestamp: new Date().toISOString()
|
|
265
|
+
});
|
|
266
|
+
}, [settings]);
|
|
267
|
+
|
|
268
|
+
useEffect(() => {
|
|
269
|
+
console.log('🔍 DataGrid form prop changed:', {
|
|
270
|
+
form: form,
|
|
271
|
+
primaryKey: form?.primaryKey,
|
|
272
|
+
timestamp: new Date().toISOString()
|
|
273
|
+
});
|
|
274
|
+
}, [form]);
|
|
275
|
+
|
|
253
276
|
/** Audio */
|
|
254
277
|
const [audioSource, setAudioSource] = useState('');
|
|
255
278
|
|
|
@@ -285,6 +308,11 @@ const DataGrid = forwardRef(
|
|
|
285
308
|
|
|
286
309
|
/** Modal Functions */
|
|
287
310
|
const modalOpen = (formType, formId) => {
|
|
311
|
+
console.log('🔍 modalOpen called:', {
|
|
312
|
+
formType: formType,
|
|
313
|
+
formId: formId,
|
|
314
|
+
timestamp: new Date().toISOString()
|
|
315
|
+
});
|
|
288
316
|
setModalShow(true);
|
|
289
317
|
setFormType(formType);
|
|
290
318
|
setFormId(formId);
|
|
@@ -303,6 +331,25 @@ const DataGrid = forwardRef(
|
|
|
303
331
|
/** Table States */
|
|
304
332
|
const dataRef = useRef(null);
|
|
305
333
|
const [dSearch, setDSearch] = useState('');
|
|
334
|
+
|
|
335
|
+
/** Optimized refs for settings and form to avoid unnecessary re-renders */
|
|
336
|
+
const settingsRef = useRef(settings);
|
|
337
|
+
const formRef = useRef(form);
|
|
338
|
+
|
|
339
|
+
// Keep refs updated with current values
|
|
340
|
+
useEffect(() => {
|
|
341
|
+
settingsRef.current = settings;
|
|
342
|
+
}, [settings]);
|
|
343
|
+
|
|
344
|
+
useEffect(() => {
|
|
345
|
+
formRef.current = form;
|
|
346
|
+
}, [form]);
|
|
347
|
+
|
|
348
|
+
// Memoize settings to avoid unnecessary re-renders when array reference changes but content is same
|
|
349
|
+
const memoizedSettings = useMemo(() => settings, [
|
|
350
|
+
settings?.length,
|
|
351
|
+
settings?.map(s => `${s.id}-${s.roles?.join(',') || ''}-${s.active}`).join('|')
|
|
352
|
+
]);
|
|
306
353
|
|
|
307
354
|
/** Group expansion state */
|
|
308
355
|
const [collapsedGroups, setCollapsedGroups] = useState({});
|
|
@@ -1463,13 +1510,46 @@ const DataGrid = forwardRef(
|
|
|
1463
1510
|
}
|
|
1464
1511
|
};
|
|
1465
1512
|
|
|
1513
|
+
/**
|
|
1514
|
+
* DEBUG: Row Click Analysis
|
|
1515
|
+
*
|
|
1516
|
+
* When row clicks aren't working, check the console for these debug messages:
|
|
1517
|
+
*
|
|
1518
|
+
* 1. "Row onClick triggered" - Initial row click detection
|
|
1519
|
+
* 2. "Group row check" - Whether it's a group row (should be false for data rows)
|
|
1520
|
+
* 3. "Cell element in row handler" - Cell element detection
|
|
1521
|
+
* 4. "Row handler column analysis" - Column identification
|
|
1522
|
+
* 5. "Non-checkbox column - calling onRowClick" - Normal row click path
|
|
1523
|
+
* 6. "DataGrid onRowClick triggered" - Main onRowClick function entry
|
|
1524
|
+
* 7. "Column analysis" - Column detection and type checking
|
|
1525
|
+
* 8. "Checking for update setting" - Modal opening prerequisites
|
|
1526
|
+
* 9. "Update setting found" - Whether update setting exists
|
|
1527
|
+
* 10. "Opening modal with" / "No update setting found" - Final modal decision
|
|
1528
|
+
* 11. "modalOpen called" - Modal function execution
|
|
1529
|
+
*
|
|
1530
|
+
* Common issues:
|
|
1531
|
+
* - Missing cell element: Check if click target is within grid
|
|
1532
|
+
* - Wrong column type: Check column configuration
|
|
1533
|
+
* - No update setting: Check config.settings for update permission
|
|
1534
|
+
* - Group row interference: Check if data is being treated as group row
|
|
1535
|
+
*/
|
|
1466
1536
|
const onRowClick = useCallback((rowProps, event) => {
|
|
1537
|
+
console.log('🔍 DataGrid onRowClick triggered:', {
|
|
1538
|
+
rowData: rowProps.data,
|
|
1539
|
+
event: event,
|
|
1540
|
+
target: event.target,
|
|
1541
|
+
timestamp: new Date().toISOString()
|
|
1542
|
+
});
|
|
1543
|
+
|
|
1467
1544
|
const cellElement = event.target.closest(
|
|
1468
1545
|
'.InovuaReactDataGrid__cell'
|
|
1469
1546
|
);
|
|
1470
1547
|
|
|
1548
|
+
console.log('🔍 Cell element found:', cellElement);
|
|
1549
|
+
|
|
1471
1550
|
// Add null check to prevent errors when cellElement is null
|
|
1472
1551
|
if (!cellElement) {
|
|
1552
|
+
console.warn('⚠️ No cell element found - row click aborted');
|
|
1473
1553
|
return; // Exit early if no cell element was found
|
|
1474
1554
|
}
|
|
1475
1555
|
|
|
@@ -1477,13 +1557,26 @@ const DataGrid = forwardRef(
|
|
|
1477
1557
|
cellElement.parentNode.children
|
|
1478
1558
|
).indexOf(cellElement);
|
|
1479
1559
|
|
|
1560
|
+
console.log('🔍 Column analysis:', {
|
|
1561
|
+
columnIndex: columnIndex,
|
|
1562
|
+
totalColumns: rowProps.columns.length,
|
|
1563
|
+
isLastColumn: columnIndex === rowProps.columns.length - 1,
|
|
1564
|
+
columns: rowProps.columns.map(col => ({ id: col.id, type: col.type }))
|
|
1565
|
+
});
|
|
1566
|
+
|
|
1480
1567
|
if (
|
|
1481
1568
|
rowProps.columns.length > 1 &&
|
|
1482
1569
|
columnIndex === rowProps.columns.length - 1
|
|
1483
1570
|
) {
|
|
1571
|
+
console.log('🔍 Last column clicked - no action');
|
|
1484
1572
|
// Handle last column click
|
|
1485
1573
|
} else {
|
|
1486
1574
|
const column = rowProps.columns[columnIndex];
|
|
1575
|
+
console.log('🔍 Column clicked:', {
|
|
1576
|
+
columnId: column?.id,
|
|
1577
|
+
columnType: column?.type,
|
|
1578
|
+
hasLink: !!column?.link
|
|
1579
|
+
});
|
|
1487
1580
|
|
|
1488
1581
|
if (
|
|
1489
1582
|
column.type !== 'dropdown' &&
|
|
@@ -1554,21 +1647,36 @@ const DataGrid = forwardRef(
|
|
|
1554
1647
|
'width=1440,height=1024,menubar=1,resizable=1,status=1,titlebar=1,toolbar=1'
|
|
1555
1648
|
);
|
|
1556
1649
|
} else {
|
|
1557
|
-
|
|
1650
|
+
console.log('🔍 Checking for update setting:', {
|
|
1651
|
+
settings: settingsRef.current,
|
|
1652
|
+
form: formRef.current,
|
|
1653
|
+
primaryKey: formRef.current?.primaryKey,
|
|
1654
|
+
rowId: rowProps.data[formRef.current?.primaryKey]
|
|
1655
|
+
});
|
|
1656
|
+
|
|
1657
|
+
const updateSetting = settingsRef.current.find(
|
|
1558
1658
|
(setting) => setting.id === 'update'
|
|
1559
1659
|
);
|
|
1560
1660
|
|
|
1661
|
+
console.log('🔍 Update setting found:', updateSetting);
|
|
1662
|
+
|
|
1561
1663
|
if (updateSetting) {
|
|
1664
|
+
console.log('✅ Opening modal with:', {
|
|
1665
|
+
type: 'update',
|
|
1666
|
+
id: rowProps.data[formRef.current.primaryKey]
|
|
1667
|
+
});
|
|
1562
1668
|
modalOpen(
|
|
1563
1669
|
'update',
|
|
1564
|
-
rowProps.data[
|
|
1670
|
+
rowProps.data[formRef.current.primaryKey]
|
|
1565
1671
|
);
|
|
1672
|
+
} else {
|
|
1673
|
+
console.warn('⚠️ No update setting found - modal will not open');
|
|
1566
1674
|
}
|
|
1567
1675
|
}
|
|
1568
1676
|
}
|
|
1569
1677
|
}
|
|
1570
1678
|
}
|
|
1571
|
-
}, []);
|
|
1679
|
+
}, [modalOpen, navigate]);
|
|
1572
1680
|
|
|
1573
1681
|
const onRenderRow = useCallback(
|
|
1574
1682
|
(rowProps) => {
|
|
@@ -1576,6 +1684,14 @@ const DataGrid = forwardRef(
|
|
|
1576
1684
|
const { onClick } = rowProps;
|
|
1577
1685
|
|
|
1578
1686
|
rowProps.onClick = (event) => {
|
|
1687
|
+
console.log('🔍 Row onClick triggered:', {
|
|
1688
|
+
rowId: rowProps.data?.id,
|
|
1689
|
+
rowData: rowProps.data,
|
|
1690
|
+
event: event,
|
|
1691
|
+
target: event.target,
|
|
1692
|
+
timestamp: new Date().toISOString()
|
|
1693
|
+
});
|
|
1694
|
+
|
|
1579
1695
|
// Check if this is a group row - group rows should only handle expand/collapse, not onRowClick
|
|
1580
1696
|
const isGroupRow =
|
|
1581
1697
|
rowProps.isGroupRow ||
|
|
@@ -1587,7 +1703,10 @@ const DataGrid = forwardRef(
|
|
|
1587
1703
|
'.InovuaReactDataGrid__group-cell'
|
|
1588
1704
|
);
|
|
1589
1705
|
|
|
1706
|
+
console.log('🔍 Group row check:', isGroupRow);
|
|
1707
|
+
|
|
1590
1708
|
if (isGroupRow) {
|
|
1709
|
+
console.log('🔍 Group row detected - calling original onClick only');
|
|
1591
1710
|
// For group rows, only allow the original onClick handler (for expand/collapse)
|
|
1592
1711
|
// Do NOT call onRowClick as it should only apply to data rows
|
|
1593
1712
|
if (onClick) {
|
|
@@ -1600,8 +1719,11 @@ const DataGrid = forwardRef(
|
|
|
1600
1719
|
'.InovuaReactDataGrid__cell'
|
|
1601
1720
|
);
|
|
1602
1721
|
|
|
1722
|
+
console.log('🔍 Cell element in row handler:', cellElement);
|
|
1723
|
+
|
|
1603
1724
|
// Add null check to prevent errors when cellElement is null
|
|
1604
1725
|
if (!cellElement) {
|
|
1726
|
+
console.warn('⚠️ No cell element found in row handler - exiting');
|
|
1605
1727
|
return; // Exit early if no cell element was found
|
|
1606
1728
|
}
|
|
1607
1729
|
|
|
@@ -1611,7 +1733,14 @@ const DataGrid = forwardRef(
|
|
|
1611
1733
|
|
|
1612
1734
|
const column = rowProps.columns[columnIndex];
|
|
1613
1735
|
|
|
1736
|
+
console.log('🔍 Row handler column analysis:', {
|
|
1737
|
+
columnIndex: columnIndex,
|
|
1738
|
+
columnId: column?.id,
|
|
1739
|
+
isCheckboxColumn: column?.id === '__checkbox-column'
|
|
1740
|
+
});
|
|
1741
|
+
|
|
1614
1742
|
if (column.id === '__checkbox-column') {
|
|
1743
|
+
console.log('🔍 Checkbox column clicked - handling checkbox logic');
|
|
1615
1744
|
// For checkbox column clicks, we need to handle them specially
|
|
1616
1745
|
// to ensure consistent behavior whether clicking checkbox or cell area
|
|
1617
1746
|
|
|
@@ -1657,10 +1786,12 @@ const DataGrid = forwardRef(
|
|
|
1657
1786
|
onClick(event);
|
|
1658
1787
|
}
|
|
1659
1788
|
} else {
|
|
1789
|
+
console.log('🔍 Non-checkbox column - calling onRowClick');
|
|
1660
1790
|
// For non-checkbox columns, handle normal row clicks
|
|
1661
1791
|
// But do NOT trigger checkbox selection
|
|
1662
1792
|
onRowClick(rowProps, event);
|
|
1663
1793
|
|
|
1794
|
+
console.log('🔍 Calling original onClick handler:', !!onClick);
|
|
1664
1795
|
// Call the original onClick handler
|
|
1665
1796
|
if (onClick) {
|
|
1666
1797
|
onClick(event);
|
|
@@ -1942,6 +2073,14 @@ const DataGrid = forwardRef(
|
|
|
1942
2073
|
}, [search, setDSearch]);
|
|
1943
2074
|
|
|
1944
2075
|
const renderSetting = (s, d) => {
|
|
2076
|
+
console.log('🔍 renderSetting called for:', {
|
|
2077
|
+
settingId: s.id,
|
|
2078
|
+
settingRoles: s.roles,
|
|
2079
|
+
userRoles: userProfile?.roles?.map(r => r.name),
|
|
2080
|
+
settingActive: s.active,
|
|
2081
|
+
rowData: d?.id || 'unknown'
|
|
2082
|
+
});
|
|
2083
|
+
|
|
1945
2084
|
let iconStyle = {};
|
|
1946
2085
|
let allow = true;
|
|
1947
2086
|
|
|
@@ -1955,6 +2094,11 @@ const DataGrid = forwardRef(
|
|
|
1955
2094
|
);
|
|
1956
2095
|
|
|
1957
2096
|
if (!hasRequiredRole) {
|
|
2097
|
+
console.log('🔍 Setting filtered out by role permissions:', {
|
|
2098
|
+
settingId: s.id,
|
|
2099
|
+
requiredRoles: s.roles,
|
|
2100
|
+
userRoles: userProfile?.roles?.map(r => r.name)
|
|
2101
|
+
});
|
|
1958
2102
|
allow = false;
|
|
1959
2103
|
}
|
|
1960
2104
|
}
|
|
@@ -2231,10 +2375,21 @@ const DataGrid = forwardRef(
|
|
|
2231
2375
|
}
|
|
2232
2376
|
|
|
2233
2377
|
if (!tmpCheckValue) {
|
|
2378
|
+
console.log('🔍 Setting filtered out by active condition:', {
|
|
2379
|
+
settingId: s.id,
|
|
2380
|
+
activeCondition: s.active,
|
|
2381
|
+
rowData: d?.id || 'unknown'
|
|
2382
|
+
});
|
|
2234
2383
|
allow = false;
|
|
2235
2384
|
}
|
|
2236
2385
|
}
|
|
2237
2386
|
|
|
2387
|
+
console.log('🔍 renderSetting final decision:', {
|
|
2388
|
+
settingId: s.id,
|
|
2389
|
+
allowed: allow,
|
|
2390
|
+
willRender: allow ? 'YES' : 'NO'
|
|
2391
|
+
});
|
|
2392
|
+
|
|
2238
2393
|
if (allow) {
|
|
2239
2394
|
switch (s.id) {
|
|
2240
2395
|
case 'activate':
|
|
@@ -2283,6 +2438,10 @@ const DataGrid = forwardRef(
|
|
|
2283
2438
|
return null;
|
|
2284
2439
|
}
|
|
2285
2440
|
} else {
|
|
2441
|
+
console.log('🔍 Setting NOT rendered (allow=false):', {
|
|
2442
|
+
settingId: s.id,
|
|
2443
|
+
reason: 'filtered out by permissions or active conditions'
|
|
2444
|
+
});
|
|
2286
2445
|
return null;
|
|
2287
2446
|
}
|
|
2288
2447
|
|
|
@@ -2874,10 +3033,10 @@ const DataGrid = forwardRef(
|
|
|
2874
3033
|
|
|
2875
3034
|
// Function to check if any settings would be visible for any row
|
|
2876
3035
|
const hasVisibleSettings = () => {
|
|
2877
|
-
if (
|
|
3036
|
+
if (memoizedSettings.length === 0) return false;
|
|
2878
3037
|
|
|
2879
3038
|
// Check if any setting would be visible based on role permissions
|
|
2880
|
-
return
|
|
3039
|
+
return memoizedSettings.some(setting => {
|
|
2881
3040
|
// Check role-based permissions
|
|
2882
3041
|
if (setting.roles && Array.isArray(setting.roles) && setting.roles.length > 0) {
|
|
2883
3042
|
const hasRequiredRole = setting.roles.some(requiredRole =>
|
|
@@ -2903,7 +3062,7 @@ const DataGrid = forwardRef(
|
|
|
2903
3062
|
render: ({ data }) => {
|
|
2904
3063
|
return (
|
|
2905
3064
|
<div className={styles.tdactions}>
|
|
2906
|
-
{
|
|
3065
|
+
{memoizedSettings.map((setting) =>
|
|
2907
3066
|
renderSetting(setting, data)
|
|
2908
3067
|
)}
|
|
2909
3068
|
</div>
|
|
@@ -2986,7 +3145,7 @@ const DataGrid = forwardRef(
|
|
|
2986
3145
|
.catch((error) => {
|
|
2987
3146
|
console.error('Error in fetching dropdown data: ', error);
|
|
2988
3147
|
});
|
|
2989
|
-
}, [columns, filterDataSource]);
|
|
3148
|
+
}, [columns, filterDataSource, memoizedSettings]);
|
|
2990
3149
|
|
|
2991
3150
|
useEffect(() => {
|
|
2992
3151
|
if (setFilterData) {
|
package/src/components/Form.jsx
CHANGED
|
@@ -125,45 +125,49 @@ function Form({
|
|
|
125
125
|
|
|
126
126
|
if (e.target.files && e.target.files.length > 0) {
|
|
127
127
|
// Find the field settings to check if multiple is enabled
|
|
128
|
-
const fieldSettings = formSettings?.fields?.find(
|
|
128
|
+
const fieldSettings = formSettings?.fields?.find(
|
|
129
|
+
(field) => field.id === id
|
|
130
|
+
);
|
|
129
131
|
const isMultiple = fieldSettings?.multiple === true;
|
|
130
|
-
|
|
132
|
+
|
|
131
133
|
// Debug logging for development
|
|
132
134
|
if (process.env.NODE_ENV === 'development') {
|
|
133
135
|
console.log('File input change:', {
|
|
134
136
|
id,
|
|
135
137
|
filesCount: e.target.files.length,
|
|
136
138
|
isMultiple,
|
|
137
|
-
fieldSettings
|
|
139
|
+
fieldSettings,
|
|
138
140
|
});
|
|
139
141
|
}
|
|
140
|
-
|
|
142
|
+
|
|
141
143
|
if (isMultiple) {
|
|
142
144
|
// For multiple file inputs, append new files to existing ones
|
|
143
145
|
setFormData((prevState) => {
|
|
144
146
|
const existingFiles = prevState[id] || [];
|
|
145
147
|
const newFiles = Array.from(e.target.files);
|
|
146
|
-
|
|
148
|
+
|
|
147
149
|
// Ensure existingFiles is always an array for multiple inputs
|
|
148
|
-
const currentFiles = Array.isArray(existingFiles)
|
|
149
|
-
|
|
150
|
+
const currentFiles = Array.isArray(existingFiles)
|
|
151
|
+
? existingFiles
|
|
152
|
+
: [];
|
|
153
|
+
|
|
150
154
|
const updatedFiles = [...currentFiles, ...newFiles];
|
|
151
|
-
|
|
155
|
+
|
|
152
156
|
// Debug logging for development
|
|
153
157
|
if (process.env.NODE_ENV === 'development') {
|
|
154
158
|
console.log('Multiple file update:', {
|
|
155
159
|
existingCount: currentFiles.length,
|
|
156
160
|
newCount: newFiles.length,
|
|
157
|
-
totalCount: updatedFiles.length
|
|
161
|
+
totalCount: updatedFiles.length,
|
|
158
162
|
});
|
|
159
163
|
}
|
|
160
|
-
|
|
164
|
+
|
|
161
165
|
return {
|
|
162
166
|
...prevState,
|
|
163
167
|
[id]: updatedFiles,
|
|
164
168
|
};
|
|
165
169
|
});
|
|
166
|
-
|
|
170
|
+
|
|
167
171
|
// Clear the input so the same files can be selected again
|
|
168
172
|
setTimeout(() => {
|
|
169
173
|
if (e.target) {
|
|
@@ -495,7 +499,7 @@ function Form({
|
|
|
495
499
|
const handleFileDownload = async (fileData) => {
|
|
496
500
|
try {
|
|
497
501
|
console.info('File download data:', fileData);
|
|
498
|
-
|
|
502
|
+
|
|
499
503
|
if (!fileData) {
|
|
500
504
|
toast.error('No file data available for download');
|
|
501
505
|
return;
|
|
@@ -503,7 +507,11 @@ function Form({
|
|
|
503
507
|
|
|
504
508
|
// Handle different file data structures
|
|
505
509
|
let downloadUrl = null;
|
|
506
|
-
let fileName =
|
|
510
|
+
let fileName =
|
|
511
|
+
fileData.filename ||
|
|
512
|
+
fileData.name ||
|
|
513
|
+
fileData.file_name ||
|
|
514
|
+
'download';
|
|
507
515
|
|
|
508
516
|
// Priority order for download methods:
|
|
509
517
|
// 1. Direct file URL (S3, CDN, etc.)
|
|
@@ -518,7 +526,9 @@ function Form({
|
|
|
518
526
|
downloadUrl = filePath;
|
|
519
527
|
} else {
|
|
520
528
|
// Construct URL - adjust this based on your API structure
|
|
521
|
-
downloadUrl = `/api/files/download?path=${encodeURIComponent(
|
|
529
|
+
downloadUrl = `/api/files/download?path=${encodeURIComponent(
|
|
530
|
+
filePath
|
|
531
|
+
)}`;
|
|
522
532
|
}
|
|
523
533
|
}
|
|
524
534
|
// 3. Legacy key/uuid method
|
|
@@ -529,7 +539,7 @@ function Form({
|
|
|
529
539
|
else if (fileData.id) {
|
|
530
540
|
downloadUrl = `/api/files/download/${fileData.id}`;
|
|
531
541
|
}
|
|
532
|
-
|
|
542
|
+
|
|
533
543
|
if (!downloadUrl) {
|
|
534
544
|
toast.error('Unable to determine download URL for this file');
|
|
535
545
|
return;
|
|
@@ -540,14 +550,13 @@ function Form({
|
|
|
540
550
|
link.href = downloadUrl;
|
|
541
551
|
link.download = fileName;
|
|
542
552
|
link.target = '_blank';
|
|
543
|
-
|
|
553
|
+
|
|
544
554
|
// Add to DOM, click, and remove
|
|
545
555
|
document.body.appendChild(link);
|
|
546
556
|
link.click();
|
|
547
557
|
document.body.removeChild(link);
|
|
548
|
-
|
|
558
|
+
|
|
549
559
|
toast.success(`Downloading ${fileName}...`);
|
|
550
|
-
|
|
551
560
|
} catch (error) {
|
|
552
561
|
console.error('File download error:', error);
|
|
553
562
|
toast.error('Failed to download file');
|
|
@@ -925,11 +934,19 @@ function Form({
|
|
|
925
934
|
|
|
926
935
|
// Check if formData[item.id] is null, undefined, or an empty string AND there's no auto value
|
|
927
936
|
// Note: 0 is considered a valid value for dropdowns/options
|
|
928
|
-
if (
|
|
937
|
+
if (
|
|
938
|
+
(formData[item.id] === null ||
|
|
939
|
+
formData[item.id] === undefined ||
|
|
940
|
+
formData[item.id] === '') &&
|
|
941
|
+
!autoValue
|
|
942
|
+
) {
|
|
929
943
|
// Check for required_check dependency
|
|
930
944
|
if (
|
|
931
945
|
item.required_check &&
|
|
932
|
-
(formData[item.required_check] === null ||
|
|
946
|
+
(formData[item.required_check] === null ||
|
|
947
|
+
formData[item.required_check] ===
|
|
948
|
+
undefined ||
|
|
949
|
+
formData[item.required_check] === '')
|
|
933
950
|
) {
|
|
934
951
|
validation += `${item.label} is a required field.<br/>`;
|
|
935
952
|
_inputClass[item.id] = styles.inputError;
|
|
@@ -943,7 +960,9 @@ function Form({
|
|
|
943
960
|
} else if (
|
|
944
961
|
item.required_rely &&
|
|
945
962
|
formData[item.required_rely] &&
|
|
946
|
-
(formData[item.id] === null ||
|
|
963
|
+
(formData[item.id] === null ||
|
|
964
|
+
formData[item.id] === undefined ||
|
|
965
|
+
formData[item.id] === '')
|
|
947
966
|
) {
|
|
948
967
|
// Check if the dependent required field is empty when it should be filled
|
|
949
968
|
validation += `${item.label} is a required field.<br/>`;
|
|
@@ -994,9 +1013,13 @@ function Form({
|
|
|
994
1013
|
method = formSettings.customMethod;
|
|
995
1014
|
} else {
|
|
996
1015
|
// Check if this is bulk edit mode
|
|
997
|
-
if (
|
|
1016
|
+
if (
|
|
1017
|
+
bulkEditMode &&
|
|
1018
|
+
bulkEditGroupData?.iconConfig?.formModal
|
|
1019
|
+
) {
|
|
998
1020
|
// Use bulk edit endpoint configuration
|
|
999
|
-
const formModalConfig =
|
|
1021
|
+
const formModalConfig =
|
|
1022
|
+
bulkEditGroupData.iconConfig.formModal;
|
|
1000
1023
|
url = formModalConfig.url || url;
|
|
1001
1024
|
method = formModalConfig.method || 'POST';
|
|
1002
1025
|
} else {
|
|
@@ -1020,7 +1043,9 @@ function Form({
|
|
|
1020
1043
|
}`;
|
|
1021
1044
|
} else {
|
|
1022
1045
|
url += `/${
|
|
1023
|
-
formData[
|
|
1046
|
+
formData[
|
|
1047
|
+
formSettings.primaryKey
|
|
1048
|
+
]
|
|
1024
1049
|
}`;
|
|
1025
1050
|
}
|
|
1026
1051
|
method =
|
|
@@ -1179,9 +1204,11 @@ function Form({
|
|
|
1179
1204
|
...payload,
|
|
1180
1205
|
bulkEdit: true,
|
|
1181
1206
|
groupValue: bulkEditGroupData.groupValue,
|
|
1182
|
-
groupKey:
|
|
1207
|
+
groupKey:
|
|
1208
|
+
bulkEditGroupData.iconConfig.formModal
|
|
1209
|
+
?.groupKey || ajaxSetting?.groupBy?.[0],
|
|
1183
1210
|
rowIds: bulkEditGroupData.groupRowIds,
|
|
1184
|
-
...bulkEditGroupData.iconConfig.formModal?.data
|
|
1211
|
+
...bulkEditGroupData.iconConfig.formModal?.data,
|
|
1185
1212
|
};
|
|
1186
1213
|
}
|
|
1187
1214
|
|
|
@@ -1237,7 +1264,8 @@ function Form({
|
|
|
1237
1264
|
if (resSaveAnother.data.error === '') {
|
|
1238
1265
|
toast.success(saveAnother.message);
|
|
1239
1266
|
if (fetchTable) {
|
|
1240
|
-
const createdItem =
|
|
1267
|
+
const createdItem =
|
|
1268
|
+
res.data.data || res.data;
|
|
1241
1269
|
fetchTable(createdItem);
|
|
1242
1270
|
}
|
|
1243
1271
|
}
|
|
@@ -1846,28 +1874,36 @@ function Form({
|
|
|
1846
1874
|
/>
|
|
1847
1875
|
</div>
|
|
1848
1876
|
{tableData?.dataSource?.length > 0 && (
|
|
1849
|
-
<div
|
|
1877
|
+
<div
|
|
1850
1878
|
className={`${styles.formItem} ${styles.fwItem}`}
|
|
1851
1879
|
style={{
|
|
1852
|
-
width: formSettings?.save?.return?.width
|
|
1853
|
-
? `min(${parseInt(
|
|
1880
|
+
width: formSettings?.save?.return?.width
|
|
1881
|
+
? `min(${parseInt(
|
|
1882
|
+
formSettings.save.return.width
|
|
1883
|
+
)}px, 100vw - 40px)`
|
|
1854
1884
|
: '100%',
|
|
1855
|
-
maxWidth: formSettings?.save?.return?.width
|
|
1856
|
-
? `${parseInt(
|
|
1885
|
+
maxWidth: formSettings?.save?.return?.width
|
|
1886
|
+
? `${parseInt(
|
|
1887
|
+
formSettings.save.return.width
|
|
1888
|
+
)}px`
|
|
1857
1889
|
: '100%',
|
|
1858
1890
|
overflow: 'auto',
|
|
1859
|
-
margin: formSettings?.save?.return?.width
|
|
1891
|
+
margin: formSettings?.save?.return?.width
|
|
1892
|
+
? '0 auto'
|
|
1893
|
+
: undefined,
|
|
1860
1894
|
}}
|
|
1861
1895
|
>
|
|
1862
1896
|
<ReactDataGrid
|
|
1863
1897
|
idProperty="form-table-result"
|
|
1864
1898
|
columns={tableData.columns}
|
|
1865
1899
|
dataSource={tableData.dataSource}
|
|
1866
|
-
style={{
|
|
1900
|
+
style={{
|
|
1867
1901
|
minHeight: 550,
|
|
1868
|
-
width: formSettings?.save?.return?.width
|
|
1869
|
-
? `${parseInt(
|
|
1870
|
-
|
|
1902
|
+
width: formSettings?.save?.return?.width
|
|
1903
|
+
? `${parseInt(
|
|
1904
|
+
formSettings.save.return.width
|
|
1905
|
+
)}px`
|
|
1906
|
+
: '100%',
|
|
1871
1907
|
}}
|
|
1872
1908
|
showActiveRowIndicator={false}
|
|
1873
1909
|
selected={selected}
|
|
@@ -2361,9 +2397,13 @@ function Form({
|
|
|
2361
2397
|
<div className={styles.modal__header}>
|
|
2362
2398
|
<h1>
|
|
2363
2399
|
{bulkEditMode && bulkEditGroupData
|
|
2364
|
-
? `${
|
|
2365
|
-
|
|
2366
|
-
|
|
2400
|
+
? `${
|
|
2401
|
+
bulkEditGroupData.iconConfig.formModal
|
|
2402
|
+
?.title || 'Bulk Edit'
|
|
2403
|
+
} - ${bulkEditGroupData.groupValue} (${
|
|
2404
|
+
bulkEditGroupData.groupRows.length
|
|
2405
|
+
} items)`
|
|
2406
|
+
: formSettings[formType]?.title}
|
|
2367
2407
|
</h1>
|
|
2368
2408
|
<button
|
|
2369
2409
|
className={styles.modal__close}
|
|
@@ -2398,9 +2438,12 @@ function Form({
|
|
|
2398
2438
|
}
|
|
2399
2439
|
// In bulk edit mode, only show fields specified in the formModal configuration
|
|
2400
2440
|
if (
|
|
2401
|
-
bulkEditMode &&
|
|
2402
|
-
bulkEditGroupData?.iconConfig?.formModal
|
|
2403
|
-
|
|
2441
|
+
bulkEditMode &&
|
|
2442
|
+
bulkEditGroupData?.iconConfig?.formModal
|
|
2443
|
+
?.fields &&
|
|
2444
|
+
!bulkEditGroupData.iconConfig.formModal.fields.includes(
|
|
2445
|
+
item.id
|
|
2446
|
+
)
|
|
2404
2447
|
) {
|
|
2405
2448
|
return null;
|
|
2406
2449
|
}
|