es-grid-template 1.5.17 → 1.6.1
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/CheckboxFilter2.js +0 -4
- package/es/grid-component/ColumnsChoose.js +9 -4
- package/es/grid-component/ColumnsGroup/ColumnsGroup.js +11 -4
- package/es/grid-component/EditForm/EditForm.d.ts +27 -0
- package/es/grid-component/EditForm/EditForm.js +391 -0
- package/es/grid-component/EditForm/index.d.ts +1 -0
- package/es/grid-component/EditForm/index.js +1 -0
- package/es/grid-component/EditableCell.js +72 -52
- package/es/grid-component/InternalTable.js +79 -27
- package/es/grid-component/TableGrid.js +39 -107
- package/es/grid-component/control/InputControl/InputControl.d.ts +26 -0
- package/es/grid-component/control/InputControl/InputControl.js +121 -0
- package/es/grid-component/control/InputControl/index.d.ts +1 -0
- package/es/grid-component/control/InputControl/index.js +1 -0
- package/es/grid-component/hooks/columns/index.d.ts +3 -2
- package/es/grid-component/hooks/columns/index.js +84 -8
- package/es/grid-component/hooks/content/ControlCheckbox.d.ts +13 -0
- package/es/grid-component/hooks/content/ControlCheckbox.js +87 -0
- package/es/grid-component/hooks/content/HeaderContent.d.ts +1 -1
- package/es/grid-component/hooks/content/HeaderContent.js +9 -4
- package/es/grid-component/hooks/useColumns.js +5 -5
- package/es/grid-component/hooks/utils.d.ts +28 -3
- package/es/grid-component/hooks/utils.js +544 -12
- package/es/grid-component/styles.scss +50 -1
- package/es/grid-component/table/Grid.d.ts +3 -0
- package/es/grid-component/table/GridEdit.d.ts +3 -0
- package/es/grid-component/table/GridEdit.js +353 -328
- package/es/grid-component/table/Group.d.ts +3 -0
- package/es/grid-component/table/InfiniteTable.d.ts +3 -0
- package/es/grid-component/table/InfiniteTable.js +4 -2
- package/es/grid-component/type.d.ts +28 -0
- package/es/grid-component/useContext.d.ts +0 -1
- package/es/index.d.ts +2 -0
- package/es/index.js +1 -0
- package/es/select/index.d.ts +1 -1
- package/lib/grid-component/CheckboxFilter2.js +0 -4
- package/lib/grid-component/ColumnsChoose.js +9 -4
- package/lib/grid-component/ColumnsGroup/ColumnsGroup.js +11 -4
- package/lib/grid-component/EditForm/EditForm.d.ts +27 -0
- package/lib/grid-component/EditForm/EditForm.js +401 -0
- package/lib/grid-component/EditForm/index.d.ts +1 -0
- package/lib/grid-component/EditForm/index.js +16 -0
- package/lib/grid-component/EditableCell.js +72 -52
- package/lib/grid-component/InternalTable.js +78 -26
- package/lib/grid-component/TableGrid.js +37 -105
- package/lib/grid-component/control/InputControl/InputControl.d.ts +26 -0
- package/lib/grid-component/control/InputControl/InputControl.js +131 -0
- package/lib/grid-component/control/InputControl/index.d.ts +1 -0
- package/lib/grid-component/control/InputControl/index.js +16 -0
- package/lib/grid-component/hooks/columns/index.d.ts +3 -2
- package/lib/grid-component/hooks/columns/index.js +86 -9
- package/lib/grid-component/hooks/content/ControlCheckbox.d.ts +13 -0
- package/lib/grid-component/hooks/content/ControlCheckbox.js +95 -0
- package/lib/grid-component/hooks/content/HeaderContent.d.ts +1 -1
- package/lib/grid-component/hooks/content/HeaderContent.js +9 -4
- package/lib/grid-component/hooks/useColumns.js +5 -5
- package/lib/grid-component/hooks/utils.d.ts +28 -3
- package/lib/grid-component/hooks/utils.js +565 -19
- package/lib/grid-component/styles.scss +50 -1
- package/lib/grid-component/table/Grid.d.ts +3 -0
- package/lib/grid-component/table/GridEdit.d.ts +3 -0
- package/lib/grid-component/table/GridEdit.js +343 -325
- package/lib/grid-component/table/Group.d.ts +3 -0
- package/lib/grid-component/table/InfiniteTable.d.ts +3 -0
- package/lib/grid-component/table/InfiniteTable.js +4 -2
- package/lib/grid-component/type.d.ts +28 -0
- package/lib/grid-component/useContext.d.ts +0 -1
- package/lib/index.d.ts +2 -0
- package/lib/index.js +7 -0
- package/lib/select/index.d.ts +1 -1
- package/package.json +2 -1
|
@@ -5,17 +5,19 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
value: true
|
|
6
6
|
});
|
|
7
7
|
exports.addRowIdArray = exports.addClassCellIndexSelected = exports.addClassBorderPasteCell = exports.addBorderPasteClass = exports.addBorderClass = void 0;
|
|
8
|
-
exports.
|
|
8
|
+
exports.addRowsDown = addRowsDown;
|
|
9
|
+
exports.addRowsDownWithCtrl = addRowsDownWithCtrl;
|
|
9
10
|
exports.addRowsUp = addRowsUp;
|
|
11
|
+
exports.addRowsUpWithCtrl = addRowsUpWithCtrl;
|
|
10
12
|
exports.checkThousandSeparator = exports.checkFieldKey = exports.checkDecimalSeparator = exports.checkChild = exports.buildConnectedRegions = void 0;
|
|
11
13
|
exports.compareDate = compareDate;
|
|
12
14
|
exports.compareDates = compareDates;
|
|
13
|
-
exports.convertFlatColumn = exports.convertDayjsToDate = exports.convertDateToDayjs = exports.convertColumns = exports.convertArrayWithIndent = void 0;
|
|
15
|
+
exports.convertFlatColumn = exports.convertFilters = exports.convertDayjsToDate = exports.convertDateToDayjs = exports.convertColumns = exports.convertArrayWithIndent = void 0;
|
|
14
16
|
exports.convertFormat = convertFormat;
|
|
15
|
-
exports.filterDataByColumns3 = exports.filterDataByColumns2 = exports.filterDataByColumns = exports.editAbleColumns = exports.detectSeparators = exports.customWeekStartEndFormat = exports.countItemsBeforeIndex = exports.convertLabelToTitle = void 0;
|
|
17
|
+
exports.filterDataByColumns3 = exports.filterDataByColumns2 = exports.filterDataByColumns = exports.editAbleColumns = exports.detectSeparators = exports.customWeekStartEndFormat = exports.customFilterOption = exports.countItemsBeforeIndex = exports.convertLabelToTitle = void 0;
|
|
16
18
|
exports.filterDataByColumns4 = filterDataByColumns4;
|
|
17
19
|
exports.findAllChildrenKeys = findAllChildrenKeys;
|
|
18
|
-
exports.getAllVisibleKeys = exports.genPresets = exports.flattenData = exports.flattenArray = exports.findItemPath = exports.findItemByKey = void 0;
|
|
20
|
+
exports.getAllVisibleKeys = exports.getAllRowKey = exports.genPresets = exports.flattenData = exports.flattenArray = exports.findItemPath = exports.findItemByKey = void 0;
|
|
19
21
|
exports.getBottomRowCells = getBottomRowCells;
|
|
20
22
|
exports.getCellsByPosition = getCellsByPosition;
|
|
21
23
|
exports.getCellsByPosition2 = getCellsByPosition2;
|
|
@@ -33,8 +35,13 @@ exports.isEmpty = exports.isEditable = exports.isDisable = void 0;
|
|
|
33
35
|
exports.isEqualSet = isEqualSet;
|
|
34
36
|
exports.isRangeCell = exports.isObjEmpty = exports.isNullOrUndefined = exports.isNameColor = exports.isFormattedNumber = void 0;
|
|
35
37
|
exports.isRightMostInRegion = isRightMostInRegion;
|
|
36
|
-
exports.
|
|
37
|
-
exports.
|
|
38
|
+
exports.isTopMostInRegion = exports.isSelectedCell = void 0;
|
|
39
|
+
exports.mergeWithFilter = mergeWithFilter;
|
|
40
|
+
exports.mergeWithFilter2 = mergeWithFilter2;
|
|
41
|
+
exports.removeInvisibleColumns = exports.removeFieldRecursive = exports.removeColumns = exports.removeClassCellIndexSelected = exports.removeClassBorderPasteCell = exports.removeBorderPasteClass = exports.removeBorderClass2 = exports.removeBorderClass = exports.parseCells = exports.parseBooleanToValue = exports.onRemoveBorderSelectedCell = exports.onRemoveBgSelectedCell = exports.onRemoveBgCellIndex = exports.onAddBorderSelectedCell = exports.onAddBgSelectedCell = exports.onAddBgCellIndex = exports.newGuid = exports.mergedSets = void 0;
|
|
42
|
+
exports.updateData = exports.updateColumnsByGroup = exports.updateColumns = exports.updateArrayByKey = exports.unFlattenData = exports.transformColumns1 = exports.transformColumns = exports.totalFixedWidth = exports.sumDataByField = exports.sumByField = exports.sortedSetDSC = exports.sortedSetASC = exports.showDraggingPoint = exports.shouldInclude = exports.removeVietnameseTones = void 0;
|
|
43
|
+
exports.updateDataByFilter = updateDataByFilter;
|
|
44
|
+
exports.updateOrInsert = updateOrInsert;
|
|
38
45
|
var _dayjs = _interopRequireDefault(require("dayjs"));
|
|
39
46
|
var _moment = _interopRequireDefault(require("moment/moment"));
|
|
40
47
|
var _uuid = require("uuid");
|
|
@@ -100,6 +107,18 @@ const isEmpty = d => {
|
|
|
100
107
|
return d === null || d === undefined || d === '';
|
|
101
108
|
};
|
|
102
109
|
exports.isEmpty = isEmpty;
|
|
110
|
+
const removeVietnameseTones = str => {
|
|
111
|
+
if (!str) {
|
|
112
|
+
return '';
|
|
113
|
+
}
|
|
114
|
+
return str.normalize('NFD') // Tách các ký tự có dấu thành ký tự cơ bản + dấu
|
|
115
|
+
.replace(/[\u0300-\u036f]/g, '') // Xóa dấu
|
|
116
|
+
.replace(/đ/g, 'd') // Thay thế đ
|
|
117
|
+
.replace(/Đ/g, 'D').replace(/[^a-zA-Z0-9\s]/g, '') // Loại bỏ ký tự đặc biệt
|
|
118
|
+
.replace(/\s+/g, ' ') // Thay nhiều khoảng trắng thành 1 khoảng trắng
|
|
119
|
+
.trim();
|
|
120
|
+
};
|
|
121
|
+
exports.removeVietnameseTones = removeVietnameseTones;
|
|
103
122
|
const isNullOrUndefined = d => {
|
|
104
123
|
return d === null || d === undefined;
|
|
105
124
|
};
|
|
@@ -374,7 +393,7 @@ const getEditType = (column, rowData) => {
|
|
|
374
393
|
if (column && typeof column.editType === 'function') {
|
|
375
394
|
return column.editType(rowData);
|
|
376
395
|
}
|
|
377
|
-
return column
|
|
396
|
+
return column?.editType ?? 'text';
|
|
378
397
|
};
|
|
379
398
|
exports.getEditType = getEditType;
|
|
380
399
|
const isDisable = (column, rowData) => {
|
|
@@ -433,9 +452,9 @@ const convertArrayWithIndent = (inputArray, parentIndent = 0) => {
|
|
|
433
452
|
}
|
|
434
453
|
};
|
|
435
454
|
exports.convertArrayWithIndent = convertArrayWithIndent;
|
|
436
|
-
const getTemplate = template => {
|
|
455
|
+
const getTemplate = (template, column) => {
|
|
437
456
|
if (template && typeof template === 'function') {
|
|
438
|
-
return template();
|
|
457
|
+
return template(column);
|
|
439
458
|
}
|
|
440
459
|
return template;
|
|
441
460
|
};
|
|
@@ -533,6 +552,36 @@ const flattenData = (childrenColumnName, data) => {
|
|
|
533
552
|
return list;
|
|
534
553
|
};
|
|
535
554
|
exports.flattenData = flattenData;
|
|
555
|
+
const unFlattenData = data => {
|
|
556
|
+
const idToNodeMap = {};
|
|
557
|
+
const tree = [];
|
|
558
|
+
|
|
559
|
+
// Bước 1: Tạo map id -> node
|
|
560
|
+
data.forEach(item => {
|
|
561
|
+
idToNodeMap[item.rowId] = {
|
|
562
|
+
...item,
|
|
563
|
+
children: []
|
|
564
|
+
};
|
|
565
|
+
});
|
|
566
|
+
|
|
567
|
+
// Bước 2: Gắn vào parent hoặc đẩy lên root nếu không có parent
|
|
568
|
+
data.forEach(item => {
|
|
569
|
+
const currentNode = idToNodeMap[item.rowId];
|
|
570
|
+
if (item.parentId === null) {
|
|
571
|
+
tree.push(currentNode);
|
|
572
|
+
} else {
|
|
573
|
+
const parentNode = idToNodeMap[item.parentId];
|
|
574
|
+
if (parentNode) {
|
|
575
|
+
parentNode.children.push(currentNode);
|
|
576
|
+
} else {
|
|
577
|
+
// Nếu parentId không tồn tại thì xem như root
|
|
578
|
+
tree.push(currentNode);
|
|
579
|
+
}
|
|
580
|
+
}
|
|
581
|
+
});
|
|
582
|
+
return tree;
|
|
583
|
+
};
|
|
584
|
+
exports.unFlattenData = unFlattenData;
|
|
536
585
|
const countItemsBeforeIndex = (array, index) => {
|
|
537
586
|
let count = 0;
|
|
538
587
|
for (let i = 0; i < index; i++) {
|
|
@@ -629,7 +678,7 @@ const getRowsPasteIndex = pasteRows => {
|
|
|
629
678
|
return [...new Set(result)];
|
|
630
679
|
};
|
|
631
680
|
exports.getRowsPasteIndex = getRowsPasteIndex;
|
|
632
|
-
function
|
|
681
|
+
function addRowsDownWithCtrl(arr, n) {
|
|
633
682
|
if (!Array.isArray(arr) || arr.length === 0) {
|
|
634
683
|
return {
|
|
635
684
|
combined: arr,
|
|
@@ -767,7 +816,155 @@ function addRows8(arr, n) {
|
|
|
767
816
|
addedRows
|
|
768
817
|
};
|
|
769
818
|
}
|
|
770
|
-
function
|
|
819
|
+
function addRowsDown(arr, n) {
|
|
820
|
+
if (!Array.isArray(arr) || arr.length === 0) {
|
|
821
|
+
return {
|
|
822
|
+
combined: arr,
|
|
823
|
+
addedRows: []
|
|
824
|
+
};
|
|
825
|
+
}
|
|
826
|
+
const m = arr.length;
|
|
827
|
+
const numCols = arr[0].length;
|
|
828
|
+
const addedRows = [];
|
|
829
|
+
|
|
830
|
+
// // Hàm kiểm tra kiểu date hợp lệ
|
|
831
|
+
// const isValidDate = (item: any) => {
|
|
832
|
+
//
|
|
833
|
+
//
|
|
834
|
+
// // console.log('!isNaN(Date.parse(d))', !isNaN(Date.parse(d)))
|
|
835
|
+
// // return !isNaN(Date.parse(d))
|
|
836
|
+
//
|
|
837
|
+
// if (typeof item === 'number') {
|
|
838
|
+
// // return 'number'
|
|
839
|
+
// return false
|
|
840
|
+
// }
|
|
841
|
+
// if (typeof item === 'string') {
|
|
842
|
+
// // Kiểm tra nếu là chuỗi ISO date hợp lệ
|
|
843
|
+
// const date = new Date(item)
|
|
844
|
+
// if (!isNaN(date.getTime()) && item.includes('T')) {
|
|
845
|
+
// // return 'date'
|
|
846
|
+
// return true
|
|
847
|
+
// }
|
|
848
|
+
// // return 'string'
|
|
849
|
+
// return false
|
|
850
|
+
// }
|
|
851
|
+
//
|
|
852
|
+
// return !isNaN(Date.parse(item))
|
|
853
|
+
//
|
|
854
|
+
// }
|
|
855
|
+
|
|
856
|
+
// Lấy giá trị mẫu của cột j từ hàng đầu tiên
|
|
857
|
+
const getSample = j => arr[0][j];
|
|
858
|
+
|
|
859
|
+
// Xác định chế độ xử lý cho mỗi cột:
|
|
860
|
+
// mode = 'number-stepping' | 'date-stepping' | 'number-constant' | 'cycle'
|
|
861
|
+
const modes = [];
|
|
862
|
+
const steps = []; // bước tăng, nếu có (cho number hoặc date)
|
|
863
|
+
|
|
864
|
+
for (let j = 0; j < numCols; j++) {
|
|
865
|
+
const sample = getSample(j);
|
|
866
|
+
if (m === 1) {
|
|
867
|
+
// 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.
|
|
868
|
+
if (typeof sample === "number") {
|
|
869
|
+
modes[j] = "number-constant";
|
|
870
|
+
}
|
|
871
|
+
// else if (isValidDate(sample)) {
|
|
872
|
+
// modes[j] = "date-stepping"
|
|
873
|
+
// steps[j] = 24 * 3600 * 1000 // 1 ngày = 86400000 ms
|
|
874
|
+
// }
|
|
875
|
+
else {
|
|
876
|
+
modes[j] = "cycle";
|
|
877
|
+
}
|
|
878
|
+
} else if (m === 2) {
|
|
879
|
+
// 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
|
|
880
|
+
const first = arr[0][j],
|
|
881
|
+
second = arr[1][j];
|
|
882
|
+
if (typeof first === "number" && typeof second === "number") {
|
|
883
|
+
modes[j] = "number-stepping";
|
|
884
|
+
steps[j] = second - first;
|
|
885
|
+
}
|
|
886
|
+
// else if (isValidDate(first) && isValidDate(second)) {
|
|
887
|
+
// modes[j] = "date-stepping"
|
|
888
|
+
// steps[j] = Date.parse(second) - Date.parse(first)
|
|
889
|
+
// }
|
|
890
|
+
else {
|
|
891
|
+
modes[j] = "cycle";
|
|
892
|
+
}
|
|
893
|
+
} else {
|
|
894
|
+
// Nếu mảng có >2 hàng
|
|
895
|
+
const first = arr[0][j],
|
|
896
|
+
second = arr[1][j],
|
|
897
|
+
third = arr[2][j];
|
|
898
|
+
if (typeof first === "number" && typeof second === "number" && typeof third === "number") {
|
|
899
|
+
const step1 = second - first;
|
|
900
|
+
const step2 = third - second;
|
|
901
|
+
if (step1 === step2) {
|
|
902
|
+
modes[j] = "number-stepping";
|
|
903
|
+
steps[j] = step1;
|
|
904
|
+
} else {
|
|
905
|
+
modes[j] = "cycle";
|
|
906
|
+
}
|
|
907
|
+
}
|
|
908
|
+
// else if (isValidDate(first) && isValidDate(second) && isValidDate(third)) {
|
|
909
|
+
// const step1 = Date.parse(second) - Date.parse(first)
|
|
910
|
+
// const step2 = Date.parse(third) - Date.parse(second)
|
|
911
|
+
// if (step1 === step2) {
|
|
912
|
+
// modes[j] = "date-stepping"
|
|
913
|
+
// steps[j] = step1
|
|
914
|
+
// } else {
|
|
915
|
+
// modes[j] = "cycle"
|
|
916
|
+
// }
|
|
917
|
+
// }
|
|
918
|
+
else {
|
|
919
|
+
modes[j] = "cycle";
|
|
920
|
+
}
|
|
921
|
+
}
|
|
922
|
+
}
|
|
923
|
+
|
|
924
|
+
// Tạo các dòng mới (thêm n dòng)
|
|
925
|
+
// 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
|
|
926
|
+
// Nếu chế độ là cycle thì dùng arr[i mod m][j]
|
|
927
|
+
for (let i = 0; i < n; i++) {
|
|
928
|
+
const newRow = [];
|
|
929
|
+
for (let j = 0; j < numCols; j++) {
|
|
930
|
+
let newValue;
|
|
931
|
+
switch (modes[j]) {
|
|
932
|
+
case "number-constant":
|
|
933
|
+
// Mảng có 1 hàng, số giữ nguyên
|
|
934
|
+
newValue = arr[0][j];
|
|
935
|
+
break;
|
|
936
|
+
case "number-stepping":
|
|
937
|
+
{
|
|
938
|
+
// Lấy giá trị cuối của cột j trong mảng ban đầu
|
|
939
|
+
const lastValue = arr[m - 1][j];
|
|
940
|
+
newValue = lastValue + (i + 1) * steps[j];
|
|
941
|
+
}
|
|
942
|
+
break;
|
|
943
|
+
// case "date-stepping":
|
|
944
|
+
// {
|
|
945
|
+
// // 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
|
|
946
|
+
// const lastDate = new Date(arr[m - 1][j])
|
|
947
|
+
// const newTime = lastDate.getTime() + (i + 1) * steps[j]
|
|
948
|
+
// newValue = moment(new Date(newTime)).format()
|
|
949
|
+
// }
|
|
950
|
+
// break
|
|
951
|
+
case "cycle":
|
|
952
|
+
default:
|
|
953
|
+
// Lặp lại nội dung theo vòng tròn: dùng hàng thứ (i mod m)
|
|
954
|
+
newValue = arr[i % m][j];
|
|
955
|
+
break;
|
|
956
|
+
}
|
|
957
|
+
newRow.push(newValue);
|
|
958
|
+
}
|
|
959
|
+
addedRows.push(newRow);
|
|
960
|
+
}
|
|
961
|
+
const combined = arr.concat(addedRows);
|
|
962
|
+
return {
|
|
963
|
+
combined,
|
|
964
|
+
addedRows
|
|
965
|
+
};
|
|
966
|
+
}
|
|
967
|
+
function addRowsUpWithCtrl(array, n) {
|
|
771
968
|
const arr = array.reverse();
|
|
772
969
|
if (!Array.isArray(arr) || arr.length === 0) {
|
|
773
970
|
return {
|
|
@@ -909,6 +1106,128 @@ function addRowsUp(array, n) {
|
|
|
909
1106
|
addedRows
|
|
910
1107
|
};
|
|
911
1108
|
}
|
|
1109
|
+
function addRowsUp(array, n) {
|
|
1110
|
+
const arr = array.reverse();
|
|
1111
|
+
if (!Array.isArray(arr) || arr.length === 0) {
|
|
1112
|
+
return {
|
|
1113
|
+
combined: arr,
|
|
1114
|
+
addedRows: []
|
|
1115
|
+
};
|
|
1116
|
+
}
|
|
1117
|
+
const m = arr.length;
|
|
1118
|
+
const numCols = arr[0].length;
|
|
1119
|
+
const addedRows = [];
|
|
1120
|
+
|
|
1121
|
+
// Hàm kiểm tra kiểu date hợp lệ
|
|
1122
|
+
// const isValidDate = (item: any) => {
|
|
1123
|
+
//
|
|
1124
|
+
//
|
|
1125
|
+
// // console.log('!isNaN(Date.parse(d))', !isNaN(Date.parse(d)))
|
|
1126
|
+
// // return !isNaN(Date.parse(d))
|
|
1127
|
+
//
|
|
1128
|
+
// if (typeof item === 'number') {
|
|
1129
|
+
// // return 'number'
|
|
1130
|
+
// return false
|
|
1131
|
+
// }
|
|
1132
|
+
// if (typeof item === 'string') {
|
|
1133
|
+
// // Kiểm tra nếu là chuỗi ISO date hợp lệ
|
|
1134
|
+
// const date = new Date(item)
|
|
1135
|
+
// if (!isNaN(date.getTime()) && item.includes('T')) {
|
|
1136
|
+
// // return 'date'
|
|
1137
|
+
// return true
|
|
1138
|
+
// }
|
|
1139
|
+
// // return 'string'
|
|
1140
|
+
// return false
|
|
1141
|
+
// }
|
|
1142
|
+
//
|
|
1143
|
+
// return !isNaN(Date.parse(item))
|
|
1144
|
+
//
|
|
1145
|
+
// }
|
|
1146
|
+
|
|
1147
|
+
// Lấy giá trị mẫu của cột j từ hàng đầu tiên
|
|
1148
|
+
const getSample = j => arr[0][j];
|
|
1149
|
+
|
|
1150
|
+
// Xác định chế độ xử lý cho mỗi cột:
|
|
1151
|
+
// mode = 'number-stepping' | 'date-stepping' | 'number-constant' | 'cycle'
|
|
1152
|
+
const modes = [];
|
|
1153
|
+
const steps = []; // bước tăng, nếu có (cho number hoặc date)
|
|
1154
|
+
|
|
1155
|
+
for (let j = 0; j < numCols; j++) {
|
|
1156
|
+
const sample = getSample(j);
|
|
1157
|
+
if (m === 1) {
|
|
1158
|
+
// 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.
|
|
1159
|
+
if (typeof sample === "number") {
|
|
1160
|
+
modes[j] = "number-constant";
|
|
1161
|
+
} else {
|
|
1162
|
+
modes[j] = "cycle";
|
|
1163
|
+
}
|
|
1164
|
+
} else if (m === 2) {
|
|
1165
|
+
// 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
|
|
1166
|
+
const first = arr[0][j],
|
|
1167
|
+
second = arr[1][j];
|
|
1168
|
+
if (typeof first === "number" && typeof second === "number") {
|
|
1169
|
+
modes[j] = "number-stepping";
|
|
1170
|
+
steps[j] = second - first;
|
|
1171
|
+
} else {
|
|
1172
|
+
modes[j] = "cycle";
|
|
1173
|
+
}
|
|
1174
|
+
} else {
|
|
1175
|
+
// Nếu mảng có >2 hàng
|
|
1176
|
+
const first = arr[0][j],
|
|
1177
|
+
second = arr[1][j],
|
|
1178
|
+
third = arr[2][j];
|
|
1179
|
+
if (typeof first === "number" && typeof second === "number" && typeof third === "number") {
|
|
1180
|
+
const step1 = second - first;
|
|
1181
|
+
const step2 = third - second;
|
|
1182
|
+
if (step1 === step2) {
|
|
1183
|
+
modes[j] = "number-stepping";
|
|
1184
|
+
steps[j] = step1;
|
|
1185
|
+
} else {
|
|
1186
|
+
modes[j] = "cycle";
|
|
1187
|
+
}
|
|
1188
|
+
} else {
|
|
1189
|
+
modes[j] = "cycle";
|
|
1190
|
+
}
|
|
1191
|
+
}
|
|
1192
|
+
}
|
|
1193
|
+
|
|
1194
|
+
// Tạo các dòng mới (thêm n dòng)
|
|
1195
|
+
// 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
|
|
1196
|
+
// Nếu chế độ là cycle thì dùng arr[i mod m][j]
|
|
1197
|
+
for (let i = n - 1; i >= 0; i--) {
|
|
1198
|
+
const newRow = [];
|
|
1199
|
+
for (let j = 0; j < numCols; j++) {
|
|
1200
|
+
let newValue;
|
|
1201
|
+
switch (modes[j]) {
|
|
1202
|
+
case "number-constant":
|
|
1203
|
+
// Mảng có 1 hàng, số giữ nguyên
|
|
1204
|
+
newValue = arr[0][j];
|
|
1205
|
+
break;
|
|
1206
|
+
case "number-stepping":
|
|
1207
|
+
{
|
|
1208
|
+
// Lấy giá trị cuối của cột j trong mảng ban đầu
|
|
1209
|
+
|
|
1210
|
+
const lastValue = arr[m - 1][j];
|
|
1211
|
+
newValue = lastValue - (i + 1) * steps[j] * -1;
|
|
1212
|
+
}
|
|
1213
|
+
break;
|
|
1214
|
+
case "cycle":
|
|
1215
|
+
default:
|
|
1216
|
+
// Lặp lại nội dung theo vòng tròn: dùng hàng thứ (i mod m)
|
|
1217
|
+
|
|
1218
|
+
newValue = arr[i % m][j];
|
|
1219
|
+
break;
|
|
1220
|
+
}
|
|
1221
|
+
newRow.push(newValue);
|
|
1222
|
+
}
|
|
1223
|
+
addedRows.push(newRow);
|
|
1224
|
+
}
|
|
1225
|
+
const combined = arr.concat(addedRows);
|
|
1226
|
+
return {
|
|
1227
|
+
combined,
|
|
1228
|
+
addedRows
|
|
1229
|
+
};
|
|
1230
|
+
}
|
|
912
1231
|
const transformColumns = (cols, convertColumns, t) => {
|
|
913
1232
|
// @ts-ignore
|
|
914
1233
|
return cols.map(column => {
|
|
@@ -1342,8 +1661,8 @@ const shouldInclude = (item, queries) => {
|
|
|
1342
1661
|
const isDateComparison = isDate(itemValue) || isDateString(value);
|
|
1343
1662
|
const itemDate = isDateComparison ? new Date(itemValue) : null;
|
|
1344
1663
|
const queryDate = isDateComparison ? parseToDate(value) : null;
|
|
1345
|
-
const itemStr = itemValue?.toString().toLowerCase?.();
|
|
1346
|
-
const queryStr = value?.toString().toLowerCase?.();
|
|
1664
|
+
const itemStr = removeVietnameseTones(itemValue?.toString().toLowerCase?.() ?? '');
|
|
1665
|
+
const queryStr = removeVietnameseTones(value?.toString().toLowerCase?.() ?? '');
|
|
1347
1666
|
switch (operator.toLowerCase()) {
|
|
1348
1667
|
case "equal":
|
|
1349
1668
|
condition = isDateComparison ? compareDates(itemDate, queryDate) : itemValue === value;
|
|
@@ -1391,7 +1710,7 @@ const shouldInclude = (item, queries) => {
|
|
|
1391
1710
|
return result;
|
|
1392
1711
|
};
|
|
1393
1712
|
exports.shouldInclude = shouldInclude;
|
|
1394
|
-
function filterDataByColumns4(data, queries) {
|
|
1713
|
+
function filterDataByColumns4(data, queries, keysFilter) {
|
|
1395
1714
|
if (!queries || queries.length === 0) {
|
|
1396
1715
|
return data;
|
|
1397
1716
|
}
|
|
@@ -1400,9 +1719,9 @@ function filterDataByColumns4(data, queries) {
|
|
|
1400
1719
|
...item
|
|
1401
1720
|
};
|
|
1402
1721
|
if (Array.isArray(item.children)) {
|
|
1403
|
-
newItem.children = filterDataByColumns4(item.children, queries);
|
|
1722
|
+
newItem.children = filterDataByColumns4(item.children, queries, keysFilter);
|
|
1404
1723
|
}
|
|
1405
|
-
const isSelfMatched = shouldInclude(item, queries);
|
|
1724
|
+
const isSelfMatched = shouldInclude(item, queries) || keysFilter?.includes(newItem?.rowId);
|
|
1406
1725
|
|
|
1407
1726
|
// Nếu chính item thỏa hoặc có con thỏa → giữ lại
|
|
1408
1727
|
if (isSelfMatched || newItem.children && newItem.children.length > 0) {
|
|
@@ -2148,6 +2467,9 @@ const isSelectedCell = (selectedCells, rowIndex, colIndex) => {
|
|
|
2148
2467
|
exports.isSelectedCell = isSelectedCell;
|
|
2149
2468
|
function groupArrayByColumns(arr, columns) {
|
|
2150
2469
|
const result = [];
|
|
2470
|
+
const checkEmpty = d => {
|
|
2471
|
+
return d === null || d === undefined || d === '';
|
|
2472
|
+
};
|
|
2151
2473
|
if (columns) {
|
|
2152
2474
|
arr.forEach(item => {
|
|
2153
2475
|
let currentLevel = result;
|
|
@@ -2175,9 +2497,9 @@ function groupArrayByColumns(arr, columns) {
|
|
|
2175
2497
|
currentLevel.push({
|
|
2176
2498
|
...item,
|
|
2177
2499
|
rowId: item.id ?? item.rowId,
|
|
2178
|
-
parentId: !
|
|
2500
|
+
parentId: !checkEmpty(columns[columns.length - 1]) ? item[columns[columns.length - 1]] : null
|
|
2179
2501
|
// parentId: item.rowId[columns.length - 1],
|
|
2180
|
-
indent: columns.length
|
|
2502
|
+
// indent: columns.length
|
|
2181
2503
|
});
|
|
2182
2504
|
});
|
|
2183
2505
|
return result;
|
|
@@ -2245,4 +2567,228 @@ const detectSeparators = str => {
|
|
|
2245
2567
|
// Không có dấu hoặc không hợp lệ
|
|
2246
2568
|
return null;
|
|
2247
2569
|
};
|
|
2248
|
-
exports.detectSeparators = detectSeparators;
|
|
2570
|
+
exports.detectSeparators = detectSeparators;
|
|
2571
|
+
const convertFilters = filters => {
|
|
2572
|
+
const result = [];
|
|
2573
|
+
filters.forEach(({
|
|
2574
|
+
key,
|
|
2575
|
+
column,
|
|
2576
|
+
filteredKeys,
|
|
2577
|
+
operator
|
|
2578
|
+
}) => {
|
|
2579
|
+
if (!filteredKeys || filteredKeys.length === 0) {
|
|
2580
|
+
return;
|
|
2581
|
+
}
|
|
2582
|
+
if (column?.typeFilter === "DateRange" && filteredKeys.length === 2) {
|
|
2583
|
+
result.push({
|
|
2584
|
+
key,
|
|
2585
|
+
field: column?.dataIndex,
|
|
2586
|
+
value: filteredKeys[0],
|
|
2587
|
+
predicate: "and",
|
|
2588
|
+
operator: "greaterthanorequal"
|
|
2589
|
+
}, {
|
|
2590
|
+
key,
|
|
2591
|
+
field: column?.dataIndex,
|
|
2592
|
+
value: filteredKeys[1],
|
|
2593
|
+
predicate: "and",
|
|
2594
|
+
operator: "lessthanorequal"
|
|
2595
|
+
});
|
|
2596
|
+
} else if (column?.typeFilter === "NumberRange") {
|
|
2597
|
+
if ((filteredKeys[0] || filteredKeys[0] === 0) && !filteredKeys[1]) {
|
|
2598
|
+
result.push({
|
|
2599
|
+
key,
|
|
2600
|
+
field: column?.dataIndex,
|
|
2601
|
+
value: filteredKeys[0],
|
|
2602
|
+
predicate: "and",
|
|
2603
|
+
operator: "greaterthanorequal"
|
|
2604
|
+
});
|
|
2605
|
+
}
|
|
2606
|
+
if ((filteredKeys[1] || filteredKeys[1] === 0) && !filteredKeys[0]) {
|
|
2607
|
+
result.push({
|
|
2608
|
+
key,
|
|
2609
|
+
field: column?.dataIndex,
|
|
2610
|
+
value: filteredKeys[1],
|
|
2611
|
+
predicate: "and",
|
|
2612
|
+
operator: "lessthanorequal"
|
|
2613
|
+
});
|
|
2614
|
+
}
|
|
2615
|
+
if ((filteredKeys[0] || filteredKeys[0] === 0) && (filteredKeys[1] || filteredKeys[1] === 0)) {
|
|
2616
|
+
result.push({
|
|
2617
|
+
key,
|
|
2618
|
+
field: column?.dataIndex,
|
|
2619
|
+
value: filteredKeys[0],
|
|
2620
|
+
predicate: "and",
|
|
2621
|
+
operator: "greaterthanorequal"
|
|
2622
|
+
}, {
|
|
2623
|
+
key,
|
|
2624
|
+
field: column?.dataIndex,
|
|
2625
|
+
value: filteredKeys[1],
|
|
2626
|
+
predicate: "and",
|
|
2627
|
+
operator: "lessthanorequal"
|
|
2628
|
+
});
|
|
2629
|
+
}
|
|
2630
|
+
} else if (column?.typeFilter === 'Checkbox') {
|
|
2631
|
+
filteredKeys.forEach(value => {
|
|
2632
|
+
result.push({
|
|
2633
|
+
key,
|
|
2634
|
+
field: column?.dataIndex,
|
|
2635
|
+
value,
|
|
2636
|
+
predicate: "or",
|
|
2637
|
+
operator
|
|
2638
|
+
});
|
|
2639
|
+
});
|
|
2640
|
+
} else {
|
|
2641
|
+
result.push({
|
|
2642
|
+
key,
|
|
2643
|
+
field: column?.dataIndex,
|
|
2644
|
+
value: filteredKeys[0],
|
|
2645
|
+
predicate: 'and',
|
|
2646
|
+
operator
|
|
2647
|
+
});
|
|
2648
|
+
}
|
|
2649
|
+
});
|
|
2650
|
+
return result;
|
|
2651
|
+
};
|
|
2652
|
+
exports.convertFilters = convertFilters;
|
|
2653
|
+
const getAllRowKey = data => {
|
|
2654
|
+
const a = flattenArray(data);
|
|
2655
|
+
return a.length ? a.map(it => it.rowId) : undefined;
|
|
2656
|
+
};
|
|
2657
|
+
exports.getAllRowKey = getAllRowKey;
|
|
2658
|
+
function updateDataByFilter(tree, filter) {
|
|
2659
|
+
return tree.map(node => {
|
|
2660
|
+
// Tìm bản ghi đã update từ filter
|
|
2661
|
+
const updatedNode = filter.find(f => f.rowId === node.rowId);
|
|
2662
|
+
|
|
2663
|
+
// Nếu có updatedNode thì merge, nếu không thì giữ nguyên node
|
|
2664
|
+
const newNode = updatedNode ? {
|
|
2665
|
+
...node,
|
|
2666
|
+
...updatedNode
|
|
2667
|
+
} : node;
|
|
2668
|
+
|
|
2669
|
+
// Nếu có children thì đệ quy cập nhật con
|
|
2670
|
+
if (newNode.children) {
|
|
2671
|
+
newNode.children = updateDataByFilter(newNode.children, filter);
|
|
2672
|
+
}
|
|
2673
|
+
return newNode;
|
|
2674
|
+
});
|
|
2675
|
+
}
|
|
2676
|
+
function updateOrInsert(dataArray, dataFilter) {
|
|
2677
|
+
const updatedArray = [...dataArray];
|
|
2678
|
+
dataFilter.forEach(filterItem => {
|
|
2679
|
+
const existingIndex = updatedArray.findIndex(item => item.rowId === filterItem.rowId);
|
|
2680
|
+
if (existingIndex !== -1) {
|
|
2681
|
+
// Cập nhật item đã tồn tại
|
|
2682
|
+
updatedArray[existingIndex] = {
|
|
2683
|
+
...updatedArray[existingIndex],
|
|
2684
|
+
...filterItem
|
|
2685
|
+
};
|
|
2686
|
+
} else {
|
|
2687
|
+
// Tìm vị trí cuối cùng của item trước đó trong dataFilter
|
|
2688
|
+
const prevIndexInFilter = dataFilter.findIndex(f => f.rowId === filterItem.rowId) - 1;
|
|
2689
|
+
if (prevIndexInFilter >= 0) {
|
|
2690
|
+
const prevId = dataFilter[prevIndexInFilter].rowId;
|
|
2691
|
+
const prevIndexInArray = updatedArray.findIndex(item => item.rowId === prevId);
|
|
2692
|
+
if (prevIndexInArray !== -1) {
|
|
2693
|
+
// Thêm ngay sau phần tử trước đó
|
|
2694
|
+
updatedArray.splice(prevIndexInArray + 1, 0, filterItem);
|
|
2695
|
+
return;
|
|
2696
|
+
}
|
|
2697
|
+
}
|
|
2698
|
+
|
|
2699
|
+
// 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
|
|
2700
|
+
updatedArray.push(filterItem);
|
|
2701
|
+
}
|
|
2702
|
+
});
|
|
2703
|
+
return updatedArray;
|
|
2704
|
+
}
|
|
2705
|
+
function mergeWithFilter(dataArray, dataFilter) {
|
|
2706
|
+
const result = [...dataArray];
|
|
2707
|
+
dataFilter.forEach((filterItem, i) => {
|
|
2708
|
+
const existsInArray = result.find(item => item.rowId === filterItem.rowId);
|
|
2709
|
+
|
|
2710
|
+
// console.log('existsInArray', existsInArray)
|
|
2711
|
+
|
|
2712
|
+
if (!existsInArray) {
|
|
2713
|
+
// tìm index của phần tử trước đó trong dataFilter
|
|
2714
|
+
for (let j = i - 1; j >= 0; j--) {
|
|
2715
|
+
const prevFilterItem = dataFilter[j];
|
|
2716
|
+
const indexInResult = result.findIndex(item => item.rowId === prevFilterItem.rowId);
|
|
2717
|
+
if (indexInResult !== -1) {
|
|
2718
|
+
// console.log('filterItem', filterItem)
|
|
2719
|
+
|
|
2720
|
+
result.splice(indexInResult + 1, 0, filterItem);
|
|
2721
|
+
return;
|
|
2722
|
+
}
|
|
2723
|
+
}
|
|
2724
|
+
|
|
2725
|
+
// nếu không tìm thấy phần tử trước đó thì push cuối
|
|
2726
|
+
result.push(filterItem);
|
|
2727
|
+
} else {
|
|
2728
|
+
result[i] = {
|
|
2729
|
+
...filterItem
|
|
2730
|
+
};
|
|
2731
|
+
}
|
|
2732
|
+
});
|
|
2733
|
+
return result;
|
|
2734
|
+
}
|
|
2735
|
+
function mergeWithFilter2(dataArray, dataFilter) {
|
|
2736
|
+
const result = [...dataArray];
|
|
2737
|
+
dataFilter.forEach((filterItem, i) => {
|
|
2738
|
+
const existsInArray = result.find(item => item.rowId === filterItem.rowId);
|
|
2739
|
+
|
|
2740
|
+
// console.log('existsInArray', existsInArray)
|
|
2741
|
+
|
|
2742
|
+
if (!existsInArray) {
|
|
2743
|
+
// tìm index của phần tử trước đó trong dataFilter
|
|
2744
|
+
for (let j = i - 1; j >= 0; j--) {
|
|
2745
|
+
const prevFilterItem = dataFilter[j];
|
|
2746
|
+
const indexInResult = result.findIndex(item => item.rowId === prevFilterItem.rowId);
|
|
2747
|
+
if (indexInResult !== -1) {
|
|
2748
|
+
// console.log('filterItem', filterItem)
|
|
2749
|
+
|
|
2750
|
+
result.splice(indexInResult + 1, 0, filterItem);
|
|
2751
|
+
return;
|
|
2752
|
+
}
|
|
2753
|
+
}
|
|
2754
|
+
|
|
2755
|
+
// nếu không tìm thấy phần tử trước đó thì push cuối
|
|
2756
|
+
result.push(filterItem);
|
|
2757
|
+
}
|
|
2758
|
+
});
|
|
2759
|
+
return result;
|
|
2760
|
+
}
|
|
2761
|
+
const removeInvisibleColumns = columns => {
|
|
2762
|
+
const tmp = [...columns];
|
|
2763
|
+
return tmp.map(col => {
|
|
2764
|
+
const newCol = {
|
|
2765
|
+
...col
|
|
2766
|
+
};
|
|
2767
|
+
if (col.children) {
|
|
2768
|
+
// Recursively process children
|
|
2769
|
+
newCol.children = removeInvisibleColumns(newCol.children);
|
|
2770
|
+
}
|
|
2771
|
+
// Return the column only if it's visible or has visible children
|
|
2772
|
+
return newCol.visible !== false && (newCol.children ? newCol.children.length > 0 : true) ? newCol : null;
|
|
2773
|
+
}).filter(Boolean); // Filter out null items
|
|
2774
|
+
};
|
|
2775
|
+
exports.removeInvisibleColumns = removeInvisibleColumns;
|
|
2776
|
+
const sumByField = (data, field) => {
|
|
2777
|
+
return data.reduce((total, item) => {
|
|
2778
|
+
if (item[field] != null) {
|
|
2779
|
+
return total + item[field];
|
|
2780
|
+
} else if (item.children && item.children.length > 0) {
|
|
2781
|
+
return total + sumByField(item.children, field);
|
|
2782
|
+
}
|
|
2783
|
+
return total;
|
|
2784
|
+
}, 0);
|
|
2785
|
+
};
|
|
2786
|
+
exports.sumByField = sumByField;
|
|
2787
|
+
const customFilterOption = (input, option) => {
|
|
2788
|
+
if (!option) return false;
|
|
2789
|
+
const valueStr = removeVietnameseTones(String(option.value).toLowerCase() ?? '');
|
|
2790
|
+
const labelStr = removeVietnameseTones(String(option.label).toLowerCase() ?? '');
|
|
2791
|
+
const inputStr = removeVietnameseTones(input.toLowerCase() ?? '');
|
|
2792
|
+
return valueStr.includes(inputStr) || labelStr.includes(inputStr);
|
|
2793
|
+
};
|
|
2794
|
+
exports.customFilterOption = customFilterOption;
|