@visns-studio/visns-components 5.13.5 → 5.13.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/package.json
CHANGED
|
@@ -24,19 +24,20 @@
|
|
|
24
24
|
"dayjs": "^1.11.13",
|
|
25
25
|
"fabric": "^6.7.0",
|
|
26
26
|
"file-saver": "^2.0.5",
|
|
27
|
-
"framer-motion": "^12.23.
|
|
27
|
+
"framer-motion": "^12.23.1",
|
|
28
28
|
"html-react-parser": "^5.2.5",
|
|
29
29
|
"lodash": "^4.17.21",
|
|
30
30
|
"lodash.debounce": "^4.0.8",
|
|
31
31
|
"lucide-react": "^0.525.0",
|
|
32
32
|
"moment": "^2.30.1",
|
|
33
|
-
"motion": "^12.23.
|
|
33
|
+
"motion": "^12.23.1",
|
|
34
34
|
"numeral": "^2.0.6",
|
|
35
35
|
"pluralize": "^8.0.0",
|
|
36
36
|
"qrcode.react": "^4.2.0",
|
|
37
37
|
"quill-image-uploader": "^1.3.0",
|
|
38
38
|
"react-big-calendar": "^1.19.4",
|
|
39
39
|
"react-copy-to-clipboard": "^5.1.0",
|
|
40
|
+
"react-currency-input-field": "^3.10.0",
|
|
40
41
|
"react-datepicker": "^8.4.0",
|
|
41
42
|
"react-dropzone": "^14.3.8",
|
|
42
43
|
"react-grid-gallery": "^1.0.1",
|
|
@@ -87,7 +88,7 @@
|
|
|
87
88
|
"react-dom": "^17.0.0 || ^18.0.0"
|
|
88
89
|
},
|
|
89
90
|
"name": "@visns-studio/visns-components",
|
|
90
|
-
"version": "5.13.
|
|
91
|
+
"version": "5.13.7",
|
|
91
92
|
"description": "Various packages to assist in the development of our Custom Applications.",
|
|
92
93
|
"main": "src/index.js",
|
|
93
94
|
"files": [
|
|
@@ -114,6 +114,7 @@ import {
|
|
|
114
114
|
renderDateRangeColumn,
|
|
115
115
|
renderStageCounterColumn,
|
|
116
116
|
renderGalleryColumn,
|
|
117
|
+
renderTotalColumn,
|
|
117
118
|
} from './columns/ColumnRenderers.jsx';
|
|
118
119
|
import _ from 'lodash';
|
|
119
120
|
|
|
@@ -2720,6 +2721,11 @@ const DataGrid = forwardRef(
|
|
|
2720
2721
|
setLocalInputValues,
|
|
2721
2722
|
handleInputUpdate,
|
|
2722
2723
|
});
|
|
2724
|
+
case 'total':
|
|
2725
|
+
return renderTotalColumn()({
|
|
2726
|
+
column,
|
|
2727
|
+
commonProps,
|
|
2728
|
+
});
|
|
2723
2729
|
default:
|
|
2724
2730
|
columnId = Array.isArray(column.id)
|
|
2725
2731
|
? column.id.join('-')
|
|
@@ -2472,3 +2472,52 @@ export const renderStageCounterColumn = ({ column, commonProps, navigate, onUpda
|
|
|
2472
2472
|
},
|
|
2473
2473
|
};
|
|
2474
2474
|
};
|
|
2475
|
+
|
|
2476
|
+
// Calculate total for columns of type 'total'
|
|
2477
|
+
const calculateTotal = (entry, keys) => {
|
|
2478
|
+
let total = 0;
|
|
2479
|
+
if (Array.isArray(keys)) {
|
|
2480
|
+
total = keys.reduce(
|
|
2481
|
+
(sum, key) => sum + (parseFloat(entry[key]) || 0),
|
|
2482
|
+
0
|
|
2483
|
+
);
|
|
2484
|
+
} else if (
|
|
2485
|
+
keys &&
|
|
2486
|
+
typeof keys === 'object' &&
|
|
2487
|
+
keys.price &&
|
|
2488
|
+
keys.unit
|
|
2489
|
+
) {
|
|
2490
|
+
const { price: priceKeys, unit: unitKeys } = keys;
|
|
2491
|
+
if (unitKeys.length === 1) {
|
|
2492
|
+
const unitValue = parseFloat(entry[unitKeys[0]]) || 0;
|
|
2493
|
+
total = priceKeys.reduce(
|
|
2494
|
+
(sum, key) =>
|
|
2495
|
+
sum + (parseFloat(entry[key]) || 0) * unitValue,
|
|
2496
|
+
0
|
|
2497
|
+
);
|
|
2498
|
+
} else if (priceKeys.length === unitKeys.length) {
|
|
2499
|
+
total = priceKeys.reduce(
|
|
2500
|
+
(sum, key, index) =>
|
|
2501
|
+
sum +
|
|
2502
|
+
(parseFloat(entry[key]) || 0) *
|
|
2503
|
+
(parseFloat(entry[unitKeys[index]]) || 0),
|
|
2504
|
+
0
|
|
2505
|
+
);
|
|
2506
|
+
}
|
|
2507
|
+
}
|
|
2508
|
+
return total;
|
|
2509
|
+
};
|
|
2510
|
+
|
|
2511
|
+
|
|
2512
|
+
export const renderTotalColumn = () => {
|
|
2513
|
+
return {
|
|
2514
|
+
render: ({ data: rowData, column }) => {
|
|
2515
|
+
// For individual rows, calculate the total for that specific row
|
|
2516
|
+
const subtotal = calculateTotal(rowData, column.keys);
|
|
2517
|
+
return new Intl.NumberFormat('en-AU', {
|
|
2518
|
+
style: 'currency',
|
|
2519
|
+
currency: 'AUD',
|
|
2520
|
+
}).format(subtotal);
|
|
2521
|
+
},
|
|
2522
|
+
};
|
|
2523
|
+
};
|
|
@@ -5,6 +5,7 @@ import { toast } from 'react-toastify';
|
|
|
5
5
|
import { Trash2, ArrowUp, ArrowDown, Copy, Droplets } from 'lucide-react';
|
|
6
6
|
import { Compact } from '@uiw/react-color';
|
|
7
7
|
import { confirmDialog } from '../utils/ConfirmDialog';
|
|
8
|
+
import CurrencyInput from 'react-currency-input-field';
|
|
8
9
|
|
|
9
10
|
import CustomFetch from '../Fetch';
|
|
10
11
|
import MultiSelect from '../MultiSelect';
|
|
@@ -419,6 +420,18 @@ const GenericEditableTable = ({
|
|
|
419
420
|
return totalProjectCost * (percentage / 100);
|
|
420
421
|
};
|
|
421
422
|
|
|
423
|
+
// Check if row matches where conditions
|
|
424
|
+
const matchesWhereConditions = (row, whereConditions) => {
|
|
425
|
+
if (!whereConditions || !Array.isArray(whereConditions)) {
|
|
426
|
+
return true;
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
return whereConditions.every(condition => {
|
|
430
|
+
const { id, value } = condition;
|
|
431
|
+
return row[id] === value;
|
|
432
|
+
});
|
|
433
|
+
};
|
|
434
|
+
|
|
422
435
|
// Calculate total for columns of type 'total'
|
|
423
436
|
const calculateTotal = (entry, keys) => {
|
|
424
437
|
let total = 0;
|
|
@@ -454,6 +467,19 @@ const GenericEditableTable = ({
|
|
|
454
467
|
return total;
|
|
455
468
|
};
|
|
456
469
|
|
|
470
|
+
// Calculate total across all data with where clause filtering
|
|
471
|
+
const calculateTotalFromData = (data, keys, whereConditions) => {
|
|
472
|
+
if (!data || !Array.isArray(data)) {
|
|
473
|
+
return 0;
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
const filteredData = data.filter(row => matchesWhereConditions(row, whereConditions));
|
|
477
|
+
|
|
478
|
+
return filteredData.reduce((sum, entry) => {
|
|
479
|
+
return sum + calculateTotal(entry, keys);
|
|
480
|
+
}, 0);
|
|
481
|
+
};
|
|
482
|
+
|
|
457
483
|
// Debounced update to save entire dataSets array
|
|
458
484
|
const debouncedUpdate = useMemo(
|
|
459
485
|
() =>
|
|
@@ -895,6 +921,27 @@ const GenericEditableTable = ({
|
|
|
895
921
|
// For other colour columns, picker is rendered in the action column
|
|
896
922
|
return null;
|
|
897
923
|
case 'currency':
|
|
924
|
+
return (
|
|
925
|
+
<CurrencyInput
|
|
926
|
+
id={`currency-${column.id}-${keyCounter}`}
|
|
927
|
+
name={column.id}
|
|
928
|
+
placeholder="$0.00"
|
|
929
|
+
defaultValue={entry[column.id] || ''}
|
|
930
|
+
decimalsLimit={2}
|
|
931
|
+
prefix="$"
|
|
932
|
+
decimalSeparator="."
|
|
933
|
+
groupSeparator=","
|
|
934
|
+
onValueChange={(value) =>
|
|
935
|
+
handleFieldChange(
|
|
936
|
+
value || '',
|
|
937
|
+
column.id,
|
|
938
|
+
keyCounter
|
|
939
|
+
)
|
|
940
|
+
}
|
|
941
|
+
style={{ textAlign: 'right', width: '100%' }}
|
|
942
|
+
readOnly={column.readOnly || false}
|
|
943
|
+
/>
|
|
944
|
+
);
|
|
898
945
|
case 'number':
|
|
899
946
|
return (
|
|
900
947
|
<input
|
|
@@ -1051,6 +1098,26 @@ const GenericEditableTable = ({
|
|
|
1051
1098
|
// For other colour columns, picker is rendered in the action column
|
|
1052
1099
|
return null;
|
|
1053
1100
|
case 'currency':
|
|
1101
|
+
return (
|
|
1102
|
+
<CurrencyInput
|
|
1103
|
+
id={`new-currency-${column.id}-${groupId || 'default'}`}
|
|
1104
|
+
name={column.id}
|
|
1105
|
+
placeholder="$0.00"
|
|
1106
|
+
defaultValue={value || ''}
|
|
1107
|
+
decimalsLimit={2}
|
|
1108
|
+
prefix="$"
|
|
1109
|
+
decimalSeparator="."
|
|
1110
|
+
groupSeparator=","
|
|
1111
|
+
onValueChange={(value) =>
|
|
1112
|
+
handleNewFieldChange(
|
|
1113
|
+
value || '',
|
|
1114
|
+
column.id,
|
|
1115
|
+
groupId
|
|
1116
|
+
)
|
|
1117
|
+
}
|
|
1118
|
+
style={{ textAlign: 'right', width: '100%' }}
|
|
1119
|
+
/>
|
|
1120
|
+
);
|
|
1054
1121
|
case 'number':
|
|
1055
1122
|
return (
|
|
1056
1123
|
<input
|
|
@@ -1594,18 +1661,19 @@ const GenericEditableTable = ({
|
|
|
1594
1661
|
);
|
|
1595
1662
|
}
|
|
1596
1663
|
if (index === totalColIndex) {
|
|
1664
|
+
const totalColumn = columns[totalColIndex];
|
|
1597
1665
|
const groupTotal =
|
|
1598
|
-
group.entries
|
|
1599
|
-
(
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1666
|
+
group.entries
|
|
1667
|
+
.filter(entry => matchesWhereConditions(entry, totalColumn.where))
|
|
1668
|
+
.reduce(
|
|
1669
|
+
(sum, entry) =>
|
|
1670
|
+
sum +
|
|
1671
|
+
calculateTotal(
|
|
1672
|
+
entry,
|
|
1673
|
+
totalColumn.keys
|
|
1674
|
+
),
|
|
1675
|
+
0
|
|
1676
|
+
);
|
|
1609
1677
|
return (
|
|
1610
1678
|
<td key={col.id}>
|
|
1611
1679
|
{groupTotal.toLocaleString(
|
|
@@ -1749,17 +1817,18 @@ const GenericEditableTable = ({
|
|
|
1749
1817
|
);
|
|
1750
1818
|
}
|
|
1751
1819
|
if (index === totalColIndex) {
|
|
1820
|
+
const totalColumn = columns[totalColIndex];
|
|
1752
1821
|
const overallTotal =
|
|
1753
1822
|
sortBySortOrder(
|
|
1754
1823
|
localData
|
|
1755
|
-
)
|
|
1824
|
+
)
|
|
1825
|
+
.filter(entry => matchesWhereConditions(entry, totalColumn.where))
|
|
1826
|
+
.reduce(
|
|
1756
1827
|
(sum, entry) =>
|
|
1757
1828
|
sum +
|
|
1758
1829
|
calculateTotal(
|
|
1759
1830
|
entry,
|
|
1760
|
-
|
|
1761
|
-
totalColIndex
|
|
1762
|
-
].keys
|
|
1831
|
+
totalColumn.keys
|
|
1763
1832
|
),
|
|
1764
1833
|
0
|
|
1765
1834
|
);
|