es-grid-template 1.7.23 → 1.7.25

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 (163) hide show
  1. package/es/index.d.ts +1 -0
  2. package/es/index.js +3 -1
  3. package/es/table-component/ColumnsChoose.d.ts +13 -0
  4. package/es/table-component/ColumnsChoose.js +206 -0
  5. package/es/table-component/ContextMenu.d.ts +20 -0
  6. package/es/table-component/ContextMenu.js +75 -0
  7. package/es/table-component/InternalTable.d.ts +9 -0
  8. package/es/table-component/InternalTable.js +308 -0
  9. package/es/table-component/TableContainer.d.ts +31 -0
  10. package/es/table-component/TableContainer.js +249 -0
  11. package/es/table-component/TableContainerEdit.d.ts +31 -0
  12. package/es/table-component/TableContainerEdit.js +1301 -0
  13. package/es/table-component/body/EditableCell.d.ts +16 -0
  14. package/es/table-component/body/EditableCell.js +1039 -0
  15. package/es/table-component/body/TableBody.d.ts +19 -0
  16. package/es/table-component/body/TableBody.js +64 -0
  17. package/es/table-component/body/TableBodyCell.d.ts +12 -0
  18. package/es/table-component/body/TableBodyCell.js +149 -0
  19. package/es/table-component/body/TableBodyCellEdit.d.ts +16 -0
  20. package/es/table-component/body/TableBodyCellEdit.js +931 -0
  21. package/es/table-component/body/TableBodyRow.d.ts +21 -0
  22. package/es/table-component/body/TableBodyRow.js +151 -0
  23. package/es/table-component/components/ControlCheckbox.d.ts +13 -0
  24. package/es/table-component/components/ControlCheckbox.js +84 -0
  25. package/es/table-component/components/EditForm/EditForm.d.ts +27 -0
  26. package/es/table-component/components/EditForm/EditForm.js +395 -0
  27. package/es/table-component/components/EditForm/index.d.ts +1 -0
  28. package/es/table-component/components/EditForm/index.js +1 -0
  29. package/es/table-component/components/InputControl/InputControl.d.ts +27 -0
  30. package/es/table-component/components/InputControl/InputControl.js +121 -0
  31. package/es/table-component/components/InputControl/index.d.ts +1 -0
  32. package/es/table-component/components/InputControl/index.js +1 -0
  33. package/es/table-component/components/async-select/index.d.ts +11 -0
  34. package/es/table-component/components/async-select/index.js +41 -0
  35. package/es/table-component/components/async-table-select/index.d.ts +11 -0
  36. package/es/table-component/components/async-table-select/index.js +44 -0
  37. package/es/table-component/components/checkbox-control/index.d.ts +13 -0
  38. package/es/table-component/components/checkbox-control/index.js +40 -0
  39. package/es/table-component/components/checkbox-filter/CheckboxFilter.d.ts +18 -0
  40. package/es/table-component/components/checkbox-filter/CheckboxFilter.js +240 -0
  41. package/es/table-component/components/checkbox-filter/FilterSearch.d.ts +12 -0
  42. package/es/table-component/components/checkbox-filter/FilterSearch.js +36 -0
  43. package/es/table-component/components/command/Command.d.ts +10 -0
  44. package/es/table-component/components/command/Command.js +33 -0
  45. package/es/table-component/components/number/index.d.ts +10 -0
  46. package/es/table-component/components/number/index.js +42 -0
  47. package/es/table-component/components/number-range/index.d.ts +11 -0
  48. package/es/table-component/components/number-range/index.js +66 -0
  49. package/es/table-component/features/operator.d.ts +24 -0
  50. package/es/table-component/features/operator.js +62 -0
  51. package/es/table-component/footer/TableFooter.d.ts +13 -0
  52. package/es/table-component/footer/TableFooter.js +33 -0
  53. package/es/table-component/footer/TableFooterCell.d.ts +10 -0
  54. package/es/table-component/footer/TableFooterCell.js +66 -0
  55. package/es/table-component/footer/TableFooterRow.d.ts +14 -0
  56. package/es/table-component/footer/TableFooterRow.js +73 -0
  57. package/es/table-component/header/TableHead.d.ts +14 -0
  58. package/es/table-component/header/TableHead.js +60 -0
  59. package/es/table-component/header/TableHeadCell.d.ts +14 -0
  60. package/es/table-component/header/TableHeadCell.js +343 -0
  61. package/es/table-component/header/TableHeadRow.d.ts +16 -0
  62. package/es/table-component/header/TableHeadRow.js +76 -0
  63. package/es/table-component/header/renderFilter.d.ts +20 -0
  64. package/es/table-component/header/renderFilter.js +281 -0
  65. package/es/table-component/hook/constant.d.ts +73 -0
  66. package/es/table-component/hook/constant.js +240 -0
  67. package/es/table-component/hook/useColumns.d.ts +9 -0
  68. package/es/table-component/hook/useColumns.js +169 -0
  69. package/es/table-component/hook/useFilterOperator.d.ts +7 -0
  70. package/es/table-component/hook/useFilterOperator.js +33 -0
  71. package/es/table-component/hook/utils.d.ts +133 -0
  72. package/es/table-component/hook/utils.js +1870 -0
  73. package/es/table-component/index.d.ts +5 -0
  74. package/es/table-component/index.js +2 -0
  75. package/es/table-component/style.scss +1129 -0
  76. package/es/table-component/table/Grid.d.ts +24 -0
  77. package/es/table-component/table/Grid.js +234 -0
  78. package/es/table-component/type.d.ts +513 -0
  79. package/es/table-component/type.js +1 -0
  80. package/es/table-component/useContext.d.ts +74 -0
  81. package/es/table-component/useContext.js +15 -0
  82. package/lib/index.d.ts +1 -0
  83. package/lib/index.js +8 -1
  84. package/lib/table-component/ColumnsChoose.d.ts +13 -0
  85. package/lib/table-component/ColumnsChoose.js +216 -0
  86. package/lib/table-component/ContextMenu.d.ts +20 -0
  87. package/lib/table-component/ContextMenu.js +85 -0
  88. package/lib/table-component/InternalTable.d.ts +9 -0
  89. package/lib/table-component/InternalTable.js +313 -0
  90. package/lib/table-component/TableContainer.d.ts +31 -0
  91. package/lib/table-component/TableContainer.js +257 -0
  92. package/lib/table-component/TableContainerEdit.d.ts +31 -0
  93. package/lib/table-component/TableContainerEdit.js +1310 -0
  94. package/lib/table-component/body/EditableCell.d.ts +16 -0
  95. package/lib/table-component/body/EditableCell.js +1041 -0
  96. package/lib/table-component/body/TableBody.d.ts +19 -0
  97. package/lib/table-component/body/TableBody.js +72 -0
  98. package/lib/table-component/body/TableBodyCell.d.ts +12 -0
  99. package/lib/table-component/body/TableBodyCell.js +158 -0
  100. package/lib/table-component/body/TableBodyCellEdit.d.ts +16 -0
  101. package/lib/table-component/body/TableBodyCellEdit.js +938 -0
  102. package/lib/table-component/body/TableBodyRow.d.ts +21 -0
  103. package/lib/table-component/body/TableBodyRow.js +158 -0
  104. package/lib/table-component/components/ControlCheckbox.d.ts +13 -0
  105. package/lib/table-component/components/ControlCheckbox.js +92 -0
  106. package/lib/table-component/components/EditForm/EditForm.d.ts +27 -0
  107. package/lib/table-component/components/EditForm/EditForm.js +406 -0
  108. package/lib/table-component/components/EditForm/index.d.ts +1 -0
  109. package/lib/table-component/components/EditForm/index.js +16 -0
  110. package/lib/table-component/components/InputControl/InputControl.d.ts +27 -0
  111. package/lib/table-component/components/InputControl/InputControl.js +131 -0
  112. package/lib/table-component/components/InputControl/index.d.ts +1 -0
  113. package/lib/table-component/components/InputControl/index.js +16 -0
  114. package/lib/table-component/components/async-select/index.d.ts +11 -0
  115. package/lib/table-component/components/async-select/index.js +49 -0
  116. package/lib/table-component/components/async-table-select/index.d.ts +11 -0
  117. package/lib/table-component/components/async-table-select/index.js +53 -0
  118. package/lib/table-component/components/checkbox-control/index.d.ts +13 -0
  119. package/lib/table-component/components/checkbox-control/index.js +48 -0
  120. package/lib/table-component/components/checkbox-filter/CheckboxFilter.d.ts +18 -0
  121. package/lib/table-component/components/checkbox-filter/CheckboxFilter.js +249 -0
  122. package/lib/table-component/components/checkbox-filter/FilterSearch.d.ts +12 -0
  123. package/lib/table-component/components/checkbox-filter/FilterSearch.js +44 -0
  124. package/lib/table-component/components/command/Command.d.ts +10 -0
  125. package/lib/table-component/components/command/Command.js +42 -0
  126. package/lib/table-component/components/number/index.d.ts +10 -0
  127. package/lib/table-component/components/number/index.js +50 -0
  128. package/lib/table-component/components/number-range/index.d.ts +11 -0
  129. package/lib/table-component/components/number-range/index.js +74 -0
  130. package/lib/table-component/features/operator.d.ts +24 -0
  131. package/lib/table-component/features/operator.js +67 -0
  132. package/lib/table-component/footer/TableFooter.d.ts +13 -0
  133. package/lib/table-component/footer/TableFooter.js +42 -0
  134. package/lib/table-component/footer/TableFooterCell.d.ts +10 -0
  135. package/lib/table-component/footer/TableFooterCell.js +76 -0
  136. package/lib/table-component/footer/TableFooterRow.d.ts +14 -0
  137. package/lib/table-component/footer/TableFooterRow.js +81 -0
  138. package/lib/table-component/header/TableHead.d.ts +14 -0
  139. package/lib/table-component/header/TableHead.js +69 -0
  140. package/lib/table-component/header/TableHeadCell.d.ts +14 -0
  141. package/lib/table-component/header/TableHeadCell.js +352 -0
  142. package/lib/table-component/header/TableHeadRow.d.ts +16 -0
  143. package/lib/table-component/header/TableHeadRow.js +84 -0
  144. package/lib/table-component/header/renderFilter.d.ts +20 -0
  145. package/lib/table-component/header/renderFilter.js +291 -0
  146. package/lib/table-component/hook/constant.d.ts +73 -0
  147. package/lib/table-component/hook/constant.js +247 -0
  148. package/lib/table-component/hook/useColumns.d.ts +9 -0
  149. package/lib/table-component/hook/useColumns.js +180 -0
  150. package/lib/table-component/hook/useFilterOperator.d.ts +7 -0
  151. package/lib/table-component/hook/useFilterOperator.js +40 -0
  152. package/lib/table-component/hook/utils.d.ts +133 -0
  153. package/lib/table-component/hook/utils.js +1969 -0
  154. package/lib/table-component/index.d.ts +5 -0
  155. package/lib/table-component/index.js +9 -0
  156. package/lib/table-component/style.scss +1129 -0
  157. package/lib/table-component/table/Grid.d.ts +24 -0
  158. package/lib/table-component/table/Grid.js +236 -0
  159. package/lib/table-component/type.d.ts +513 -0
  160. package/lib/table-component/type.js +5 -0
  161. package/lib/table-component/useContext.d.ts +74 -0
  162. package/lib/table-component/useContext.js +21 -0
  163. package/package.json +4 -2
