es-grid-template 1.5.17 → 1.6.0

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.
Files changed (53) hide show
  1. package/es/grid-component/CheckboxFilter2.js +0 -4
  2. package/es/grid-component/ColumnsChoose.js +9 -4
  3. package/es/grid-component/ColumnsGroup/ColumnsGroup.js +11 -4
  4. package/es/grid-component/EditableCell.js +26 -9
  5. package/es/grid-component/InternalTable.js +79 -27
  6. package/es/grid-component/TableGrid.js +39 -107
  7. package/es/grid-component/hooks/columns/index.d.ts +3 -2
  8. package/es/grid-component/hooks/columns/index.js +84 -8
  9. package/es/grid-component/hooks/content/ControlCheckbox.d.ts +13 -0
  10. package/es/grid-component/hooks/content/ControlCheckbox.js +87 -0
  11. package/es/grid-component/hooks/content/HeaderContent.d.ts +1 -1
  12. package/es/grid-component/hooks/content/HeaderContent.js +9 -4
  13. package/es/grid-component/hooks/useColumns.js +5 -5
  14. package/es/grid-component/hooks/utils.d.ts +28 -3
  15. package/es/grid-component/hooks/utils.js +544 -12
  16. package/es/grid-component/styles.scss +50 -1
  17. package/es/grid-component/table/Grid.d.ts +3 -0
  18. package/es/grid-component/table/GridEdit.d.ts +3 -0
  19. package/es/grid-component/table/GridEdit.js +349 -324
  20. package/es/grid-component/table/Group.d.ts +3 -0
  21. package/es/grid-component/table/InfiniteTable.d.ts +3 -0
  22. package/es/grid-component/table/InfiniteTable.js +4 -2
  23. package/es/grid-component/type.d.ts +1 -0
  24. package/es/index.d.ts +2 -0
  25. package/es/index.js +1 -0
  26. package/es/select/index.d.ts +1 -1
  27. package/lib/grid-component/CheckboxFilter2.js +0 -4
  28. package/lib/grid-component/ColumnsChoose.js +9 -4
  29. package/lib/grid-component/ColumnsGroup/ColumnsGroup.js +11 -4
  30. package/lib/grid-component/EditableCell.js +26 -9
  31. package/lib/grid-component/InternalTable.js +78 -26
  32. package/lib/grid-component/TableGrid.js +37 -105
  33. package/lib/grid-component/hooks/columns/index.d.ts +3 -2
  34. package/lib/grid-component/hooks/columns/index.js +86 -9
  35. package/lib/grid-component/hooks/content/ControlCheckbox.d.ts +13 -0
  36. package/lib/grid-component/hooks/content/ControlCheckbox.js +95 -0
  37. package/lib/grid-component/hooks/content/HeaderContent.d.ts +1 -1
  38. package/lib/grid-component/hooks/content/HeaderContent.js +9 -4
  39. package/lib/grid-component/hooks/useColumns.js +5 -5
  40. package/lib/grid-component/hooks/utils.d.ts +28 -3
  41. package/lib/grid-component/hooks/utils.js +565 -19
  42. package/lib/grid-component/styles.scss +50 -1
  43. package/lib/grid-component/table/Grid.d.ts +3 -0
  44. package/lib/grid-component/table/GridEdit.d.ts +3 -0
  45. package/lib/grid-component/table/GridEdit.js +339 -322
  46. package/lib/grid-component/table/Group.d.ts +3 -0
  47. package/lib/grid-component/table/InfiniteTable.d.ts +3 -0
  48. package/lib/grid-component/table/InfiniteTable.js +4 -2
  49. package/lib/grid-component/type.d.ts +1 -0
  50. package/lib/index.d.ts +2 -0
  51. package/lib/index.js +7 -0
  52. package/lib/select/index.d.ts +1 -1
  53. package/package.json +1 -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.addRows8 = addRows8;
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.transformColumns1 = exports.transformColumns = exports.totalFixedWidth = exports.sumDataByField = exports.sortedSetDSC = exports.sortedSetASC = exports.showDraggingPoint = exports.shouldInclude = 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 = exports.isTopMostInRegion = exports.isSelectedCell = void 0;
37
- exports.updateData = exports.updateColumnsByGroup = exports.updateColumns = exports.updateArrayByKey = void 0;
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.editType ?? 'text';
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 addRows8(arr, n) {
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 addRowsUp(array, n) {
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: !isEmpty(columns[columns.length - 1]) ? item[columns[columns.length - 1]] : null,
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;