es-grid-template 1.8.70 → 1.8.72
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/es/grid-component/TempTable.js +2 -1
- package/es/group-component/ColumnsChoose.d.ts +13 -0
- package/es/group-component/ColumnsChoose.js +211 -0
- package/es/group-component/ColumnsGroup/ColumnsGroup.d.ts +12 -0
- package/es/group-component/ColumnsGroup/ColumnsGroup.js +230 -0
- package/es/group-component/ColumnsGroup/index.d.ts +1 -0
- package/es/group-component/ColumnsGroup/index.js +1 -0
- package/es/group-component/ContextMenu.d.ts +19 -0
- package/es/group-component/ContextMenu.js +74 -0
- package/es/group-component/InternalTable.d.ts +8 -0
- package/es/group-component/InternalTable.js +224 -0
- package/es/group-component/TableContainer.d.ts +49 -0
- package/es/group-component/TableContainer.js +375 -0
- package/es/group-component/TableContainerEdit.d.ts +48 -0
- package/es/group-component/TableContainerEdit.js +2068 -0
- package/es/group-component/body/EditableCell.d.ts +16 -0
- package/es/group-component/body/EditableCell.js +1066 -0
- package/es/group-component/body/TableBody.d.ts +14 -0
- package/es/group-component/body/TableBody.js +82 -0
- package/es/group-component/body/TableBodyCell.d.ts +12 -0
- package/es/group-component/body/TableBodyCell.js +587 -0
- package/es/group-component/body/TableBodyCellEdit.d.ts +17 -0
- package/es/group-component/body/TableBodyCellEdit.js +1398 -0
- package/es/group-component/body/TableBodyCellEmpty.d.ts +12 -0
- package/es/group-component/body/TableBodyCellEmpty.js +149 -0
- package/es/group-component/body/TableBodyRow.d.ts +21 -0
- package/es/group-component/body/TableBodyRow.js +199 -0
- package/es/group-component/body/TableBodyRowGroupCell.d.ts +12 -0
- package/es/group-component/body/TableBodyRowGroupCell.js +567 -0
- package/es/group-component/components/ControlCheckbox.d.ts +13 -0
- package/es/group-component/components/ControlCheckbox.js +84 -0
- package/es/group-component/components/EditForm/EditForm.d.ts +27 -0
- package/es/group-component/components/EditForm/EditForm.js +394 -0
- package/es/group-component/components/EditForm/index.d.ts +1 -0
- package/es/group-component/components/EditForm/index.js +1 -0
- package/es/group-component/components/InputControl/InputControl.d.ts +27 -0
- package/es/group-component/components/InputControl/InputControl.js +118 -0
- package/es/group-component/components/InputControl/index.d.ts +1 -0
- package/es/group-component/components/InputControl/index.js +1 -0
- package/es/group-component/components/async-select/index.d.ts +11 -0
- package/es/group-component/components/async-select/index.js +38 -0
- package/es/group-component/components/async-table-select/index.d.ts +11 -0
- package/es/group-component/components/async-table-select/index.js +40 -0
- package/es/group-component/components/checkbox-control/index.d.ts +13 -0
- package/es/group-component/components/checkbox-control/index.js +40 -0
- package/es/group-component/components/checkbox-filter/CheckboxFilter.d.ts +18 -0
- package/es/group-component/components/checkbox-filter/CheckboxFilter.js +258 -0
- package/es/group-component/components/checkbox-filter/FilterSearch.d.ts +12 -0
- package/es/group-component/components/checkbox-filter/FilterSearch.js +36 -0
- package/es/group-component/components/command/Command.d.ts +10 -0
- package/es/group-component/components/command/Command.js +35 -0
- package/es/group-component/components/number/index.d.ts +12 -0
- package/es/group-component/components/number/index.js +42 -0
- package/es/group-component/components/number-range/index.d.ts +13 -0
- package/es/group-component/components/number-range/index.js +79 -0
- package/es/group-component/features/operator.d.ts +24 -0
- package/es/group-component/features/operator.js +62 -0
- package/es/group-component/footer/TableFooter.d.ts +7 -0
- package/es/group-component/footer/TableFooter.js +34 -0
- package/es/group-component/footer/TableFooterCell.d.ts +7 -0
- package/es/group-component/footer/TableFooterCell.js +66 -0
- package/es/group-component/footer/TableFooterRow.d.ts +8 -0
- package/es/group-component/footer/TableFooterRow.js +30 -0
- package/es/group-component/header/TableHead.d.ts +15 -0
- package/es/group-component/header/TableHead.js +98 -0
- package/es/group-component/header/TableHeadCell.d.ts +15 -0
- package/es/group-component/header/TableHeadCell.js +310 -0
- package/es/group-component/header/TableHeadCell2.d.ts +17 -0
- package/es/group-component/header/TableHeadCell2.js +321 -0
- package/es/group-component/header/TableHeadGroupCell.d.ts +17 -0
- package/es/group-component/header/TableHeadGroupCell.js +94 -0
- package/es/group-component/header/TableHeadRow.d.ts +15 -0
- package/es/group-component/header/TableHeadRow.js +52 -0
- package/es/group-component/header/renderFilter.d.ts +20 -0
- package/es/group-component/header/renderFilter.js +291 -0
- package/es/group-component/hook/convert.d.ts +1 -0
- package/es/group-component/hook/convert.js +28 -0
- package/es/group-component/hook/useColumns.d.ts +28 -0
- package/es/group-component/hook/useColumns.js +306 -0
- package/es/group-component/hook/useFilterOperator.d.ts +7 -0
- package/es/group-component/hook/useFilterOperator.js +33 -0
- package/es/group-component/hook/utils.d.ts +220 -0
- package/es/group-component/hook/utils.js +2340 -0
- package/es/group-component/index.d.ts +2 -0
- package/es/group-component/index.js +2 -0
- package/es/group-component/style.d.ts +22 -0
- package/es/group-component/style.js +48 -0
- package/es/group-component/style.scss +1438 -0
- package/es/group-component/table/Grid.d.ts +33 -0
- package/es/group-component/table/Grid.js +438 -0
- package/es/group-component/table/TableWrapper.d.ts +33 -0
- package/es/group-component/table/TableWrapper.js +250 -0
- package/es/group-component/useContext.d.ts +100 -0
- package/es/group-component/useContext.js +21 -0
- package/es/table-component/InternalTable.js +6 -1
- package/es/table-component/TableContainer.js +4 -2
- package/es/table-component/TableContainerEdit.js +2 -2
- package/es/table-component/body/TableBodyCell.js +49 -40
- package/es/table-component/body/TableBodyCellEdit.js +9 -3
- package/es/table-component/body/TableBodyRow.js +4 -1
- package/es/table-component/hook/utils.d.ts +1 -0
- package/es/table-component/hook/utils.js +15 -7
- package/es/table-component/style.js +1 -1
- package/es/table-component/table/Grid.js +3 -0
- package/es/table-component/useContext.d.ts +5 -0
- package/es/table-virtuoso/InternalTable.js +2 -2
- package/es/table-virtuoso/body/TableBodyCell.js +2 -7
- package/es/table-virtuoso/body/TableBodyCellRowGroup.d.ts +14 -0
- package/es/table-virtuoso/body/TableBodyCellRowGroup.js +196 -0
- package/es/table-virtuoso/body/TableBodyRow.d.ts +1 -1
- package/es/table-virtuoso/body/TableBodyRow.js +43 -1
- package/es/table-virtuoso/hook/utils.d.ts +1 -0
- package/es/table-virtuoso/hook/utils.js +29 -0
- package/es/table-virtuoso/style.js +3 -1
- package/es/table-virtuoso/table/Grid.js +2 -2
- package/es/table-virtuoso/table/TableWrapper.d.ts +7 -1
- package/es/table-virtuoso/table/TableWrapper.js +24 -5
- package/es/table-virtuoso/useContext.d.ts +6 -3
- package/es/table-virtuoso/useContext.js +18 -0
- package/lib/grid-component/TempTable.js +2 -1
- package/lib/group-component/ColumnsChoose.d.ts +13 -0
- package/lib/group-component/ColumnsChoose.js +221 -0
- package/lib/group-component/ColumnsGroup/ColumnsGroup.d.ts +12 -0
- package/lib/group-component/ColumnsGroup/ColumnsGroup.js +241 -0
- package/lib/group-component/ColumnsGroup/index.d.ts +1 -0
- package/lib/group-component/ColumnsGroup/index.js +16 -0
- package/lib/group-component/ContextMenu.d.ts +19 -0
- package/lib/group-component/ContextMenu.js +83 -0
- package/lib/group-component/InternalTable.d.ts +8 -0
- package/lib/group-component/InternalTable.js +233 -0
- package/lib/group-component/TableContainer.d.ts +49 -0
- package/lib/group-component/TableContainer.js +382 -0
- package/lib/group-component/TableContainerEdit.d.ts +48 -0
- package/lib/group-component/TableContainerEdit.js +2075 -0
- package/lib/group-component/body/EditableCell.d.ts +16 -0
- package/lib/group-component/body/EditableCell.js +1075 -0
- package/lib/group-component/body/TableBody.d.ts +14 -0
- package/lib/group-component/body/TableBody.js +91 -0
- package/lib/group-component/body/TableBodyCell.d.ts +12 -0
- package/lib/group-component/body/TableBodyCell.js +595 -0
- package/lib/group-component/body/TableBodyCellEdit.d.ts +17 -0
- package/lib/group-component/body/TableBodyCellEdit.js +1405 -0
- package/lib/group-component/body/TableBodyCellEmpty.d.ts +12 -0
- package/lib/group-component/body/TableBodyCellEmpty.js +156 -0
- package/lib/group-component/body/TableBodyRow.d.ts +21 -0
- package/lib/group-component/body/TableBodyRow.js +206 -0
- package/lib/group-component/body/TableBodyRowGroupCell.d.ts +12 -0
- package/lib/group-component/body/TableBodyRowGroupCell.js +575 -0
- package/lib/group-component/components/ControlCheckbox.d.ts +13 -0
- package/lib/group-component/components/ControlCheckbox.js +92 -0
- package/lib/group-component/components/EditForm/EditForm.d.ts +27 -0
- package/lib/group-component/components/EditForm/EditForm.js +404 -0
- package/lib/group-component/components/EditForm/index.d.ts +1 -0
- package/lib/group-component/components/EditForm/index.js +16 -0
- package/lib/group-component/components/InputControl/InputControl.d.ts +27 -0
- package/lib/group-component/components/InputControl/InputControl.js +127 -0
- package/lib/group-component/components/InputControl/index.d.ts +1 -0
- package/lib/group-component/components/InputControl/index.js +16 -0
- package/lib/group-component/components/async-select/index.d.ts +11 -0
- package/lib/group-component/components/async-select/index.js +47 -0
- package/lib/group-component/components/async-table-select/index.d.ts +11 -0
- package/lib/group-component/components/async-table-select/index.js +49 -0
- package/lib/group-component/components/checkbox-control/index.d.ts +13 -0
- package/lib/group-component/components/checkbox-control/index.js +48 -0
- package/lib/group-component/components/checkbox-filter/CheckboxFilter.d.ts +18 -0
- package/lib/group-component/components/checkbox-filter/CheckboxFilter.js +267 -0
- package/lib/group-component/components/checkbox-filter/FilterSearch.d.ts +12 -0
- package/lib/group-component/components/checkbox-filter/FilterSearch.js +44 -0
- package/lib/group-component/components/command/Command.d.ts +10 -0
- package/lib/group-component/components/command/Command.js +44 -0
- package/lib/group-component/components/number/index.d.ts +12 -0
- package/lib/group-component/components/number/index.js +50 -0
- package/lib/group-component/components/number-range/index.d.ts +13 -0
- package/lib/group-component/components/number-range/index.js +87 -0
- package/lib/group-component/features/operator.d.ts +24 -0
- package/lib/group-component/features/operator.js +67 -0
- package/lib/group-component/footer/TableFooter.d.ts +7 -0
- package/lib/group-component/footer/TableFooter.js +44 -0
- package/lib/group-component/footer/TableFooterCell.d.ts +7 -0
- package/lib/group-component/footer/TableFooterCell.js +75 -0
- package/lib/group-component/footer/TableFooterRow.d.ts +8 -0
- package/lib/group-component/footer/TableFooterRow.js +37 -0
- package/lib/group-component/header/TableHead.d.ts +15 -0
- package/lib/group-component/header/TableHead.js +107 -0
- package/lib/group-component/header/TableHeadCell.d.ts +15 -0
- package/lib/group-component/header/TableHeadCell.js +319 -0
- package/lib/group-component/header/TableHeadCell2.d.ts +17 -0
- package/lib/group-component/header/TableHeadCell2.js +330 -0
- package/lib/group-component/header/TableHeadGroupCell.d.ts +17 -0
- package/lib/group-component/header/TableHeadGroupCell.js +103 -0
- package/lib/group-component/header/TableHeadRow.d.ts +15 -0
- package/lib/group-component/header/TableHeadRow.js +59 -0
- package/lib/group-component/header/renderFilter.d.ts +20 -0
- package/lib/group-component/header/renderFilter.js +301 -0
- package/lib/group-component/hook/convert.d.ts +1 -0
- package/lib/group-component/hook/convert.js +34 -0
- package/lib/group-component/hook/useColumns.d.ts +28 -0
- package/lib/group-component/hook/useColumns.js +318 -0
- package/lib/group-component/hook/useFilterOperator.d.ts +7 -0
- package/lib/group-component/hook/useFilterOperator.js +40 -0
- package/lib/group-component/hook/utils.d.ts +220 -0
- package/lib/group-component/hook/utils.js +2468 -0
- package/lib/group-component/index.d.ts +2 -0
- package/lib/group-component/index.js +9 -0
- package/lib/group-component/style.d.ts +22 -0
- package/lib/group-component/style.js +55 -0
- package/lib/group-component/style.scss +1438 -0
- package/lib/group-component/table/Grid.d.ts +33 -0
- package/lib/group-component/table/Grid.js +443 -0
- package/lib/group-component/table/TableWrapper.d.ts +33 -0
- package/lib/group-component/table/TableWrapper.js +259 -0
- package/lib/group-component/useContext.d.ts +100 -0
- package/lib/group-component/useContext.js +27 -0
- package/lib/table-component/InternalTable.js +6 -1
- package/lib/table-component/TableContainer.js +4 -2
- package/lib/table-component/TableContainerEdit.js +2 -2
- package/lib/table-component/body/TableBodyCell.js +49 -40
- package/lib/table-component/body/TableBodyCellEdit.js +9 -3
- package/lib/table-component/body/TableBodyRow.js +4 -1
- package/lib/table-component/hook/utils.d.ts +1 -0
- package/lib/table-component/hook/utils.js +16 -7
- package/lib/table-component/style.js +1 -1
- package/lib/table-component/table/Grid.js +3 -0
- package/lib/table-component/useContext.d.ts +5 -0
- package/lib/table-virtuoso/InternalTable.js +2 -2
- package/lib/table-virtuoso/body/TableBodyCell.js +2 -7
- package/lib/table-virtuoso/body/TableBodyCellRowGroup.d.ts +14 -0
- package/lib/table-virtuoso/body/TableBodyCellRowGroup.js +203 -0
- package/lib/table-virtuoso/body/TableBodyRow.d.ts +1 -1
- package/lib/table-virtuoso/body/TableBodyRow.js +43 -1
- package/lib/table-virtuoso/hook/utils.d.ts +1 -0
- package/lib/table-virtuoso/hook/utils.js +32 -1
- package/lib/table-virtuoso/style.js +3 -1
- package/lib/table-virtuoso/table/Grid.js +2 -2
- package/lib/table-virtuoso/table/TableWrapper.d.ts +7 -1
- package/lib/table-virtuoso/table/TableWrapper.js +24 -5
- package/lib/table-virtuoso/useContext.d.ts +6 -3
- package/lib/table-virtuoso/useContext.js +18 -0
- package/package.json +1 -1
|
@@ -0,0 +1,2468 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
Object.defineProperty(exports, "__esModule", {
|
|
5
|
+
value: true
|
|
6
|
+
});
|
|
7
|
+
exports.addRowIdArray = void 0;
|
|
8
|
+
exports.addRowsDown = addRowsDown;
|
|
9
|
+
exports.addRowsDownWithCtrl = addRowsDownWithCtrl;
|
|
10
|
+
exports.addRowsUp = addRowsUp;
|
|
11
|
+
exports.addRowsUpWithCtrl = addRowsUpWithCtrl;
|
|
12
|
+
exports.appendIfNotExists = void 0;
|
|
13
|
+
exports.areStringArraysEqual = areStringArraysEqual;
|
|
14
|
+
exports.arraysEqualIgnoreOrderFast = arraysEqualIgnoreOrderFast;
|
|
15
|
+
exports.checkThousandSeparator = exports.checkFieldKey = exports.checkDecimalSeparator = void 0;
|
|
16
|
+
exports.compareDate = compareDate;
|
|
17
|
+
exports.compareDates = compareDates;
|
|
18
|
+
exports.convertArrayWithIndent = void 0;
|
|
19
|
+
exports.convertColumnsToTreeData = convertColumnsToTreeData;
|
|
20
|
+
exports.convertFlatColumn1 = exports.convertFilters = exports.convertDayjsToDate = exports.convertDateToDayjs = void 0;
|
|
21
|
+
exports.convertFormat = convertFormat;
|
|
22
|
+
exports.convertToObjTrue = exports.convertToObj = exports.convertLabelToTitle = void 0;
|
|
23
|
+
exports.countUnselectedChildren = countUnselectedChildren;
|
|
24
|
+
exports.detectSeparators = exports.customWeekStartEndFormat = void 0;
|
|
25
|
+
exports.excludeItems = excludeItems;
|
|
26
|
+
exports.extendsObject = void 0;
|
|
27
|
+
exports.filterByIds = filterByIds;
|
|
28
|
+
exports.filterDataByColumns = filterDataByColumns;
|
|
29
|
+
exports.findAllChildrenKeys2 = findAllChildrenKeys2;
|
|
30
|
+
exports.findFirst = findFirst;
|
|
31
|
+
exports.genPresets = exports.flattenData = exports.flattenArray = exports.flatColumns2 = exports.fixColumnsLeft = exports.findItemByKey = void 0;
|
|
32
|
+
exports.getAllChildren = getAllChildren;
|
|
33
|
+
exports.getAllVisibleKeys1 = exports.getAllVisibleKeys = exports.getAllRowKey = void 0;
|
|
34
|
+
exports.getCellsByPosition = getCellsByPosition;
|
|
35
|
+
exports.getColIdsBetween = getColIdsBetween;
|
|
36
|
+
exports.getFormat = exports.getFixedFields = exports.getEditType = exports.getDiffent2Array = exports.getDefaultValue = exports.getDefaultOperator = exports.getDatepickerFormat = exports.getDateRangeFormat = exports.getCommonPinningStyles2 = exports.getCommonPinningStyles = void 0;
|
|
37
|
+
exports.getHiddenParentKeys = getHiddenParentKeys;
|
|
38
|
+
exports.getHiddenParentKeys1 = getHiddenParentKeys1;
|
|
39
|
+
exports.getInvisibleColumns = getInvisibleColumns;
|
|
40
|
+
exports.getNewItemsOnly = exports.getLastSelectCell = void 0;
|
|
41
|
+
exports.getRowIdsBetween = getRowIdsBetween;
|
|
42
|
+
exports.getVisibleColumnKeys1 = exports.getVisibleColumnKeys = exports.getTypeFilter = exports.getTableHeight = exports.getSelectedCellMatrix = void 0;
|
|
43
|
+
exports.groupArrayByColumns = groupArrayByColumns;
|
|
44
|
+
exports.isColor = void 0;
|
|
45
|
+
exports.isDateString = isDateString;
|
|
46
|
+
exports.isEmpty = exports.isEditable = exports.isDisable = void 0;
|
|
47
|
+
exports.isEqualSet = isEqualSet;
|
|
48
|
+
exports.isObjEmpty = exports.isNullOrUndefined = exports.isNameColor = exports.isFormattedNumber = void 0;
|
|
49
|
+
exports.isObjEqual = isObjEqual;
|
|
50
|
+
exports.isTreeArray = isTreeArray;
|
|
51
|
+
exports.parseBooleanToValue = exports.onRemoveBgSelectedCell = exports.onAddBgSelectedCell = exports.newGuid = void 0;
|
|
52
|
+
exports.parseClipboardEvent = parseClipboardEvent;
|
|
53
|
+
exports.parseExcelClipboard = parseExcelClipboard;
|
|
54
|
+
exports.parseExcelClipboardText = parseExcelClipboardText;
|
|
55
|
+
exports.parseExcelText = parseExcelText;
|
|
56
|
+
exports.removeColumns = void 0;
|
|
57
|
+
exports.removeDuplicatesByKey = removeDuplicatesByKey;
|
|
58
|
+
exports.sortByType = exports.shouldInclude = exports.removeVietnameseTones = void 0;
|
|
59
|
+
exports.sortColumnsByField = sortColumnsByField;
|
|
60
|
+
exports.sortData = sortData;
|
|
61
|
+
exports.sumSize = void 0;
|
|
62
|
+
exports.toggleRowAndChildren = toggleRowAndChildren;
|
|
63
|
+
exports.updateArrayByKey = exports.unFlattenData = void 0;
|
|
64
|
+
exports.updateColumnWidthsRecursive = updateColumnWidthsRecursive;
|
|
65
|
+
exports.updateColumnsByGroup = exports.updateColumns1 = void 0;
|
|
66
|
+
exports.updateOrInsert = updateOrInsert;
|
|
67
|
+
exports.updateWidthsByOther = updateWidthsByOther;
|
|
68
|
+
var _uuid = require("uuid");
|
|
69
|
+
var _colors = require("@ant-design/colors");
|
|
70
|
+
var _dayjs = _interopRequireDefault(require("dayjs"));
|
|
71
|
+
var _moment = _interopRequireDefault(require("moment"));
|
|
72
|
+
const newGuid = () => {
|
|
73
|
+
for (let i = 0; i < 20; i++) {
|
|
74
|
+
// @ts-ignore
|
|
75
|
+
// const id = crypto.randomUUID()
|
|
76
|
+
return (0, _uuid.v4)();
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
exports.newGuid = newGuid;
|
|
80
|
+
const convertDayjsToDate = (dateString, format) => {
|
|
81
|
+
const dayjsDate = (0, _dayjs.default)(dateString, format); // Parse using the provided format
|
|
82
|
+
if (!dayjsDate.isValid()) {
|
|
83
|
+
throw new Error('Invalid date or format');
|
|
84
|
+
}
|
|
85
|
+
// return moment(dayjsDate.toDate()).format() // Convert to JavaScript Date
|
|
86
|
+
return dayjsDate.toDate(); // Convert to JavaScript Date
|
|
87
|
+
};
|
|
88
|
+
exports.convertDayjsToDate = convertDayjsToDate;
|
|
89
|
+
const convertDateToDayjs = (date, format) => {
|
|
90
|
+
const dateValue = date ? (0, _dayjs.default)(date).format(format) : null;
|
|
91
|
+
return dateValue ? (0, _dayjs.default)(dateValue, format) : null;
|
|
92
|
+
};
|
|
93
|
+
exports.convertDateToDayjs = convertDateToDayjs;
|
|
94
|
+
const getCommonPinningStyles = column => {
|
|
95
|
+
const isPinned = column.getIsPinned();
|
|
96
|
+
return {
|
|
97
|
+
left: isPinned === "left" ? `${column.getStart("left")}px` : undefined,
|
|
98
|
+
right: isPinned === "right" ? `${column.getAfter("right")}px` : undefined,
|
|
99
|
+
opacity: 1,
|
|
100
|
+
position: isPinned ? "sticky" : "relative",
|
|
101
|
+
width: 'auto',
|
|
102
|
+
zIndex: isPinned ? 2 : 0
|
|
103
|
+
};
|
|
104
|
+
};
|
|
105
|
+
exports.getCommonPinningStyles = getCommonPinningStyles;
|
|
106
|
+
const getCommonPinningStyles2 = header => {
|
|
107
|
+
const isPinned = header.column.getIsPinned();
|
|
108
|
+
// const isLastLeftPinnedColumn = isPinned === "left" && column.getIsLastColumn("left");
|
|
109
|
+
// const isFirstRightPinnedColumn =isPinned === "right" && column.getIsFirstColumn("right");
|
|
110
|
+
|
|
111
|
+
return {
|
|
112
|
+
// boxShadow: isFirstRightPinnedColumn
|
|
113
|
+
// ? "#e0e0e0 2px 0px 1px -1px inset"
|
|
114
|
+
// : undefined,
|
|
115
|
+
|
|
116
|
+
left: isPinned === "left" ? `${header.getStart("left")}px` : undefined,
|
|
117
|
+
right: isPinned === "right" ? `${header.getAfter("right")}px` : undefined,
|
|
118
|
+
opacity: 1,
|
|
119
|
+
position: isPinned ? "sticky" : "relative",
|
|
120
|
+
width: 'auto',
|
|
121
|
+
zIndex: isPinned ? 2 : 0
|
|
122
|
+
};
|
|
123
|
+
};
|
|
124
|
+
exports.getCommonPinningStyles2 = getCommonPinningStyles2;
|
|
125
|
+
const sumSize = items => {
|
|
126
|
+
return items.reduce((total, item) => total + item.size, 0);
|
|
127
|
+
};
|
|
128
|
+
exports.sumSize = sumSize;
|
|
129
|
+
const appendIfNotExists = (a, b) => {
|
|
130
|
+
const existingKeys = new Set(a.map(item => item.index));
|
|
131
|
+
b.forEach(item => {
|
|
132
|
+
if (!existingKeys.has(item.index)) {
|
|
133
|
+
a.push(item);
|
|
134
|
+
}
|
|
135
|
+
});
|
|
136
|
+
return a;
|
|
137
|
+
};
|
|
138
|
+
exports.appendIfNotExists = appendIfNotExists;
|
|
139
|
+
const getNewItemsOnly = (a, b) => {
|
|
140
|
+
const existingKeys = new Set(a.map(item => item.key));
|
|
141
|
+
return b.filter(item => !existingKeys.has(item.key));
|
|
142
|
+
};
|
|
143
|
+
exports.getNewItemsOnly = getNewItemsOnly;
|
|
144
|
+
const extendsObject = (...list) => {
|
|
145
|
+
const result = {
|
|
146
|
+
...list[0]
|
|
147
|
+
};
|
|
148
|
+
for (let i = 1; i < list.length; i++) {
|
|
149
|
+
const obj = list[i];
|
|
150
|
+
if (obj) {
|
|
151
|
+
Object.keys(obj).forEach(key => {
|
|
152
|
+
const val = obj[key];
|
|
153
|
+
if (val !== undefined) {
|
|
154
|
+
result[key] = val;
|
|
155
|
+
}
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
return result;
|
|
160
|
+
};
|
|
161
|
+
exports.extendsObject = extendsObject;
|
|
162
|
+
const isEmpty = d => {
|
|
163
|
+
return d === null || d === undefined || d === '';
|
|
164
|
+
};
|
|
165
|
+
exports.isEmpty = isEmpty;
|
|
166
|
+
const getFormat = (colFormat, format) => {
|
|
167
|
+
return {
|
|
168
|
+
thousandSeparator: colFormat?.thousandSeparator ?? format?.thousandSeparator,
|
|
169
|
+
decimalSeparator: colFormat?.decimalSeparator ?? format?.decimalSeparator,
|
|
170
|
+
decimalScale: colFormat?.decimalScale ?? format?.decimalScale ? Number(colFormat?.decimalScale ?? format?.decimalScale) : colFormat?.decimalScale ?? format?.decimalScale,
|
|
171
|
+
allowNegative: colFormat?.allowNegative ?? format?.allowNegative,
|
|
172
|
+
// check nhập số âm
|
|
173
|
+
prefix: colFormat?.prefix ?? format?.prefix,
|
|
174
|
+
suffix: colFormat?.suffix ?? format?.suffix,
|
|
175
|
+
fixedDecimalScale: colFormat?.fixedDecimalScale ?? format?.fixedDecimalScale,
|
|
176
|
+
// mặc định thêm số 0 sau số thập phân
|
|
177
|
+
dateFormat: colFormat?.dateFormat ?? format?.dateFormat,
|
|
178
|
+
datetimeFormat: colFormat?.datetimeFormat ?? format?.datetimeFormat,
|
|
179
|
+
timeFormat: colFormat?.timeFormat ?? format?.timeFormat,
|
|
180
|
+
weekFormat: colFormat?.weekFormat ?? format?.weekFormat,
|
|
181
|
+
monthFormat: colFormat?.monthFormat ?? format?.monthFormat,
|
|
182
|
+
yearFormat: colFormat?.yearFormat ?? format?.yearFormat
|
|
183
|
+
};
|
|
184
|
+
};
|
|
185
|
+
exports.getFormat = getFormat;
|
|
186
|
+
function convertFormat(formatStr) {
|
|
187
|
+
// return formatStr.split('').map((char, i) => {
|
|
188
|
+
// if (char === 'D' || char === 'd') {
|
|
189
|
+
// return 'd'; // ngày: lowercase
|
|
190
|
+
// }
|
|
191
|
+
// if (char === 'Y' || char === 'y') {
|
|
192
|
+
// return 'y'; // năm: lowercase
|
|
193
|
+
// }
|
|
194
|
+
// if (char === 'M' || char === 'm') {
|
|
195
|
+
// return char; // tháng: giữ nguyên
|
|
196
|
+
// }
|
|
197
|
+
// return char; // separator
|
|
198
|
+
// }).join('');
|
|
199
|
+
|
|
200
|
+
return formatStr.split('').map(char => {
|
|
201
|
+
if (char === 'D' || char === 'd') return 'd';
|
|
202
|
+
if (char === 'Y' || char === 'y') return 'y';
|
|
203
|
+
if ('Hhmsa'.includes(char)) return char; // giờ, phút, giây, am/pm
|
|
204
|
+
if (char === 'M' || char === 'm') return char; // tháng: giữ nguyên
|
|
205
|
+
return char; // dấu phân cách
|
|
206
|
+
}).join('');
|
|
207
|
+
}
|
|
208
|
+
const getDatepickerFormat = (type, format) => {
|
|
209
|
+
const typeFormat = type ? type.toLowerCase() : '';
|
|
210
|
+
switch (typeFormat) {
|
|
211
|
+
case "date":
|
|
212
|
+
case "daterange":
|
|
213
|
+
return format?.dateFormat ?? 'DD/MM/YYYY';
|
|
214
|
+
case "datetime":
|
|
215
|
+
return format?.datetimeFormat ?? 'DD/MM/YYYY HH:mm';
|
|
216
|
+
case "week":
|
|
217
|
+
return format?.weekFormat ?? 'DD/MM';
|
|
218
|
+
case "month":
|
|
219
|
+
return format?.monthFormat ?? 'MM/YYYY';
|
|
220
|
+
case "quarter":
|
|
221
|
+
return format?.dateFormat ?? 'DD/MM/YYYY';
|
|
222
|
+
case "year":
|
|
223
|
+
return format?.yearFormat ?? 'YYYY';
|
|
224
|
+
case "time":
|
|
225
|
+
return format?.timeFormat ?? 'HH:mm';
|
|
226
|
+
default:
|
|
227
|
+
return 'DD/MM/YYYY';
|
|
228
|
+
}
|
|
229
|
+
};
|
|
230
|
+
exports.getDatepickerFormat = getDatepickerFormat;
|
|
231
|
+
const getDateRangeFormat = (type, format) => {
|
|
232
|
+
const typeFormat = type ? type.toLowerCase() : '';
|
|
233
|
+
switch (typeFormat) {
|
|
234
|
+
case "date":
|
|
235
|
+
case "daterange":
|
|
236
|
+
return convertFormat(format?.dateFormat ?? 'dd/MM/yyyy');
|
|
237
|
+
case "datetime":
|
|
238
|
+
return format?.datetimeFormat ?? 'dd/MM/yyyy HH:mm';
|
|
239
|
+
case "week":
|
|
240
|
+
return format?.weekFormat ?? 'dd/MM';
|
|
241
|
+
case "month":
|
|
242
|
+
return format?.monthFormat ?? 'MM/yyyy';
|
|
243
|
+
case "quarter":
|
|
244
|
+
return format?.dateFormat ?? 'dd/MM/yyyy';
|
|
245
|
+
case "year":
|
|
246
|
+
return format?.yearFormat ?? 'yyyy';
|
|
247
|
+
case "time":
|
|
248
|
+
return format?.timeFormat ?? 'HH:mm';
|
|
249
|
+
default:
|
|
250
|
+
return 'dd/MM/yyyy';
|
|
251
|
+
}
|
|
252
|
+
};
|
|
253
|
+
exports.getDateRangeFormat = getDateRangeFormat;
|
|
254
|
+
const getTypeFilter = col => {
|
|
255
|
+
if (col?.typeFilter) {
|
|
256
|
+
return col.typeFilter;
|
|
257
|
+
}
|
|
258
|
+
const type = col?.type ?? 'Text';
|
|
259
|
+
switch (type) {
|
|
260
|
+
case "number":
|
|
261
|
+
return 'Number';
|
|
262
|
+
case "date":
|
|
263
|
+
return 'Date';
|
|
264
|
+
case "datetime":
|
|
265
|
+
return 'Datetime';
|
|
266
|
+
case "boolean":
|
|
267
|
+
return 'Checkbox';
|
|
268
|
+
case "checkbox":
|
|
269
|
+
return 'Checkbox';
|
|
270
|
+
|
|
271
|
+
// case "week": return ''
|
|
272
|
+
// case "month": return 'Month'
|
|
273
|
+
// case "quarter": return col.format?.dateFormat ? col.format?.dateFormat : 'DD/MM/YYYY'
|
|
274
|
+
// case "year": return col.format?.yearFormat ? col.format?.yearFormat : 'YYYY'
|
|
275
|
+
// case "time": return col.format?.timeFormat ? col.format?.timeFormat : 'HH:mm'
|
|
276
|
+
case "string":
|
|
277
|
+
default:
|
|
278
|
+
return 'Text';
|
|
279
|
+
}
|
|
280
|
+
};
|
|
281
|
+
exports.getTypeFilter = getTypeFilter;
|
|
282
|
+
const addRowIdArray = inputArray => {
|
|
283
|
+
if (inputArray) {
|
|
284
|
+
return inputArray.map(item => {
|
|
285
|
+
if (typeof item.children !== "string" && item.children && item.children.length > 0) {
|
|
286
|
+
item.children = addRowIdArray(item.children);
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
// return { ...item, rowId: item.rowId ?? item.id ?? newGuid() }
|
|
290
|
+
return {
|
|
291
|
+
...item,
|
|
292
|
+
rowId: item.id ?? item.rowId ?? newGuid()
|
|
293
|
+
};
|
|
294
|
+
});
|
|
295
|
+
} else {
|
|
296
|
+
return [];
|
|
297
|
+
}
|
|
298
|
+
};
|
|
299
|
+
exports.addRowIdArray = addRowIdArray;
|
|
300
|
+
function groupArrayByColumns(arr, columns) {
|
|
301
|
+
const result = [];
|
|
302
|
+
const checkEmpty = d => {
|
|
303
|
+
return d === null || d === undefined || d === '';
|
|
304
|
+
};
|
|
305
|
+
if (columns) {
|
|
306
|
+
arr.forEach(item => {
|
|
307
|
+
let currentLevel = result;
|
|
308
|
+
columns.forEach((column, index) => {
|
|
309
|
+
const value = item[column];
|
|
310
|
+
const existingItem = currentLevel.find(i => i[column] === value);
|
|
311
|
+
if (existingItem) {
|
|
312
|
+
currentLevel = existingItem.children;
|
|
313
|
+
} else {
|
|
314
|
+
// const newItem = {[column]: value, field: column, rowId: !isEmpty(value) ? (value) : newGuid(), parentId: !isEmpty(item[columns[index - 1]]) ? (item[columns[index - 1]]) : null, indent: index, children: [] }
|
|
315
|
+
const newItem = {
|
|
316
|
+
[column]: value,
|
|
317
|
+
field: column,
|
|
318
|
+
rowId: newGuid(),
|
|
319
|
+
// rowId: item[column],
|
|
320
|
+
parentId: !isEmpty(item[columns[index - 1]]) ? item[columns[index - 1]] : null,
|
|
321
|
+
// parentId: item.rowId[index - 1],
|
|
322
|
+
// indent: index,
|
|
323
|
+
children: []
|
|
324
|
+
};
|
|
325
|
+
currentLevel.push(newItem);
|
|
326
|
+
currentLevel = newItem.children;
|
|
327
|
+
}
|
|
328
|
+
});
|
|
329
|
+
currentLevel.push({
|
|
330
|
+
...item,
|
|
331
|
+
rowId: item.id ?? item.rowId,
|
|
332
|
+
parentId: !checkEmpty(columns[columns.length - 1]) ? item[columns[columns.length - 1]] : null
|
|
333
|
+
// parentId: item.rowId[columns.length - 1],
|
|
334
|
+
// indent: columns.length
|
|
335
|
+
});
|
|
336
|
+
});
|
|
337
|
+
return result;
|
|
338
|
+
} else {
|
|
339
|
+
return arr;
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
const flatColumns2 = columns => {
|
|
343
|
+
return columns.reduce((list, column) => {
|
|
344
|
+
const subColumns = column.children;
|
|
345
|
+
if (column.field === 'selection_column') {
|
|
346
|
+
return [...list, {
|
|
347
|
+
...column
|
|
348
|
+
}];
|
|
349
|
+
}
|
|
350
|
+
if (subColumns && subColumns.length > 0) {
|
|
351
|
+
return [...list, ...flatColumns2(subColumns).map(subColum => ({
|
|
352
|
+
...subColum
|
|
353
|
+
}))];
|
|
354
|
+
}
|
|
355
|
+
return [...list, {
|
|
356
|
+
...column
|
|
357
|
+
}];
|
|
358
|
+
}, []);
|
|
359
|
+
};
|
|
360
|
+
exports.flatColumns2 = flatColumns2;
|
|
361
|
+
const checkThousandSeparator = (thousandSeparator, decimalSeparator) => {
|
|
362
|
+
if (thousandSeparator) {
|
|
363
|
+
if (decimalSeparator) {
|
|
364
|
+
if (thousandSeparator === decimalSeparator) {
|
|
365
|
+
return ',';
|
|
366
|
+
} else {
|
|
367
|
+
return thousandSeparator;
|
|
368
|
+
}
|
|
369
|
+
} else {
|
|
370
|
+
return thousandSeparator;
|
|
371
|
+
}
|
|
372
|
+
} else {
|
|
373
|
+
return undefined;
|
|
374
|
+
}
|
|
375
|
+
};
|
|
376
|
+
exports.checkThousandSeparator = checkThousandSeparator;
|
|
377
|
+
const checkDecimalSeparator = (thousandSeparator, decimalSeparator) => {
|
|
378
|
+
if (decimalSeparator) {
|
|
379
|
+
if (thousandSeparator) {
|
|
380
|
+
if (thousandSeparator === decimalSeparator) {
|
|
381
|
+
return '.';
|
|
382
|
+
} else {
|
|
383
|
+
return decimalSeparator;
|
|
384
|
+
}
|
|
385
|
+
} else {
|
|
386
|
+
return decimalSeparator;
|
|
387
|
+
}
|
|
388
|
+
} else {
|
|
389
|
+
if (thousandSeparator && thousandSeparator === '.') {
|
|
390
|
+
return ',';
|
|
391
|
+
}
|
|
392
|
+
return '.';
|
|
393
|
+
}
|
|
394
|
+
};
|
|
395
|
+
exports.checkDecimalSeparator = checkDecimalSeparator;
|
|
396
|
+
const getFixedFields = (columns, type) => {
|
|
397
|
+
const result = [];
|
|
398
|
+
function traverse(cols) {
|
|
399
|
+
for (const col of cols) {
|
|
400
|
+
if ((col.fixed ?? col.fixedType) === type && col.field && (col.visible !== false || col.hidden)) {
|
|
401
|
+
result.push(col.field);
|
|
402
|
+
}
|
|
403
|
+
if (col.children && col.children.length > 0) {
|
|
404
|
+
traverse(col.children);
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
traverse(columns);
|
|
409
|
+
return result;
|
|
410
|
+
};
|
|
411
|
+
exports.getFixedFields = getFixedFields;
|
|
412
|
+
function areStringArraysEqual(a, b) {
|
|
413
|
+
if (a.length !== b.length) return false;
|
|
414
|
+
const sortedA = [...a].sort();
|
|
415
|
+
const sortedB = [...b].sort();
|
|
416
|
+
return sortedA.every((val, index) => val === sortedB[index]);
|
|
417
|
+
}
|
|
418
|
+
const getDefaultOperator = col => {
|
|
419
|
+
if (col.operator) {
|
|
420
|
+
return col.operator;
|
|
421
|
+
}
|
|
422
|
+
if (col.typeFilter) {
|
|
423
|
+
switch (col.typeFilter) {
|
|
424
|
+
case 'Number':
|
|
425
|
+
case 'Date':
|
|
426
|
+
case 'Datetime':
|
|
427
|
+
case 'Time':
|
|
428
|
+
case 'Month':
|
|
429
|
+
case 'Quarter':
|
|
430
|
+
case 'Year':
|
|
431
|
+
case 'Week':
|
|
432
|
+
case 'Dropdown':
|
|
433
|
+
case 'Checkbox':
|
|
434
|
+
case 'CheckboxDropdown':
|
|
435
|
+
case 'CheckboxTree':
|
|
436
|
+
case 'DropTree':
|
|
437
|
+
return 'equal';
|
|
438
|
+
case 'Text':
|
|
439
|
+
default:
|
|
440
|
+
return 'contains';
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
switch (col.type) {
|
|
444
|
+
case 'number':
|
|
445
|
+
case 'date':
|
|
446
|
+
case 'datetime':
|
|
447
|
+
case 'week':
|
|
448
|
+
case 'year':
|
|
449
|
+
case 'quarter':
|
|
450
|
+
return 'equal';
|
|
451
|
+
case 'string':
|
|
452
|
+
default:
|
|
453
|
+
return 'contains';
|
|
454
|
+
}
|
|
455
|
+
};
|
|
456
|
+
exports.getDefaultOperator = getDefaultOperator;
|
|
457
|
+
function isEqualSet(setA, setB) {
|
|
458
|
+
if (setA.size !== setB.size) {
|
|
459
|
+
return false;
|
|
460
|
+
}
|
|
461
|
+
for (const item of setA) {
|
|
462
|
+
if (!setB.has(item)) {
|
|
463
|
+
return false;
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
return true;
|
|
467
|
+
}
|
|
468
|
+
const getLastSelectCell = selectCells => {
|
|
469
|
+
if (selectCells.size === 0) {
|
|
470
|
+
return {
|
|
471
|
+
row: 0,
|
|
472
|
+
col: 0
|
|
473
|
+
};
|
|
474
|
+
}
|
|
475
|
+
const lastValue = [...selectCells].at(-1);
|
|
476
|
+
const [row, col] = lastValue.split("-").map(Number);
|
|
477
|
+
return {
|
|
478
|
+
row,
|
|
479
|
+
col
|
|
480
|
+
};
|
|
481
|
+
};
|
|
482
|
+
exports.getLastSelectCell = getLastSelectCell;
|
|
483
|
+
function getCellsByPosition(cellSet, position = "bottom") {
|
|
484
|
+
const cells = Array.from(cellSet).map(key => {
|
|
485
|
+
const [row, col] = key.split("-").map(Number);
|
|
486
|
+
return {
|
|
487
|
+
row,
|
|
488
|
+
col,
|
|
489
|
+
key
|
|
490
|
+
};
|
|
491
|
+
});
|
|
492
|
+
switch (position) {
|
|
493
|
+
case "top":
|
|
494
|
+
{
|
|
495
|
+
// const minRow = Math.min(...cells.map(c => c.row));
|
|
496
|
+
// return cells.filter(c => c.row === minRow).map(c => c.key);
|
|
497
|
+
|
|
498
|
+
// const rows = cells.map(c => c.row).filter(r => r > 0);
|
|
499
|
+
// if (rows.length === 0) return [];
|
|
500
|
+
// const minRow = Math.min(...rows);
|
|
501
|
+
// return cells.filter(c => c.row === minRow).map(c => c.key);
|
|
502
|
+
|
|
503
|
+
const minRow = Math.min(...cells.map(c => c.row));
|
|
504
|
+
if (minRow === 0) {
|
|
505
|
+
return [];
|
|
506
|
+
} // Bỏ qua nếu rowIndex = 0
|
|
507
|
+
|
|
508
|
+
return cells.filter(c => c.row === minRow).map(c => `${c.row}-${c.col}`);
|
|
509
|
+
}
|
|
510
|
+
case "bottom":
|
|
511
|
+
{
|
|
512
|
+
const maxRow = Math.max(...cells.map(c => c.row));
|
|
513
|
+
return cells.filter(c => c.row === maxRow).map(c => c.key);
|
|
514
|
+
}
|
|
515
|
+
case "left":
|
|
516
|
+
{
|
|
517
|
+
// const minCol = Math.min(...cells.map(c => c.col));
|
|
518
|
+
// return cells.filter(c => c.col === minCol).map(c => c.key);
|
|
519
|
+
|
|
520
|
+
// const cols = cells.map(c => c.col).filter(c => c > 0);
|
|
521
|
+
// if (cols.length === 0) return [];
|
|
522
|
+
// const minCol = Math.min(...cols);
|
|
523
|
+
// return cells.filter(c => c.col === minCol).map(c => c.key);
|
|
524
|
+
|
|
525
|
+
const minCol = Math.min(...cells.map(c => c.col));
|
|
526
|
+
if (minCol === 0) {
|
|
527
|
+
return [];
|
|
528
|
+
} // Bỏ qua nếu colIndex = 0
|
|
529
|
+
|
|
530
|
+
// Trả về các ô cùng row, nhưng ở cột bên trái
|
|
531
|
+
return cells.filter(c => c.col === minCol).map(c => `${c.row}-${c.col}`);
|
|
532
|
+
}
|
|
533
|
+
case "right":
|
|
534
|
+
{
|
|
535
|
+
const maxCol = Math.max(...cells.map(c => c.col));
|
|
536
|
+
return cells.filter(c => c.col === maxCol).map(c => c.key);
|
|
537
|
+
}
|
|
538
|
+
default:
|
|
539
|
+
return [];
|
|
540
|
+
}
|
|
541
|
+
}
|
|
542
|
+
const onAddBgSelectedCell = (selectedCells, id, isFocusCellIndex) => {
|
|
543
|
+
const selectors = Array.from(selectedCells).map(pos => {
|
|
544
|
+
const [row1, col1] = pos.split('-');
|
|
545
|
+
return `[data-row-index="${row1}"][data-col-index="${col1}"]`;
|
|
546
|
+
});
|
|
547
|
+
const table = document.querySelector(`#${id}`);
|
|
548
|
+
|
|
549
|
+
//// xóa class các ô đã chọn trước đó
|
|
550
|
+
const cellsSelected = table ? table?.querySelectorAll('.ui-rc-table-cell.selected-bg') : null;
|
|
551
|
+
if (cellsSelected) {
|
|
552
|
+
cellsSelected.forEach(cell => {
|
|
553
|
+
cell.classList.remove('selected-bg');
|
|
554
|
+
});
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
/// thêm class
|
|
558
|
+
const cells = table && selectors.length > 0 ? table?.querySelectorAll(selectors.join(',')) : null;
|
|
559
|
+
if (cells) {
|
|
560
|
+
cells.forEach(cell => {
|
|
561
|
+
cell.classList.add('selected-bg');
|
|
562
|
+
});
|
|
563
|
+
}
|
|
564
|
+
const rowsArray = [...new Set([...selectedCells].map(item => item.split("-")[0]))];
|
|
565
|
+
const rowsSelectors = rowsArray.map(r => `.rc-ui-cell-index[data-row-index="${r}"]`).join(", ");
|
|
566
|
+
const cellsIndex = table && rowsSelectors.length > 0 ? table?.querySelectorAll(rowsSelectors) : null;
|
|
567
|
+
if (cellsIndex && isFocusCellIndex !== false) {
|
|
568
|
+
cellsIndex.forEach(cell => {
|
|
569
|
+
cell.classList.add('focus');
|
|
570
|
+
});
|
|
571
|
+
}
|
|
572
|
+
|
|
573
|
+
// // tăng z-index để hiển thị round point paste
|
|
574
|
+
// const row = getLastSelectCell(selectedCells).row
|
|
575
|
+
// const col = getLastSelectCell(selectedCells).col
|
|
576
|
+
// const cell: any = table?.querySelector(`.ui-rc-table-cell[data-row-index="${row}"][data-col-index="${col}"]`)
|
|
577
|
+
//
|
|
578
|
+
// if (cell) {
|
|
579
|
+
// cell.style.zIndex = 1
|
|
580
|
+
// }
|
|
581
|
+
//
|
|
582
|
+
// if (cell && cell.classList.contains('ui-rc-table-cell-fix-left')) {
|
|
583
|
+
// cell.style.zIndex = 3;
|
|
584
|
+
// }
|
|
585
|
+
|
|
586
|
+
// thêm class border selected
|
|
587
|
+
|
|
588
|
+
// addBorderClass(selectedCells, 'bottom', 'cell-border-bottom', id)
|
|
589
|
+
// addBorderClass(selectedCells, 'right', 'cell-border-right', id)
|
|
590
|
+
// addBorderClass(selectedCells, 'top', 'cell-border-top', id)
|
|
591
|
+
// addBorderClass(selectedCells, 'left', 'cell-border-left', id)
|
|
592
|
+
};
|
|
593
|
+
exports.onAddBgSelectedCell = onAddBgSelectedCell;
|
|
594
|
+
const onRemoveBgSelectedCell = (selectedCells, id, rowsSelected) => {
|
|
595
|
+
const table = document.querySelector(`#${id}`);
|
|
596
|
+
const cells = table ? table?.querySelectorAll('.ui-rc-table-cell.selected-bg') : null;
|
|
597
|
+
if (cells) {
|
|
598
|
+
cells.forEach(cell => {
|
|
599
|
+
cell.classList.remove('selected-bg');
|
|
600
|
+
});
|
|
601
|
+
}
|
|
602
|
+
const cellsIndex = table ? table?.querySelectorAll('.ui-rc-table-cell.focus') : null;
|
|
603
|
+
if (cellsIndex) {
|
|
604
|
+
cellsIndex.forEach(cell => {
|
|
605
|
+
cell.classList.remove('focus');
|
|
606
|
+
});
|
|
607
|
+
}
|
|
608
|
+
|
|
609
|
+
// xóa class selected ô STT
|
|
610
|
+
|
|
611
|
+
if (rowsSelected && rowsSelected.size > 0) {
|
|
612
|
+
const rowsSelectedArray = [...new Set([...rowsSelected].map(item => item.split("-")[0]))];
|
|
613
|
+
const rowsSelectedSelectors = rowsSelectedArray.map(r => `.rc-ui-cell-index[data-row-index="${r}"]`).join(", ");
|
|
614
|
+
const cellsSelectedIndex = table && rowsSelectedSelectors.length > 0 ? table?.querySelectorAll(rowsSelectedSelectors) : null;
|
|
615
|
+
if (cellsSelectedIndex) {
|
|
616
|
+
cellsSelectedIndex.forEach(cell => {
|
|
617
|
+
cell.classList.remove('selected');
|
|
618
|
+
});
|
|
619
|
+
}
|
|
620
|
+
}
|
|
621
|
+
};
|
|
622
|
+
exports.onRemoveBgSelectedCell = onRemoveBgSelectedCell;
|
|
623
|
+
function getColIdsBetween(table, a, b) {
|
|
624
|
+
const ids = table.getVisibleLeafColumns().map(c => c.id);
|
|
625
|
+
const [start, end] = [ids.indexOf(a), ids.indexOf(b)].sort((x, y) => x - y);
|
|
626
|
+
return ids.slice(start, end + 1);
|
|
627
|
+
}
|
|
628
|
+
function getRowIdsBetween(table, a, b) {
|
|
629
|
+
// const ids = table.getRowModel().rows.map(r => r.id);
|
|
630
|
+
const ids = table.getRowModel().flatRows.map(r => r.id);
|
|
631
|
+
const [start, end] = [ids.indexOf(a), ids.indexOf(b)].sort((x, y) => x - y);
|
|
632
|
+
return ids.slice(start, end + 1);
|
|
633
|
+
}
|
|
634
|
+
const updateArrayByKey = (arr, element, key) => {
|
|
635
|
+
if (arr) {
|
|
636
|
+
return arr.map(it => {
|
|
637
|
+
const item = {
|
|
638
|
+
...it
|
|
639
|
+
};
|
|
640
|
+
if (item[key] === element[key]) {
|
|
641
|
+
return {
|
|
642
|
+
...item,
|
|
643
|
+
...element
|
|
644
|
+
};
|
|
645
|
+
} else if (item.children && item.children.length > 0) {
|
|
646
|
+
item.children = updateArrayByKey(item.children, element, key);
|
|
647
|
+
}
|
|
648
|
+
return item;
|
|
649
|
+
});
|
|
650
|
+
} else {
|
|
651
|
+
return [];
|
|
652
|
+
}
|
|
653
|
+
};
|
|
654
|
+
exports.updateArrayByKey = updateArrayByKey;
|
|
655
|
+
const unFlattenData = data => {
|
|
656
|
+
const idToNodeMap = {};
|
|
657
|
+
const tree = [];
|
|
658
|
+
|
|
659
|
+
// Bước 1: Tạo map id -> node
|
|
660
|
+
data.forEach(item => {
|
|
661
|
+
// idToNodeMap[item.rowId] = { ...item, children: [] }
|
|
662
|
+
idToNodeMap[item.rowId] = {
|
|
663
|
+
...item
|
|
664
|
+
};
|
|
665
|
+
});
|
|
666
|
+
|
|
667
|
+
// Bước 2: Gắn vào parent hoặc đẩy lên root nếu không có parent
|
|
668
|
+
data.forEach(item => {
|
|
669
|
+
const currentNode = idToNodeMap[item.rowId];
|
|
670
|
+
if (!item.parentId) {
|
|
671
|
+
tree.push(currentNode);
|
|
672
|
+
} else {
|
|
673
|
+
const parentNode = idToNodeMap[item.parentId];
|
|
674
|
+
if (parentNode) {
|
|
675
|
+
parentNode.children = parentNode.children ?? [];
|
|
676
|
+
parentNode.children.push(currentNode);
|
|
677
|
+
} else {
|
|
678
|
+
// Nếu parentId không tồn tại thì xem như root
|
|
679
|
+
tree.push(currentNode);
|
|
680
|
+
}
|
|
681
|
+
}
|
|
682
|
+
});
|
|
683
|
+
return tree;
|
|
684
|
+
};
|
|
685
|
+
exports.unFlattenData = unFlattenData;
|
|
686
|
+
const flattenArray = arr => {
|
|
687
|
+
if (!arr) {
|
|
688
|
+
return [];
|
|
689
|
+
}
|
|
690
|
+
return arr.reduce((r, {
|
|
691
|
+
children,
|
|
692
|
+
...rest
|
|
693
|
+
}) => {
|
|
694
|
+
r.push(rest);
|
|
695
|
+
if (children) {
|
|
696
|
+
r.push(...flattenArray(children));
|
|
697
|
+
}
|
|
698
|
+
return r;
|
|
699
|
+
}, []);
|
|
700
|
+
};
|
|
701
|
+
exports.flattenArray = flattenArray;
|
|
702
|
+
function updateOrInsert(dataArray, dataFilter) {
|
|
703
|
+
const updatedArray = [...dataArray];
|
|
704
|
+
dataFilter.forEach(filterItem => {
|
|
705
|
+
const existingIndex = updatedArray.findIndex(item => item.rowId === filterItem.rowId);
|
|
706
|
+
if (existingIndex !== -1) {
|
|
707
|
+
// Cập nhật item đã tồn tại
|
|
708
|
+
updatedArray[existingIndex] = {
|
|
709
|
+
...updatedArray[existingIndex],
|
|
710
|
+
...filterItem
|
|
711
|
+
};
|
|
712
|
+
} else {
|
|
713
|
+
// Tìm vị trí cuối cùng của item trước đó trong dataFilter
|
|
714
|
+
const prevIndexInFilter = dataFilter.findIndex(f => f.rowId === filterItem.rowId) - 1;
|
|
715
|
+
if (prevIndexInFilter >= 0) {
|
|
716
|
+
const prevId = dataFilter[prevIndexInFilter].rowId;
|
|
717
|
+
const prevIndexInArray = updatedArray.findIndex(item => item.rowId === prevId);
|
|
718
|
+
if (prevIndexInArray !== -1) {
|
|
719
|
+
// Thêm ngay sau phần tử trước đó
|
|
720
|
+
updatedArray.splice(prevIndexInArray + 1, 0, filterItem);
|
|
721
|
+
return;
|
|
722
|
+
}
|
|
723
|
+
}
|
|
724
|
+
|
|
725
|
+
// Nếu không tìm thấy phần tử trước đó, hoặc là phần đầu tiên, thì push vào cuối
|
|
726
|
+
updatedArray.push(filterItem);
|
|
727
|
+
}
|
|
728
|
+
});
|
|
729
|
+
return updatedArray;
|
|
730
|
+
}
|
|
731
|
+
const findItemByKey = (array, key, value) => {
|
|
732
|
+
for (let i = 0; i < array.length; i++) {
|
|
733
|
+
const item = array[i];
|
|
734
|
+
if (item[key] === value) {
|
|
735
|
+
return item;
|
|
736
|
+
}
|
|
737
|
+
if (item.children && item.children.length > 0) {
|
|
738
|
+
const foundInChildren = findItemByKey(item.children, key, value);
|
|
739
|
+
if (foundInChildren) {
|
|
740
|
+
return foundInChildren;
|
|
741
|
+
}
|
|
742
|
+
}
|
|
743
|
+
}
|
|
744
|
+
return null;
|
|
745
|
+
};
|
|
746
|
+
exports.findItemByKey = findItemByKey;
|
|
747
|
+
const isFormattedNumber = str => {
|
|
748
|
+
if (!str) return false;
|
|
749
|
+
if (typeof str !== 'string') return false;
|
|
750
|
+
const regexUS = /^\d{1,3}(,\d{3})*(\.\d+)?$/; // 100,000.111
|
|
751
|
+
const regexEU = /^\d{1,3}(\.\d{3})*(,\d+)?$/; // 100.000,111
|
|
752
|
+
|
|
753
|
+
// Không có dấu hàng nghìn, chỉ dấu thập phân: 100000.1 hoặc 100000,01
|
|
754
|
+
const regexDecimalOnly = /^-?\d+([.,]\d{1,})$/;
|
|
755
|
+
return regexUS.test(str) || regexEU.test(str) || regexDecimalOnly.test(str);
|
|
756
|
+
};
|
|
757
|
+
exports.isFormattedNumber = isFormattedNumber;
|
|
758
|
+
const detectSeparators = str => {
|
|
759
|
+
if (typeof str !== 'string') return null;
|
|
760
|
+
const hasComma = str.includes(',');
|
|
761
|
+
const hasDot = str.includes('.');
|
|
762
|
+
|
|
763
|
+
// Trường hợp có cả dấu , và .
|
|
764
|
+
if (hasComma && hasDot) {
|
|
765
|
+
const lastComma = str.lastIndexOf(',');
|
|
766
|
+
const lastDot = str.lastIndexOf('.');
|
|
767
|
+
return lastComma > lastDot ? {
|
|
768
|
+
thousandSeparator: '.',
|
|
769
|
+
decimalSeparator: ','
|
|
770
|
+
} : {
|
|
771
|
+
thousandSeparator: ',',
|
|
772
|
+
decimalSeparator: '.'
|
|
773
|
+
};
|
|
774
|
+
}
|
|
775
|
+
|
|
776
|
+
// Trường hợp chỉ có dấu phẩy
|
|
777
|
+
if (hasComma && !hasDot) {
|
|
778
|
+
const parts = str.split(',');
|
|
779
|
+
if (parts.length === 2) {
|
|
780
|
+
return parts[1].length === 3 ? {
|
|
781
|
+
thousandSeparator: ',',
|
|
782
|
+
decimalSeparator: undefined
|
|
783
|
+
} : {
|
|
784
|
+
thousandSeparator: undefined,
|
|
785
|
+
decimalSeparator: ','
|
|
786
|
+
};
|
|
787
|
+
}
|
|
788
|
+
}
|
|
789
|
+
|
|
790
|
+
// Trường hợp chỉ có dấu chấm
|
|
791
|
+
if (hasDot && !hasComma) {
|
|
792
|
+
const parts = str.split('.');
|
|
793
|
+
if (parts.length === 2) {
|
|
794
|
+
return parts[1].length === 3 ? {
|
|
795
|
+
thousandSeparator: '.',
|
|
796
|
+
decimalSeparator: undefined
|
|
797
|
+
} : {
|
|
798
|
+
thousandSeparator: undefined,
|
|
799
|
+
decimalSeparator: '.'
|
|
800
|
+
};
|
|
801
|
+
}
|
|
802
|
+
}
|
|
803
|
+
|
|
804
|
+
// Không có dấu hoặc không hợp lệ
|
|
805
|
+
return null;
|
|
806
|
+
};
|
|
807
|
+
exports.detectSeparators = detectSeparators;
|
|
808
|
+
function isDate(value) {
|
|
809
|
+
if (value instanceof Date) {
|
|
810
|
+
return !isNaN(value.getTime());
|
|
811
|
+
}
|
|
812
|
+
if (typeof value === "string") {
|
|
813
|
+
// Chỉ chấp nhận định dạng yyyy-mm-dd hoặc mm/yyyy
|
|
814
|
+
return /^\d{4}-\d{2}-\d{2}$/.test(value) || /^\d{2}\/\d{4}$/.test(value);
|
|
815
|
+
}
|
|
816
|
+
return false;
|
|
817
|
+
}
|
|
818
|
+
|
|
819
|
+
// Chuỗi MM/YYYY → Date
|
|
820
|
+
function isDateString(str) {
|
|
821
|
+
return typeof str === "string" && (/^\d{2}\/\d{4}$/.test(str) || /^\d{4}-\d{2}-\d{2}$/.test(str));
|
|
822
|
+
}
|
|
823
|
+
function parseToDate(str) {
|
|
824
|
+
if (/^\d{2}\/\d{4}$/.test(str)) {
|
|
825
|
+
const [month, year] = str.split('/');
|
|
826
|
+
return new Date(parseInt(year), parseInt(month) - 1, 1);
|
|
827
|
+
}
|
|
828
|
+
return new Date(str);
|
|
829
|
+
}
|
|
830
|
+
|
|
831
|
+
// So sánh ngày (cùng ngày/tháng/năm)
|
|
832
|
+
function compareDates(date1, date2) {
|
|
833
|
+
return date1.getDate() === date2.getDate() && date1.getMonth() === date2.getMonth() && date1.getFullYear() === date2.getFullYear();
|
|
834
|
+
}
|
|
835
|
+
|
|
836
|
+
// Helper: compare MM/YYYY date string with itemValue
|
|
837
|
+
function compareDate(itemValue, value) {
|
|
838
|
+
const [month, year] = value.split('/').map(Number);
|
|
839
|
+
const date = new Date(itemValue);
|
|
840
|
+
return date.getMonth() + 1 === month && date.getFullYear() === year;
|
|
841
|
+
}
|
|
842
|
+
const removeVietnameseTones = str => {
|
|
843
|
+
if (!str) {
|
|
844
|
+
return '';
|
|
845
|
+
}
|
|
846
|
+
return str.normalize('NFD') // Tách các ký tự có dấu thành ký tự cơ bản + dấu
|
|
847
|
+
.replace(/[\u0300-\u036f]/g, '') // Xóa dấu
|
|
848
|
+
.replace(/đ/g, 'd') // Thay thế đ
|
|
849
|
+
.replace(/Đ/g, 'D').replace(/[^a-zA-Z0-9\s]/g, '') // Loại bỏ ký tự đặc biệt
|
|
850
|
+
.replace(/\s+/g, ' ') // Thay nhiều khoảng trắng thành 1 khoảng trắng
|
|
851
|
+
.trim();
|
|
852
|
+
};
|
|
853
|
+
exports.removeVietnameseTones = removeVietnameseTones;
|
|
854
|
+
const shouldInclude = (item, queries) => {
|
|
855
|
+
if (item.isFilterState === true) {
|
|
856
|
+
return true;
|
|
857
|
+
}
|
|
858
|
+
let result = null;
|
|
859
|
+
for (const query of queries) {
|
|
860
|
+
const {
|
|
861
|
+
field,
|
|
862
|
+
value,
|
|
863
|
+
operator,
|
|
864
|
+
predicate
|
|
865
|
+
} = query;
|
|
866
|
+
const itemValue = item[field];
|
|
867
|
+
let condition = false;
|
|
868
|
+
const isDateComparison = isDate(itemValue) || isDateString(value);
|
|
869
|
+
const itemDate = isDateComparison ? new Date(itemValue) : null;
|
|
870
|
+
const queryDate = isDateComparison ? parseToDate(value) : null;
|
|
871
|
+
const itemStr = removeVietnameseTones(itemValue?.toString().toLowerCase?.() ?? '');
|
|
872
|
+
const queryStr = removeVietnameseTones(value?.toString().toLowerCase?.() ?? '');
|
|
873
|
+
switch (operator.toLowerCase()) {
|
|
874
|
+
case "equal":
|
|
875
|
+
condition = isDateComparison ? compareDates(itemDate, queryDate) : itemValue === value;
|
|
876
|
+
break;
|
|
877
|
+
case "notequal":
|
|
878
|
+
condition = isDateComparison ? !compareDates(itemDate, queryDate) : itemValue !== value;
|
|
879
|
+
break;
|
|
880
|
+
case "greaterthan":
|
|
881
|
+
// @ts-ignore
|
|
882
|
+
condition = isDateComparison ? itemDate > queryDate : itemValue > value;
|
|
883
|
+
|
|
884
|
+
// condition = isDateComparison ? invalidDate(itemDate) && invalidDate(queryDate) && itemDate > queryDate : itemValue > value;
|
|
885
|
+
break;
|
|
886
|
+
case "greaterthanorequal":
|
|
887
|
+
// @ts-ignore
|
|
888
|
+
condition = isDateComparison ? itemDate >= queryDate : itemValue >= value;
|
|
889
|
+
break;
|
|
890
|
+
case "lessthan":
|
|
891
|
+
// @ts-ignore
|
|
892
|
+
condition = isDateComparison ? itemDate < queryDate : itemValue < value;
|
|
893
|
+
break;
|
|
894
|
+
case "lessthanorequal":
|
|
895
|
+
// @ts-ignore
|
|
896
|
+
condition = isDateComparison ? itemDate <= queryDate : itemValue <= value;
|
|
897
|
+
break;
|
|
898
|
+
case "contains":
|
|
899
|
+
condition = itemStr?.includes(queryStr);
|
|
900
|
+
break;
|
|
901
|
+
case "startswith":
|
|
902
|
+
condition = itemStr?.startsWith(queryStr);
|
|
903
|
+
break;
|
|
904
|
+
case "endswith":
|
|
905
|
+
condition = itemStr?.endsWith(queryStr);
|
|
906
|
+
break;
|
|
907
|
+
default:
|
|
908
|
+
console.warn(`Unknown operator: ${operator}`);
|
|
909
|
+
break;
|
|
910
|
+
}
|
|
911
|
+
if (predicate === "and") {
|
|
912
|
+
result = result === null ? condition : result && condition;
|
|
913
|
+
} else if (predicate === "or") {
|
|
914
|
+
result = result === null ? condition : result || condition;
|
|
915
|
+
}
|
|
916
|
+
}
|
|
917
|
+
return result;
|
|
918
|
+
};
|
|
919
|
+
|
|
920
|
+
// function compareValues(a: any, b: any, order: "ascend" | "descend") {
|
|
921
|
+
// const desc = order === "descend";
|
|
922
|
+
|
|
923
|
+
// if (a == null && b == null) return 0;
|
|
924
|
+
// if (a == null) return desc ? 1 : -1;
|
|
925
|
+
// if (b == null) return desc ? -1 : 1;
|
|
926
|
+
|
|
927
|
+
// // Nếu là số
|
|
928
|
+
// if (typeof a === "number" && typeof b === "number") {
|
|
929
|
+
// return desc ? b - a : a - b;
|
|
930
|
+
// }
|
|
931
|
+
|
|
932
|
+
// // Nếu là ngày hợp lệ
|
|
933
|
+
// const dateA = new Date(a);
|
|
934
|
+
// const dateB = new Date(b);
|
|
935
|
+
// if (!isNaN(dateA.getTime()) && !isNaN(dateB.getTime())) {
|
|
936
|
+
// return desc
|
|
937
|
+
// ? dateB.getTime() - dateA.getTime()
|
|
938
|
+
// : dateA.getTime() - dateB.getTime();
|
|
939
|
+
// }
|
|
940
|
+
|
|
941
|
+
// // Mặc định coi như string
|
|
942
|
+
// return desc
|
|
943
|
+
// ? String(b).localeCompare(String(a))
|
|
944
|
+
// : String(a).localeCompare(String(b));
|
|
945
|
+
// }
|
|
946
|
+
|
|
947
|
+
// export function sortData(data: any[], sorter: Sorter[]): any[] {
|
|
948
|
+
// const sorted = [...data].sort((a, b) => {
|
|
949
|
+
// for (const { field, order } of sorter) {
|
|
950
|
+
// const result = compareValues(a[field], b[field], order);
|
|
951
|
+
// if (result !== 0) return result;
|
|
952
|
+
// }
|
|
953
|
+
// return 0;
|
|
954
|
+
// });
|
|
955
|
+
|
|
956
|
+
// return sorted.map(item => ({
|
|
957
|
+
// ...item,
|
|
958
|
+
// children: item.children
|
|
959
|
+
// ? sortData(item.children, sorter)
|
|
960
|
+
// : undefined
|
|
961
|
+
// }));
|
|
962
|
+
// }
|
|
963
|
+
|
|
964
|
+
// export function filterDataByColumns(data: any[], queries: any[], sorter: Sorter[], keysFilter: string[] | undefined) {
|
|
965
|
+
|
|
966
|
+
// if (!queries || queries.length === 0) {
|
|
967
|
+
// return sorter ? sortData(data, sorter) : data;
|
|
968
|
+
// }
|
|
969
|
+
|
|
970
|
+
// let filtered = data.map(item => {
|
|
971
|
+
// const newItem = { ...item }
|
|
972
|
+
|
|
973
|
+
// if (Array.isArray(item.children)) {
|
|
974
|
+
// newItem.children = filterDataByColumns(item.children, queries, sorter, keysFilter)
|
|
975
|
+
// }
|
|
976
|
+
|
|
977
|
+
// const isSelfMatched = shouldInclude(item, queries) || keysFilter?.includes(newItem?.rowId)
|
|
978
|
+
|
|
979
|
+
// // Nếu chính item thỏa hoặc có con thỏa → giữ lại
|
|
980
|
+
// if (isSelfMatched || (newItem.children && newItem.children.length > 0)) {
|
|
981
|
+
// return newItem
|
|
982
|
+
// }
|
|
983
|
+
|
|
984
|
+
// return null // loại bỏ node không phù hợp
|
|
985
|
+
// })
|
|
986
|
+
// .filter(Boolean) // xóa các null
|
|
987
|
+
|
|
988
|
+
// if (sorter && sorter.length > 0) {
|
|
989
|
+
// filtered = sortData(filtered, sorter);
|
|
990
|
+
// }
|
|
991
|
+
|
|
992
|
+
// return filtered;
|
|
993
|
+
// }
|
|
994
|
+
exports.shouldInclude = shouldInclude;
|
|
995
|
+
function getSortValue(item, field) {
|
|
996
|
+
if (item[field] !== undefined) return item[field];
|
|
997
|
+
if (item.children && item.children.length > 0) {
|
|
998
|
+
return getSortValue(item.children[0], field);
|
|
999
|
+
}
|
|
1000
|
+
return undefined;
|
|
1001
|
+
}
|
|
1002
|
+
function compareValues(a, b, order) {
|
|
1003
|
+
const desc = order === "descend";
|
|
1004
|
+
if (a == null && b == null) return 0;
|
|
1005
|
+
if (a == null) return desc ? 1 : -1;
|
|
1006
|
+
if (b == null) return desc ? -1 : 1;
|
|
1007
|
+
|
|
1008
|
+
// Nếu là số
|
|
1009
|
+
if (typeof a === "number" && typeof b === "number") {
|
|
1010
|
+
return desc ? b - a : a - b;
|
|
1011
|
+
}
|
|
1012
|
+
|
|
1013
|
+
// Nếu là ngày hợp lệ
|
|
1014
|
+
const dateA = new Date(a);
|
|
1015
|
+
const dateB = new Date(b);
|
|
1016
|
+
if (!isNaN(dateA.getTime()) && !isNaN(dateB.getTime())) {
|
|
1017
|
+
return desc ? dateB.getTime() - dateA.getTime() : dateA.getTime() - dateB.getTime();
|
|
1018
|
+
}
|
|
1019
|
+
|
|
1020
|
+
// Mặc định coi như string
|
|
1021
|
+
return desc ? String(b).localeCompare(String(a)) : String(a).localeCompare(String(b));
|
|
1022
|
+
}
|
|
1023
|
+
function sortData(data, sorter) {
|
|
1024
|
+
const sorted = [...data].sort((a, b) => {
|
|
1025
|
+
for (const {
|
|
1026
|
+
field,
|
|
1027
|
+
order
|
|
1028
|
+
} of sorter) {
|
|
1029
|
+
const result = compareValues(getSortValue(a, field), getSortValue(b, field), order);
|
|
1030
|
+
if (result !== 0) return result;
|
|
1031
|
+
}
|
|
1032
|
+
return 0;
|
|
1033
|
+
});
|
|
1034
|
+
return sorted.map(item => ({
|
|
1035
|
+
...item,
|
|
1036
|
+
children: item.children ? sortData(item.children, sorter) : undefined
|
|
1037
|
+
}));
|
|
1038
|
+
}
|
|
1039
|
+
function filterDataByColumns(data, queries, sorter, keysFilter) {
|
|
1040
|
+
if (!queries || queries.length === 0) {
|
|
1041
|
+
return sorter ? sortData(data, sorter) : data;
|
|
1042
|
+
}
|
|
1043
|
+
let filtered = data.map(item => {
|
|
1044
|
+
const newItem = {
|
|
1045
|
+
...item
|
|
1046
|
+
};
|
|
1047
|
+
if (Array.isArray(item.children)) {
|
|
1048
|
+
newItem.children = filterDataByColumns(item.children, queries, sorter, keysFilter);
|
|
1049
|
+
}
|
|
1050
|
+
const isSelfMatched = shouldInclude(item, queries) || keysFilter?.includes(newItem?.rowId);
|
|
1051
|
+
|
|
1052
|
+
// Nếu chính item thỏa hoặc có con thỏa → giữ lại
|
|
1053
|
+
if (isSelfMatched || newItem.children && newItem.children.length > 0) {
|
|
1054
|
+
return newItem;
|
|
1055
|
+
}
|
|
1056
|
+
return null; // loại bỏ node không phù hợp
|
|
1057
|
+
}).filter(Boolean); // xóa các null
|
|
1058
|
+
|
|
1059
|
+
if (sorter && sorter.length > 0) {
|
|
1060
|
+
filtered = sortData(filtered, sorter);
|
|
1061
|
+
}
|
|
1062
|
+
return filtered;
|
|
1063
|
+
}
|
|
1064
|
+
const getAllRowKey = data => {
|
|
1065
|
+
const a = flattenArray(data);
|
|
1066
|
+
return a.length ? a.map(it => it.rowId) : undefined;
|
|
1067
|
+
};
|
|
1068
|
+
exports.getAllRowKey = getAllRowKey;
|
|
1069
|
+
const isEditable = (column, rowData) => {
|
|
1070
|
+
if (column && typeof column.editEnable === 'function') {
|
|
1071
|
+
return column.editEnable(rowData);
|
|
1072
|
+
}
|
|
1073
|
+
return column?.editEnable;
|
|
1074
|
+
};
|
|
1075
|
+
exports.isEditable = isEditable;
|
|
1076
|
+
const checkFieldKey = key => {
|
|
1077
|
+
if (key) {
|
|
1078
|
+
return key;
|
|
1079
|
+
} else {
|
|
1080
|
+
return 'value';
|
|
1081
|
+
}
|
|
1082
|
+
};
|
|
1083
|
+
exports.checkFieldKey = checkFieldKey;
|
|
1084
|
+
const convertArrayWithIndent = (inputArray, parentIndent = 0) => {
|
|
1085
|
+
if (inputArray) {
|
|
1086
|
+
return inputArray.map(item => {
|
|
1087
|
+
const indent = parentIndent;
|
|
1088
|
+
if (item.children && item.children.length > 0) {
|
|
1089
|
+
item.children = convertArrayWithIndent(item.children, indent + 1);
|
|
1090
|
+
}
|
|
1091
|
+
return {
|
|
1092
|
+
...item,
|
|
1093
|
+
indent,
|
|
1094
|
+
rowId: item.rowId ? item.rowId : item.id ? item.id : newGuid()
|
|
1095
|
+
};
|
|
1096
|
+
});
|
|
1097
|
+
} else {
|
|
1098
|
+
return [];
|
|
1099
|
+
}
|
|
1100
|
+
};
|
|
1101
|
+
exports.convertArrayWithIndent = convertArrayWithIndent;
|
|
1102
|
+
const convertLabelToTitle = data => {
|
|
1103
|
+
return data.map(item => {
|
|
1104
|
+
const {
|
|
1105
|
+
label,
|
|
1106
|
+
title,
|
|
1107
|
+
value,
|
|
1108
|
+
key,
|
|
1109
|
+
...rest
|
|
1110
|
+
} = item;
|
|
1111
|
+
const newItem = {
|
|
1112
|
+
...rest,
|
|
1113
|
+
value,
|
|
1114
|
+
label,
|
|
1115
|
+
key: key ?? value,
|
|
1116
|
+
title: title ?? label
|
|
1117
|
+
};
|
|
1118
|
+
if (item.children) {
|
|
1119
|
+
newItem.children = convertLabelToTitle(item.children);
|
|
1120
|
+
}
|
|
1121
|
+
return newItem;
|
|
1122
|
+
});
|
|
1123
|
+
};
|
|
1124
|
+
exports.convertLabelToTitle = convertLabelToTitle;
|
|
1125
|
+
const isNullOrUndefined = d => {
|
|
1126
|
+
return d === null || d === undefined;
|
|
1127
|
+
};
|
|
1128
|
+
exports.isNullOrUndefined = isNullOrUndefined;
|
|
1129
|
+
const isObjEmpty = obj => {
|
|
1130
|
+
if (isNullOrUndefined(obj)) {
|
|
1131
|
+
return true;
|
|
1132
|
+
} else {
|
|
1133
|
+
return Object.keys(obj).length === 0;
|
|
1134
|
+
}
|
|
1135
|
+
};
|
|
1136
|
+
exports.isObjEmpty = isObjEmpty;
|
|
1137
|
+
const isDisable = (column, rowData) => {
|
|
1138
|
+
if (column && typeof column?.disable === 'function') {
|
|
1139
|
+
return column.disable(rowData);
|
|
1140
|
+
}
|
|
1141
|
+
return !!column?.disable;
|
|
1142
|
+
};
|
|
1143
|
+
exports.isDisable = isDisable;
|
|
1144
|
+
const customWeekStartEndFormat = (value, weekFormat) => {
|
|
1145
|
+
return `${(0, _dayjs.default)(value).startOf('week').format(weekFormat)} ~ ${(0, _dayjs.default)(value).endOf('week').format(weekFormat)}`;
|
|
1146
|
+
};
|
|
1147
|
+
exports.customWeekStartEndFormat = customWeekStartEndFormat;
|
|
1148
|
+
const parseBooleanToValue = (value, type) => {
|
|
1149
|
+
return type === 'boolean' ? value : Number(value);
|
|
1150
|
+
};
|
|
1151
|
+
exports.parseBooleanToValue = parseBooleanToValue;
|
|
1152
|
+
const isNameColor = strColor => {
|
|
1153
|
+
const s = new Option().style;
|
|
1154
|
+
s.color = strColor;
|
|
1155
|
+
return s.color === strColor;
|
|
1156
|
+
};
|
|
1157
|
+
exports.isNameColor = isNameColor;
|
|
1158
|
+
const isColor = value => {
|
|
1159
|
+
const hexRegex = /^#([0-9A-F]{3}){1,2}$/i;
|
|
1160
|
+
const rgbRegex = /^rgb\((\d{1,3}), (\d{1,3}), (\d{1,3})\)$/;
|
|
1161
|
+
const rgbaRegex = /^rgba\((\d{1,3}), (\d{1,3}), (\d{1,3}), (0|1|0?\.\d+)\)$/;
|
|
1162
|
+
const hslRegex = /^hsl\(\d{1,3}, \d{1,3}%, \d{1,3}%\)$/;
|
|
1163
|
+
const hslaRegex = /^hsla\(\d{1,3}, \d{1,3}%, \d{1,3}%, (0|1|0?\.\d+)\)$/;
|
|
1164
|
+
const namedColors = /^(?:aqua|black|blue|fuchsia|gray|green|lime|maroon|navy|olive|purple|red|silver|teal|white|yellow)$/i;
|
|
1165
|
+
return hexRegex.test(value) || rgbRegex.test(value) || rgbaRegex.test(value) || hslRegex.test(value) || hslaRegex.test(value) || namedColors.test(value) || isNameColor(value);
|
|
1166
|
+
};
|
|
1167
|
+
exports.isColor = isColor;
|
|
1168
|
+
const genPresets = (presets = _colors.presetPalettes) => {
|
|
1169
|
+
return Object.entries(presets).map(([label, colors]) => ({
|
|
1170
|
+
label,
|
|
1171
|
+
colors,
|
|
1172
|
+
key: label
|
|
1173
|
+
}));
|
|
1174
|
+
};
|
|
1175
|
+
exports.genPresets = genPresets;
|
|
1176
|
+
const getEditType = (column, rowData) => {
|
|
1177
|
+
if (column && typeof column.editType === 'function') {
|
|
1178
|
+
return column.editType(rowData);
|
|
1179
|
+
}
|
|
1180
|
+
return column?.editType ?? 'text';
|
|
1181
|
+
};
|
|
1182
|
+
exports.getEditType = getEditType;
|
|
1183
|
+
const getDefaultValue = defaultValue => {
|
|
1184
|
+
if (defaultValue && typeof defaultValue === 'function') {
|
|
1185
|
+
return defaultValue();
|
|
1186
|
+
}
|
|
1187
|
+
return defaultValue;
|
|
1188
|
+
};
|
|
1189
|
+
exports.getDefaultValue = getDefaultValue;
|
|
1190
|
+
const flattenData = (childrenColumnName, data) => {
|
|
1191
|
+
let list = [];
|
|
1192
|
+
(data || []).forEach(record => {
|
|
1193
|
+
list.push(record);
|
|
1194
|
+
if (record && typeof record === 'object' && childrenColumnName in record) {
|
|
1195
|
+
list = [...list, ...flattenData(childrenColumnName, record[childrenColumnName])];
|
|
1196
|
+
}
|
|
1197
|
+
});
|
|
1198
|
+
return list;
|
|
1199
|
+
};
|
|
1200
|
+
exports.flattenData = flattenData;
|
|
1201
|
+
const getSelectedCellMatrix = (table, startCell, endCell) => {
|
|
1202
|
+
if (!startCell || !endCell) return {
|
|
1203
|
+
rowIds: [],
|
|
1204
|
+
colIds: [],
|
|
1205
|
+
startRowIndex: undefined,
|
|
1206
|
+
endRowIndex: undefined,
|
|
1207
|
+
startColIndex: undefined,
|
|
1208
|
+
endColIndex: undefined,
|
|
1209
|
+
colRange: [],
|
|
1210
|
+
rowRange: []
|
|
1211
|
+
};
|
|
1212
|
+
|
|
1213
|
+
// const rowIds = table.getRowModel().rows.map(r => r.id);
|
|
1214
|
+
const rowIds = table.getRowModel().flatRows.map(r => r.id);
|
|
1215
|
+
const colIds = table.getVisibleLeafColumns().map(c => c.id);
|
|
1216
|
+
|
|
1217
|
+
// const colIds = table.getAllLeafColumns().map(c => c.id);
|
|
1218
|
+
|
|
1219
|
+
const [startRowIndex, endRowIndex] = [rowIds.indexOf(startCell.rowId), rowIds.indexOf(endCell.rowId)].sort((a, b) => a - b);
|
|
1220
|
+
const [startColIndex, endColIndex] = [colIds.indexOf(startCell.colId), colIds.indexOf(endCell.colId)].sort((a, b) => a - b);
|
|
1221
|
+
return {
|
|
1222
|
+
rowRange: rowIds.slice(startRowIndex, endRowIndex + 1),
|
|
1223
|
+
colRange: colIds.slice(startColIndex, endColIndex + 1),
|
|
1224
|
+
startRowIndex,
|
|
1225
|
+
endRowIndex,
|
|
1226
|
+
startColIndex,
|
|
1227
|
+
endColIndex,
|
|
1228
|
+
rowIds,
|
|
1229
|
+
colIds
|
|
1230
|
+
};
|
|
1231
|
+
};
|
|
1232
|
+
exports.getSelectedCellMatrix = getSelectedCellMatrix;
|
|
1233
|
+
function addRowsDownWithCtrl(arr, n) {
|
|
1234
|
+
if (!Array.isArray(arr) || arr.length === 0) {
|
|
1235
|
+
return {
|
|
1236
|
+
combined: arr,
|
|
1237
|
+
addedRows: []
|
|
1238
|
+
};
|
|
1239
|
+
}
|
|
1240
|
+
const m = arr.length;
|
|
1241
|
+
const numCols = arr[0].length;
|
|
1242
|
+
const addedRows = [];
|
|
1243
|
+
|
|
1244
|
+
// Hàm kiểm tra kiểu date hợp lệ
|
|
1245
|
+
const isValidDate = item => {
|
|
1246
|
+
// return !isNaN(Date.parse(d))
|
|
1247
|
+
|
|
1248
|
+
if (typeof item === 'number') {
|
|
1249
|
+
// return 'number'
|
|
1250
|
+
return false;
|
|
1251
|
+
}
|
|
1252
|
+
if (typeof item === 'string') {
|
|
1253
|
+
// Kiểm tra nếu là chuỗi ISO date hợp lệ
|
|
1254
|
+
const date = new Date(item);
|
|
1255
|
+
if (!isNaN(date.getTime()) && item.includes('T')) {
|
|
1256
|
+
// return 'date'
|
|
1257
|
+
return true;
|
|
1258
|
+
}
|
|
1259
|
+
// return 'string'
|
|
1260
|
+
return false;
|
|
1261
|
+
}
|
|
1262
|
+
return !isNaN(Date.parse(item));
|
|
1263
|
+
};
|
|
1264
|
+
|
|
1265
|
+
// Lấy giá trị mẫu của cột j từ hàng đầu tiên
|
|
1266
|
+
const getSample = j => arr[0][j];
|
|
1267
|
+
|
|
1268
|
+
// Xác định chế độ xử lý cho mỗi cột:
|
|
1269
|
+
// mode = 'number-stepping' | 'date-stepping' | 'number-constant' | 'cycle'
|
|
1270
|
+
const modes = [];
|
|
1271
|
+
const steps = []; // bước tăng, nếu có (cho number hoặc date)
|
|
1272
|
+
|
|
1273
|
+
for (let j = 0; j < numCols; j++) {
|
|
1274
|
+
const sample = getSample(j);
|
|
1275
|
+
if (m === 1) {
|
|
1276
|
+
// Nếu mảng chỉ có 1 hàng: nếu là số thì giữ nguyên; nếu là date thì tăng 1 ngày; còn lại giữ nguyên.
|
|
1277
|
+
if (typeof sample === "number") {
|
|
1278
|
+
modes[j] = "number-constant";
|
|
1279
|
+
} else if (isValidDate(sample)) {
|
|
1280
|
+
modes[j] = "date-stepping";
|
|
1281
|
+
steps[j] = 24 * 3600 * 1000; // 1 ngày = 86400000 ms
|
|
1282
|
+
} else {
|
|
1283
|
+
modes[j] = "cycle";
|
|
1284
|
+
}
|
|
1285
|
+
} else if (m === 2) {
|
|
1286
|
+
// Nếu mảng có 2 hàng: nếu là số thì tính bước = row2 - row1, tương tự với date
|
|
1287
|
+
const first = arr[0][j],
|
|
1288
|
+
second = arr[1][j];
|
|
1289
|
+
if (typeof first === "number" && typeof second === "number") {
|
|
1290
|
+
modes[j] = "number-stepping";
|
|
1291
|
+
steps[j] = second - first;
|
|
1292
|
+
} else if (isValidDate(first) && isValidDate(second)) {
|
|
1293
|
+
modes[j] = "date-stepping";
|
|
1294
|
+
steps[j] = Date.parse(second) - Date.parse(first);
|
|
1295
|
+
} else {
|
|
1296
|
+
modes[j] = "cycle";
|
|
1297
|
+
}
|
|
1298
|
+
} else {
|
|
1299
|
+
// Nếu mảng có >2 hàng
|
|
1300
|
+
const first = arr[0][j],
|
|
1301
|
+
second = arr[1][j],
|
|
1302
|
+
third = arr[2][j];
|
|
1303
|
+
if (typeof first === "number" && typeof second === "number" && typeof third === "number") {
|
|
1304
|
+
const step1 = second - first;
|
|
1305
|
+
const step2 = third - second;
|
|
1306
|
+
if (step1 === step2) {
|
|
1307
|
+
modes[j] = "number-stepping";
|
|
1308
|
+
steps[j] = step1;
|
|
1309
|
+
} else {
|
|
1310
|
+
modes[j] = "cycle";
|
|
1311
|
+
}
|
|
1312
|
+
} else if (isValidDate(first) && isValidDate(second) && isValidDate(third)) {
|
|
1313
|
+
const step1 = Date.parse(second) - Date.parse(first);
|
|
1314
|
+
const step2 = Date.parse(third) - Date.parse(second);
|
|
1315
|
+
if (step1 === step2) {
|
|
1316
|
+
modes[j] = "date-stepping";
|
|
1317
|
+
steps[j] = step1;
|
|
1318
|
+
} else {
|
|
1319
|
+
modes[j] = "cycle";
|
|
1320
|
+
}
|
|
1321
|
+
} else {
|
|
1322
|
+
modes[j] = "cycle";
|
|
1323
|
+
}
|
|
1324
|
+
}
|
|
1325
|
+
}
|
|
1326
|
+
|
|
1327
|
+
// Tạo các dòng mới (thêm n dòng)
|
|
1328
|
+
// Với mỗi cột, nếu chế độ là stepping thì lấy giá trị cuối của mảng ban đầu và cộng thêm (i+1)*step
|
|
1329
|
+
// Nếu chế độ là cycle thì dùng arr[i mod m][j]
|
|
1330
|
+
for (let i = 0; i < n; i++) {
|
|
1331
|
+
const newRow = [];
|
|
1332
|
+
for (let j = 0; j < numCols; j++) {
|
|
1333
|
+
let newValue;
|
|
1334
|
+
switch (modes[j]) {
|
|
1335
|
+
case "number-constant":
|
|
1336
|
+
// Mảng có 1 hàng, số giữ nguyên
|
|
1337
|
+
newValue = arr[0][j];
|
|
1338
|
+
break;
|
|
1339
|
+
case "number-stepping":
|
|
1340
|
+
{
|
|
1341
|
+
// Lấy giá trị cuối của cột j trong mảng ban đầu
|
|
1342
|
+
const lastValue = arr[m - 1][j];
|
|
1343
|
+
newValue = lastValue + (i + 1) * steps[j];
|
|
1344
|
+
}
|
|
1345
|
+
break;
|
|
1346
|
+
case "date-stepping":
|
|
1347
|
+
{
|
|
1348
|
+
// Lấy giá trị cuối, chuyển về date, cộng thêm (i+1)*step, chuyển lại về định dạng ISO
|
|
1349
|
+
const lastDate = new Date(arr[m - 1][j]);
|
|
1350
|
+
const newTime = lastDate.getTime() + (i + 1) * steps[j];
|
|
1351
|
+
newValue = (0, _moment.default)(new Date(newTime)).format();
|
|
1352
|
+
}
|
|
1353
|
+
break;
|
|
1354
|
+
case "cycle":
|
|
1355
|
+
default:
|
|
1356
|
+
// Lặp lại nội dung theo vòng tròn: dùng hàng thứ (i mod m)
|
|
1357
|
+
newValue = arr[i % m][j];
|
|
1358
|
+
break;
|
|
1359
|
+
}
|
|
1360
|
+
newRow.push(newValue);
|
|
1361
|
+
}
|
|
1362
|
+
addedRows.push(newRow);
|
|
1363
|
+
}
|
|
1364
|
+
const combined = arr.concat(addedRows);
|
|
1365
|
+
return {
|
|
1366
|
+
combined,
|
|
1367
|
+
addedRows
|
|
1368
|
+
};
|
|
1369
|
+
}
|
|
1370
|
+
function addRowsDown(arr, n) {
|
|
1371
|
+
if (!Array.isArray(arr) || arr.length === 0) {
|
|
1372
|
+
return {
|
|
1373
|
+
combined: arr,
|
|
1374
|
+
addedRows: []
|
|
1375
|
+
};
|
|
1376
|
+
}
|
|
1377
|
+
const m = arr.length;
|
|
1378
|
+
const numCols = arr[0].length;
|
|
1379
|
+
const addedRows = [];
|
|
1380
|
+
|
|
1381
|
+
// // Hàm kiểm tra kiểu date hợp lệ
|
|
1382
|
+
// const isValidDate = (item: any) => {
|
|
1383
|
+
//
|
|
1384
|
+
//
|
|
1385
|
+
// // return !isNaN(Date.parse(d))
|
|
1386
|
+
//
|
|
1387
|
+
// if (typeof item === 'number') {
|
|
1388
|
+
// // return 'number'
|
|
1389
|
+
// return false
|
|
1390
|
+
// }
|
|
1391
|
+
// if (typeof item === 'string') {
|
|
1392
|
+
// // Kiểm tra nếu là chuỗi ISO date hợp lệ
|
|
1393
|
+
// const date = new Date(item)
|
|
1394
|
+
// if (!isNaN(date.getTime()) && item.includes('T')) {
|
|
1395
|
+
// // return 'date'
|
|
1396
|
+
// return true
|
|
1397
|
+
// }
|
|
1398
|
+
// // return 'string'
|
|
1399
|
+
// return false
|
|
1400
|
+
// }
|
|
1401
|
+
//
|
|
1402
|
+
// return !isNaN(Date.parse(item))
|
|
1403
|
+
//
|
|
1404
|
+
// }
|
|
1405
|
+
|
|
1406
|
+
// Lấy giá trị mẫu của cột j từ hàng đầu tiên
|
|
1407
|
+
const getSample = j => arr[0][j];
|
|
1408
|
+
|
|
1409
|
+
// Xác định chế độ xử lý cho mỗi cột:
|
|
1410
|
+
// mode = 'number-stepping' | 'date-stepping' | 'number-constant' | 'cycle'
|
|
1411
|
+
const modes = [];
|
|
1412
|
+
const steps = []; // bước tăng, nếu có (cho number hoặc date)
|
|
1413
|
+
|
|
1414
|
+
for (let j = 0; j < numCols; j++) {
|
|
1415
|
+
const sample = getSample(j);
|
|
1416
|
+
if (m === 1) {
|
|
1417
|
+
// Nếu mảng chỉ có 1 hàng: nếu là số thì giữ nguyên; nếu là date thì tăng 1 ngày; còn lại giữ nguyên.
|
|
1418
|
+
if (typeof sample === "number") {
|
|
1419
|
+
modes[j] = "number-constant";
|
|
1420
|
+
}
|
|
1421
|
+
// else if (isValidDate(sample)) {
|
|
1422
|
+
// modes[j] = "date-stepping"
|
|
1423
|
+
// steps[j] = 24 * 3600 * 1000 // 1 ngày = 86400000 ms
|
|
1424
|
+
// }
|
|
1425
|
+
else {
|
|
1426
|
+
modes[j] = "cycle";
|
|
1427
|
+
}
|
|
1428
|
+
} else if (m === 2) {
|
|
1429
|
+
// Nếu mảng có 2 hàng: nếu là số thì tính bước = row2 - row1, tương tự với date
|
|
1430
|
+
const first = arr[0][j],
|
|
1431
|
+
second = arr[1][j];
|
|
1432
|
+
if (typeof first === "number" && typeof second === "number") {
|
|
1433
|
+
modes[j] = "number-stepping";
|
|
1434
|
+
steps[j] = second - first;
|
|
1435
|
+
}
|
|
1436
|
+
// else if (isValidDate(first) && isValidDate(second)) {
|
|
1437
|
+
// modes[j] = "date-stepping"
|
|
1438
|
+
// steps[j] = Date.parse(second) - Date.parse(first)
|
|
1439
|
+
// }
|
|
1440
|
+
else {
|
|
1441
|
+
modes[j] = "cycle";
|
|
1442
|
+
}
|
|
1443
|
+
} else {
|
|
1444
|
+
// Nếu mảng có >2 hàng
|
|
1445
|
+
const first = arr[0][j],
|
|
1446
|
+
second = arr[1][j],
|
|
1447
|
+
third = arr[2][j];
|
|
1448
|
+
if (typeof first === "number" && typeof second === "number" && typeof third === "number") {
|
|
1449
|
+
const step1 = second - first;
|
|
1450
|
+
const step2 = third - second;
|
|
1451
|
+
if (step1 === step2) {
|
|
1452
|
+
modes[j] = "number-stepping";
|
|
1453
|
+
steps[j] = step1;
|
|
1454
|
+
} else {
|
|
1455
|
+
modes[j] = "cycle";
|
|
1456
|
+
}
|
|
1457
|
+
}
|
|
1458
|
+
// else if (isValidDate(first) && isValidDate(second) && isValidDate(third)) {
|
|
1459
|
+
// const step1 = Date.parse(second) - Date.parse(first)
|
|
1460
|
+
// const step2 = Date.parse(third) - Date.parse(second)
|
|
1461
|
+
// if (step1 === step2) {
|
|
1462
|
+
// modes[j] = "date-stepping"
|
|
1463
|
+
// steps[j] = step1
|
|
1464
|
+
// } else {
|
|
1465
|
+
// modes[j] = "cycle"
|
|
1466
|
+
// }
|
|
1467
|
+
// }
|
|
1468
|
+
else {
|
|
1469
|
+
modes[j] = "cycle";
|
|
1470
|
+
}
|
|
1471
|
+
}
|
|
1472
|
+
}
|
|
1473
|
+
|
|
1474
|
+
// Tạo các dòng mới (thêm n dòng)
|
|
1475
|
+
// Với mỗi cột, nếu chế độ là stepping thì lấy giá trị cuối của mảng ban đầu và cộng thêm (i+1)*step
|
|
1476
|
+
// Nếu chế độ là cycle thì dùng arr[i mod m][j]
|
|
1477
|
+
for (let i = 0; i < n; i++) {
|
|
1478
|
+
const newRow = [];
|
|
1479
|
+
for (let j = 0; j < numCols; j++) {
|
|
1480
|
+
let newValue;
|
|
1481
|
+
switch (modes[j]) {
|
|
1482
|
+
case "number-constant":
|
|
1483
|
+
// Mảng có 1 hàng, số giữ nguyên
|
|
1484
|
+
newValue = arr[0][j];
|
|
1485
|
+
break;
|
|
1486
|
+
case "number-stepping":
|
|
1487
|
+
{
|
|
1488
|
+
// Lấy giá trị cuối của cột j trong mảng ban đầu
|
|
1489
|
+
const lastValue = arr[m - 1][j];
|
|
1490
|
+
newValue = lastValue + (i + 1) * steps[j];
|
|
1491
|
+
}
|
|
1492
|
+
break;
|
|
1493
|
+
// case "date-stepping":
|
|
1494
|
+
// {
|
|
1495
|
+
// // Lấy giá trị cuối, chuyển về date, cộng thêm (i+1)*step, chuyển lại về định dạng ISO
|
|
1496
|
+
// const lastDate = new Date(arr[m - 1][j])
|
|
1497
|
+
// const newTime = lastDate.getTime() + (i + 1) * steps[j]
|
|
1498
|
+
// newValue = moment(new Date(newTime)).format()
|
|
1499
|
+
// }
|
|
1500
|
+
// break
|
|
1501
|
+
case "cycle":
|
|
1502
|
+
default:
|
|
1503
|
+
// Lặp lại nội dung theo vòng tròn: dùng hàng thứ (i mod m)
|
|
1504
|
+
newValue = arr[i % m][j];
|
|
1505
|
+
break;
|
|
1506
|
+
}
|
|
1507
|
+
newRow.push(newValue);
|
|
1508
|
+
}
|
|
1509
|
+
addedRows.push(newRow);
|
|
1510
|
+
}
|
|
1511
|
+
const combined = arr.concat(addedRows);
|
|
1512
|
+
return {
|
|
1513
|
+
combined,
|
|
1514
|
+
addedRows
|
|
1515
|
+
};
|
|
1516
|
+
}
|
|
1517
|
+
function addRowsUpWithCtrl(array, n) {
|
|
1518
|
+
const arr = array.reverse();
|
|
1519
|
+
if (!Array.isArray(arr) || arr.length === 0) {
|
|
1520
|
+
return {
|
|
1521
|
+
combined: arr,
|
|
1522
|
+
addedRows: []
|
|
1523
|
+
};
|
|
1524
|
+
}
|
|
1525
|
+
const m = arr.length;
|
|
1526
|
+
const numCols = arr[0].length;
|
|
1527
|
+
const addedRows = [];
|
|
1528
|
+
|
|
1529
|
+
// Hàm kiểm tra kiểu date hợp lệ
|
|
1530
|
+
const isValidDate = item => {
|
|
1531
|
+
// return !isNaN(Date.parse(d))
|
|
1532
|
+
|
|
1533
|
+
if (typeof item === 'number') {
|
|
1534
|
+
// return 'number'
|
|
1535
|
+
return false;
|
|
1536
|
+
}
|
|
1537
|
+
if (typeof item === 'string') {
|
|
1538
|
+
// Kiểm tra nếu là chuỗi ISO date hợp lệ
|
|
1539
|
+
const date = new Date(item);
|
|
1540
|
+
if (!isNaN(date.getTime()) && item.includes('T')) {
|
|
1541
|
+
// return 'date'
|
|
1542
|
+
return true;
|
|
1543
|
+
}
|
|
1544
|
+
// return 'string'
|
|
1545
|
+
return false;
|
|
1546
|
+
}
|
|
1547
|
+
return !isNaN(Date.parse(item));
|
|
1548
|
+
};
|
|
1549
|
+
|
|
1550
|
+
// Lấy giá trị mẫu của cột j từ hàng đầu tiên
|
|
1551
|
+
const getSample = j => arr[0][j];
|
|
1552
|
+
|
|
1553
|
+
// Xác định chế độ xử lý cho mỗi cột:
|
|
1554
|
+
// mode = 'number-stepping' | 'date-stepping' | 'number-constant' | 'cycle'
|
|
1555
|
+
const modes = [];
|
|
1556
|
+
const steps = []; // bước tăng, nếu có (cho number hoặc date)
|
|
1557
|
+
|
|
1558
|
+
for (let j = 0; j < numCols; j++) {
|
|
1559
|
+
const sample = getSample(j);
|
|
1560
|
+
if (m === 1) {
|
|
1561
|
+
// Nếu mảng chỉ có 1 hàng: nếu là số thì giữ nguyên; nếu là date thì tăng 1 ngày; còn lại giữ nguyên.
|
|
1562
|
+
if (typeof sample === "number") {
|
|
1563
|
+
modes[j] = "number-constant";
|
|
1564
|
+
} else if (isValidDate(sample)) {
|
|
1565
|
+
modes[j] = "date-stepping";
|
|
1566
|
+
steps[j] = 24 * 3600 * 1000; // 1 ngày = 86400000 ms
|
|
1567
|
+
} else {
|
|
1568
|
+
modes[j] = "cycle";
|
|
1569
|
+
}
|
|
1570
|
+
} else if (m === 2) {
|
|
1571
|
+
// Nếu mảng có 2 hàng: nếu là số thì tính bước = row2 - row1, tương tự với date
|
|
1572
|
+
const first = arr[0][j],
|
|
1573
|
+
second = arr[1][j];
|
|
1574
|
+
if (typeof first === "number" && typeof second === "number") {
|
|
1575
|
+
modes[j] = "number-stepping";
|
|
1576
|
+
steps[j] = second - first;
|
|
1577
|
+
} else if (isValidDate(first) && isValidDate(second)) {
|
|
1578
|
+
modes[j] = "date-stepping";
|
|
1579
|
+
steps[j] = Date.parse(second) - Date.parse(first);
|
|
1580
|
+
} else {
|
|
1581
|
+
modes[j] = "cycle";
|
|
1582
|
+
}
|
|
1583
|
+
} else {
|
|
1584
|
+
// Nếu mảng có >2 hàng
|
|
1585
|
+
const first = arr[0][j],
|
|
1586
|
+
second = arr[1][j],
|
|
1587
|
+
third = arr[2][j];
|
|
1588
|
+
if (typeof first === "number" && typeof second === "number" && typeof third === "number") {
|
|
1589
|
+
const step1 = second - first;
|
|
1590
|
+
const step2 = third - second;
|
|
1591
|
+
if (step1 === step2) {
|
|
1592
|
+
modes[j] = "number-stepping";
|
|
1593
|
+
steps[j] = step1;
|
|
1594
|
+
} else {
|
|
1595
|
+
modes[j] = "cycle";
|
|
1596
|
+
}
|
|
1597
|
+
} else if (isValidDate(first) && isValidDate(second) && isValidDate(third)) {
|
|
1598
|
+
const step1 = Date.parse(second) - Date.parse(first);
|
|
1599
|
+
const step2 = Date.parse(third) - Date.parse(second);
|
|
1600
|
+
if (step1 === step2) {
|
|
1601
|
+
modes[j] = "date-stepping";
|
|
1602
|
+
steps[j] = step1;
|
|
1603
|
+
} else {
|
|
1604
|
+
modes[j] = "cycle";
|
|
1605
|
+
}
|
|
1606
|
+
} else {
|
|
1607
|
+
modes[j] = "cycle";
|
|
1608
|
+
}
|
|
1609
|
+
}
|
|
1610
|
+
}
|
|
1611
|
+
|
|
1612
|
+
// Tạo các dòng mới (thêm n dòng)
|
|
1613
|
+
// Với mỗi cột, nếu chế độ là stepping thì lấy giá trị cuối của mảng ban đầu và cộng thêm (i+1)*step
|
|
1614
|
+
// Nếu chế độ là cycle thì dùng arr[i mod m][j]
|
|
1615
|
+
for (let i = n - 1; i >= 0; i--) {
|
|
1616
|
+
const newRow = [];
|
|
1617
|
+
for (let j = 0; j < numCols; j++) {
|
|
1618
|
+
let newValue;
|
|
1619
|
+
switch (modes[j]) {
|
|
1620
|
+
case "number-constant":
|
|
1621
|
+
// Mảng có 1 hàng, số giữ nguyên
|
|
1622
|
+
newValue = arr[0][j];
|
|
1623
|
+
break;
|
|
1624
|
+
case "number-stepping":
|
|
1625
|
+
{
|
|
1626
|
+
// Lấy giá trị cuối của cột j trong mảng ban đầu
|
|
1627
|
+
|
|
1628
|
+
const lastValue = arr[m - 1][j];
|
|
1629
|
+
newValue = lastValue - (i + 1) * steps[j] * -1;
|
|
1630
|
+
}
|
|
1631
|
+
break;
|
|
1632
|
+
case "date-stepping":
|
|
1633
|
+
{
|
|
1634
|
+
// Lấy giá trị cuối, chuyển về date, cộng thêm (i+1)*step, chuyển lại về định dạng ISO
|
|
1635
|
+
|
|
1636
|
+
const lastDate = new Date(arr[m - 1][j]);
|
|
1637
|
+
const newTime = m === 1 ? lastDate.getTime() - (i + 1) * steps[j] : lastDate.getTime() - (i + 1) * steps[j] * -1;
|
|
1638
|
+
newValue = (0, _moment.default)(new Date(newTime)).format();
|
|
1639
|
+
}
|
|
1640
|
+
break;
|
|
1641
|
+
case "cycle":
|
|
1642
|
+
default:
|
|
1643
|
+
// Lặp lại nội dung theo vòng tròn: dùng hàng thứ (i mod m)
|
|
1644
|
+
|
|
1645
|
+
newValue = arr[i % m][j];
|
|
1646
|
+
break;
|
|
1647
|
+
}
|
|
1648
|
+
newRow.push(newValue);
|
|
1649
|
+
}
|
|
1650
|
+
addedRows.push(newRow);
|
|
1651
|
+
}
|
|
1652
|
+
const combined = arr.concat(addedRows);
|
|
1653
|
+
return {
|
|
1654
|
+
combined,
|
|
1655
|
+
addedRows
|
|
1656
|
+
};
|
|
1657
|
+
}
|
|
1658
|
+
function addRowsUp(array, n) {
|
|
1659
|
+
const arr = array.reverse();
|
|
1660
|
+
if (!Array.isArray(arr) || arr.length === 0) {
|
|
1661
|
+
return {
|
|
1662
|
+
combined: arr,
|
|
1663
|
+
addedRows: []
|
|
1664
|
+
};
|
|
1665
|
+
}
|
|
1666
|
+
const m = arr.length;
|
|
1667
|
+
const numCols = arr[0].length;
|
|
1668
|
+
const addedRows = [];
|
|
1669
|
+
|
|
1670
|
+
// Hàm kiểm tra kiểu date hợp lệ
|
|
1671
|
+
// const isValidDate = (item: any) => {
|
|
1672
|
+
//
|
|
1673
|
+
//
|
|
1674
|
+
// // return !isNaN(Date.parse(d))
|
|
1675
|
+
//
|
|
1676
|
+
// if (typeof item === 'number') {
|
|
1677
|
+
// // return 'number'
|
|
1678
|
+
// return false
|
|
1679
|
+
// }
|
|
1680
|
+
// if (typeof item === 'string') {
|
|
1681
|
+
// // Kiểm tra nếu là chuỗi ISO date hợp lệ
|
|
1682
|
+
// const date = new Date(item)
|
|
1683
|
+
// if (!isNaN(date.getTime()) && item.includes('T')) {
|
|
1684
|
+
// // return 'date'
|
|
1685
|
+
// return true
|
|
1686
|
+
// }
|
|
1687
|
+
// // return 'string'
|
|
1688
|
+
// return false
|
|
1689
|
+
// }
|
|
1690
|
+
//
|
|
1691
|
+
// return !isNaN(Date.parse(item))
|
|
1692
|
+
//
|
|
1693
|
+
// }
|
|
1694
|
+
|
|
1695
|
+
// Lấy giá trị mẫu của cột j từ hàng đầu tiên
|
|
1696
|
+
const getSample = j => arr[0][j];
|
|
1697
|
+
|
|
1698
|
+
// Xác định chế độ xử lý cho mỗi cột:
|
|
1699
|
+
// mode = 'number-stepping' | 'date-stepping' | 'number-constant' | 'cycle'
|
|
1700
|
+
const modes = [];
|
|
1701
|
+
const steps = []; // bước tăng, nếu có (cho number hoặc date)
|
|
1702
|
+
|
|
1703
|
+
for (let j = 0; j < numCols; j++) {
|
|
1704
|
+
const sample = getSample(j);
|
|
1705
|
+
if (m === 1) {
|
|
1706
|
+
// Nếu mảng chỉ có 1 hàng: nếu là số thì giữ nguyên; nếu là date thì tăng 1 ngày; còn lại giữ nguyên.
|
|
1707
|
+
if (typeof sample === "number") {
|
|
1708
|
+
modes[j] = "number-constant";
|
|
1709
|
+
} else {
|
|
1710
|
+
modes[j] = "cycle";
|
|
1711
|
+
}
|
|
1712
|
+
} else if (m === 2) {
|
|
1713
|
+
// Nếu mảng có 2 hàng: nếu là số thì tính bước = row2 - row1, tương tự với date
|
|
1714
|
+
const first = arr[0][j],
|
|
1715
|
+
second = arr[1][j];
|
|
1716
|
+
if (typeof first === "number" && typeof second === "number") {
|
|
1717
|
+
modes[j] = "number-stepping";
|
|
1718
|
+
steps[j] = second - first;
|
|
1719
|
+
} else {
|
|
1720
|
+
modes[j] = "cycle";
|
|
1721
|
+
}
|
|
1722
|
+
} else {
|
|
1723
|
+
// Nếu mảng có >2 hàng
|
|
1724
|
+
const first = arr[0][j],
|
|
1725
|
+
second = arr[1][j],
|
|
1726
|
+
third = arr[2][j];
|
|
1727
|
+
if (typeof first === "number" && typeof second === "number" && typeof third === "number") {
|
|
1728
|
+
const step1 = second - first;
|
|
1729
|
+
const step2 = third - second;
|
|
1730
|
+
if (step1 === step2) {
|
|
1731
|
+
modes[j] = "number-stepping";
|
|
1732
|
+
steps[j] = step1;
|
|
1733
|
+
} else {
|
|
1734
|
+
modes[j] = "cycle";
|
|
1735
|
+
}
|
|
1736
|
+
} else {
|
|
1737
|
+
modes[j] = "cycle";
|
|
1738
|
+
}
|
|
1739
|
+
}
|
|
1740
|
+
}
|
|
1741
|
+
|
|
1742
|
+
// Tạo các dòng mới (thêm n dòng)
|
|
1743
|
+
// Với mỗi cột, nếu chế độ là stepping thì lấy giá trị cuối của mảng ban đầu và cộng thêm (i+1)*step
|
|
1744
|
+
// Nếu chế độ là cycle thì dùng arr[i mod m][j]
|
|
1745
|
+
for (let i = n - 1; i >= 0; i--) {
|
|
1746
|
+
const newRow = [];
|
|
1747
|
+
for (let j = 0; j < numCols; j++) {
|
|
1748
|
+
let newValue;
|
|
1749
|
+
switch (modes[j]) {
|
|
1750
|
+
case "number-constant":
|
|
1751
|
+
// Mảng có 1 hàng, số giữ nguyên
|
|
1752
|
+
newValue = arr[0][j];
|
|
1753
|
+
break;
|
|
1754
|
+
case "number-stepping":
|
|
1755
|
+
{
|
|
1756
|
+
// Lấy giá trị cuối của cột j trong mảng ban đầu
|
|
1757
|
+
|
|
1758
|
+
const lastValue = arr[m - 1][j];
|
|
1759
|
+
newValue = lastValue - (i + 1) * steps[j] * -1;
|
|
1760
|
+
}
|
|
1761
|
+
break;
|
|
1762
|
+
case "cycle":
|
|
1763
|
+
default:
|
|
1764
|
+
// Lặp lại nội dung theo vòng tròn: dùng hàng thứ (i mod m)
|
|
1765
|
+
|
|
1766
|
+
newValue = arr[i % m][j];
|
|
1767
|
+
break;
|
|
1768
|
+
}
|
|
1769
|
+
newRow.push(newValue);
|
|
1770
|
+
}
|
|
1771
|
+
addedRows.push(newRow);
|
|
1772
|
+
}
|
|
1773
|
+
const combined = arr.concat(addedRows);
|
|
1774
|
+
return {
|
|
1775
|
+
combined,
|
|
1776
|
+
addedRows
|
|
1777
|
+
};
|
|
1778
|
+
}
|
|
1779
|
+
const convertFilters = filters => {
|
|
1780
|
+
const result = [];
|
|
1781
|
+
filters.forEach(({
|
|
1782
|
+
key,
|
|
1783
|
+
column,
|
|
1784
|
+
filteredKeys,
|
|
1785
|
+
operator
|
|
1786
|
+
}) => {
|
|
1787
|
+
if (!filteredKeys || filteredKeys.length === 0) {
|
|
1788
|
+
return;
|
|
1789
|
+
}
|
|
1790
|
+
if (column?.typeFilter === "DateRange" && filteredKeys.length === 2) {
|
|
1791
|
+
result.push({
|
|
1792
|
+
key,
|
|
1793
|
+
field: column?.field,
|
|
1794
|
+
value: filteredKeys[0],
|
|
1795
|
+
predicate: "and",
|
|
1796
|
+
operator: "greaterthanorequal"
|
|
1797
|
+
}, {
|
|
1798
|
+
key,
|
|
1799
|
+
field: column?.field,
|
|
1800
|
+
value: filteredKeys[1],
|
|
1801
|
+
predicate: "and",
|
|
1802
|
+
operator: "lessthanorequal"
|
|
1803
|
+
});
|
|
1804
|
+
} else if (column?.typeFilter === "NumberRange") {
|
|
1805
|
+
if ((filteredKeys[0] || filteredKeys[0] === 0) && !filteredKeys[1]) {
|
|
1806
|
+
result.push({
|
|
1807
|
+
key,
|
|
1808
|
+
field: column?.field,
|
|
1809
|
+
value: filteredKeys[0],
|
|
1810
|
+
predicate: "and",
|
|
1811
|
+
operator: "greaterthanorequal"
|
|
1812
|
+
});
|
|
1813
|
+
}
|
|
1814
|
+
if ((filteredKeys[1] || filteredKeys[1] === 0) && !filteredKeys[0]) {
|
|
1815
|
+
result.push({
|
|
1816
|
+
key,
|
|
1817
|
+
field: column?.field,
|
|
1818
|
+
value: filteredKeys[1],
|
|
1819
|
+
predicate: "and",
|
|
1820
|
+
operator: "lessthanorequal"
|
|
1821
|
+
});
|
|
1822
|
+
}
|
|
1823
|
+
if ((filteredKeys[0] || filteredKeys[0] === 0) && (filteredKeys[1] || filteredKeys[1] === 0)) {
|
|
1824
|
+
result.push({
|
|
1825
|
+
key,
|
|
1826
|
+
field: column?.field,
|
|
1827
|
+
value: filteredKeys[0],
|
|
1828
|
+
predicate: "and",
|
|
1829
|
+
operator: "greaterthanorequal"
|
|
1830
|
+
}, {
|
|
1831
|
+
key,
|
|
1832
|
+
field: column?.field,
|
|
1833
|
+
value: filteredKeys[1],
|
|
1834
|
+
predicate: "and",
|
|
1835
|
+
operator: "lessthanorequal"
|
|
1836
|
+
});
|
|
1837
|
+
}
|
|
1838
|
+
} else if (column?.typeFilter === 'Checkbox') {
|
|
1839
|
+
filteredKeys.forEach(value => {
|
|
1840
|
+
result.push({
|
|
1841
|
+
key,
|
|
1842
|
+
field: column?.field,
|
|
1843
|
+
value,
|
|
1844
|
+
predicate: "or",
|
|
1845
|
+
operator
|
|
1846
|
+
});
|
|
1847
|
+
});
|
|
1848
|
+
} else {
|
|
1849
|
+
result.push({
|
|
1850
|
+
key,
|
|
1851
|
+
field: column?.field,
|
|
1852
|
+
value: filteredKeys[0],
|
|
1853
|
+
predicate: 'and',
|
|
1854
|
+
operator
|
|
1855
|
+
});
|
|
1856
|
+
}
|
|
1857
|
+
});
|
|
1858
|
+
return result;
|
|
1859
|
+
};
|
|
1860
|
+
|
|
1861
|
+
// export function getInvisibleColumns(columns: ColumnTable[]): Record<string, boolean> {
|
|
1862
|
+
// const result: Record<string, boolean> = {};
|
|
1863
|
+
// for (const col of columns) {
|
|
1864
|
+
// if (col.visible === false || col.hidden) {
|
|
1865
|
+
// result[col.field ?? ''] = false;
|
|
1866
|
+
// }
|
|
1867
|
+
// }
|
|
1868
|
+
// return result;
|
|
1869
|
+
// }
|
|
1870
|
+
exports.convertFilters = convertFilters;
|
|
1871
|
+
function getInvisibleColumns(columns) {
|
|
1872
|
+
const result = {};
|
|
1873
|
+
function traverse(cols) {
|
|
1874
|
+
for (const col of cols) {
|
|
1875
|
+
if (col.visible === false) {
|
|
1876
|
+
result[col.field ?? ''] = false;
|
|
1877
|
+
}
|
|
1878
|
+
if (col.children && col.children.length > 0) {
|
|
1879
|
+
traverse(col.children);
|
|
1880
|
+
}
|
|
1881
|
+
}
|
|
1882
|
+
}
|
|
1883
|
+
traverse(columns);
|
|
1884
|
+
return result;
|
|
1885
|
+
}
|
|
1886
|
+
const getAllVisibleKeys = columns => {
|
|
1887
|
+
const keys = [];
|
|
1888
|
+
const traverse = (cols, parentHidden = false) => {
|
|
1889
|
+
for (const col of cols) {
|
|
1890
|
+
if (col.hidden || parentHidden) {
|
|
1891
|
+
continue;
|
|
1892
|
+
}
|
|
1893
|
+
if (col.key) {
|
|
1894
|
+
keys.push(col.key);
|
|
1895
|
+
}
|
|
1896
|
+
if (col.children) {
|
|
1897
|
+
traverse(col.children, col.hidden);
|
|
1898
|
+
}
|
|
1899
|
+
}
|
|
1900
|
+
};
|
|
1901
|
+
traverse(columns);
|
|
1902
|
+
return keys;
|
|
1903
|
+
};
|
|
1904
|
+
exports.getAllVisibleKeys = getAllVisibleKeys;
|
|
1905
|
+
const getAllVisibleKeys1 = columns => {
|
|
1906
|
+
const keys = [];
|
|
1907
|
+
const traverse = (cols, parentHidden = false) => {
|
|
1908
|
+
for (const col of cols) {
|
|
1909
|
+
if (col.visible === false || col.hidden || parentHidden) {
|
|
1910
|
+
continue;
|
|
1911
|
+
}
|
|
1912
|
+
if (col.field) {
|
|
1913
|
+
keys.push(col.field);
|
|
1914
|
+
}
|
|
1915
|
+
if (col.children) {
|
|
1916
|
+
traverse(col.children, col.visible);
|
|
1917
|
+
}
|
|
1918
|
+
}
|
|
1919
|
+
};
|
|
1920
|
+
traverse(columns);
|
|
1921
|
+
return keys;
|
|
1922
|
+
};
|
|
1923
|
+
exports.getAllVisibleKeys1 = getAllVisibleKeys1;
|
|
1924
|
+
function getHiddenParentKeys(columns, parentKeys = []) {
|
|
1925
|
+
const hiddenParents = new Set();
|
|
1926
|
+
for (const column of columns) {
|
|
1927
|
+
if (column.children) {
|
|
1928
|
+
const currentPath = column.key ? [...parentKeys, column.key] : [...parentKeys];
|
|
1929
|
+
const childHiddenParents = getHiddenParentKeys(column.children, currentPath);
|
|
1930
|
+
if (childHiddenParents.length > 0) {
|
|
1931
|
+
childHiddenParents.forEach(key => hiddenParents.add(key));
|
|
1932
|
+
currentPath.forEach(key => hiddenParents.add(key));
|
|
1933
|
+
}
|
|
1934
|
+
} else if (column.hidden) {
|
|
1935
|
+
parentKeys.forEach(key => hiddenParents.add(key));
|
|
1936
|
+
}
|
|
1937
|
+
}
|
|
1938
|
+
return Array.from(hiddenParents);
|
|
1939
|
+
}
|
|
1940
|
+
function getHiddenParentKeys1(columns, parentKeys = []) {
|
|
1941
|
+
const hiddenParents = new Set();
|
|
1942
|
+
for (const column of columns) {
|
|
1943
|
+
if (column.children) {
|
|
1944
|
+
const currentPath = column.field ? [...parentKeys, column.field] : [...parentKeys];
|
|
1945
|
+
const childHiddenParents = getHiddenParentKeys1(column.children, currentPath);
|
|
1946
|
+
if (childHiddenParents.length > 0) {
|
|
1947
|
+
childHiddenParents.forEach(key => hiddenParents.add(key));
|
|
1948
|
+
currentPath.forEach(key => hiddenParents.add(key));
|
|
1949
|
+
}
|
|
1950
|
+
} else if (column.visible !== false && column.hidden !== true) {
|
|
1951
|
+
parentKeys.forEach(key => hiddenParents.add(key));
|
|
1952
|
+
}
|
|
1953
|
+
}
|
|
1954
|
+
return Array.from(hiddenParents);
|
|
1955
|
+
}
|
|
1956
|
+
const getVisibleColumnKeys = columns => {
|
|
1957
|
+
const allKeys = getAllVisibleKeys(columns);
|
|
1958
|
+
const allParentKeys = getHiddenParentKeys(columns);
|
|
1959
|
+
return allKeys.filter(item => !allParentKeys.includes(item));
|
|
1960
|
+
};
|
|
1961
|
+
exports.getVisibleColumnKeys = getVisibleColumnKeys;
|
|
1962
|
+
const getVisibleColumnKeys1 = columns => {
|
|
1963
|
+
const allKeys = getAllVisibleKeys1(columns);
|
|
1964
|
+
const allParentKeys = getHiddenParentKeys1(columns);
|
|
1965
|
+
return allKeys.filter(item => !allParentKeys.includes(item));
|
|
1966
|
+
};
|
|
1967
|
+
exports.getVisibleColumnKeys1 = getVisibleColumnKeys1;
|
|
1968
|
+
function isObjEqual(obj1, obj2) {
|
|
1969
|
+
// Trường hợp tham chiếu bằng nhau
|
|
1970
|
+
if (obj1 === obj2) return true;
|
|
1971
|
+
|
|
1972
|
+
// Nếu 1 trong 2 không phải object hoặc null thì so sánh trực tiếp
|
|
1973
|
+
if (typeof obj1 !== 'object' || obj1 === null || typeof obj2 !== 'object' || obj2 === null) {
|
|
1974
|
+
return obj1 === obj2;
|
|
1975
|
+
}
|
|
1976
|
+
|
|
1977
|
+
// Lấy danh sách key
|
|
1978
|
+
const keys1 = Object.keys(obj1);
|
|
1979
|
+
const keys2 = Object.keys(obj2);
|
|
1980
|
+
|
|
1981
|
+
// Nếu số key khác nhau thì khác nhau
|
|
1982
|
+
if (keys1.length !== keys2.length) return false;
|
|
1983
|
+
|
|
1984
|
+
// Duyệt và so sánh từng key
|
|
1985
|
+
for (const key of keys1) {
|
|
1986
|
+
if (!keys2.includes(key)) return false;
|
|
1987
|
+
if (!isObjEqual(obj1[key], obj2[key])) return false;
|
|
1988
|
+
}
|
|
1989
|
+
return true;
|
|
1990
|
+
}
|
|
1991
|
+
|
|
1992
|
+
// Sorting function
|
|
1993
|
+
const sortByType = arr => {
|
|
1994
|
+
if (arr) {
|
|
1995
|
+
return arr.sort((a, b) => {
|
|
1996
|
+
if ((a.fixed ?? a.fixedType) === 'left' && (b.fixed ?? b.fixedType) !== 'left') {
|
|
1997
|
+
return -1;
|
|
1998
|
+
} else if ((a.fixed ?? a.fixedType) !== 'left' && (b.fixed ?? b.fixedType) === 'left') {
|
|
1999
|
+
return 1;
|
|
2000
|
+
} else if ((a.fixed ?? a.fixedType) === 'right' && (b.fixed ?? b.fixedType) !== 'right') {
|
|
2001
|
+
return 1;
|
|
2002
|
+
} else if ((a.fixed ?? a.fixedType) !== 'right' && (b.fixed ?? b.fixedType) === 'right') {
|
|
2003
|
+
return -1;
|
|
2004
|
+
}
|
|
2005
|
+
return 0;
|
|
2006
|
+
});
|
|
2007
|
+
} else {
|
|
2008
|
+
return [];
|
|
2009
|
+
}
|
|
2010
|
+
};
|
|
2011
|
+
exports.sortByType = sortByType;
|
|
2012
|
+
function convertColumnsToTreeData(columns, groupColumns) {
|
|
2013
|
+
// return columns.map((col) => {
|
|
2014
|
+
// const node: TreeDataNode = {
|
|
2015
|
+
// key: String(col.id ?? col.id ?? col.header), // key duy nhất
|
|
2016
|
+
// title: String(col.header ?? col.id ?? ''), // tiêu đề
|
|
2017
|
+
// }
|
|
2018
|
+
|
|
2019
|
+
// // Nếu có children (nested columns)
|
|
2020
|
+
// if ('columns' in col && Array.isArray((col as any).columns)) {
|
|
2021
|
+
// node.children = convertColumnsToTreeData(
|
|
2022
|
+
// (col as any).columns as ColumnDef<T, any>[]
|
|
2023
|
+
// )
|
|
2024
|
+
// }
|
|
2025
|
+
|
|
2026
|
+
// return node
|
|
2027
|
+
// })
|
|
2028
|
+
|
|
2029
|
+
return columns.filter(col => {
|
|
2030
|
+
const meta = col.meta ?? {};
|
|
2031
|
+
const inGroup = groupColumns ? groupColumns.includes(String(col.id ?? col.id)) : false;
|
|
2032
|
+
|
|
2033
|
+
// Điều kiện filter:
|
|
2034
|
+
// - Nếu meta.showInColumnChoose = false => loại bỏ
|
|
2035
|
+
// - Nếu không nằm trong groupColumns và không phải column group => loại bỏ
|
|
2036
|
+
if (meta.showInColumnChoose === false) return false;
|
|
2037
|
+
if (inGroup && !('columns' in col && Array.isArray(col.columns))) {
|
|
2038
|
+
return false;
|
|
2039
|
+
}
|
|
2040
|
+
return true;
|
|
2041
|
+
}).map(col => {
|
|
2042
|
+
const node = {
|
|
2043
|
+
key: String(col.id ?? col.id ?? col.header),
|
|
2044
|
+
// title: () => col.header as any
|
|
2045
|
+
title: col.header
|
|
2046
|
+
|
|
2047
|
+
// title: String(col.header ?? col.id ?? ''),
|
|
2048
|
+
};
|
|
2049
|
+
if ('columns' in col && Array.isArray(col.columns)) {
|
|
2050
|
+
const children = convertColumnsToTreeData(col.columns, groupColumns);
|
|
2051
|
+
if (children.length > 0) {
|
|
2052
|
+
node.children = children;
|
|
2053
|
+
}
|
|
2054
|
+
}
|
|
2055
|
+
return node;
|
|
2056
|
+
});
|
|
2057
|
+
}
|
|
2058
|
+
const updateColumns1 = (columns, includes) => {
|
|
2059
|
+
return columns.map(column => {
|
|
2060
|
+
const newColumn = {
|
|
2061
|
+
...column
|
|
2062
|
+
};
|
|
2063
|
+
let hasVisibleChild = false;
|
|
2064
|
+
if (!column.field) {
|
|
2065
|
+
return column;
|
|
2066
|
+
}
|
|
2067
|
+
if (newColumn.children) {
|
|
2068
|
+
newColumn.children = updateColumns1(newColumn.children, includes);
|
|
2069
|
+
hasVisibleChild = newColumn.children.some(child => !child.hidden);
|
|
2070
|
+
}
|
|
2071
|
+
newColumn.visible = !!(newColumn.field && includes.includes(newColumn.field));
|
|
2072
|
+
if (newColumn.children && newColumn.children.length > 0) {
|
|
2073
|
+
newColumn.visible = !hasVisibleChild;
|
|
2074
|
+
}
|
|
2075
|
+
return newColumn;
|
|
2076
|
+
});
|
|
2077
|
+
};
|
|
2078
|
+
exports.updateColumns1 = updateColumns1;
|
|
2079
|
+
const convertToObj = arr => {
|
|
2080
|
+
// const result = Object.keys(obj).reduce((acc: any, key) => {
|
|
2081
|
+
// acc[key] = false;
|
|
2082
|
+
// return acc;
|
|
2083
|
+
// }, {});
|
|
2084
|
+
|
|
2085
|
+
// return result
|
|
2086
|
+
|
|
2087
|
+
return Object.fromEntries(arr.map(key => [key, false]));
|
|
2088
|
+
};
|
|
2089
|
+
exports.convertToObj = convertToObj;
|
|
2090
|
+
const convertToObjTrue = arr => {
|
|
2091
|
+
// const result = Object.keys(obj).reduce((acc: any, key) => {
|
|
2092
|
+
// acc[key] = false;
|
|
2093
|
+
// return acc;
|
|
2094
|
+
// }, {});
|
|
2095
|
+
|
|
2096
|
+
// return result
|
|
2097
|
+
|
|
2098
|
+
return Object.fromEntries(arr.map(key => [key, true]));
|
|
2099
|
+
};
|
|
2100
|
+
exports.convertToObjTrue = convertToObjTrue;
|
|
2101
|
+
const getDiffent2Array = (a, b) => {
|
|
2102
|
+
return [...a.filter(x => !b.includes(x)), ...b.filter(x => !a.includes(x))];
|
|
2103
|
+
};
|
|
2104
|
+
exports.getDiffent2Array = getDiffent2Array;
|
|
2105
|
+
function findFirst(items) {
|
|
2106
|
+
// const leftItem = items.find(item => item.getIsPinned() === 'left')
|
|
2107
|
+
const leftItem = items.find(item => item.getIsPinned() === 'left');
|
|
2108
|
+
if (leftItem) return leftItem;
|
|
2109
|
+
return null;
|
|
2110
|
+
}
|
|
2111
|
+
function isTreeArray(arr) {
|
|
2112
|
+
if (!Array.isArray(arr) || arr.length === 0) {
|
|
2113
|
+
return false;
|
|
2114
|
+
}
|
|
2115
|
+
for (const item of arr) {
|
|
2116
|
+
if (!item) {
|
|
2117
|
+
return false;
|
|
2118
|
+
}
|
|
2119
|
+
if (item.children?.length > 0) {
|
|
2120
|
+
return true;
|
|
2121
|
+
}
|
|
2122
|
+
}
|
|
2123
|
+
return false;
|
|
2124
|
+
}
|
|
2125
|
+
function updateColumnWidthsRecursive(columns, sizing) {
|
|
2126
|
+
return columns.map(col => {
|
|
2127
|
+
const updated = {
|
|
2128
|
+
...col
|
|
2129
|
+
};
|
|
2130
|
+
|
|
2131
|
+
// cập nhật width nếu có trong sizing
|
|
2132
|
+
if (sizing[col.field] !== undefined) {
|
|
2133
|
+
updated.width = sizing[col.field];
|
|
2134
|
+
}
|
|
2135
|
+
|
|
2136
|
+
// nếu có children thì gọi đệ quy
|
|
2137
|
+
if (col.children && col.children.length > 0) {
|
|
2138
|
+
updated.children = updateColumnWidthsRecursive(col.children, sizing);
|
|
2139
|
+
}
|
|
2140
|
+
return updated;
|
|
2141
|
+
});
|
|
2142
|
+
}
|
|
2143
|
+
function updateWidthsByOther(source, target) {
|
|
2144
|
+
const targetMap = new Map();
|
|
2145
|
+
|
|
2146
|
+
// tạo map {field -> width} từ target
|
|
2147
|
+
const buildMap = cols => {
|
|
2148
|
+
cols.forEach(col => {
|
|
2149
|
+
if (col.width !== undefined) {
|
|
2150
|
+
targetMap.set(col.field, col.width);
|
|
2151
|
+
}
|
|
2152
|
+
if (col.children) {
|
|
2153
|
+
buildMap(col.children);
|
|
2154
|
+
}
|
|
2155
|
+
});
|
|
2156
|
+
};
|
|
2157
|
+
buildMap(target);
|
|
2158
|
+
|
|
2159
|
+
// cập nhật width từ map
|
|
2160
|
+
const update = cols => cols.map(col => {
|
|
2161
|
+
const updated = {
|
|
2162
|
+
...col
|
|
2163
|
+
};
|
|
2164
|
+
if (targetMap.has(col.field)) {
|
|
2165
|
+
updated.width = targetMap.get(col.field);
|
|
2166
|
+
}
|
|
2167
|
+
if (col.children) {
|
|
2168
|
+
updated.children = update(col.children);
|
|
2169
|
+
}
|
|
2170
|
+
return updated;
|
|
2171
|
+
});
|
|
2172
|
+
return update(source);
|
|
2173
|
+
}
|
|
2174
|
+
function findAllChildrenKeys2(data, rowKey, childrenColumnName) {
|
|
2175
|
+
const keys = [];
|
|
2176
|
+
function dig(list) {
|
|
2177
|
+
(list || []).forEach(item => {
|
|
2178
|
+
keys.push(item[rowKey]);
|
|
2179
|
+
dig(item[childrenColumnName]);
|
|
2180
|
+
});
|
|
2181
|
+
}
|
|
2182
|
+
dig(data);
|
|
2183
|
+
return keys;
|
|
2184
|
+
}
|
|
2185
|
+
function parseExcelText(text) {
|
|
2186
|
+
// const text = e.clipboardData?.getData('text/plain') ?? '';
|
|
2187
|
+
if (!text) return [];
|
|
2188
|
+
|
|
2189
|
+
// Excel thường dùng \r\n giữa dòng, \t giữa cột
|
|
2190
|
+
const rows = text.split(/\r?\n/) // tách theo dòng
|
|
2191
|
+
.filter(r => r.trim() !== '') // bỏ dòng trống
|
|
2192
|
+
.map(row => row.split('\t') // tách theo cột
|
|
2193
|
+
.map(cell => cell.replace(/\r/g, '').replace(/\n/g, '\n')) // giữ xuống dòng trong ô
|
|
2194
|
+
);
|
|
2195
|
+
return rows;
|
|
2196
|
+
}
|
|
2197
|
+
function parseExcelClipboard(e) {
|
|
2198
|
+
const text = e.clipboardData?.getData('text/plain') ?? '';
|
|
2199
|
+
if (!text) return [];
|
|
2200
|
+
|
|
2201
|
+
// Excel thường dùng \r\n giữa dòng, \t giữa cột
|
|
2202
|
+
const rows = text.split(/\r?\n/) // tách theo dòng
|
|
2203
|
+
.filter(r => r.trim() !== '') // bỏ dòng trống
|
|
2204
|
+
.map(row => row.split('\t') // tách theo cột
|
|
2205
|
+
.map(cell => cell.replace(/\r/g, '').replace(/\n/g, '\n')) // giữ xuống dòng trong ô
|
|
2206
|
+
);
|
|
2207
|
+
return rows;
|
|
2208
|
+
}
|
|
2209
|
+
function parseExcelClipboardText(text) {
|
|
2210
|
+
const rows = [];
|
|
2211
|
+
let curRow = [];
|
|
2212
|
+
let curCell = '';
|
|
2213
|
+
let inQuotes = false;
|
|
2214
|
+
for (let i = 0; i < text.length; i++) {
|
|
2215
|
+
const ch = text[i];
|
|
2216
|
+
if (ch === '"') {
|
|
2217
|
+
// "" -> an escaped quote inside quoted field
|
|
2218
|
+
if (inQuotes && text[i + 1] === '"') {
|
|
2219
|
+
curCell += '"';
|
|
2220
|
+
i++; // skip next
|
|
2221
|
+
} else {
|
|
2222
|
+
inQuotes = !inQuotes; // open/close quote
|
|
2223
|
+
}
|
|
2224
|
+
continue;
|
|
2225
|
+
}
|
|
2226
|
+
|
|
2227
|
+
// tab as column separator (only if not inside quotes)
|
|
2228
|
+
if (ch === '\t' && !inQuotes) {
|
|
2229
|
+
curRow.push(curCell);
|
|
2230
|
+
curCell = '';
|
|
2231
|
+
continue;
|
|
2232
|
+
}
|
|
2233
|
+
|
|
2234
|
+
// newline as row separator (handle \r\n and lone \r or \n), only outside quotes
|
|
2235
|
+
if ((ch === '\r' || ch === '\n') && !inQuotes) {
|
|
2236
|
+
// handle CRLF
|
|
2237
|
+
if (ch === '\r' && text[i + 1] === '\n') i++;
|
|
2238
|
+
curRow.push(curCell);
|
|
2239
|
+
curCell = '';
|
|
2240
|
+
rows.push(curRow);
|
|
2241
|
+
curRow = [];
|
|
2242
|
+
continue;
|
|
2243
|
+
}
|
|
2244
|
+
|
|
2245
|
+
// normal character
|
|
2246
|
+
curCell += ch;
|
|
2247
|
+
}
|
|
2248
|
+
|
|
2249
|
+
// push last cell/row (if any)
|
|
2250
|
+
// avoid adding one spurious empty row when text ends with newline (we already pushed that row)
|
|
2251
|
+
if (curCell !== '' || curRow.length > 0) {
|
|
2252
|
+
curRow.push(curCell);
|
|
2253
|
+
rows.push(curRow);
|
|
2254
|
+
}
|
|
2255
|
+
|
|
2256
|
+
// if the whole input was empty, return []
|
|
2257
|
+
if (rows.length === 1 && rows[0].length === 1 && rows[0][0] === '' && text.trim() === '') {
|
|
2258
|
+
return [];
|
|
2259
|
+
}
|
|
2260
|
+
return rows;
|
|
2261
|
+
}
|
|
2262
|
+
function parseClipboardEvent(e) {
|
|
2263
|
+
const dataTransfer = e.clipboardData ?? e.nativeEvent?.clipboardData;
|
|
2264
|
+
if (!dataTransfer) return [];
|
|
2265
|
+
|
|
2266
|
+
// 1) try HTML (better fidelity for Excel)
|
|
2267
|
+
const html = dataTransfer.getData?.('text/html');
|
|
2268
|
+
if (html) {
|
|
2269
|
+
try {
|
|
2270
|
+
const doc = new DOMParser().parseFromString(html, 'text/html');
|
|
2271
|
+
const table = doc.querySelector('table');
|
|
2272
|
+
if (table) {
|
|
2273
|
+
const result = [];
|
|
2274
|
+
for (const tr of Array.from(table.rows)) {
|
|
2275
|
+
const row = [];
|
|
2276
|
+
for (const cell of Array.from(tr.cells)) {
|
|
2277
|
+
// innerText preserves newlines from <br>
|
|
2278
|
+
row.push(cell.innerText ?? '');
|
|
2279
|
+
}
|
|
2280
|
+
result.push(row);
|
|
2281
|
+
}
|
|
2282
|
+
if (result.length) return result;
|
|
2283
|
+
}
|
|
2284
|
+
} catch {
|
|
2285
|
+
// fallback to text parsing
|
|
2286
|
+
}
|
|
2287
|
+
}
|
|
2288
|
+
|
|
2289
|
+
// 2) fallback: parse plain text (TSV with quoted fields)
|
|
2290
|
+
const text = dataTransfer.getData?.('text/plain') ?? '';
|
|
2291
|
+
return parseExcelClipboardText(text);
|
|
2292
|
+
}
|
|
2293
|
+
function arraysEqualIgnoreOrderFast(a, b) {
|
|
2294
|
+
if (a.length !== b.length) return false;
|
|
2295
|
+
const count = Object.create(null);
|
|
2296
|
+
for (let i = 0; i < a.length; i++) {
|
|
2297
|
+
const key = a[i];
|
|
2298
|
+
count[key] = (count[key] || 0) + 1;
|
|
2299
|
+
}
|
|
2300
|
+
for (let i = 0; i < b.length; i++) {
|
|
2301
|
+
const key = b[i];
|
|
2302
|
+
if (!count[key]) return false;
|
|
2303
|
+
count[key]--;
|
|
2304
|
+
if (count[key] === 0) delete count[key];
|
|
2305
|
+
}
|
|
2306
|
+
return Object.keys(count).length === 0;
|
|
2307
|
+
}
|
|
2308
|
+
function filterByIds(a, b) {
|
|
2309
|
+
const idSet = new Set(a);
|
|
2310
|
+
return b.filter(item => idSet.has(item.id));
|
|
2311
|
+
}
|
|
2312
|
+
function excludeItems(arrayA, arrayB) {
|
|
2313
|
+
const idsInB = new Set(arrayB.map(item => item.id));
|
|
2314
|
+
|
|
2315
|
+
// Lọc A, chỉ giữ lại phần tử không có trong B
|
|
2316
|
+
return arrayA.filter(item => !idsInB.has(item.id));
|
|
2317
|
+
}
|
|
2318
|
+
function getAllChildren(row) {
|
|
2319
|
+
const children = row.subRows ?? [];
|
|
2320
|
+
return children.reduce((acc, child) => {
|
|
2321
|
+
return acc.concat(child, getAllChildren(child));
|
|
2322
|
+
}, []);
|
|
2323
|
+
}
|
|
2324
|
+
|
|
2325
|
+
// export function toggleSelectAllChildren(row: any) {
|
|
2326
|
+
// const children = row.subRows ?? [];
|
|
2327
|
+
|
|
2328
|
+
// return children.reduce((acc: any, child: any) => {
|
|
2329
|
+
// return acc.concat(child, getAllChildren(child));
|
|
2330
|
+
// }, []);
|
|
2331
|
+
// }
|
|
2332
|
+
|
|
2333
|
+
function toggleRowAndChildren(row, isSelected) {
|
|
2334
|
+
// Toggle chính row hiện tại
|
|
2335
|
+
row.toggleSelected(isSelected);
|
|
2336
|
+
|
|
2337
|
+
// Nếu có subRows thì gọi đệ quy
|
|
2338
|
+
if (row.subRows && row.subRows.length > 0) {
|
|
2339
|
+
row.subRows.forEach(subRow => toggleRowAndChildren(subRow, isSelected));
|
|
2340
|
+
}
|
|
2341
|
+
}
|
|
2342
|
+
function countUnselectedChildren(row) {
|
|
2343
|
+
const parent = row.getParentRow();
|
|
2344
|
+
if (!parent) return 0; // Không có cha thì return 0
|
|
2345
|
+
|
|
2346
|
+
const unselectedCount = parent.subRows.filter(child => !child.getIsSelected()).length;
|
|
2347
|
+
return unselectedCount;
|
|
2348
|
+
}
|
|
2349
|
+
function removeDuplicatesByKey(arr, key = 'id') {
|
|
2350
|
+
const map = new Map();
|
|
2351
|
+
for (const item of arr) {
|
|
2352
|
+
if (!map.has(item[key])) {
|
|
2353
|
+
map.set(item[key], item);
|
|
2354
|
+
}
|
|
2355
|
+
}
|
|
2356
|
+
return Array.from(map.values());
|
|
2357
|
+
}
|
|
2358
|
+
const getTableHeight = (height, minHeight) => {
|
|
2359
|
+
if (height && !minHeight) {
|
|
2360
|
+
return height;
|
|
2361
|
+
}
|
|
2362
|
+
if (minHeight && !height) {
|
|
2363
|
+
return minHeight;
|
|
2364
|
+
}
|
|
2365
|
+
if (minHeight && height) {
|
|
2366
|
+
return Math.max(minHeight, height);
|
|
2367
|
+
// if (height > minHeight) {
|
|
2368
|
+
// return height
|
|
2369
|
+
// }
|
|
2370
|
+
|
|
2371
|
+
// if (minHeight > height) {
|
|
2372
|
+
// return minHeight
|
|
2373
|
+
// }
|
|
2374
|
+
}
|
|
2375
|
+
};
|
|
2376
|
+
exports.getTableHeight = getTableHeight;
|
|
2377
|
+
const convertFlatColumn1 = array => {
|
|
2378
|
+
const tmp = [...array];
|
|
2379
|
+
let result = [];
|
|
2380
|
+
tmp.forEach(item => {
|
|
2381
|
+
if (item.children) {
|
|
2382
|
+
result = result.concat(convertFlatColumn1(item.children));
|
|
2383
|
+
} else {
|
|
2384
|
+
result.push(item);
|
|
2385
|
+
}
|
|
2386
|
+
});
|
|
2387
|
+
return result;
|
|
2388
|
+
};
|
|
2389
|
+
exports.convertFlatColumn1 = convertFlatColumn1;
|
|
2390
|
+
const updateColumnsByGroup = (columns, columnsGroup) => {
|
|
2391
|
+
return columns.map(column => {
|
|
2392
|
+
const newColumn = {
|
|
2393
|
+
...column
|
|
2394
|
+
};
|
|
2395
|
+
let hasVisibleChild = false;
|
|
2396
|
+
if (!column.field) {
|
|
2397
|
+
return column;
|
|
2398
|
+
}
|
|
2399
|
+
if (newColumn.children) {
|
|
2400
|
+
newColumn.children = updateColumnsByGroup(newColumn.children, columnsGroup);
|
|
2401
|
+
hasVisibleChild = newColumn.children.some(child => child.visible !== false);
|
|
2402
|
+
}
|
|
2403
|
+
|
|
2404
|
+
// Map previous behaviour (hidden = true when field in columnsGroup)
|
|
2405
|
+
// to the new `visible` property: visible = !hidden
|
|
2406
|
+
newColumn.visible = !(newColumn.field && columnsGroup.includes(newColumn.field));
|
|
2407
|
+
|
|
2408
|
+
// For parent columns, visibility depends on whether any child is visible
|
|
2409
|
+
if (newColumn.children && newColumn.children.length > 0) {
|
|
2410
|
+
newColumn.visible = !!hasVisibleChild;
|
|
2411
|
+
}
|
|
2412
|
+
return newColumn;
|
|
2413
|
+
});
|
|
2414
|
+
};
|
|
2415
|
+
exports.updateColumnsByGroup = updateColumnsByGroup;
|
|
2416
|
+
const removeColumns = (columns, groupColumns) => {
|
|
2417
|
+
const ttt = [...columns];
|
|
2418
|
+
return ttt.filter(column => !groupColumns.includes(column.field)).map(column => {
|
|
2419
|
+
const newCol = {
|
|
2420
|
+
...column
|
|
2421
|
+
};
|
|
2422
|
+
if (newCol?.children && newCol?.children.length > 0) {
|
|
2423
|
+
newCol.children = removeColumns(newCol.children, groupColumns);
|
|
2424
|
+
}
|
|
2425
|
+
return newCol;
|
|
2426
|
+
});
|
|
2427
|
+
};
|
|
2428
|
+
exports.removeColumns = removeColumns;
|
|
2429
|
+
const fixColumnsLeft = (columns, fixedFields) => {
|
|
2430
|
+
return columns.map(col => {
|
|
2431
|
+
const isFixed = col.field && fixedFields.includes(col.field);
|
|
2432
|
+
const newCol = {
|
|
2433
|
+
...col,
|
|
2434
|
+
...(isFixed && {
|
|
2435
|
+
fixed: 'left'
|
|
2436
|
+
})
|
|
2437
|
+
};
|
|
2438
|
+
if (col.children?.length) {
|
|
2439
|
+
// @ts-ignore
|
|
2440
|
+
newCol.children = fixColumnsLeft(col.children, fixedFields);
|
|
2441
|
+
}
|
|
2442
|
+
return newCol;
|
|
2443
|
+
});
|
|
2444
|
+
};
|
|
2445
|
+
exports.fixColumnsLeft = fixColumnsLeft;
|
|
2446
|
+
const SPECIAL_FIELDS = ['selection_column', '#'];
|
|
2447
|
+
function sortColumnsByField(columns, priorityFields) {
|
|
2448
|
+
// xử lý children trước
|
|
2449
|
+
const normalized = columns.map(col => ({
|
|
2450
|
+
...col,
|
|
2451
|
+
...(col.children && {
|
|
2452
|
+
children: sortColumnsByField(col.children, priorityFields)
|
|
2453
|
+
})
|
|
2454
|
+
}));
|
|
2455
|
+
const specialFixedLeft = [];
|
|
2456
|
+
const priority = [];
|
|
2457
|
+
const rest = [];
|
|
2458
|
+
for (const col of normalized) {
|
|
2459
|
+
if (col.fixed === 'left' && col.field && SPECIAL_FIELDS.includes(col.field)) {
|
|
2460
|
+
specialFixedLeft.push(col);
|
|
2461
|
+
} else if (col.field && priorityFields.includes(col.field)) {
|
|
2462
|
+
priority.push(col);
|
|
2463
|
+
} else {
|
|
2464
|
+
rest.push(col);
|
|
2465
|
+
}
|
|
2466
|
+
}
|
|
2467
|
+
return [...specialFixedLeft, ...priority, ...rest];
|
|
2468
|
+
}
|