@@ -0,0 +1,1969 @@
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.checkThousandSeparator = exports.checkFieldKey = exports.checkDecimalSeparator = void 0;
15
+ exports.compareDate = compareDate;
16
+ exports.compareDates = compareDates;
17
+ exports.convertArrayWithIndent = void 0;
18
+ exports.convertColumnsToTreeData = convertColumnsToTreeData;
19
+ exports.convertFilters = exports.convertDayjsToDate = exports.convertDateToDayjs = void 0;
20
+ exports.convertFormat = convertFormat;
21
+ exports.extendsObject = exports.detectSeparators = exports.customWeekStartEndFormat = exports.convertToObj = exports.convertLabelToTitle = void 0;
22
+ exports.filterDataByColumns = filterDataByColumns;
23
+ exports.getAllVisibleKeys1 = exports.getAllVisibleKeys = exports.getAllRowKey = exports.genPresets = exports.flattenData = exports.flattenArray = exports.flatColumns2 = exports.findItemByKey = void 0;
24
+ exports.getCellsByPosition = getCellsByPosition;
25
+ exports.getColIdsBetween = getColIdsBetween;
26
+ exports.getEditType = exports.getDiffent2Array = exports.getDefaultValue = exports.getDefaultOperator = exports.getDatepickerFormat = exports.getDateRangeFormat = exports.getCommonPinningStyles = void 0;
27
+ exports.getFixedFields = getFixedFields;
28
+ exports.getFormat = void 0;
29
+ exports.getHiddenParentKeys = getHiddenParentKeys;
30
+ exports.getHiddenParentKeys1 = getHiddenParentKeys1;
31
+ exports.getInvisibleColumns = getInvisibleColumns;
32
+ exports.getNewItemsOnly = exports.getLastSelectCell = void 0;
33
+ exports.getRowIdsBetween = getRowIdsBetween;
34
+ exports.getVisibleColumnKeys1 = exports.getVisibleColumnKeys = exports.getTypeFilter = exports.getSelectedCellMatrix = void 0;
35
+ exports.groupArrayByColumns = groupArrayByColumns;
36
+ exports.isColor = void 0;
37
+ exports.isDateString = isDateString;
38
+ exports.isEmpty = exports.isEditable = exports.isDisable = void 0;
39
+ exports.isEqualSet = isEqualSet;
40
+ exports.isObjEmpty = exports.isNullOrUndefined = exports.isNameColor = exports.isFormattedNumber = void 0;
41
+ exports.isObjEqual = isObjEqual;
42
+ exports.sortByType = exports.shouldInclude = exports.removeVietnameseTones = exports.parseBooleanToValue = exports.onRemoveBgSelectedCell = exports.onAddBgSelectedCell = exports.newGuid = void 0;
43
+ exports.sortData = sortData;
44
+ exports.updateColumns1 = exports.updateArrayByKey = exports.unFlattenData = exports.sumSize = void 0;
45
+ exports.updateOrInsert = updateOrInsert;
46
+ var _useSelection = require("rc-master-ui/es/table/hooks/useSelection");
47
+ var _uuid = require("uuid");
48
+ var _colors = require("@ant-design/colors");
49
+ var _dayjs = _interopRequireDefault(require("dayjs"));
50
+ var _moment = _interopRequireDefault(require("moment"));
51
+ // import type { AnyObject } from './type';
52
+
53
+ // import moment from "moment/moment"
54
+
55
+ const newGuid = () => {
56
+ for (let i = 0; i < 20; i++) {
57
+ // @ts-ignore
58
+ // const id = crypto.randomUUID()
59
+ return (0, _uuid.v4)();
60
+ }
61
+ };
62
+ exports.newGuid = newGuid;
63
+ const convertDayjsToDate = (dateString, format) => {
64
+ const dayjsDate = (0, _dayjs.default)(dateString, format); // Parse using the provided format
65
+ if (!dayjsDate.isValid()) {
66
+ throw new Error('Invalid date or format');
67
+ }
68
+ // return moment(dayjsDate.toDate()).format() // Convert to JavaScript Date
69
+ return dayjsDate.toDate(); // Convert to JavaScript Date
70
+ };
71
+ exports.convertDayjsToDate = convertDayjsToDate;
72
+ const convertDateToDayjs = (date, format) => {
73
+ const dateValue = date ? (0, _dayjs.default)(date).format(format) : null;
74
+ return dateValue ? (0, _dayjs.default)(dateValue, format) : null;
75
+ };
76
+ exports.convertDateToDayjs = convertDateToDayjs;
77
+ const getCommonPinningStyles = column => {
78
+ const isPinned = column.getIsPinned();
79
+ // const isLastLeftPinnedColumn = isPinned === "left" && column.getIsLastColumn("left");
80
+ // const isFirstRightPinnedColumn =isPinned === "right" && column.getIsFirstColumn("right");
81
+
82
+ return {
83
+ // boxShadow: isFirstRightPinnedColumn
84
+ // ? "#e0e0e0 2px 0px 1px -1px inset"
85
+ // : undefined,
86
+
87
+ left: isPinned === "left" ? `${column.getStart("left")}px` : undefined,
88
+ right: isPinned === "right" ? `${column.getAfter("right")}px` : undefined,
89
+ // opacity: isPinned ? 0.5 : 1,
90
+ opacity: 1,
91
+ position: isPinned ? "sticky" : "relative",
92
+ width: column.getSize(),
93
+ zIndex: isPinned ? 2 : 0
94
+ };
95
+ };
96
+ exports.getCommonPinningStyles = getCommonPinningStyles;
97
+ const sumSize = items => {
98
+ return items.reduce((total, item) => total + item.size, 0);
99
+ };
100
+ exports.sumSize = sumSize;
101
+ const appendIfNotExists = (a, b) => {
102
+ const existingKeys = new Set(a.map(item => item.index));
103
+ b.forEach(item => {
104
+ if (!existingKeys.has(item.index)) {
105
+ a.push(item);
106
+ }
107
+ });
108
+ return a;
109
+ };
110
+ exports.appendIfNotExists = appendIfNotExists;
111
+ const getNewItemsOnly = (a, b) => {
112
+ const existingKeys = new Set(a.map(item => item.key));
113
+ return b.filter(item => !existingKeys.has(item.key));
114
+ };
115
+ exports.getNewItemsOnly = getNewItemsOnly;
116
+ const extendsObject = (...list) => {
117
+ const result = {
118
+ ...list[0]
119
+ };
120
+ for (let i = 1; i < list.length; i++) {
121
+ const obj = list[i];
122
+ if (obj) {
123
+ Object.keys(obj).forEach(key => {
124
+ const val = obj[key];
125
+ if (val !== undefined) {
126
+ result[key] = val;
127
+ }
128
+ });
129
+ }
130
+ }
131
+ return result;
132
+ };
133
+ exports.extendsObject = extendsObject;
134
+ const isEmpty = d => {
135
+ return d === null || d === undefined || d === '';
136
+ };
137
+ exports.isEmpty = isEmpty;
138
+ const getFormat = (colFormat, format) => {
139
+ return {
140
+ thousandSeparator: colFormat?.thousandSeparator ?? format?.thousandSeparator,
141
+ decimalSeparator: colFormat?.decimalSeparator ?? format?.decimalSeparator,
142
+ decimalScale: colFormat?.decimalScale ?? format?.decimalScale ? Number(colFormat?.decimalScale ?? format?.decimalScale) : colFormat?.decimalScale ?? format?.decimalScale,
143
+ allowNegative: colFormat?.allowNegative ?? format?.allowNegative,
144
+ // check nhập số âm
145
+ prefix: colFormat?.prefix ?? format?.prefix,
146
+ suffix: colFormat?.suffix ?? format?.suffix,
147
+ fixedDecimalScale: colFormat?.fixedDecimalScale ?? format?.fixedDecimalScale,
148
+ // mặc định thêm số 0 sau số thập phân
149
+ dateFormat: colFormat?.dateFormat ?? format?.dateFormat,
150
+ datetimeFormat: colFormat?.datetimeFormat ?? format?.datetimeFormat,
151
+ timeFormat: colFormat?.timeFormat ?? format?.timeFormat,
152
+ weekFormat: colFormat?.weekFormat ?? format?.weekFormat,
153
+ monthFormat: colFormat?.monthFormat ?? format?.monthFormat,
154
+ yearFormat: colFormat?.yearFormat ?? format?.yearFormat
155
+ };
156
+ };
157
+ exports.getFormat = getFormat;
158
+ function convertFormat(formatStr) {
159
+ // return formatStr.split('').map((char, i) => {
160
+ // if (char === 'D' || char === 'd') {
161
+ // return 'd'; // ngày: lowercase
162
+ // }
163
+ // if (char === 'Y' || char === 'y') {
164
+ // return 'y'; // năm: lowercase
165
+ // }
166
+ // if (char === 'M' || char === 'm') {
167
+ // return char; // tháng: giữ nguyên
168
+ // }
169
+ // return char; // separator
170
+ // }).join('');
171
+
172
+ return formatStr.split('').map(char => {
173
+ if (char === 'D' || char === 'd') return 'd';
174
+ if (char === 'Y' || char === 'y') return 'y';
175
+ if ('Hhmsa'.includes(char)) return char; // giờ, phút, giây, am/pm
176
+ if (char === 'M' || char === 'm') return char; // tháng: giữ nguyên
177
+ return char; // dấu phân cách
178
+ }).join('');
179
+ }
180
+ const getDatepickerFormat = (type, format) => {
181
+ const typeFormat = type ? type.toLowerCase() : '';
182
+ switch (typeFormat) {
183
+ case "date":
184
+ case "daterange":
185
+ return format?.dateFormat ?? 'DD/MM/YYYY';
186
+ case "datetime":
187
+ return format?.datetimeFormat ?? 'DD/MM/YYYY HH:mm';
188
+ case "week":
189
+ return format?.weekFormat ?? 'DD/MM';
190
+ case "month":
191
+ return format?.monthFormat ?? 'MM/YYYY';
192
+ case "quarter":
193
+ return format?.dateFormat ?? 'DD/MM/YYYY';
194
+ case "year":
195
+ return format?.yearFormat ?? 'YYYY';
196
+ case "time":
197
+ return format?.timeFormat ?? 'HH:mm';
198
+ default:
199
+ return 'DD/MM/YYYY';
200
+ }
201
+ };
202
+ exports.getDatepickerFormat = getDatepickerFormat;
203
+ const getDateRangeFormat = (type, format) => {
204
+ const typeFormat = type ? type.toLowerCase() : '';
205
+ switch (typeFormat) {
206
+ case "date":
207
+ case "daterange":
208
+ return convertFormat(format?.dateFormat ?? 'dd/MM/yyyy');
209
+ case "datetime":
210
+ return format?.datetimeFormat ?? 'dd/MM/yyyy HH:mm';
211
+ case "week":
212
+ return format?.weekFormat ?? 'dd/MM';
213
+ case "month":
214
+ return format?.monthFormat ?? 'MM/yyyy';
215
+ case "quarter":
216
+ return format?.dateFormat ?? 'dd/MM/yyyy';
217
+ case "year":
218
+ return format?.yearFormat ?? 'yyyy';
219
+ case "time":
220
+ return format?.timeFormat ?? 'HH:mm';
221
+ default:
222
+ return 'dd/MM/yyyy';
223
+ }
224
+ };
225
+ exports.getDateRangeFormat = getDateRangeFormat;
226
+ const getTypeFilter = col => {
227
+ if (col?.typeFilter) {
228
+ return col.typeFilter;
229
+ }
230
+ const type = col?.type ?? 'Text';
231
+ switch (type) {
232
+ case "number":
233
+ return 'Number';
234
+ case "date":
235
+ return 'Date';
236
+ case "datetime":
237
+ return 'Datetime';
238
+ case "boolean":
239
+ return 'Checkbox';
240
+ case "checkbox":
241
+ return 'Checkbox';
242
+
243
+ // case "week": return ''
244
+ // case "month": return 'Month'
245
+ // case "quarter": return col.format?.dateFormat ? col.format?.dateFormat : 'DD/MM/YYYY'
246
+ // case "year": return col.format?.yearFormat ? col.format?.yearFormat : 'YYYY'
247
+ // case "time": return col.format?.timeFormat ? col.format?.timeFormat : 'HH:mm'
248
+ case "string":
249
+ default:
250
+ return 'Text';
251
+ }
252
+ };
253
+ exports.getTypeFilter = getTypeFilter;
254
+ const addRowIdArray = inputArray => {
255
+ if (inputArray) {
256
+ return inputArray.map(item => {
257
+ if (typeof item.children !== "string" && item.children && item.children.length > 0) {
258
+ item.children = addRowIdArray(item.children);
259
+ }
260
+ return {
261
+ ...item,
262
+ rowId: item.rowId ?? item.id ?? newGuid()
263
+ };
264
+ });
265
+ } else {
266
+ return [];
267
+ }
268
+ };
269
+ exports.addRowIdArray = addRowIdArray;
270
+ function groupArrayByColumns(arr, columns) {
271
+ const result = [];
272
+ const checkEmpty = d => {
273
+ return d === null || d === undefined || d === '';
274
+ };
275
+ if (columns) {
276
+ arr.forEach(item => {
277
+ let currentLevel = result;
278
+ columns.forEach((column, index) => {
279
+ const value = item[column];
280
+ const existingItem = currentLevel.find(i => i[column] === value);
281
+ if (existingItem) {
282
+ currentLevel = existingItem.children;
283
+ } else {
284
+ // 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: [] }
285
+ const newItem = {
286
+ [column]: value,
287
+ field: column,
288
+ rowId: newGuid(),
289
+ // rowId: item[column],
290
+ parentId: !isEmpty(item[columns[index - 1]]) ? item[columns[index - 1]] : null,
291
+ // parentId: item.rowId[index - 1],
292
+ // indent: index,
293
+ children: []
294
+ };
295
+ currentLevel.push(newItem);
296
+ currentLevel = newItem.children;
297
+ }
298
+ });
299
+ currentLevel.push({
300
+ ...item,
301
+ rowId: item.id ?? item.rowId,
302
+ parentId: !checkEmpty(columns[columns.length - 1]) ? item[columns[columns.length - 1]] : null
303
+ // parentId: item.rowId[columns.length - 1],
304
+ // indent: columns.length
305
+ });
306
+ });
307
+ return result;
308
+ } else {
309
+ return arr;
310
+ }
311
+ }
312
+ const flatColumns2 = columns => {
313
+ return columns.reduce((list, column) => {
314
+ const subColumns = column.children;
315
+ if (column === _useSelection.SELECTION_COLUMN) {
316
+ return [...list, {
317
+ ...column
318
+ }];
319
+ }
320
+ if (subColumns && subColumns.length > 0) {
321
+ return [...list, ...flatColumns2(subColumns).map(subColum => ({
322
+ ...subColum
323
+ }))];
324
+ }
325
+ return [...list, {
326
+ ...column
327
+ }];
328
+ }, []);
329
+ };
330
+ exports.flatColumns2 = flatColumns2;
331
+ const checkThousandSeparator = (thousandSeparator, decimalSeparator) => {
332
+ if (thousandSeparator) {
333
+ if (decimalSeparator) {
334
+ if (thousandSeparator === decimalSeparator) {
335
+ return ',';
336
+ } else {
337
+ return thousandSeparator;
338
+ }
339
+ } else {
340
+ return thousandSeparator;
341
+ }
342
+ } else {
343
+ return undefined;
344
+ }
345
+ };
346
+ exports.checkThousandSeparator = checkThousandSeparator;
347
+ const checkDecimalSeparator = (thousandSeparator, decimalSeparator) => {
348
+ if (decimalSeparator) {
349
+ if (thousandSeparator) {
350
+ if (thousandSeparator === decimalSeparator) {
351
+ return '.';
352
+ } else {
353
+ return decimalSeparator;
354
+ }
355
+ } else {
356
+ return decimalSeparator;
357
+ }
358
+ } else {
359
+ if (thousandSeparator && thousandSeparator === '.') {
360
+ return ',';
361
+ }
362
+ return '.';
363
+ }
364
+ };
365
+ exports.checkDecimalSeparator = checkDecimalSeparator;
366
+ function getFixedFields(columns, type) {
367
+ const result = [];
368
+ function traverse(cols) {
369
+ for (const col of cols) {
370
+ if (col.fixed === type && col.field) {
371
+ result.push(col.field);
372
+ }
373
+ if (col.children && col.children.length > 0) {
374
+ traverse(col.children);
375
+ }
376
+ }
377
+ }
378
+ traverse(columns);
379
+ return result;
380
+ }
381
+ function areStringArraysEqual(a, b) {
382
+ if (a.length !== b.length) return false;
383
+ const sortedA = [...a].sort();
384
+ const sortedB = [...b].sort();
385
+ return sortedA.every((val, index) => val === sortedB[index]);
386
+ }
387
+ const getDefaultOperator = col => {
388
+ if (col.operator) {
389
+ return col.operator;
390
+ }
391
+ if (col.typeFilter) {
392
+ switch (col.typeFilter) {
393
+ case 'Number':
394
+ case 'Date':
395
+ case 'Datetime':
396
+ case 'Time':
397
+ case 'Month':
398
+ case 'Quarter':
399
+ case 'Year':
400
+ case 'Week':
401
+ case 'Dropdown':
402
+ case 'Checkbox':
403
+ case 'CheckboxDropdown':
404
+ case 'CheckboxTree':
405
+ case 'DropTree':
406
+ return 'equal';
407
+ case 'Text':
408
+ default:
409
+ return 'contains';
410
+ }
411
+ }
412
+ switch (col.type) {
413
+ case 'number':
414
+ case 'date':
415
+ case 'datetime':
416
+ case 'week':
417
+ case 'year':
418
+ case 'quarter':
419
+ return 'equal';
420
+ case 'string':
421
+ default:
422
+ return 'contains';
423
+ }
424
+ };
425
+ exports.getDefaultOperator = getDefaultOperator;
426
+ function isEqualSet(setA, setB) {
427
+ if (setA.size !== setB.size) {
428
+ return false;
429
+ }
430
+ for (const item of setA) {
431
+ if (!setB.has(item)) {
432
+ return false;
433
+ }
434
+ }
435
+ return true;
436
+ }
437
+ const getLastSelectCell = selectCells => {
438
+ if (selectCells.size === 0) {
439
+ return {
440
+ row: 0,
441
+ col: 0
442
+ };
443
+ }
444
+ const lastValue = [...selectCells].at(-1);
445
+ const [row, col] = lastValue.split("-").map(Number);
446
+ return {
447
+ row,
448
+ col
449
+ };
450
+ };
451
+ exports.getLastSelectCell = getLastSelectCell;
452
+ function getCellsByPosition(cellSet, position = "bottom") {
453
+ const cells = Array.from(cellSet).map(key => {
454
+ const [row, col] = key.split("-").map(Number);
455
+ return {
456
+ row,
457
+ col,
458
+ key
459
+ };
460
+ });
461
+ switch (position) {
462
+ case "top":
463
+ {
464
+ // const minRow = Math.min(...cells.map(c => c.row));
465
+ // return cells.filter(c => c.row === minRow).map(c => c.key);
466
+
467
+ // const rows = cells.map(c => c.row).filter(r => r > 0);
468
+ // if (rows.length === 0) return [];
469
+ // const minRow = Math.min(...rows);
470
+ // return cells.filter(c => c.row === minRow).map(c => c.key);
471
+
472
+ const minRow = Math.min(...cells.map(c => c.row));
473
+ if (minRow === 0) {
474
+ return [];
475
+ } // Bỏ qua nếu rowIndex = 0
476
+
477
+ return cells.filter(c => c.row === minRow).map(c => `${c.row}-${c.col}`);
478
+ }
479
+ case "bottom":
480
+ {
481
+ const maxRow = Math.max(...cells.map(c => c.row));
482
+ return cells.filter(c => c.row === maxRow).map(c => c.key);
483
+ }
484
+ case "left":
485
+ {
486
+ // const minCol = Math.min(...cells.map(c => c.col));
487
+ // return cells.filter(c => c.col === minCol).map(c => c.key);
488
+
489
+ // const cols = cells.map(c => c.col).filter(c => c > 0);
490
+ // if (cols.length === 0) return [];
491
+ // const minCol = Math.min(...cols);
492
+ // return cells.filter(c => c.col === minCol).map(c => c.key);
493
+
494
+ const minCol = Math.min(...cells.map(c => c.col));
495
+ if (minCol === 0) {
496
+ return [];
497
+ } // Bỏ qua nếu colIndex = 0
498
+
499
+ // Trả về các ô cùng row, nhưng ở cột bên trái
500
+ return cells.filter(c => c.col === minCol).map(c => `${c.row}-${c.col}`);
501
+ }
502
+ case "right":
503
+ {
504
+ const maxCol = Math.max(...cells.map(c => c.col));
505
+ return cells.filter(c => c.col === maxCol).map(c => c.key);
506
+ }
507
+ default:
508
+ return [];
509
+ }
510
+ }
511
+ const onAddBgSelectedCell = (selectedCells, id, isFocusCellIndex) => {
512
+ const selectors = Array.from(selectedCells).map(pos => {
513
+ const [row1, col1] = pos.split('-');
514
+ return `[data-row-index="${row1}"][data-col-index="${col1}"]`;
515
+ });
516
+ const table = document.querySelector(`#${id}`);
517
+
518
+ //// xóa class các ô đã chọn trước đó
519
+ const cellsSelected = table ? table?.querySelectorAll('.ui-rc-table-cell.selected-bg') : null;
520
+ if (cellsSelected) {
521
+ cellsSelected.forEach(cell => {
522
+ cell.classList.remove('selected-bg');
523
+ });
524
+ }
525
+
526
+ /// thêm class
527
+ const cells = table && selectors.length > 0 ? table?.querySelectorAll(selectors.join(',')) : null;
528
+ if (cells) {
529
+ cells.forEach(cell => {
530
+ cell.classList.add('selected-bg');
531
+ });
532
+ }
533
+ const rowsArray = [...new Set([...selectedCells].map(item => item.split("-")[0]))];
534
+ const rowsSelectors = rowsArray.map(r => `.rc-ui-cell-index[data-row-index="${r}"]`).join(", ");
535
+ const cellsIndex = table && rowsSelectors.length > 0 ? table?.querySelectorAll(rowsSelectors) : null;
536
+ if (cellsIndex && isFocusCellIndex !== false) {
537
+ cellsIndex.forEach(cell => {
538
+ cell.classList.add('focus');
539
+ });
540
+ }
541
+
542
+ // // tăng z-index để hiển thị round point paste
543
+ // const row = getLastSelectCell(selectedCells).row
544
+ // const col = getLastSelectCell(selectedCells).col
545
+ // const cell: any = table?.querySelector(`.ui-rc-table-cell[data-row-index="${row}"][data-col-index="${col}"]`)
546
+ //
547
+ // if (cell) {
548
+ // cell.style.zIndex = 1
549
+ // }
550
+ //
551
+ // if (cell && cell.classList.contains('ui-rc-table-cell-fix-left')) {
552
+ // cell.style.zIndex = 3;
553
+ // }
554
+
555
+ // thêm class border selected
556
+
557
+ // addBorderClass(selectedCells, 'bottom', 'cell-border-bottom', id)
558
+ // addBorderClass(selectedCells, 'right', 'cell-border-right', id)
559
+ // addBorderClass(selectedCells, 'top', 'cell-border-top', id)
560
+ // addBorderClass(selectedCells, 'left', 'cell-border-left', id)
561
+ };
562
+ exports.onAddBgSelectedCell = onAddBgSelectedCell;
563
+ const onRemoveBgSelectedCell = (selectedCells, id, rowsSelected) => {
564
+ const table = document.querySelector(`#${id}`);
565
+ const cells = table ? table?.querySelectorAll('.ui-rc-table-cell.selected-bg') : null;
566
+ if (cells) {
567
+ cells.forEach(cell => {
568
+ cell.classList.remove('selected-bg');
569
+ });
570
+ }
571
+ const cellsIndex = table ? table?.querySelectorAll('.ui-rc-table-cell.focus') : null;
572
+ if (cellsIndex) {
573
+ cellsIndex.forEach(cell => {
574
+ cell.classList.remove('focus');
575
+ });
576
+ }
577
+
578
+ // xóa class selected ô STT
579
+
580
+ if (rowsSelected && rowsSelected.size > 0) {
581
+ const rowsSelectedArray = [...new Set([...rowsSelected].map(item => item.split("-")[0]))];
582
+ const rowsSelectedSelectors = rowsSelectedArray.map(r => `.rc-ui-cell-index[data-row-index="${r}"]`).join(", ");
583
+ const cellsSelectedIndex = table && rowsSelectedSelectors.length > 0 ? table?.querySelectorAll(rowsSelectedSelectors) : null;
584
+ if (cellsSelectedIndex) {
585
+ cellsSelectedIndex.forEach(cell => {
586
+ cell.classList.remove('selected');
587
+ });
588
+ }
589
+ }
590
+ };
591
+ exports.onRemoveBgSelectedCell = onRemoveBgSelectedCell;
592
+ function getColIdsBetween(table, a, b) {
593
+ const ids = table.getVisibleLeafColumns().map(c => c.id);
594
+ const [start, end] = [ids.indexOf(a), ids.indexOf(b)].sort((x, y) => x - y);
595
+ return ids.slice(start, end + 1);
596
+ }
597
+ function getRowIdsBetween(table, a, b) {
598
+ // const ids = table.getRowModel().rows.map(r => r.id);
599
+ const ids = table.getRowModel().flatRows.map(r => r.id);
600
+ const [start, end] = [ids.indexOf(a), ids.indexOf(b)].sort((x, y) => x - y);
601
+ return ids.slice(start, end + 1);
602
+ }
603
+ const updateArrayByKey = (arr, element, key) => {
604
+ if (arr) {
605
+ return arr.map(it => {
606
+ const item = {
607
+ ...it
608
+ };
609
+ if (item[key] === element[key]) {
610
+ return {
611
+ ...item,
612
+ ...element
613
+ };
614
+ } else if (item.children && item.children.length > 0) {
615
+ item.children = updateArrayByKey(item.children, element, key);
616
+ }
617
+ return item;
618
+ });
619
+ } else {
620
+ return [];
621
+ }
622
+ };
623
+ exports.updateArrayByKey = updateArrayByKey;
624
+ const unFlattenData = data => {
625
+ const idToNodeMap = {};
626
+ const tree = [];
627
+
628
+ // Bước 1: Tạo map id -> node
629
+ data.forEach(item => {
630
+ // idToNodeMap[item.rowId] = { ...item, children: [] }
631
+ idToNodeMap[item.rowId] = {
632
+ ...item
633
+ };
634
+ });
635
+
636
+ // Bước 2: Gắn vào parent hoặc đẩy lên root nếu không có parent
637
+ data.forEach(item => {
638
+ const currentNode = idToNodeMap[item.rowId];
639
+ if (!item.parentId) {
640
+ tree.push(currentNode);
641
+ } else {
642
+ const parentNode = idToNodeMap[item.parentId];
643
+ if (parentNode) {
644
+ parentNode.children = parentNode.children ?? [];
645
+ parentNode.children.push(currentNode);
646
+ } else {
647
+ // Nếu parentId không tồn tại thì xem như root
648
+ tree.push(currentNode);
649
+ }
650
+ }
651
+ });
652
+ return tree;
653
+ };
654
+ exports.unFlattenData = unFlattenData;
655
+ const flattenArray = arr => {
656
+ if (!arr) {
657
+ return [];
658
+ }
659
+ return arr.reduce((r, {
660
+ children,
661
+ ...rest
662
+ }) => {
663
+ r.push(rest);
664
+ if (children) {
665
+ r.push(...flattenArray(children));
666
+ }
667
+ return r;
668
+ }, []);
669
+ };
670
+ exports.flattenArray = flattenArray;
671
+ function updateOrInsert(dataArray, dataFilter) {
672
+ const updatedArray = [...dataArray];
673
+ dataFilter.forEach(filterItem => {
674
+ const existingIndex = updatedArray.findIndex(item => item.rowId === filterItem.rowId);
675
+ if (existingIndex !== -1) {
676
+ // Cập nhật item đã tồn tại
677
+ updatedArray[existingIndex] = {
678
+ ...updatedArray[existingIndex],
679
+ ...filterItem
680
+ };
681
+ } else {
682
+ // Tìm vị trí cuối cùng của item trước đó trong dataFilter
683
+ const prevIndexInFilter = dataFilter.findIndex(f => f.rowId === filterItem.rowId) - 1;
684
+ if (prevIndexInFilter >= 0) {
685
+ const prevId = dataFilter[prevIndexInFilter].rowId;
686
+ const prevIndexInArray = updatedArray.findIndex(item => item.rowId === prevId);
687
+ if (prevIndexInArray !== -1) {
688
+ // Thêm ngay sau phần tử trước đó
689
+ updatedArray.splice(prevIndexInArray + 1, 0, filterItem);
690
+ return;
691
+ }
692
+ }
693
+
694
+ // 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
695
+ updatedArray.push(filterItem);
696
+ }
697
+ });
698
+ return updatedArray;
699
+ }
700
+ const findItemByKey = (array, key, value) => {
701
+ for (let i = 0; i < array.length; i++) {
702
+ const item = array[i];
703
+ if (item[key] === value) {
704
+ return item;
705
+ }
706
+ if (item.children && item.children.length > 0) {
707
+ const foundInChildren = findItemByKey(item.children, key, value);
708
+ if (foundInChildren) {
709
+ return foundInChildren;
710
+ }
711
+ }
712
+ }
713
+ return null;
714
+ };
715
+ exports.findItemByKey = findItemByKey;
716
+ const isFormattedNumber = str => {
717
+ if (!str) return false;
718
+ if (typeof str !== 'string') return false;
719
+ const regexUS = /^\d{1,3}(,\d{3})*(\.\d+)?$/; // 100,000.111
720
+ const regexEU = /^\d{1,3}(\.\d{3})*(,\d+)?$/; // 100.000,111
721
+
722
+ // Không có dấu hàng nghìn, chỉ dấu thập phân: 100000.1 hoặc 100000,01
723
+ const regexDecimalOnly = /^\d+([.,]\d{1,})$/;
724
+ return regexUS.test(str) || regexEU.test(str) || regexDecimalOnly.test(str);
725
+ };
726
+ exports.isFormattedNumber = isFormattedNumber;
727
+ const detectSeparators = str => {
728
+ if (typeof str !== 'string') return null;
729
+ const hasComma = str.includes(',');
730
+ const hasDot = str.includes('.');
731
+
732
+ // Trường hợp có cả dấu , và .
733
+ if (hasComma && hasDot) {
734
+ const lastComma = str.lastIndexOf(',');
735
+ const lastDot = str.lastIndexOf('.');
736
+ return lastComma > lastDot ? {
737
+ thousandSeparator: '.',
738
+ decimalSeparator: ','
739
+ } : {
740
+ thousandSeparator: ',',
741
+ decimalSeparator: '.'
742
+ };
743
+ }
744
+
745
+ // Trường hợp chỉ có dấu phẩy
746
+ if (hasComma && !hasDot) {
747
+ const parts = str.split(',');
748
+ if (parts.length === 2) {
749
+ return parts[1].length === 3 ? {
750
+ thousandSeparator: ',',
751
+ decimalSeparator: null
752
+ } : {
753
+ thousandSeparator: null,
754
+ decimalSeparator: ','
755
+ };
756
+ }
757
+ }
758
+
759
+ // Trường hợp chỉ có dấu chấm
760
+ if (hasDot && !hasComma) {
761
+ const parts = str.split('.');
762
+ if (parts.length === 2) {
763
+ return parts[1].length === 3 ? {
764
+ thousandSeparator: '.',
765
+ decimalSeparator: null
766
+ } : {
767
+ thousandSeparator: null,
768
+ decimalSeparator: '.'
769
+ };
770
+ }
771
+ }
772
+
773
+ // Không có dấu hoặc không hợp lệ
774
+ return null;
775
+ };
776
+ exports.detectSeparators = detectSeparators;
777
+ function isDate(value) {
778
+ if (value instanceof Date) {
779
+ return !isNaN(value.getTime());
780
+ }
781
+ if (typeof value === "string") {
782
+ // Chỉ chấp nhận định dạng yyyy-mm-dd hoặc mm/yyyy
783
+ return /^\d{4}-\d{2}-\d{2}$/.test(value) || /^\d{2}\/\d{4}$/.test(value);
784
+ }
785
+ return false;
786
+ }
787
+
788
+ // Chuỗi MM/YYYY → Date
789
+ function isDateString(str) {
790
+ return typeof str === "string" && (/^\d{2}\/\d{4}$/.test(str) || /^\d{4}-\d{2}-\d{2}$/.test(str));
791
+ }
792
+ function parseToDate(str) {
793
+ if (/^\d{2}\/\d{4}$/.test(str)) {
794
+ const [month, year] = str.split('/');
795
+ return new Date(parseInt(year), parseInt(month) - 1, 1);
796
+ }
797
+ return new Date(str);
798
+ }
799
+
800
+ // So sánh ngày (cùng ngày/tháng/năm)
801
+ function compareDates(date1, date2) {
802
+ return date1.getDate() === date2.getDate() && date1.getMonth() === date2.getMonth() && date1.getFullYear() === date2.getFullYear();
803
+ }
804
+
805
+ // Helper: compare MM/YYYY date string with itemValue
806
+ function compareDate(itemValue, value) {
807
+ const [month, year] = value.split('/').map(Number);
808
+ const date = new Date(itemValue);
809
+ return date.getMonth() + 1 === month && date.getFullYear() === year;
810
+ }
811
+ const removeVietnameseTones = str => {
812
+ if (!str) {
813
+ return '';
814
+ }
815
+ return str.normalize('NFD') // Tách các ký tự có dấu thành ký tự cơ bản + dấu
816
+ .replace(/[\u0300-\u036f]/g, '') // Xóa dấu
817
+ .replace(/đ/g, 'd') // Thay thế đ
818
+ .replace(/Đ/g, 'D').replace(/[^a-zA-Z0-9\s]/g, '') // Loại bỏ ký tự đặc biệt
819
+ .replace(/\s+/g, ' ') // Thay nhiều khoảng trắng thành 1 khoảng trắng
820
+ .trim();
821
+ };
822
+ exports.removeVietnameseTones = removeVietnameseTones;
823
+ const shouldInclude = (item, queries) => {
824
+ if (item.isFilterState === true) {
825
+ return true;
826
+ }
827
+ let result = null;
828
+ for (const query of queries) {
829
+ const {
830
+ field,
831
+ value,
832
+ operator,
833
+ predicate
834
+ } = query;
835
+ const itemValue = item[field];
836
+ let condition = false;
837
+ const isDateComparison = isDate(itemValue) || isDateString(value);
838
+ const itemDate = isDateComparison ? new Date(itemValue) : null;
839
+ const queryDate = isDateComparison ? parseToDate(value) : null;
840
+ const itemStr = removeVietnameseTones(itemValue?.toString().toLowerCase?.() ?? '');
841
+ const queryStr = removeVietnameseTones(value?.toString().toLowerCase?.() ?? '');
842
+ switch (operator.toLowerCase()) {
843
+ case "equal":
844
+ condition = isDateComparison ? compareDates(itemDate, queryDate) : itemValue === value;
845
+ break;
846
+ case "notequal":
847
+ condition = isDateComparison ? !compareDates(itemDate, queryDate) : itemValue !== value;
848
+ break;
849
+ case "greaterthan":
850
+ // @ts-ignore
851
+ condition = isDateComparison ? itemDate > queryDate : itemValue > value;
852
+
853
+ // condition = isDateComparison ? invalidDate(itemDate) && invalidDate(queryDate) && itemDate > queryDate : itemValue > value;
854
+ break;
855
+ case "greaterthanorequal":
856
+ // @ts-ignore
857
+ condition = isDateComparison ? itemDate >= queryDate : itemValue >= value;
858
+ break;
859
+ case "lessthan":
860
+ // @ts-ignore
861
+ condition = isDateComparison ? itemDate < queryDate : itemValue < value;
862
+ break;
863
+ case "lessthanorequal":
864
+ // @ts-ignore
865
+ condition = isDateComparison ? itemDate <= queryDate : itemValue <= value;
866
+ break;
867
+ case "contains":
868
+ condition = itemStr?.includes(queryStr);
869
+ break;
870
+ case "startswith":
871
+ condition = itemStr?.startsWith(queryStr);
872
+ break;
873
+ case "endswith":
874
+ condition = itemStr?.endsWith(queryStr);
875
+ break;
876
+ default:
877
+ console.warn(`Unknown operator: ${operator}`);
878
+ break;
879
+ }
880
+ if (predicate === "and") {
881
+ result = result === null ? condition : result && condition;
882
+ } else if (predicate === "or") {
883
+ result = result === null ? condition : result || condition;
884
+ }
885
+ }
886
+ return result;
887
+ };
888
+ exports.shouldInclude = shouldInclude;
889
+ function compareValues(a, b, order) {
890
+ const desc = order === "descend";
891
+ if (a == null && b == null) return 0;
892
+ if (a == null) return desc ? 1 : -1;
893
+ if (b == null) return desc ? -1 : 1;
894
+
895
+ // Nếu là số
896
+ if (typeof a === "number" && typeof b === "number") {
897
+ return desc ? b - a : a - b;
898
+ }
899
+
900
+ // Nếu là ngày hợp lệ
901
+ const dateA = new Date(a);
902
+ const dateB = new Date(b);
903
+ if (!isNaN(dateA.getTime()) && !isNaN(dateB.getTime())) {
904
+ return desc ? dateB.getTime() - dateA.getTime() : dateA.getTime() - dateB.getTime();
905
+ }
906
+
907
+ // Mặc định coi như string
908
+ return desc ? String(b).localeCompare(String(a)) : String(a).localeCompare(String(b));
909
+ }
910
+ function sortData(data, sorter) {
911
+ const sorted = [...data].sort((a, b) => {
912
+ for (const {
913
+ field,
914
+ order
915
+ } of sorter) {
916
+ const result = compareValues(a[field], b[field], order);
917
+ if (result !== 0) return result;
918
+ }
919
+ return 0;
920
+ });
921
+ return sorted.map(item => ({
922
+ ...item,
923
+ children: item.children ? sortData(item.children, sorter) : undefined
924
+ }));
925
+ }
926
+ function filterDataByColumns(data, queries, sorter, keysFilter) {
927
+ if (!queries || queries.length === 0) {
928
+ return sorter ? sortData(data, sorter) : data;
929
+ }
930
+ let filtered = data.map(item => {
931
+ const newItem = {
932
+ ...item
933
+ };
934
+ if (Array.isArray(item.children)) {
935
+ newItem.children = filterDataByColumns(item.children, queries, sorter, keysFilter);
936
+ }
937
+ const isSelfMatched = shouldInclude(item, queries) || keysFilter?.includes(newItem?.rowId);
938
+
939
+ // Nếu chính item thỏa hoặc có con thỏa → giữ lại
940
+ if (isSelfMatched || newItem.children && newItem.children.length > 0) {
941
+ return newItem;
942
+ }
943
+ return null; // loại bỏ node không phù hợp
944
+ }).filter(Boolean); // xóa các null
945
+
946
+ if (sorter && sorter.length > 0) {
947
+ filtered = sortData(filtered, sorter);
948
+ }
949
+ return filtered;
950
+ }
951
+ const getAllRowKey = data => {
952
+ const a = flattenArray(data);
953
+ return a.length ? a.map(it => it.rowId) : undefined;
954
+ };
955
+ exports.getAllRowKey = getAllRowKey;
956
+ const isEditable = (column, rowData) => {
957
+ if (column && typeof column.editEnable === 'function') {
958
+ return column.editEnable(rowData);
959
+ }
960
+ return column?.editEnable;
961
+ };
962
+ exports.isEditable = isEditable;
963
+ const checkFieldKey = key => {
964
+ if (key) {
965
+ return key;
966
+ } else {
967
+ return 'value';
968
+ }
969
+ };
970
+ exports.checkFieldKey = checkFieldKey;
971
+ const convertArrayWithIndent = (inputArray, parentIndent = 0) => {
972
+ if (inputArray) {
973
+ return inputArray.map(item => {
974
+ const indent = parentIndent;
975
+ if (item.children && item.children.length > 0) {
976
+ item.children = convertArrayWithIndent(item.children, indent + 1);
977
+ }
978
+ return {
979
+ ...item,
980
+ indent,
981
+ rowId: item.rowId ? item.rowId : item.id ? item.id : newGuid()
982
+ };
983
+ });
984
+ } else {
985
+ return [];
986
+ }
987
+ };
988
+ exports.convertArrayWithIndent = convertArrayWithIndent;
989
+ const convertLabelToTitle = data => {
990
+ return data.map(item => {
991
+ const {
992
+ label,
993
+ title,
994
+ value,
995
+ key,
996
+ ...rest
997
+ } = item;
998
+ const newItem = {
999
+ ...rest,
1000
+ value,
1001
+ label,
1002
+ key: key ?? value,
1003
+ title: title ?? label
1004
+ };
1005
+ if (item.children) {
1006
+ newItem.children = convertLabelToTitle(item.children);
1007
+ }
1008
+ return newItem;
1009
+ });
1010
+ };
1011
+ exports.convertLabelToTitle = convertLabelToTitle;
1012
+ const isNullOrUndefined = d => {
1013
+ return d === null || d === undefined;
1014
+ };
1015
+ exports.isNullOrUndefined = isNullOrUndefined;
1016
+ const isObjEmpty = obj => {
1017
+ if (isNullOrUndefined(obj)) {
1018
+ return true;
1019
+ } else {
1020
+ return Object.keys(obj).length === 0;
1021
+ }
1022
+ };
1023
+ exports.isObjEmpty = isObjEmpty;
1024
+ const isDisable = (column, rowData) => {
1025
+ if (column && typeof column?.disable === 'function') {
1026
+ return column.disable(rowData);
1027
+ }
1028
+ return !!column?.disable;
1029
+ };
1030
+ exports.isDisable = isDisable;
1031
+ const customWeekStartEndFormat = (value, weekFormat) => {
1032
+ return `${(0, _dayjs.default)(value).startOf('week').format(weekFormat)} ~ ${(0, _dayjs.default)(value).endOf('week').format(weekFormat)}`;
1033
+ };
1034
+ exports.customWeekStartEndFormat = customWeekStartEndFormat;
1035
+ const parseBooleanToValue = (value, type) => {
1036
+ return type === 'boolean' ? value : Number(value);
1037
+ };
1038
+ exports.parseBooleanToValue = parseBooleanToValue;
1039
+ const isNameColor = strColor => {
1040
+ const s = new Option().style;
1041
+ s.color = strColor;
1042
+ return s.color === strColor;
1043
+ };
1044
+ exports.isNameColor = isNameColor;
1045
+ const isColor = value => {
1046
+ const hexRegex = /^#([0-9A-F]{3}){1,2}$/i;
1047
+ const rgbRegex = /^rgb\((\d{1,3}), (\d{1,3}), (\d{1,3})\)$/;
1048
+ const rgbaRegex = /^rgba\((\d{1,3}), (\d{1,3}), (\d{1,3}), (0|1|0?\.\d+)\)$/;
1049
+ const hslRegex = /^hsl\(\d{1,3}, \d{1,3}%, \d{1,3}%\)$/;
1050
+ const hslaRegex = /^hsla\(\d{1,3}, \d{1,3}%, \d{1,3}%, (0|1|0?\.\d+)\)$/;
1051
+ const namedColors = /^(?:aqua|black|blue|fuchsia|gray|green|lime|maroon|navy|olive|purple|red|silver|teal|white|yellow)$/i;
1052
+ return hexRegex.test(value) || rgbRegex.test(value) || rgbaRegex.test(value) || hslRegex.test(value) || hslaRegex.test(value) || namedColors.test(value) || isNameColor(value);
1053
+ };
1054
+ exports.isColor = isColor;
1055
+ const genPresets = (presets = _colors.presetPalettes) => {
1056
+ return Object.entries(presets).map(([label, colors]) => ({
1057
+ label,
1058
+ colors,
1059
+ key: label
1060
+ }));
1061
+ };
1062
+ exports.genPresets = genPresets;
1063
+ const getEditType = (column, rowData) => {
1064
+ if (column && typeof column.editType === 'function') {
1065
+ return column.editType(rowData);
1066
+ }
1067
+ return column?.editType ?? 'text';
1068
+ };
1069
+ exports.getEditType = getEditType;
1070
+ const getDefaultValue = defaultValue => {
1071
+ if (defaultValue && typeof defaultValue === 'function') {
1072
+ return defaultValue();
1073
+ }
1074
+ return defaultValue;
1075
+ };
1076
+ exports.getDefaultValue = getDefaultValue;
1077
+ const flattenData = (childrenColumnName, data) => {
1078
+ let list = [];
1079
+ (data || []).forEach(record => {
1080
+ list.push(record);
1081
+ if (record && typeof record === 'object' && childrenColumnName in record) {
1082
+ list = [...list, ...flattenData(childrenColumnName, record[childrenColumnName])];
1083
+ }
1084
+ });
1085
+ return list;
1086
+ };
1087
+ exports.flattenData = flattenData;
1088
+ const getSelectedCellMatrix = (table, startCell, endCell) => {
1089
+ if (!startCell || !endCell) return {
1090
+ rowIds: [],
1091
+ colIds: [],
1092
+ startRowIndex: undefined,
1093
+ endRowIndex: undefined,
1094
+ startColIndex: undefined,
1095
+ endColIndex: undefined,
1096
+ colRange: [],
1097
+ rowRange: []
1098
+ };
1099
+
1100
+ // const rowIds = table.getRowModel().rows.map(r => r.id);
1101
+ const rowIds = table.getRowModel().flatRows.map(r => r.id);
1102
+ const colIds = table.getVisibleLeafColumns().map(c => c.id);
1103
+
1104
+ // const colIds = table.getAllLeafColumns().map(c => c.id);
1105
+
1106
+ const [startRowIndex, endRowIndex] = [rowIds.indexOf(startCell.rowId), rowIds.indexOf(endCell.rowId)].sort((a, b) => a - b);
1107
+ const [startColIndex, endColIndex] = [colIds.indexOf(startCell.colId), colIds.indexOf(endCell.colId)].sort((a, b) => a - b);
1108
+ return {
1109
+ rowRange: rowIds.slice(startRowIndex, endRowIndex + 1),
1110
+ colRange: colIds.slice(startColIndex, endColIndex + 1),
1111
+ startRowIndex,
1112
+ endRowIndex,
1113
+ startColIndex,
1114
+ endColIndex,
1115
+ rowIds,
1116
+ colIds
1117
+ };
1118
+ };
1119
+ exports.getSelectedCellMatrix = getSelectedCellMatrix;
1120
+ function addRowsDownWithCtrl(arr, n) {
1121
+ if (!Array.isArray(arr) || arr.length === 0) {
1122
+ return {
1123
+ combined: arr,
1124
+ addedRows: []
1125
+ };
1126
+ }
1127
+ const m = arr.length;
1128
+ const numCols = arr[0].length;
1129
+ const addedRows = [];
1130
+
1131
+ // Hàm kiểm tra kiểu date hợp lệ
1132
+ const isValidDate = item => {
1133
+ // return !isNaN(Date.parse(d))
1134
+
1135
+ if (typeof item === 'number') {
1136
+ // return 'number'
1137
+ return false;
1138
+ }
1139
+ if (typeof item === 'string') {
1140
+ // Kiểm tra nếu là chuỗi ISO date hợp lệ
1141
+ const date = new Date(item);
1142
+ if (!isNaN(date.getTime()) && item.includes('T')) {
1143
+ // return 'date'
1144
+ return true;
1145
+ }
1146
+ // return 'string'
1147
+ return false;
1148
+ }
1149
+ return !isNaN(Date.parse(item));
1150
+ };
1151
+
1152
+ // Lấy giá trị mẫu của cột j từ hàng đầu tiên
1153
+ const getSample = j => arr[0][j];
1154
+
1155
+ // Xác định chế độ xử lý cho mỗi cột:
1156
+ // mode = 'number-stepping' | 'date-stepping' | 'number-constant' | 'cycle'
1157
+ const modes = [];
1158
+ const steps = []; // bước tăng, nếu có (cho number hoặc date)
1159
+
1160
+ for (let j = 0; j < numCols; j++) {
1161
+ const sample = getSample(j);
1162
+ if (m === 1) {
1163
+ // 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.
1164
+ if (typeof sample === "number") {
1165
+ modes[j] = "number-constant";
1166
+ } else if (isValidDate(sample)) {
1167
+ modes[j] = "date-stepping";
1168
+ steps[j] = 24 * 3600 * 1000; // 1 ngày = 86400000 ms
1169
+ } else {
1170
+ modes[j] = "cycle";
1171
+ }
1172
+ } else if (m === 2) {
1173
+ // 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
1174
+ const first = arr[0][j],
1175
+ second = arr[1][j];
1176
+ if (typeof first === "number" && typeof second === "number") {
1177
+ modes[j] = "number-stepping";
1178
+ steps[j] = second - first;
1179
+ } else if (isValidDate(first) && isValidDate(second)) {
1180
+ modes[j] = "date-stepping";
1181
+ steps[j] = Date.parse(second) - Date.parse(first);
1182
+ } else {
1183
+ modes[j] = "cycle";
1184
+ }
1185
+ } else {
1186
+ // Nếu mảng có >2 hàng
1187
+ const first = arr[0][j],
1188
+ second = arr[1][j],
1189
+ third = arr[2][j];
1190
+ if (typeof first === "number" && typeof second === "number" && typeof third === "number") {
1191
+ const step1 = second - first;
1192
+ const step2 = third - second;
1193
+ if (step1 === step2) {
1194
+ modes[j] = "number-stepping";
1195
+ steps[j] = step1;
1196
+ } else {
1197
+ modes[j] = "cycle";
1198
+ }
1199
+ } else if (isValidDate(first) && isValidDate(second) && isValidDate(third)) {
1200
+ const step1 = Date.parse(second) - Date.parse(first);
1201
+ const step2 = Date.parse(third) - Date.parse(second);
1202
+ if (step1 === step2) {
1203
+ modes[j] = "date-stepping";
1204
+ steps[j] = step1;
1205
+ } else {
1206
+ modes[j] = "cycle";
1207
+ }
1208
+ } else {
1209
+ modes[j] = "cycle";
1210
+ }
1211
+ }
1212
+ }
1213
+
1214
+ // Tạo các dòng mới (thêm n dòng)
1215
+ // 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
1216
+ // Nếu chế độ là cycle thì dùng arr[i mod m][j]
1217
+ for (let i = 0; i < n; i++) {
1218
+ const newRow = [];
1219
+ for (let j = 0; j < numCols; j++) {
1220
+ let newValue;
1221
+ switch (modes[j]) {
1222
+ case "number-constant":
1223
+ // Mảng có 1 hàng, số giữ nguyên
1224
+ newValue = arr[0][j];
1225
+ break;
1226
+ case "number-stepping":
1227
+ {
1228
+ // Lấy giá trị cuối của cột j trong mảng ban đầu
1229
+ const lastValue = arr[m - 1][j];
1230
+ newValue = lastValue + (i + 1) * steps[j];
1231
+ }
1232
+ break;
1233
+ case "date-stepping":
1234
+ {
1235
+ // 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
1236
+ const lastDate = new Date(arr[m - 1][j]);
1237
+ const newTime = lastDate.getTime() + (i + 1) * steps[j];
1238
+ newValue = (0, _moment.default)(new Date(newTime)).format();
1239
+ }
1240
+ break;
1241
+ case "cycle":
1242
+ default:
1243
+ // Lặp lại nội dung theo vòng tròn: dùng hàng thứ (i mod m)
1244
+ newValue = arr[i % m][j];
1245
+ break;
1246
+ }
1247
+ newRow.push(newValue);
1248
+ }
1249
+ addedRows.push(newRow);
1250
+ }
1251
+ const combined = arr.concat(addedRows);
1252
+ return {
1253
+ combined,
1254
+ addedRows
1255
+ };
1256
+ }
1257
+ function addRowsDown(arr, n) {
1258
+ if (!Array.isArray(arr) || arr.length === 0) {
1259
+ return {
1260
+ combined: arr,
1261
+ addedRows: []
1262
+ };
1263
+ }
1264
+ const m = arr.length;
1265
+ const numCols = arr[0].length;
1266
+ const addedRows = [];
1267
+
1268
+ // // Hàm kiểm tra kiểu date hợp lệ
1269
+ // const isValidDate = (item: any) => {
1270
+ //
1271
+ //
1272
+ // // return !isNaN(Date.parse(d))
1273
+ //
1274
+ // if (typeof item === 'number') {
1275
+ // // return 'number'
1276
+ // return false
1277
+ // }
1278
+ // if (typeof item === 'string') {
1279
+ // // Kiểm tra nếu là chuỗi ISO date hợp lệ
1280
+ // const date = new Date(item)
1281
+ // if (!isNaN(date.getTime()) && item.includes('T')) {
1282
+ // // return 'date'
1283
+ // return true
1284
+ // }
1285
+ // // return 'string'
1286
+ // return false
1287
+ // }
1288
+ //
1289
+ // return !isNaN(Date.parse(item))
1290
+ //
1291
+ // }
1292
+
1293
+ // Lấy giá trị mẫu của cột j từ hàng đầu tiên
1294
+ const getSample = j => arr[0][j];
1295
+
1296
+ // Xác định chế độ xử lý cho mỗi cột:
1297
+ // mode = 'number-stepping' | 'date-stepping' | 'number-constant' | 'cycle'
1298
+ const modes = [];
1299
+ const steps = []; // bước tăng, nếu có (cho number hoặc date)
1300
+
1301
+ for (let j = 0; j < numCols; j++) {
1302
+ const sample = getSample(j);
1303
+ if (m === 1) {
1304
+ // 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.
1305
+ if (typeof sample === "number") {
1306
+ modes[j] = "number-constant";
1307
+ }
1308
+ // else if (isValidDate(sample)) {
1309
+ // modes[j] = "date-stepping"
1310
+ // steps[j] = 24 * 3600 * 1000 // 1 ngày = 86400000 ms
1311
+ // }
1312
+ else {
1313
+ modes[j] = "cycle";
1314
+ }
1315
+ } else if (m === 2) {
1316
+ // 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
1317
+ const first = arr[0][j],
1318
+ second = arr[1][j];
1319
+ if (typeof first === "number" && typeof second === "number") {
1320
+ modes[j] = "number-stepping";
1321
+ steps[j] = second - first;
1322
+ }
1323
+ // else if (isValidDate(first) && isValidDate(second)) {
1324
+ // modes[j] = "date-stepping"
1325
+ // steps[j] = Date.parse(second) - Date.parse(first)
1326
+ // }
1327
+ else {
1328
+ modes[j] = "cycle";
1329
+ }
1330
+ } else {
1331
+ // Nếu mảng có >2 hàng
1332
+ const first = arr[0][j],
1333
+ second = arr[1][j],
1334
+ third = arr[2][j];
1335
+ if (typeof first === "number" && typeof second === "number" && typeof third === "number") {
1336
+ const step1 = second - first;
1337
+ const step2 = third - second;
1338
+ if (step1 === step2) {
1339
+ modes[j] = "number-stepping";
1340
+ steps[j] = step1;
1341
+ } else {
1342
+ modes[j] = "cycle";
1343
+ }
1344
+ }
1345
+ // else if (isValidDate(first) && isValidDate(second) && isValidDate(third)) {
1346
+ // const step1 = Date.parse(second) - Date.parse(first)
1347
+ // const step2 = Date.parse(third) - Date.parse(second)
1348
+ // if (step1 === step2) {
1349
+ // modes[j] = "date-stepping"
1350
+ // steps[j] = step1
1351
+ // } else {
1352
+ // modes[j] = "cycle"
1353
+ // }
1354
+ // }
1355
+ else {
1356
+ modes[j] = "cycle";
1357
+ }
1358
+ }
1359
+ }
1360
+
1361
+ // Tạo các dòng mới (thêm n dòng)
1362
+ // 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
1363
+ // Nếu chế độ là cycle thì dùng arr[i mod m][j]
1364
+ for (let i = 0; i < n; i++) {
1365
+ const newRow = [];
1366
+ for (let j = 0; j < numCols; j++) {
1367
+ let newValue;
1368
+ switch (modes[j]) {
1369
+ case "number-constant":
1370
+ // Mảng có 1 hàng, số giữ nguyên
1371
+ newValue = arr[0][j];
1372
+ break;
1373
+ case "number-stepping":
1374
+ {
1375
+ // Lấy giá trị cuối của cột j trong mảng ban đầu
1376
+ const lastValue = arr[m - 1][j];
1377
+ newValue = lastValue + (i + 1) * steps[j];
1378
+ }
1379
+ break;
1380
+ // case "date-stepping":
1381
+ // {
1382
+ // // 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
1383
+ // const lastDate = new Date(arr[m - 1][j])
1384
+ // const newTime = lastDate.getTime() + (i + 1) * steps[j]
1385
+ // newValue = moment(new Date(newTime)).format()
1386
+ // }
1387
+ // break
1388
+ case "cycle":
1389
+ default:
1390
+ // Lặp lại nội dung theo vòng tròn: dùng hàng thứ (i mod m)
1391
+ newValue = arr[i % m][j];
1392
+ break;
1393
+ }
1394
+ newRow.push(newValue);
1395
+ }
1396
+ addedRows.push(newRow);
1397
+ }
1398
+ const combined = arr.concat(addedRows);
1399
+ return {
1400
+ combined,
1401
+ addedRows
1402
+ };
1403
+ }
1404
+ function addRowsUpWithCtrl(array, n) {
1405
+ const arr = array.reverse();
1406
+ if (!Array.isArray(arr) || arr.length === 0) {
1407
+ return {
1408
+ combined: arr,
1409
+ addedRows: []
1410
+ };
1411
+ }
1412
+ const m = arr.length;
1413
+ const numCols = arr[0].length;
1414
+ const addedRows = [];
1415
+
1416
+ // Hàm kiểm tra kiểu date hợp lệ
1417
+ const isValidDate = item => {
1418
+ // return !isNaN(Date.parse(d))
1419
+
1420
+ if (typeof item === 'number') {
1421
+ // return 'number'
1422
+ return false;
1423
+ }
1424
+ if (typeof item === 'string') {
1425
+ // Kiểm tra nếu là chuỗi ISO date hợp lệ
1426
+ const date = new Date(item);
1427
+ if (!isNaN(date.getTime()) && item.includes('T')) {
1428
+ // return 'date'
1429
+ return true;
1430
+ }
1431
+ // return 'string'
1432
+ return false;
1433
+ }
1434
+ return !isNaN(Date.parse(item));
1435
+ };
1436
+
1437
+ // Lấy giá trị mẫu của cột j từ hàng đầu tiên
1438
+ const getSample = j => arr[0][j];
1439
+
1440
+ // Xác định chế độ xử lý cho mỗi cột:
1441
+ // mode = 'number-stepping' | 'date-stepping' | 'number-constant' | 'cycle'
1442
+ const modes = [];
1443
+ const steps = []; // bước tăng, nếu có (cho number hoặc date)
1444
+
1445
+ for (let j = 0; j < numCols; j++) {
1446
+ const sample = getSample(j);
1447
+ if (m === 1) {
1448
+ // 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.
1449
+ if (typeof sample === "number") {
1450
+ modes[j] = "number-constant";
1451
+ } else if (isValidDate(sample)) {
1452
+ modes[j] = "date-stepping";
1453
+ steps[j] = 24 * 3600 * 1000; // 1 ngày = 86400000 ms
1454
+ } else {
1455
+ modes[j] = "cycle";
1456
+ }
1457
+ } else if (m === 2) {
1458
+ // 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
1459
+ const first = arr[0][j],
1460
+ second = arr[1][j];
1461
+ if (typeof first === "number" && typeof second === "number") {
1462
+ modes[j] = "number-stepping";
1463
+ steps[j] = second - first;
1464
+ } else if (isValidDate(first) && isValidDate(second)) {
1465
+ modes[j] = "date-stepping";
1466
+ steps[j] = Date.parse(second) - Date.parse(first);
1467
+ } else {
1468
+ modes[j] = "cycle";
1469
+ }
1470
+ } else {
1471
+ // Nếu mảng có >2 hàng
1472
+ const first = arr[0][j],
1473
+ second = arr[1][j],
1474
+ third = arr[2][j];
1475
+ if (typeof first === "number" && typeof second === "number" && typeof third === "number") {
1476
+ const step1 = second - first;
1477
+ const step2 = third - second;
1478
+ if (step1 === step2) {
1479
+ modes[j] = "number-stepping";
1480
+ steps[j] = step1;
1481
+ } else {
1482
+ modes[j] = "cycle";
1483
+ }
1484
+ } else if (isValidDate(first) && isValidDate(second) && isValidDate(third)) {
1485
+ const step1 = Date.parse(second) - Date.parse(first);
1486
+ const step2 = Date.parse(third) - Date.parse(second);
1487
+ if (step1 === step2) {
1488
+ modes[j] = "date-stepping";
1489
+ steps[j] = step1;
1490
+ } else {
1491
+ modes[j] = "cycle";
1492
+ }
1493
+ } else {
1494
+ modes[j] = "cycle";
1495
+ }
1496
+ }
1497
+ }
1498
+
1499
+ // Tạo các dòng mới (thêm n dòng)
1500
+ // 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
1501
+ // Nếu chế độ là cycle thì dùng arr[i mod m][j]
1502
+ for (let i = n - 1; i >= 0; i--) {
1503
+ const newRow = [];
1504
+ for (let j = 0; j < numCols; j++) {
1505
+ let newValue;
1506
+ switch (modes[j]) {
1507
+ case "number-constant":
1508
+ // Mảng có 1 hàng, số giữ nguyên
1509
+ newValue = arr[0][j];
1510
+ break;
1511
+ case "number-stepping":
1512
+ {
1513
+ // Lấy giá trị cuối của cột j trong mảng ban đầu
1514
+
1515
+ const lastValue = arr[m - 1][j];
1516
+ newValue = lastValue - (i + 1) * steps[j] * -1;
1517
+ }
1518
+ break;
1519
+ case "date-stepping":
1520
+ {
1521
+ // 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
1522
+
1523
+ const lastDate = new Date(arr[m - 1][j]);
1524
+ const newTime = m === 1 ? lastDate.getTime() - (i + 1) * steps[j] : lastDate.getTime() - (i + 1) * steps[j] * -1;
1525
+ newValue = (0, _moment.default)(new Date(newTime)).format();
1526
+ }
1527
+ break;
1528
+ case "cycle":
1529
+ default:
1530
+ // Lặp lại nội dung theo vòng tròn: dùng hàng thứ (i mod m)
1531
+
1532
+ newValue = arr[i % m][j];
1533
+ break;
1534
+ }
1535
+ newRow.push(newValue);
1536
+ }
1537
+ addedRows.push(newRow);
1538
+ }
1539
+ const combined = arr.concat(addedRows);
1540
+ return {
1541
+ combined,
1542
+ addedRows
1543
+ };
1544
+ }
1545
+ function addRowsUp(array, n) {
1546
+ const arr = array.reverse();
1547
+ if (!Array.isArray(arr) || arr.length === 0) {
1548
+ return {
1549
+ combined: arr,
1550
+ addedRows: []
1551
+ };
1552
+ }
1553
+ const m = arr.length;
1554
+ const numCols = arr[0].length;
1555
+ const addedRows = [];
1556
+
1557
+ // Hàm kiểm tra kiểu date hợp lệ
1558
+ // const isValidDate = (item: any) => {
1559
+ //
1560
+ //
1561
+ // // return !isNaN(Date.parse(d))
1562
+ //
1563
+ // if (typeof item === 'number') {
1564
+ // // return 'number'
1565
+ // return false
1566
+ // }
1567
+ // if (typeof item === 'string') {
1568
+ // // Kiểm tra nếu là chuỗi ISO date hợp lệ
1569
+ // const date = new Date(item)
1570
+ // if (!isNaN(date.getTime()) && item.includes('T')) {
1571
+ // // return 'date'
1572
+ // return true
1573
+ // }
1574
+ // // return 'string'
1575
+ // return false
1576
+ // }
1577
+ //
1578
+ // return !isNaN(Date.parse(item))
1579
+ //
1580
+ // }
1581
+
1582
+ // Lấy giá trị mẫu của cột j từ hàng đầu tiên
1583
+ const getSample = j => arr[0][j];
1584
+
1585
+ // Xác định chế độ xử lý cho mỗi cột:
1586
+ // mode = 'number-stepping' | 'date-stepping' | 'number-constant' | 'cycle'
1587
+ const modes = [];
1588
+ const steps = []; // bước tăng, nếu có (cho number hoặc date)
1589
+
1590
+ for (let j = 0; j < numCols; j++) {
1591
+ const sample = getSample(j);
1592
+ if (m === 1) {
1593
+ // 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.
1594
+ if (typeof sample === "number") {
1595
+ modes[j] = "number-constant";
1596
+ } else {
1597
+ modes[j] = "cycle";
1598
+ }
1599
+ } else if (m === 2) {
1600
+ // 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
1601
+ const first = arr[0][j],
1602
+ second = arr[1][j];
1603
+ if (typeof first === "number" && typeof second === "number") {
1604
+ modes[j] = "number-stepping";
1605
+ steps[j] = second - first;
1606
+ } else {
1607
+ modes[j] = "cycle";
1608
+ }
1609
+ } else {
1610
+ // Nếu mảng có >2 hàng
1611
+ const first = arr[0][j],
1612
+ second = arr[1][j],
1613
+ third = arr[2][j];
1614
+ if (typeof first === "number" && typeof second === "number" && typeof third === "number") {
1615
+ const step1 = second - first;
1616
+ const step2 = third - second;
1617
+ if (step1 === step2) {
1618
+ modes[j] = "number-stepping";
1619
+ steps[j] = step1;
1620
+ } else {
1621
+ modes[j] = "cycle";
1622
+ }
1623
+ } else {
1624
+ modes[j] = "cycle";
1625
+ }
1626
+ }
1627
+ }
1628
+
1629
+ // Tạo các dòng mới (thêm n dòng)
1630
+ // 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
1631
+ // Nếu chế độ là cycle thì dùng arr[i mod m][j]
1632
+ for (let i = n - 1; i >= 0; i--) {
1633
+ const newRow = [];
1634
+ for (let j = 0; j < numCols; j++) {
1635
+ let newValue;
1636
+ switch (modes[j]) {
1637
+ case "number-constant":
1638
+ // Mảng có 1 hàng, số giữ nguyên
1639
+ newValue = arr[0][j];
1640
+ break;
1641
+ case "number-stepping":
1642
+ {
1643
+ // Lấy giá trị cuối của cột j trong mảng ban đầu
1644
+
1645
+ const lastValue = arr[m - 1][j];
1646
+ newValue = lastValue - (i + 1) * steps[j] * -1;
1647
+ }
1648
+ break;
1649
+ case "cycle":
1650
+ default:
1651
+ // Lặp lại nội dung theo vòng tròn: dùng hàng thứ (i mod m)
1652
+
1653
+ newValue = arr[i % m][j];
1654
+ break;
1655
+ }
1656
+ newRow.push(newValue);
1657
+ }
1658
+ addedRows.push(newRow);
1659
+ }
1660
+ const combined = arr.concat(addedRows);
1661
+ return {
1662
+ combined,
1663
+ addedRows
1664
+ };
1665
+ }
1666
+ const convertFilters = filters => {
1667
+ const result = [];
1668
+ filters.forEach(({
1669
+ key,
1670
+ column,
1671
+ filteredKeys,
1672
+ operator
1673
+ }) => {
1674
+ if (!filteredKeys || filteredKeys.length === 0) {
1675
+ return;
1676
+ }
1677
+ if (column?.typeFilter === "DateRange" && filteredKeys.length === 2) {
1678
+ result.push({
1679
+ key,
1680
+ field: column?.field,
1681
+ value: filteredKeys[0],
1682
+ predicate: "and",
1683
+ operator: "greaterthanorequal"
1684
+ }, {
1685
+ key,
1686
+ field: column?.field,
1687
+ value: filteredKeys[1],
1688
+ predicate: "and",
1689
+ operator: "lessthanorequal"
1690
+ });
1691
+ } else if (column?.typeFilter === "NumberRange") {
1692
+ if ((filteredKeys[0] || filteredKeys[0] === 0) && !filteredKeys[1]) {
1693
+ result.push({
1694
+ key,
1695
+ field: column?.field,
1696
+ value: filteredKeys[0],
1697
+ predicate: "and",
1698
+ operator: "greaterthanorequal"
1699
+ });
1700
+ }
1701
+ if ((filteredKeys[1] || filteredKeys[1] === 0) && !filteredKeys[0]) {
1702
+ result.push({
1703
+ key,
1704
+ field: column?.field,
1705
+ value: filteredKeys[1],
1706
+ predicate: "and",
1707
+ operator: "lessthanorequal"
1708
+ });
1709
+ }
1710
+ if ((filteredKeys[0] || filteredKeys[0] === 0) && (filteredKeys[1] || filteredKeys[1] === 0)) {
1711
+ result.push({
1712
+ key,
1713
+ field: column?.field,
1714
+ value: filteredKeys[0],
1715
+ predicate: "and",
1716
+ operator: "greaterthanorequal"
1717
+ }, {
1718
+ key,
1719
+ field: column?.field,
1720
+ value: filteredKeys[1],
1721
+ predicate: "and",
1722
+ operator: "lessthanorequal"
1723
+ });
1724
+ }
1725
+ } else if (column?.typeFilter === 'Checkbox') {
1726
+ filteredKeys.forEach(value => {
1727
+ result.push({
1728
+ key,
1729
+ field: column?.field,
1730
+ value,
1731
+ predicate: "or",
1732
+ operator
1733
+ });
1734
+ });
1735
+ } else {
1736
+ result.push({
1737
+ key,
1738
+ field: column?.field,
1739
+ value: filteredKeys[0],
1740
+ predicate: 'and',
1741
+ operator
1742
+ });
1743
+ }
1744
+ });
1745
+ return result;
1746
+ };
1747
+ exports.convertFilters = convertFilters;
1748
+ function getInvisibleColumns(columns) {
1749
+ const result = {};
1750
+ for (const col of columns) {
1751
+ if (col.visible === false) {
1752
+ result[col.field ?? ''] = false;
1753
+ }
1754
+ }
1755
+ return result;
1756
+ }
1757
+ const getAllVisibleKeys = columns => {
1758
+ const keys = [];
1759
+ const traverse = (cols, parentHidden = false) => {
1760
+ for (const col of cols) {
1761
+ if (col.hidden || parentHidden) {
1762
+ continue;
1763
+ }
1764
+ if (col.key) {
1765
+ keys.push(col.key);
1766
+ }
1767
+ if (col.children) {
1768
+ traverse(col.children, col.hidden);
1769
+ }
1770
+ }
1771
+ };
1772
+ traverse(columns);
1773
+ return keys;
1774
+ };
1775
+ exports.getAllVisibleKeys = getAllVisibleKeys;
1776
+ const getAllVisibleKeys1 = columns => {
1777
+ const keys = [];
1778
+ const traverse = (cols, parentHidden = false) => {
1779
+ for (const col of cols) {
1780
+ if (col.visible === false || parentHidden) {
1781
+ continue;
1782
+ }
1783
+ if (col.field) {
1784
+ keys.push(col.field);
1785
+ }
1786
+ if (col.children) {
1787
+ traverse(col.children, col.visible);
1788
+ }
1789
+ }
1790
+ };
1791
+ traverse(columns);
1792
+ return keys;
1793
+ };
1794
+ exports.getAllVisibleKeys1 = getAllVisibleKeys1;
1795
+ function getHiddenParentKeys(columns, parentKeys = []) {
1796
+ const hiddenParents = new Set();
1797
+ for (const column of columns) {
1798
+ if (column.children) {
1799
+ const currentPath = column.key ? [...parentKeys, column.key] : [...parentKeys];
1800
+ const childHiddenParents = getHiddenParentKeys(column.children, currentPath);
1801
+ if (childHiddenParents.length > 0) {
1802
+ childHiddenParents.forEach(key => hiddenParents.add(key));
1803
+ currentPath.forEach(key => hiddenParents.add(key));
1804
+ }
1805
+ } else if (column.hidden) {
1806
+ parentKeys.forEach(key => hiddenParents.add(key));
1807
+ }
1808
+ }
1809
+ return Array.from(hiddenParents);
1810
+ }
1811
+ function getHiddenParentKeys1(columns, parentKeys = []) {
1812
+ const hiddenParents = new Set();
1813
+ for (const column of columns) {
1814
+ if (column.children) {
1815
+ const currentPath = column.field ? [...parentKeys, column.field] : [...parentKeys];
1816
+ const childHiddenParents = getHiddenParentKeys(column.children, currentPath);
1817
+ if (childHiddenParents.length > 0) {
1818
+ childHiddenParents.forEach(key => hiddenParents.add(key));
1819
+ currentPath.forEach(key => hiddenParents.add(key));
1820
+ }
1821
+ } else if (column.visible !== false) {
1822
+ parentKeys.forEach(key => hiddenParents.add(key));
1823
+ }
1824
+ }
1825
+ return Array.from(hiddenParents);
1826
+ }
1827
+ const getVisibleColumnKeys = columns => {
1828
+ const allKeys = getAllVisibleKeys(columns);
1829
+ const allParentKeys = getHiddenParentKeys(columns);
1830
+ return allKeys.filter(item => !allParentKeys.includes(item));
1831
+ };
1832
+ exports.getVisibleColumnKeys = getVisibleColumnKeys;
1833
+ const getVisibleColumnKeys1 = columns => {
1834
+ const allKeys = getAllVisibleKeys1(columns);
1835
+ const allParentKeys = getHiddenParentKeys1(columns);
1836
+ return allKeys.filter(item => !allParentKeys.includes(item));
1837
+ };
1838
+ exports.getVisibleColumnKeys1 = getVisibleColumnKeys1;
1839
+ function isObjEqual(obj1, obj2) {
1840
+ // Trường hợp tham chiếu bằng nhau
1841
+ if (obj1 === obj2) return true;
1842
+
1843
+ // Nếu 1 trong 2 không phải object hoặc null thì so sánh trực tiếp
1844
+ if (typeof obj1 !== 'object' || obj1 === null || typeof obj2 !== 'object' || obj2 === null) {
1845
+ return obj1 === obj2;
1846
+ }
1847
+
1848
+ // Lấy danh sách key
1849
+ const keys1 = Object.keys(obj1);
1850
+ const keys2 = Object.keys(obj2);
1851
+
1852
+ // Nếu số key khác nhau thì khác nhau
1853
+ if (keys1.length !== keys2.length) return false;
1854
+
1855
+ // Duyệt và so sánh từng key
1856
+ for (const key of keys1) {
1857
+ if (!keys2.includes(key)) return false;
1858
+ if (!isObjEqual(obj1[key], obj2[key])) return false;
1859
+ }
1860
+ return true;
1861
+ }
1862
+
1863
+ // Sorting function
1864
+ const sortByType = arr => {
1865
+ if (arr) {
1866
+ return arr.sort((a, b) => {
1867
+ if (a.fixed === 'left' && b.fixed !== 'left') {
1868
+ return -1;
1869
+ } else if (a.fixed !== 'left' && b.fixed === 'left') {
1870
+ return 1;
1871
+ } else if (a.fixed === 'right' && b.fixed !== 'right') {
1872
+ return 1;
1873
+ } else if (a.fixed !== 'right' && b.fixed === 'right') {
1874
+ return -1;
1875
+ }
1876
+ return 0;
1877
+ });
1878
+ } else {
1879
+ return [];
1880
+ }
1881
+ };
1882
+ exports.sortByType = sortByType;
1883
+ function convertColumnsToTreeData(columns, groupColumns) {
1884
+ // return columns.map((col) => {
1885
+ // const node: TreeDataNode = {
1886
+ // key: String(col.id ?? col.id ?? col.header), // key duy nhất
1887
+ // title: String(col.header ?? col.id ?? ''), // tiêu đề
1888
+ // }
1889
+
1890
+ // // Nếu có children (nested columns)
1891
+ // if ('columns' in col && Array.isArray((col as any).columns)) {
1892
+ // node.children = convertColumnsToTreeData(
1893
+ // (col as any).columns as ColumnDef<T, any>[]
1894
+ // )
1895
+ // }
1896
+
1897
+ // return node
1898
+ // })
1899
+
1900
+ return columns.filter(col => {
1901
+ const meta = col.meta ?? {};
1902
+ const inGroup = groupColumns ? groupColumns.includes(String(col.id ?? col.id)) : false;
1903
+
1904
+ // Điều kiện filter:
1905
+ // - Nếu meta.showInColumnChoose = false => loại bỏ
1906
+ // - Nếu không nằm trong groupColumns và không phải column group => loại bỏ
1907
+ if (meta.showInColumnChoose === false) return false;
1908
+ if (inGroup && !('columns' in col && Array.isArray(col.columns))) {
1909
+ return false;
1910
+ }
1911
+ return true;
1912
+ }).map(col => {
1913
+ const node = {
1914
+ key: String(col.id ?? col.id ?? col.header),
1915
+ // title: () => col.header as any
1916
+ title: col.header
1917
+
1918
+ // title: String(col.header ?? col.id ?? ''),
1919
+ };
1920
+ if ('columns' in col && Array.isArray(col.columns)) {
1921
+ const children = convertColumnsToTreeData(col.columns, groupColumns);
1922
+ if (children.length > 0) {
1923
+ node.children = children;
1924
+ }
1925
+ }
1926
+ return node;
1927
+ });
1928
+ }
1929
+ const updateColumns1 = (columns, includes) => {
1930
+ return columns.map(column => {
1931
+ const newColumn = {
1932
+ ...column
1933
+ };
1934
+ let hasVisibleChild = false;
1935
+ if (!column.field) {
1936
+ return column;
1937
+ }
1938
+ if (newColumn.children) {
1939
+ newColumn.children = updateColumns1(newColumn.children, includes);
1940
+ hasVisibleChild = newColumn.children.some(child => !child.hidden);
1941
+ }
1942
+
1943
+ // newColumn.hidden = newColumn.key && !includes.includes(newColumn.key)
1944
+ newColumn.visible = !!(newColumn.field && includes.includes(newColumn.field));
1945
+ // newColumn.fixed = newColumn.field && !includes.includes(newColumn.field) ? undefined : newColumn.fixed
1946
+
1947
+ if (newColumn.children && newColumn.children.length > 0) {
1948
+ newColumn.visible = !hasVisibleChild;
1949
+ // newColumn.fixed = !hasVisibleChild ? undefined : newColumn.fixed
1950
+ }
1951
+ return newColumn;
1952
+ });
1953
+ };
1954
+ exports.updateColumns1 = updateColumns1;
1955
+ const convertToObj = arr => {
1956
+ // const result = Object.keys(obj).reduce((acc: any, key) => {
1957
+ // acc[key] = false;
1958
+ // return acc;
1959
+ // }, {});
1960
+
1961
+ // return result
1962
+
1963
+ return Object.fromEntries(arr.map(key => [key, false]));
1964
+ };
1965
+ exports.convertToObj = convertToObj;
1966
+ const getDiffent2Array = (a, b) => {
1967
+ return [...a.filter(x => !b.includes(x)), ...b.filter(x => !a.includes(x))];
1968
+ };
1969
+ exports.getDiffent2Array = getDiffent2Array;