@visns-studio/visns-components 5.3.6 → 5.3.8
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
CHANGED
|
@@ -54,8 +54,8 @@
|
|
|
54
54
|
"swapy": "^1.0.5",
|
|
55
55
|
"truncate": "^3.0.0",
|
|
56
56
|
"uuid": "^10.0.0",
|
|
57
|
-
"validator": "^13.
|
|
58
|
-
"vite": "^5.4.
|
|
57
|
+
"validator": "^13.15.0",
|
|
58
|
+
"vite": "^5.4.15",
|
|
59
59
|
"yarn": "^1.22.22"
|
|
60
60
|
},
|
|
61
61
|
"devDependencies": {
|
|
@@ -78,7 +78,7 @@
|
|
|
78
78
|
"react-dom": "^17.0.0 || ^18.0.0"
|
|
79
79
|
},
|
|
80
80
|
"name": "@visns-studio/visns-components",
|
|
81
|
-
"version": "5.3.
|
|
81
|
+
"version": "5.3.8",
|
|
82
82
|
"description": "Various packages to assist in the development of our Custom Applications.",
|
|
83
83
|
"main": "src/index.js",
|
|
84
84
|
"files": [
|
|
@@ -2,6 +2,7 @@ import React from 'react';
|
|
|
2
2
|
import { Link } from 'react-router-dom';
|
|
3
3
|
import dayjs from 'dayjs';
|
|
4
4
|
import { CircleChevronRight } from 'akar-icons';
|
|
5
|
+
import parse from 'html-react-parser';
|
|
5
6
|
|
|
6
7
|
function Breadcrumb({ data, page }) {
|
|
7
8
|
// Function to get nested data, handling array of keys
|
|
@@ -33,7 +34,7 @@ function Breadcrumb({ data, page }) {
|
|
|
33
34
|
<h1>
|
|
34
35
|
{page?.parentTitle && page?.parentUrl && (
|
|
35
36
|
<>
|
|
36
|
-
<Link to={page.parentUrl}>{page.parentTitle}</Link>
|
|
37
|
+
<Link to={page.parentUrl}>{parse(page.parentTitle)}</Link>
|
|
37
38
|
<CircleChevronRight strokeWidth={2} size={18} />
|
|
38
39
|
</>
|
|
39
40
|
)}
|
|
@@ -46,7 +47,7 @@ function Breadcrumb({ data, page }) {
|
|
|
46
47
|
page.parentUrlKey
|
|
47
48
|
)}`}
|
|
48
49
|
>
|
|
49
|
-
{nestedData}
|
|
50
|
+
{parse(nestedData)}
|
|
50
51
|
</Link>
|
|
51
52
|
<CircleChevronRight strokeWidth={2} size={18} />
|
|
52
53
|
</>
|
|
@@ -61,7 +62,7 @@ function Breadcrumb({ data, page }) {
|
|
|
61
62
|
: ''
|
|
62
63
|
}`}
|
|
63
64
|
>
|
|
64
|
-
{page.title}
|
|
65
|
+
{parse(page.title)}
|
|
65
66
|
</Link>
|
|
66
67
|
<CircleChevronRight strokeWidth={2} size={18} />
|
|
67
68
|
</>
|
|
@@ -72,10 +73,12 @@ function Breadcrumb({ data, page }) {
|
|
|
72
73
|
<>
|
|
73
74
|
{Array.isArray(page.titleKey) ? (
|
|
74
75
|
<>
|
|
75
|
-
{page.titleText &&
|
|
76
|
+
{page.titleText && (
|
|
77
|
+
<span>{parse(page.titleText)} </span>
|
|
78
|
+
)}
|
|
76
79
|
{page.titleKey.map((key, index) => (
|
|
77
80
|
<span key={index}>
|
|
78
|
-
{data[key]}
|
|
81
|
+
{parse(String(data[key] || ''))}
|
|
79
82
|
{index < page.titleKey.length - 1 && ' '}
|
|
80
83
|
</span>
|
|
81
84
|
))}
|
|
@@ -89,7 +92,12 @@ function Breadcrumb({ data, page }) {
|
|
|
89
92
|
? page.titleFormat
|
|
90
93
|
: 'DD/MM/YYYY'
|
|
91
94
|
)
|
|
92
|
-
:
|
|
95
|
+
: parse(
|
|
96
|
+
String(
|
|
97
|
+
getTitleData(data, page.titleKey) ||
|
|
98
|
+
''
|
|
99
|
+
)
|
|
100
|
+
)}
|
|
93
101
|
</>
|
|
94
102
|
)}
|
|
95
103
|
</>
|
|
@@ -224,6 +224,13 @@ const DataGrid = forwardRef(
|
|
|
224
224
|
const [limit, setLimit] = useState(0);
|
|
225
225
|
const [search, setSearch] = useState('');
|
|
226
226
|
const [selected, setSelected] = useState({});
|
|
227
|
+
const [inputDebounceTimers] = useState({});
|
|
228
|
+
const [localInputValues, setLocalInputValues] = useState({});
|
|
229
|
+
const localInputValuesRef = useRef({}); // Add this ref to track values
|
|
230
|
+
|
|
231
|
+
useEffect(() => {
|
|
232
|
+
localInputValuesRef.current = localInputValues;
|
|
233
|
+
}, [localInputValues]);
|
|
227
234
|
|
|
228
235
|
/** Table Functions */
|
|
229
236
|
useImperativeHandle(ref, () => ({
|
|
@@ -235,6 +242,27 @@ const DataGrid = forwardRef(
|
|
|
235
242
|
},
|
|
236
243
|
}));
|
|
237
244
|
|
|
245
|
+
const getRowStyle = useCallback(
|
|
246
|
+
(rowProps) => {
|
|
247
|
+
const { data } = rowProps;
|
|
248
|
+
|
|
249
|
+
if (ajaxSetting?.rowColours?.length > 0) {
|
|
250
|
+
const colorConfig = ajaxSetting.rowColours.find(
|
|
251
|
+
(config) => data[config.id] === config.value
|
|
252
|
+
);
|
|
253
|
+
|
|
254
|
+
if (colorConfig) {
|
|
255
|
+
return {
|
|
256
|
+
backgroundColor: colorConfig.colour,
|
|
257
|
+
};
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
return null;
|
|
262
|
+
},
|
|
263
|
+
[ajaxSetting]
|
|
264
|
+
);
|
|
265
|
+
|
|
238
266
|
const handleDownload = async (d) => {
|
|
239
267
|
const toastId = toast.loading('Starting download please wait...');
|
|
240
268
|
|
|
@@ -448,9 +476,42 @@ const DataGrid = forwardRef(
|
|
|
448
476
|
return 0;
|
|
449
477
|
};
|
|
450
478
|
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
479
|
+
const getDeletedNestedValue = (obj, path) => {
|
|
480
|
+
const value = path
|
|
481
|
+
.split('.')
|
|
482
|
+
.reduce(
|
|
483
|
+
(acc, part) =>
|
|
484
|
+
acc && acc[part] !== undefined
|
|
485
|
+
? acc[part]
|
|
486
|
+
: undefined,
|
|
487
|
+
obj
|
|
488
|
+
);
|
|
489
|
+
|
|
490
|
+
// Format date if the path contains 'date'
|
|
491
|
+
if (value && path.toLowerCase().includes('date')) {
|
|
492
|
+
const momentDate = moment(value);
|
|
493
|
+
if (
|
|
494
|
+
momentDate.isValid() &&
|
|
495
|
+
momentDate.format('YYYY-MM-DD') !== '1970-01-01'
|
|
496
|
+
) {
|
|
497
|
+
return momentDate.format('DD-MM-YYYY');
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
return value;
|
|
501
|
+
};
|
|
502
|
+
|
|
503
|
+
let confirmMessage = '';
|
|
504
|
+
if (s.labelKey && Array.isArray(s.labelKey)) {
|
|
505
|
+
const values = s.labelKey
|
|
506
|
+
.map((key) => {
|
|
507
|
+
const value = getDeletedNestedValue(d, key);
|
|
508
|
+
return value;
|
|
509
|
+
})
|
|
510
|
+
.filter((val) => val)
|
|
511
|
+
.join(' - ');
|
|
512
|
+
confirmMessage = `Are you sure you want to delete "${values}"?`;
|
|
513
|
+
} else {
|
|
514
|
+
confirmMessage =
|
|
454
515
|
s.description && s.description !== ''
|
|
455
516
|
? s.description
|
|
456
517
|
: `Are you sure you want to delete ${
|
|
@@ -459,7 +520,12 @@ const DataGrid = forwardRef(
|
|
|
459
520
|
: d.label
|
|
460
521
|
? d.label
|
|
461
522
|
: 'this item'
|
|
462
|
-
}
|
|
523
|
+
}?`;
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
confirmAlert({
|
|
527
|
+
title: 'Delete Item',
|
|
528
|
+
message: confirmMessage,
|
|
463
529
|
buttons: [
|
|
464
530
|
{
|
|
465
531
|
label: 'Yes',
|
|
@@ -671,7 +737,10 @@ const DataGrid = forwardRef(
|
|
|
671
737
|
} else {
|
|
672
738
|
const column = rowProps.columns[columnIndex];
|
|
673
739
|
|
|
674
|
-
if (
|
|
740
|
+
if (
|
|
741
|
+
column.type !== 'dropdown' &&
|
|
742
|
+
column.type !== 'input_text'
|
|
743
|
+
) {
|
|
675
744
|
if (column.id !== '__checkbox-column') {
|
|
676
745
|
if (column.link && column.link.hasOwnProperty('url')) {
|
|
677
746
|
if (column.link.url) {
|
|
@@ -1223,6 +1292,27 @@ const DataGrid = forwardRef(
|
|
|
1223
1292
|
}
|
|
1224
1293
|
};
|
|
1225
1294
|
|
|
1295
|
+
const handleInputUpdate = debounce(
|
|
1296
|
+
(key, url, method, value, inputKey) => {
|
|
1297
|
+
CustomFetch(url, method, { [key]: value }, (res) => {
|
|
1298
|
+
if (res.error === '') {
|
|
1299
|
+
localInputValuesRef.current = {
|
|
1300
|
+
...localInputValuesRef.current,
|
|
1301
|
+
[inputKey]: value,
|
|
1302
|
+
};
|
|
1303
|
+
|
|
1304
|
+
setLocalInputValues((prev) => ({
|
|
1305
|
+
...prev,
|
|
1306
|
+
[inputKey]: value,
|
|
1307
|
+
}));
|
|
1308
|
+
} else {
|
|
1309
|
+
toast.error(res.error);
|
|
1310
|
+
}
|
|
1311
|
+
});
|
|
1312
|
+
},
|
|
1313
|
+
500
|
|
1314
|
+
);
|
|
1315
|
+
|
|
1226
1316
|
const getDropdownData = async (ids, url, fields) => {
|
|
1227
1317
|
// Concatenate id array into a single string if it's an array
|
|
1228
1318
|
const uniqueId = Array.isArray(ids) ? ids.join('') : ids;
|
|
@@ -2409,6 +2499,80 @@ const DataGrid = forwardRef(
|
|
|
2409
2499
|
}
|
|
2410
2500
|
},
|
|
2411
2501
|
};
|
|
2502
|
+
case 'input_text':
|
|
2503
|
+
return {
|
|
2504
|
+
...commonProps,
|
|
2505
|
+
name: column.id,
|
|
2506
|
+
render: ({ data }) => {
|
|
2507
|
+
const inputKey = `${data.id}-${column.id}`;
|
|
2508
|
+
|
|
2509
|
+
// Use the ref value first, then fall back to data value
|
|
2510
|
+
const currentValue =
|
|
2511
|
+
localInputValuesRef.current[
|
|
2512
|
+
inputKey
|
|
2513
|
+
] !== undefined
|
|
2514
|
+
? localInputValuesRef.current[
|
|
2515
|
+
inputKey
|
|
2516
|
+
]
|
|
2517
|
+
: data[column.id] || '';
|
|
2518
|
+
|
|
2519
|
+
return (
|
|
2520
|
+
<input
|
|
2521
|
+
type="text"
|
|
2522
|
+
name={column.id}
|
|
2523
|
+
value={currentValue}
|
|
2524
|
+
style={{
|
|
2525
|
+
padding: '7px',
|
|
2526
|
+
width: '100%',
|
|
2527
|
+
}}
|
|
2528
|
+
onChange={(e) => {
|
|
2529
|
+
const newValue =
|
|
2530
|
+
e.target.value;
|
|
2531
|
+
|
|
2532
|
+
// Update both state and ref
|
|
2533
|
+
localInputValuesRef.current =
|
|
2534
|
+
{
|
|
2535
|
+
...localInputValuesRef.current,
|
|
2536
|
+
[inputKey]:
|
|
2537
|
+
newValue,
|
|
2538
|
+
};
|
|
2539
|
+
|
|
2540
|
+
setLocalInputValues(
|
|
2541
|
+
(prev) => ({
|
|
2542
|
+
...prev,
|
|
2543
|
+
[inputKey]:
|
|
2544
|
+
newValue,
|
|
2545
|
+
})
|
|
2546
|
+
);
|
|
2547
|
+
|
|
2548
|
+
if (
|
|
2549
|
+
column.update?.key &&
|
|
2550
|
+
column.update?.url &&
|
|
2551
|
+
column.update?.method
|
|
2552
|
+
) {
|
|
2553
|
+
handleInputUpdate(
|
|
2554
|
+
column.update.key,
|
|
2555
|
+
`${column.update.url}/${data.id}`,
|
|
2556
|
+
column.update
|
|
2557
|
+
.method,
|
|
2558
|
+
newValue,
|
|
2559
|
+
inputKey
|
|
2560
|
+
);
|
|
2561
|
+
}
|
|
2562
|
+
}}
|
|
2563
|
+
onBlur={() => {
|
|
2564
|
+
if (
|
|
2565
|
+
column.update?.key &&
|
|
2566
|
+
column.update?.url &&
|
|
2567
|
+
column.update?.method
|
|
2568
|
+
) {
|
|
2569
|
+
handleInputUpdate.flush();
|
|
2570
|
+
}
|
|
2571
|
+
}}
|
|
2572
|
+
/>
|
|
2573
|
+
);
|
|
2574
|
+
},
|
|
2575
|
+
};
|
|
2412
2576
|
default:
|
|
2413
2577
|
columnId = Array.isArray(column.id)
|
|
2414
2578
|
? column.id.join('-')
|
|
@@ -2716,6 +2880,7 @@ const DataGrid = forwardRef(
|
|
|
2716
2880
|
renderColumnContextMenu={renderColumnContextMenu}
|
|
2717
2881
|
rowClassName="vs-datagrid--row"
|
|
2718
2882
|
rowHeight={null}
|
|
2883
|
+
rowStyle={getRowStyle}
|
|
2719
2884
|
selected={selected}
|
|
2720
2885
|
showZebraRows={true}
|
|
2721
2886
|
showActiveRowIndicator={false}
|