es-grid-template 1.8.64 → 1.8.65

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 (125) hide show
  1. package/es/grid-component/ColumnsGroup/ColumnsGroup.js +4 -1
  2. package/es/grid-component/TempTable.js +2 -2
  3. package/es/grid-component/hooks/utils.d.ts +2 -8
  4. package/es/grid-component/hooks/utils.js +175 -144
  5. package/es/grid-component/index.d.ts +1 -1
  6. package/es/grid-component/index.js +0 -4
  7. package/es/grid-component/type.d.ts +7 -0
  8. package/es/table-component/type.d.ts +8 -0
  9. package/es/table-virtuoso/ColumnsGroup/ColumnsGroup.d.ts +12 -0
  10. package/es/table-virtuoso/ColumnsGroup/ColumnsGroup.js +232 -0
  11. package/es/table-virtuoso/ColumnsGroup/index.d.ts +1 -0
  12. package/es/table-virtuoso/ColumnsGroup/index.js +1 -0
  13. package/es/{grid-component → table-virtuoso}/InternalTable.d.ts +2 -3
  14. package/es/table-virtuoso/InternalTable.js +413 -0
  15. package/es/table-virtuoso/body/TableBody.d.ts +14 -0
  16. package/es/table-virtuoso/body/TableBody.js +84 -0
  17. package/es/table-virtuoso/body/TableBodyCell.d.ts +14 -0
  18. package/es/table-virtuoso/body/TableBodyCell.js +466 -0
  19. package/es/table-virtuoso/body/TableBodyRow.d.ts +13 -0
  20. package/es/table-virtuoso/body/TableBodyRow.js +116 -0
  21. package/es/table-virtuoso/footer/TableFooterCell.d.ts +7 -0
  22. package/es/table-virtuoso/footer/TableFooterCell.js +54 -0
  23. package/es/table-virtuoso/header/TableHeadCell.d.ts +14 -0
  24. package/es/table-virtuoso/header/TableHeadCell.js +265 -0
  25. package/es/table-virtuoso/header/renderFilter.d.ts +20 -0
  26. package/es/table-virtuoso/header/renderFilter.js +289 -0
  27. package/es/table-virtuoso/hook/constant.d.ts +73 -0
  28. package/es/table-virtuoso/hook/constant.js +240 -0
  29. package/es/table-virtuoso/hook/convert.d.ts +1 -0
  30. package/es/table-virtuoso/hook/convert.js +28 -0
  31. package/es/table-virtuoso/hook/useColumns.d.ts +28 -0
  32. package/es/table-virtuoso/hook/useColumns.js +302 -0
  33. package/es/table-virtuoso/hook/useFilterOperator.d.ts +7 -0
  34. package/es/table-virtuoso/hook/useFilterOperator.js +33 -0
  35. package/es/table-virtuoso/hook/utils.d.ts +159 -0
  36. package/es/table-virtuoso/hook/utils.js +2263 -0
  37. package/es/table-virtuoso/index.d.ts +2 -0
  38. package/es/table-virtuoso/index.js +2 -0
  39. package/es/table-virtuoso/style.d.ts +22 -0
  40. package/es/table-virtuoso/style.js +11 -0
  41. package/es/table-virtuoso/style.scss +1440 -0
  42. package/es/table-virtuoso/table/Grid.d.ts +37 -0
  43. package/es/table-virtuoso/table/Grid.js +302 -0
  44. package/es/table-virtuoso/table/TableContainer.d.ts +49 -0
  45. package/es/table-virtuoso/table/TableContainer.js +305 -0
  46. package/es/table-virtuoso/table/TableWrapper.d.ts +20 -0
  47. package/es/table-virtuoso/table/TableWrapper.js +158 -0
  48. package/es/table-virtuoso/type.d.ts +0 -0
  49. package/es/table-virtuoso/type.js +785 -0
  50. package/es/table-virtuoso/useContext.d.ts +97 -0
  51. package/es/table-virtuoso/useContext.js +21 -0
  52. package/lib/grid-component/ColumnsGroup/ColumnsGroup.js +4 -1
  53. package/lib/grid-component/TempTable.js +2 -2
  54. package/lib/grid-component/hooks/utils.d.ts +2 -8
  55. package/lib/grid-component/hooks/utils.js +176 -152
  56. package/lib/grid-component/index.d.ts +1 -1
  57. package/lib/grid-component/index.js +0 -3
  58. package/lib/grid-component/type.d.ts +7 -0
  59. package/lib/table-component/type.d.ts +8 -0
  60. package/lib/table-virtuoso/ColumnsGroup/ColumnsGroup.d.ts +12 -0
  61. package/lib/table-virtuoso/ColumnsGroup/ColumnsGroup.js +243 -0
  62. package/lib/table-virtuoso/ColumnsGroup/index.d.ts +1 -0
  63. package/lib/table-virtuoso/ColumnsGroup/index.js +16 -0
  64. package/lib/{grid-component → table-virtuoso}/InternalTable.d.ts +2 -3
  65. package/lib/table-virtuoso/InternalTable.js +422 -0
  66. package/lib/table-virtuoso/body/TableBody.d.ts +14 -0
  67. package/lib/table-virtuoso/body/TableBody.js +95 -0
  68. package/lib/table-virtuoso/body/TableBodyCell.d.ts +14 -0
  69. package/lib/table-virtuoso/body/TableBodyCell.js +473 -0
  70. package/lib/table-virtuoso/body/TableBodyRow.d.ts +13 -0
  71. package/lib/table-virtuoso/body/TableBodyRow.js +124 -0
  72. package/lib/table-virtuoso/footer/TableFooterCell.d.ts +7 -0
  73. package/lib/table-virtuoso/footer/TableFooterCell.js +63 -0
  74. package/lib/table-virtuoso/header/TableHeadCell.d.ts +14 -0
  75. package/lib/table-virtuoso/header/TableHeadCell.js +274 -0
  76. package/lib/table-virtuoso/header/renderFilter.d.ts +20 -0
  77. package/lib/table-virtuoso/header/renderFilter.js +299 -0
  78. package/lib/table-virtuoso/hook/constant.d.ts +73 -0
  79. package/lib/table-virtuoso/hook/constant.js +247 -0
  80. package/lib/table-virtuoso/hook/convert.d.ts +1 -0
  81. package/lib/table-virtuoso/hook/convert.js +34 -0
  82. package/lib/table-virtuoso/hook/useColumns.d.ts +28 -0
  83. package/lib/table-virtuoso/hook/useColumns.js +315 -0
  84. package/lib/table-virtuoso/hook/useFilterOperator.d.ts +7 -0
  85. package/lib/table-virtuoso/hook/useFilterOperator.js +40 -0
  86. package/lib/table-virtuoso/hook/utils.d.ts +159 -0
  87. package/lib/table-virtuoso/hook/utils.js +2389 -0
  88. package/lib/table-virtuoso/index.d.ts +2 -0
  89. package/lib/table-virtuoso/index.js +9 -0
  90. package/lib/table-virtuoso/style.d.ts +22 -0
  91. package/lib/table-virtuoso/style.js +18 -0
  92. package/lib/table-virtuoso/style.scss +1440 -0
  93. package/lib/table-virtuoso/table/Grid.d.ts +37 -0
  94. package/lib/table-virtuoso/table/Grid.js +311 -0
  95. package/lib/table-virtuoso/table/TableContainer.d.ts +49 -0
  96. package/lib/table-virtuoso/table/TableContainer.js +313 -0
  97. package/lib/table-virtuoso/table/TableWrapper.d.ts +20 -0
  98. package/lib/table-virtuoso/table/TableWrapper.js +164 -0
  99. package/lib/table-virtuoso/type.d.ts +0 -0
  100. package/lib/table-virtuoso/type.js +786 -0
  101. package/lib/table-virtuoso/useContext.d.ts +97 -0
  102. package/lib/table-virtuoso/useContext.js +27 -0
  103. package/package.json +2 -1
  104. package/es/grid-component/ConvertColumnTable.d.ts +0 -7
  105. package/es/grid-component/ConvertColumnTable.js +0 -144
  106. package/es/grid-component/InternalTable.js +0 -1170
  107. package/es/grid-component/table/Grid.d.ts +0 -23
  108. package/es/grid-component/table/Grid.js +0 -49
  109. package/es/grid-component/table/GridEdit.d.ts +0 -23
  110. package/es/grid-component/table/GridEdit.js +0 -2726
  111. package/es/grid-component/table/Group.d.ts +0 -21
  112. package/es/grid-component/table/Group.js +0 -195
  113. package/es/grid-component/table/InfiniteTable.d.ts +0 -23
  114. package/es/grid-component/table/InfiniteTable.js +0 -101
  115. package/lib/grid-component/ConvertColumnTable.d.ts +0 -7
  116. package/lib/grid-component/ConvertColumnTable.js +0 -153
  117. package/lib/grid-component/InternalTable.js +0 -1178
  118. package/lib/grid-component/table/Grid.d.ts +0 -23
  119. package/lib/grid-component/table/Grid.js +0 -58
  120. package/lib/grid-component/table/GridEdit.d.ts +0 -23
  121. package/lib/grid-component/table/GridEdit.js +0 -2723
  122. package/lib/grid-component/table/Group.d.ts +0 -21
  123. package/lib/grid-component/table/Group.js +0 -204
  124. package/lib/grid-component/table/InfiniteTable.d.ts +0 -23
  125. package/lib/grid-component/table/InfiniteTable.js +0 -109
@@ -1,2726 +0,0 @@
1
- import _extends from "@babel/runtime/helpers/esm/extends";
2
- import React, { Fragment, useMemo, useRef, useState } from 'react';
3
- import customParseFormat from 'dayjs/plugin/customParseFormat';
4
- import classNames from "classnames";
5
- // import {Button, Dropdown, Form, Modal, Typography} from "antd"
6
- import { Button, Dropdown, Modal, Typography } from "antd";
7
- import { useForm } from 'react-hook-form';
8
- import { Toaster } from "react-hot-toast";
9
- import { yupResolver } from "@hookform/resolvers/yup";
10
- import { flatColumns2, getValueCell, renderContent } from "../hooks/columns";
11
- import EditableCell from "../EditableCell";
12
- import { GridStyle } from "../GridStyle";
13
- import { TableContext } from "../useContext";
14
- import dayjs from "dayjs";
15
- import 'dayjs/locale/es';
16
- import 'dayjs/locale/vi';
17
- import TableGrid from "../TableGrid";
18
- import { addClassBorderPasteCell, addClassCellIndexSelected,
19
- // addRowsDownWithCtrl,
20
- addRowsUp, checkChild, editAbleColumns, findAllChildrenKeys, findItemByKey, findItemPath, flattenArray, flattenData, getDefaultValue, getEditType, getFirstSelectCell, getLastSelectCell, getRowNumber, getRowsPasteIndex, hideDraggingPoint, isEditable, isEqualSet, isObjEmpty, newGuid, onAddBgSelectedCell,
21
- // onRemoveBorderSelectedCell,
22
- onRemoveBgSelectedCell, removeClassBorderPasteCell, removeClassCellIndexSelected, showDraggingPoint, sortedSetASC, totalFixedWidth, updateArrayByKey, getFormat,
23
- // isRangeCell,
24
- // isSelectedCell,
25
- onRemoveBgCellIndex, onAddBgCellIndex, onAddBorderSelectedCell, onRemoveBorderSelectedCell, isFormattedNumber, checkThousandSeparator, checkDecimalSeparator, detectSeparators, unFlattenData, getAllRowKey,
26
- // updateDataByFilter,
27
- addRowsDown,
28
- // mergeWithFilter,
29
- // mergeWithFilter2,
30
- // updateDataByFilter,
31
- updateOrInsert, addRowsDownWithCtrl, addRowsUpWithCtrl } from "../hooks";
32
- import Message from "../../Message/Message";
33
- import { Toolbar, ConfigProvider, InputNumber } from "rc-master-ui";
34
- import classnames from "classnames";
35
- import { Plus, Trash2 } from "becoxy-icons";
36
- // import {faker} from "@faker-js/faker";
37
- import { SELECTION_COLUMN } from "../InternalTable";
38
- import { removeNumericFormat } from "react-numeric-component";
39
- import HeaderContent from "../hooks/content/HeaderContent";
40
- import { useSortable } from "@dnd-kit/sortable";
41
- const {
42
- Paragraph,
43
- Title
44
- } = Typography;
45
- dayjs.extend(customParseFormat);
46
- const toast = 'top-right';
47
- // const defaultContext = [
48
- // {
49
- // key: 'INSERT_BEFORE',
50
- // label: 'Thêm dòng bên trên',
51
- // icon: <Plus fontSize={14} />,
52
- // children: [
53
- // {
54
- // parentKey: 'INSERT_BEFORE',
55
- // key: 'INSERT_BEFORE_1',
56
- // label: 'Thêm 1 dòng',
57
- // row: 1
58
- // },
59
- // {
60
- // parentKey: 'INSERT_BEFORE',
61
- // key: 'INSERT_BEFORE_10',
62
- // label: 'Thêm 10 dòng',
63
- // row: 10
64
- // },
65
- // {
66
- // parentKey: 'INSERT_BEFORE',
67
- // key: 'INSERT_BEFORE_50',
68
- // label: 'Thêm 50 dòng',
69
- // row: 50
70
- // },
71
- // {
72
- // parentKey: 'INSERT_BEFORE',
73
- // key: 'INSERT_BEFORE_100',
74
- // label: 'Thêm 100 dòng',
75
- // row: 100
76
- // },
77
- // {
78
- // parentKey: 'INSERT_BEFORE',
79
- // key: 'INSERT_BEFORE_ADV',
80
- // label: 'Tùy chỉnh'
81
- // }
82
- // ]
83
- // },
84
- // {
85
- // key: 'INSERT_AFTER',
86
- // label: 'Thêm dòng bên dưới',
87
- // icon: <Plus fontSize={14} />,
88
- // children: [
89
- // {
90
- // parentKey: 'INSERT_AFTER',
91
- // key: 'INSERT_AFTER_1',
92
- // label: 'Thêm 1 dòng',
93
- // row: 1
94
- // },
95
- // {
96
- // parentKey: 'INSERT_AFTER',
97
- // key: 'INSERT_AFTER_10',
98
- // label: 'Thêm 10 dòng',
99
- // row: 10
100
- // },
101
- // {
102
- // parentKey: 'INSERT_AFTER',
103
- // key: 'INSERT_AFTER_50',
104
- // label: 'Thêm 50 dòng',
105
- // row: 50
106
- // },
107
- // {
108
- // parentKey: 'INSERT_AFTER',
109
- // key: 'INSERT_AFTER_100',
110
- // label: 'Thêm 100 dòng',
111
- // row: 100
112
- // },
113
- // {
114
- // parentKey: 'INSERT_AFTER',
115
- // key: 'INSERT_AFTER_ADV',
116
- // label: 'Tùy chỉnh'
117
- // }
118
- // ]
119
- // },
120
- // {
121
- // key: 'INSERT_CHILDREN',
122
- // // label: 'Insert item children',
123
- // label: 'Thêm cấp con',
124
- // icon: <Plus fontSize={14} />
125
- // // children: [
126
- // // {
127
- // // parentKey: 'INSERT_AFTER',
128
- // // key: 'INSERT_AFTER_1',
129
- // // label: 'Thêm 1 dòng',
130
- // // row: 1
131
- // // },
132
- // // {
133
- // // parentKey: 'INSERT_AFTER',
134
- // // key: 'INSERT_AFTER_10',
135
- // // label: 'Thêm 10 dòng',
136
- // // row: 10
137
- // // },
138
- // // {
139
- // // parentKey: 'INSERT_AFTER',
140
- // // key: 'INSERT_AFTER_50',
141
- // // label: 'Thêm 50 dòng',
142
- // // row: 50
143
- // // },
144
- // // {
145
- // // parentKey: 'INSERT_AFTER',
146
- // // key: 'INSERT_AFTER_100',
147
- // // label: 'Thêm 100 dòng',
148
- // // row: 100
149
- // // },
150
- // // {
151
- // // parentKey: 'INSERT_AFTER',
152
- // // key: 'INSERT_AFTER_ADV',
153
- // // label: 'Tùy chỉnh'
154
- // // }
155
- // // ]
156
- // },
157
- // { key: 'DELETE_CONTENT', label: 'Xóa nội dung', icon: <Trash2 fontSize={14} /> },
158
- // { key: 'DELETE_ROWS', label: 'Xóa dòng', icon: <Trash2 fontSize={14} /> }
159
- // ]
160
-
161
- const validateData = async (data, formSchema) => {
162
- if (!formSchema) {
163
- return [];
164
- } else {
165
- const errors = [];
166
- for (let i = 0; i < data.length; i++) {
167
- try {
168
- await formSchema.validate(data[i], {
169
- abortEarly: false
170
- });
171
- } catch (error) {
172
- errors.push(error.inner.reduce((acc, err) => {
173
- acc[err.path] = {
174
- field: err.path,
175
- index: i,
176
- message: err.message,
177
- type: err.type,
178
- ref: {
179
- name: err.path
180
- }
181
- };
182
- return {
183
- ...acc,
184
- index: i
185
- };
186
- }, {}));
187
- }
188
- }
189
- return errors;
190
- }
191
- };
192
- const SortableHeaderCell = ({
193
- children,
194
- columnKey
195
- }) => {
196
- const {
197
- attributes,
198
- listeners,
199
- setNodeRef,
200
- isDragging
201
- } = useSortable({
202
- id: columnKey
203
- });
204
- const style = {
205
- // ...props.style,
206
- cursor: 'move',
207
- // position: 'absolute',
208
- // left: 3,
209
- // top: -2,
210
- ...(isDragging ? {
211
- zIndex: 9999,
212
- userSelect: 'none'
213
- } : {})
214
- // ...dragActiveStyle(dragState, props.id),
215
- };
216
- return /*#__PURE__*/React.createElement("div", _extends({
217
- ref: setNodeRef,
218
- style: style
219
- }, attributes, listeners), children);
220
- };
221
- const GridEdit = props => {
222
- const {
223
- id,
224
- tableRef,
225
- t,
226
- columns,
227
- dataSource,
228
- originData,
229
- components,
230
- allowResizing,
231
- rowKey = 'id',
232
- selectionSettings,
233
- height,
234
- scrollHeight,
235
- format,
236
- triggerChangeData,
237
- triggerChangeColumns,
238
- onCellPaste,
239
- onCellChange,
240
- triggerPaste,
241
- style,
242
- getRowKey,
243
- className,
244
- toolbarItems,
245
- defaultValue,
246
- expandable,
247
- onCellClick,
248
- rowEditable,
249
- contextMenuItems: propsContext,
250
- showDefaultContext,
251
- validate,
252
- // setTooltipContent,
253
- onBlur,
254
- locale,
255
- mergedFilterKeys,
256
- setMergedFilterKeys,
257
- wrapSettings,
258
- isFullScreen,
259
- ...rest
260
- } = props;
261
- const ref = useRef(null);
262
- const isSelecting = useRef(false);
263
- const startCell = useRef(null);
264
- const childrenColumnName = 'children';
265
-
266
- // const hoveredRow: any = useRef(null)
267
- const isSelectingRow = useRef(false);
268
- const rowStart = useRef(null);
269
- const rowsSelected = useRef(new Set());
270
- const selectedCells = useRef(new Set());
271
- const pasteCells = useRef(new Set());
272
- const startSelectedCells = useRef(null);
273
-
274
- // quét vùng chọn
275
- const isDragMouse = useRef(false);
276
- const isMouseDown = useRef(false);
277
- const editingKey = useRef('');
278
- const cellEditing = useRef({});
279
-
280
- // quét vùng được paste - tiếp tục hiển thị con trỏ crosshair
281
- // const isPasteDragging = useRef(false);
282
-
283
- const visibleCols = React.useMemo(() => {
284
- return flatColumns2(columns.filter(it => it.visible !== false));
285
- }, [columns]);
286
-
287
- // const id = React.useMemo(() => {
288
- //
289
- // return tableId ?? faker.string.alpha(20)
290
- // // return tableId ?? newGuid()
291
- //
292
- // }, [tableId])
293
-
294
- const itemsAdd = React.useMemo(() => {
295
- return [{
296
- key: '10',
297
- label: `10 ${t ? t('rows') : 'rows'}`
298
- }, {
299
- key: '50',
300
- label: `50 ${t ? t('rows') : 'rows'}`
301
- }, {
302
- key: '100',
303
- label: `100 ${t ? t('rows') : 'rows'}`
304
- }];
305
- }, [t]);
306
- const defaultContext = React.useMemo(() => {
307
- return [{
308
- key: 'INSERT_BEFORE',
309
- // label: 'Thêm dòng bên trên',
310
- label: `${t ? t(locale?.add_rows_before ?? 'Add rows before') : 'Add rows before'}`,
311
- icon: /*#__PURE__*/React.createElement(Plus, {
312
- fontSize: 14
313
- }),
314
- children: [{
315
- parentKey: 'INSERT_BEFORE',
316
- key: 'INSERT_BEFORE_1',
317
- label: `${t ? t(locale?.add_1 ?? 'Add 1 rows') : 'Add 1 rows'}`,
318
- row: 1
319
- }, {
320
- parentKey: 'INSERT_BEFORE',
321
- key: 'INSERT_BEFORE_10',
322
- label: `${t ? t(locale?.add_10 ?? 'Add 10 rows') : 'Add 10 rows'}`,
323
- row: 10
324
- }, {
325
- parentKey: 'INSERT_BEFORE',
326
- key: 'INSERT_BEFORE_50',
327
- label: `${t ? t(locale?.add_50 ?? 'Add 50 rows') : 'Add 50 rows'}`,
328
- row: 50
329
- }, {
330
- parentKey: 'INSERT_BEFORE',
331
- key: 'INSERT_BEFORE_100',
332
- label: `${t ? t(locale?.add_100 ?? 'Add 100 rows') : 'Add 100 rows'}`,
333
- row: 100
334
- }, {
335
- parentKey: 'INSERT_BEFORE',
336
- key: 'INSERT_BEFORE_ADV',
337
- label: `${t ? t(locale?.custom ?? 'Custom') : 'Custom'}`
338
- }]
339
- }, {
340
- key: 'INSERT_AFTER',
341
- label: `${t ? t(locale?.add_rows_after ?? 'Add rows after') : 'Add rows before'}`,
342
- icon: /*#__PURE__*/React.createElement(Plus, {
343
- fontSize: 14
344
- }),
345
- children: [{
346
- parentKey: 'INSERT_AFTER',
347
- key: 'INSERT_AFTER_1',
348
- label: `${t ? t(locale?.add_1 ?? 'Add 1 rows') : 'Add 1 rows'}`,
349
- row: 1
350
- }, {
351
- parentKey: 'INSERT_AFTER',
352
- key: 'INSERT_AFTER_10',
353
- label: `${t ? t(locale?.add_10 ?? 'Add 10 rows') : 'Add 10 rows'}`,
354
- row: 10
355
- }, {
356
- parentKey: 'INSERT_AFTER',
357
- key: 'INSERT_AFTER_50',
358
- label: `${t ? t(locale?.add_50 ?? 'Add 50 rows') : 'Add 50 rows'}`,
359
- row: 50
360
- }, {
361
- parentKey: 'INSERT_AFTER',
362
- key: 'INSERT_AFTER_100',
363
- label: `${t ? t(locale?.add_100 ?? 'Add 100 rows') : 'Add 100 rows'}`,
364
- row: 100
365
- }, {
366
- parentKey: 'INSERT_AFTER',
367
- key: 'INSERT_AFTER_ADV',
368
- label: `${t ? t(locale?.custom ?? 'Custom') : 'Custom'}`
369
- }]
370
- }, {
371
- key: 'INSERT_CHILDREN',
372
- // label: 'Insert item children',
373
- label: `${t ? t(locale?.add_children ?? 'Add children') : 'Add children'}`,
374
- icon: /*#__PURE__*/React.createElement(Plus, {
375
- fontSize: 14
376
- })
377
- // children: [
378
- // {
379
- // parentKey: 'INSERT_AFTER',
380
- // key: 'INSERT_AFTER_1',
381
- // label: 'Thêm 1 dòng',
382
- // row: 1
383
- // },
384
- // {
385
- // parentKey: 'INSERT_AFTER',
386
- // key: 'INSERT_AFTER_10',
387
- // label: 'Thêm 10 dòng',
388
- // row: 10
389
- // },
390
- // {
391
- // parentKey: 'INSERT_AFTER',
392
- // key: 'INSERT_AFTER_50',
393
- // label: 'Thêm 50 dòng',
394
- // row: 50
395
- // },
396
- // {
397
- // parentKey: 'INSERT_AFTER',
398
- // key: 'INSERT_AFTER_100',
399
- // label: 'Thêm 100 dòng',
400
- // row: 100
401
- // },
402
- // {
403
- // parentKey: 'INSERT_AFTER',
404
- // key: 'INSERT_AFTER_ADV',
405
- // label: 'Tùy chỉnh'
406
- // }
407
- // ]
408
- }, {
409
- key: 'DELETE_CONTENT',
410
- label: `${t ? t(locale?.delete_content ?? 'Delete content') : 'Delete content'}`,
411
- icon: /*#__PURE__*/React.createElement(Trash2, {
412
- fontSize: 14
413
- })
414
- }, {
415
- key: 'DELETE_ROWS',
416
- label: `${t ? t(locale?.delete_rows ?? 'Delete rows') : 'Delete rows'}`,
417
- icon: /*#__PURE__*/React.createElement(Trash2, {
418
- fontSize: 14
419
- })
420
- }];
421
- }, [t, locale]);
422
-
423
- // const [form] = Form.useForm()
424
-
425
- // const [editingKey, setEditingKey] = useState<string | number>('')
426
-
427
- const [dataErrors, setDataErrors] = useState([]);
428
-
429
- // const abc = useMemo(() => {
430
- //
431
- // return selectedCells
432
- // // return [...new Set(Array.from(selectedCells.current).map((item: any) => parseInt(item.split('-')[0])))]
433
- //
434
- // }, [selectedCells])
435
-
436
- const [rangeCells, setRangeCells] = useState(new Set());
437
- const [openModalAddRow, setOpenModalAddRow] = useState({
438
- open: false,
439
- type: ''
440
- });
441
- const [rowsAdd, setRowsAdd] = useState(1);
442
-
443
- // const [cellEditing, setCellEditing] = useState<any>(null)
444
-
445
- const [isPasteDragging, setIsPasteDragging] = useState(false); // isPasteDragging == tiếp tục hiển thị con trỏ crosshair
446
-
447
- const [innerExpandedKeys, setInnerExpandedKeys] = React.useState(() => {
448
- // if (defaultExpandedRowKeys) {
449
- // return defaultExpandedRowKeys;
450
- // }
451
- // if (defaultExpandAllRows) {
452
- return findAllChildrenKeys(dataSource, getRowKey, childrenColumnName) ?? [];
453
- // }
454
- // return [];
455
- });
456
- const mergedExpandedKeys = React.useMemo(() => new Set(innerExpandedKeys || []), [innerExpandedKeys]);
457
- React.useEffect(() => {
458
- if (validate && dataSource && dataSource.length) {
459
- validateData(dataSource, validate).then(error => {
460
- setDataErrors([...error]);
461
- // if (getErrors) {
462
- // getErrors([...error])
463
- // }
464
- });
465
- }
466
- }, [validate, dataSource]);
467
- const rowsFocus = React.useMemo(() => {
468
- const leng = flattenArray(dataSource).length;
469
- const arr = [...new Set(Array.from(rangeCells).map(item => parseInt(item.split('-')[0])))];
470
-
471
- // return [...new Set(Array.from(rangeCells).map((item: any) => parseInt(item.split('-')[0])))] ?? []
472
- return arr.filter(it => it < leng);
473
- }, [dataSource, rangeCells]);
474
- const contextMenuItems = React.useMemo(() => {
475
- const a = showDefaultContext !== false ? [...defaultContext] : [];
476
- const b = propsContext && propsContext.length > 0 ? [...propsContext, {
477
- type: 'divider'
478
- }] : [];
479
- return [...b, ...a];
480
- }, [defaultContext, propsContext, showDefaultContext]);
481
- const {
482
- control,
483
- handleSubmit,
484
- setValue,
485
- trigger,
486
- getValues,
487
- reset,
488
- formState: {
489
- errors
490
- }
491
- } = useForm({
492
- mode: 'onChange',
493
- resolver: validate ? yupResolver(validate) : undefined
494
- });
495
- const onTriggerExpand = React.useCallback(record => {
496
- const key = getRowKey(record, dataSource.indexOf(record));
497
- let newExpandedKeys;
498
- const hasKey = mergedExpandedKeys.has(key);
499
- if (hasKey) {
500
- mergedExpandedKeys.delete(key);
501
- newExpandedKeys = [...mergedExpandedKeys];
502
- } else {
503
- newExpandedKeys = [...mergedExpandedKeys, key];
504
- }
505
- setInnerExpandedKeys(newExpandedKeys);
506
- //
507
- // onAddBgSelectedCell(rangeCells, id)
508
- // onAddBorderSelectedCell(rangeCells, id)
509
- }, [getRowKey, dataSource, mergedExpandedKeys]);
510
- const handleAddSingle = React.useCallback(item => {
511
- const defaultRowValue = getDefaultValue(defaultValue);
512
- const rowId = defaultRowValue && defaultRowValue.id ? defaultRowValue.id : newGuid();
513
- if (item && item.onClick) {
514
- item.onClick({
515
- toolbar: item
516
- });
517
- } else {
518
- const newData = [...dataSource, defaultValue ? {
519
- ...defaultRowValue,
520
- id: undefined,
521
- rowId
522
- } : {
523
- id: undefined,
524
- rowId
525
- }];
526
- triggerChangeData?.(newData, 'Add');
527
- }
528
- }, [dataSource, defaultValue, triggerChangeData]);
529
- const handleAddMulti = React.useCallback((item, n) => {
530
- if (item.onClick) {
531
- item.onClick({
532
- toolbar: item
533
- });
534
- } else {
535
- const defaultRowValue = getDefaultValue(defaultValue);
536
- const newRows = Array.from({
537
- length: n
538
- }).map(() => defaultRowValue ? {
539
- ...defaultRowValue,
540
- id: undefined,
541
- rowId: newGuid()
542
- } : {
543
- id: undefined,
544
- rowId: newGuid()
545
- });
546
- const kkk = getAllRowKey(newRows) ?? [];
547
- const rs = mergedFilterKeys ? [...mergedFilterKeys, ...kkk] : [...kkk];
548
- setMergedFilterKeys?.(rs);
549
- const newData = dataSource.concat(newRows);
550
- triggerChangeData?.(newData, 'Add');
551
- }
552
- }, [dataSource, defaultValue, mergedFilterKeys, setMergedFilterKeys, triggerChangeData]);
553
- const handleDuplicate = React.useCallback(() => {
554
- // không tính tree
555
-
556
- // Cập nhật data mới
557
- const newData = [...dataSource];
558
- const duplicatedItems = rowsFocus.map(index => ({
559
- ...newData[index],
560
- rowId: newGuid(),
561
- id: undefined,
562
- isDuplicate: true
563
- }));
564
-
565
- // Vị trí chèn là ngay sau phần tử lớn nhất trong rowsFocus
566
- const insertAfter = Math.max(...rowsFocus);
567
- const rsFilter = [...newData.slice(0, insertAfter + 1), ...duplicatedItems, ...newData.slice(insertAfter + 1)];
568
-
569
- // const rs = updateOrInsertInOrder(originData, rsFilter)
570
- const rs = updateOrInsert(originData, rsFilter);
571
- // const rs2 = mergeWithFilter(originData, rsFilter)
572
-
573
- triggerChangeData?.(rs, 'DUPLICATE');
574
- }, [dataSource, originData, rowsFocus, triggerChangeData]);
575
-
576
- // thêm n dòng bên trên
577
- const handleInsertBefore = React.useCallback((item, n) => {
578
- const defaultRowValue = getDefaultValue(defaultValue);
579
- // const rowId = defaultRowValue && defaultRowValue.id ? defaultRowValue.id : newGuid()
580
-
581
- const record = flattenData(childrenColumnName, dataSource)[rowsFocus[rowsFocus.length - 1]];
582
- if (item.onClick) {
583
- item.onClick({
584
- toolbar: item
585
- });
586
- } else {
587
- if (!record?.parentId) {
588
- // Cập nhật data mới
589
- // const newData = [...dataSource]
590
- const newData = [...originData];
591
- const newRows = Array.from({
592
- length: n
593
- }).map(() => defaultRowValue ? {
594
- ...defaultRowValue,
595
- id: undefined,
596
- rowId: newGuid()
597
- } : {
598
- id: undefined,
599
- rowId: newGuid()
600
- });
601
- const kkk = getAllRowKey(newRows) ?? [];
602
- const rs = mergedFilterKeys ? [...mergedFilterKeys, ...kkk] : [...kkk];
603
- setMergedFilterKeys?.(rs);
604
- const index = newData.findIndex(obj => obj[rowKey] === record[rowKey]);
605
- newData.splice(index, 0, ...newRows);
606
- triggerChangeData?.(newData, 'INSERT_BEFORE');
607
- } else {
608
- // const newData = [...dataSource]
609
- const newData = [...originData];
610
- const parent = findItemByKey(newData, rowKey, record.parentId);
611
- const newRows = Array.from({
612
- length: n
613
- }).map(() => defaultRowValue ? {
614
- ...defaultRowValue,
615
- id: undefined,
616
- rowId: newGuid(),
617
- parentId: parent.rowId
618
- } : {
619
- id: undefined,
620
- rowId: newGuid(),
621
- parentId: parent.rowId
622
- });
623
-
624
- // Cập nhật childData mới
625
- const childData = parent?.children ? [...parent.children] : [];
626
- const index = childData.findIndex(obj => obj[rowKey] === record[rowKey]);
627
- childData.splice(index, 0, ...newRows);
628
- const newRowData = {
629
- ...parent,
630
- children: childData
631
- };
632
- const newDataSource = updateArrayByKey(newData, newRowData, rowKey);
633
- triggerChangeData?.(newDataSource, 'INSERT_BEFORE');
634
- }
635
- }
636
- }, [dataSource, defaultValue, mergedFilterKeys, originData, rowKey, rowsFocus, setMergedFilterKeys, triggerChangeData]);
637
-
638
- //thêm 1 dòng bên dưới
639
- const handleInsertAfter = React.useCallback((item, n) => {
640
- const defaultRowValue = getDefaultValue(defaultValue);
641
- const insertAfter = Math.max(...rowsFocus);
642
- const record = flattenData(childrenColumnName, dataSource)[insertAfter];
643
-
644
- // const record: RecordType = flattenData(childrenColumnName, originData)[rowsFocus[rowsFocus.length - 1]]
645
-
646
- // const record = getRecordByKey()
647
-
648
- if (item.onClick) {
649
- item.onClick({
650
- toolbar: item
651
- });
652
- } else {
653
- if (!record?.parentId) {
654
- // Cập nhật data mới
655
- const newData = [...originData];
656
- const newRows = Array.from({
657
- length: n
658
- }).map(() => defaultRowValue ? {
659
- ...defaultRowValue,
660
- id: undefined,
661
- rowId: newGuid()
662
- } : {
663
- id: undefined,
664
- rowId: newGuid()
665
- });
666
- const kkk = getAllRowKey(newRows) ?? [];
667
- const rs = mergedFilterKeys ? [...mergedFilterKeys, ...kkk] : [...kkk];
668
- setMergedFilterKeys?.(rs);
669
- const index = newData.findIndex(obj => obj[rowKey] === record[rowKey]);
670
- newData.splice(index + 1, 0, ...newRows);
671
- triggerChangeData?.(newData, 'INSERT_AFTER');
672
- } else {
673
- const newData = [...originData];
674
- const parent = findItemByKey(newData, rowKey, record.parentId);
675
- const newRows = Array.from({
676
- length: n
677
- }).map(() => defaultRowValue ? {
678
- ...defaultRowValue,
679
- id: undefined,
680
- rowId: newGuid(),
681
- parentId: parent.rowId
682
- } : {
683
- id: undefined,
684
- rowId: newGuid(),
685
- parentId: parent.rowId
686
- });
687
- const kkk = getAllRowKey(newRows) ?? [];
688
- const rs = mergedFilterKeys ? [...mergedFilterKeys, ...kkk] : [...kkk];
689
- setMergedFilterKeys?.(rs);
690
-
691
- // Cập nhật childData mới
692
- const childData = parent?.children ? [...parent.children] : [];
693
- const index = childData.findIndex(obj => obj[rowKey] === record[rowKey]);
694
- childData.splice(index + 1, 0, ...newRows);
695
- const newRowData = {
696
- ...parent,
697
- children: childData
698
- };
699
- const newDataSource = updateArrayByKey(newData, newRowData, rowKey);
700
- triggerChangeData?.(newDataSource, 'INSERT_BEFORE');
701
- }
702
- }
703
- }, [defaultValue, dataSource, rowsFocus, originData, mergedFilterKeys, setMergedFilterKeys, triggerChangeData, rowKey]);
704
- const handleInsertChild = React.useCallback(item => {
705
- const defaultRowValue = getDefaultValue(defaultValue);
706
- const rowId = newGuid();
707
- const record = flattenData(childrenColumnName, dataSource)[rowsFocus[rowsFocus.length - 1]];
708
- if (item.onClick) {
709
- item.onClick({
710
- toolbar: item
711
- });
712
- } else {
713
- // const newData = [...dataSource]
714
- const newData = [...originData];
715
- let newElement;
716
- if (!record.children || record.children.length === 0) {
717
- newElement = {
718
- ...record,
719
- children: [{
720
- ...defaultRowValue,
721
- parentId: record.rowId,
722
- rowId
723
- }]
724
- };
725
- } else {
726
- newElement = {
727
- ...record,
728
- children: [...record.children, {
729
- ...defaultRowValue,
730
- parentId: record.rowId,
731
- rowId
732
- }]
733
- };
734
- }
735
- const rs = mergedFilterKeys ? [...mergedFilterKeys, rowId] : [rowId];
736
- setMergedFilterKeys?.(rs);
737
- const newDataSource = updateArrayByKey(newData, newElement, rowKey);
738
- triggerChangeData?.(newDataSource, 'INSERT_CHILDREN');
739
- }
740
- const key = getRowKey(record, dataSource.indexOf(record));
741
-
742
- // let newExpandedKeys: Key[];
743
- const hasKey = mergedExpandedKeys.has(key);
744
- if (!hasKey) {
745
- const newExpandedKeys = [...mergedExpandedKeys, key];
746
- setInnerExpandedKeys(newExpandedKeys);
747
- }
748
- }, [dataSource, defaultValue, getRowKey, mergedExpandedKeys, mergedFilterKeys, originData, rowKey, rowsFocus, setMergedFilterKeys, triggerChangeData]);
749
- const handleDeleteRows = React.useCallback(item => {
750
- // setTimeout(() => {
751
- // onAddBgSelectedCell(selectedCells.current, id)
752
- // onAddBorderSelectedCell(selectedCells.current, id)
753
- // })
754
-
755
- if (item.onClick) {
756
- item.onClick({
757
- toolbar: item
758
- });
759
- } else {
760
- // const filterData = flattenArray([...dataSource])
761
- const filterData = flattenArray([...originData]);
762
- const indexesToDelete = [...rowsFocus];
763
-
764
- // Sắp xếp giảm dần để xóa từ cuối lên đầu
765
- indexesToDelete.sort((a, b) => b - a).forEach(index => {
766
- filterData.splice(index, 1);
767
- });
768
-
769
- // const newData = updateOrInsert(flattenArray([...originData]), filterData)
770
- //
771
- const rs = unFlattenData(filterData);
772
- triggerChangeData?.([...rs], 'DELETE_ROWS');
773
- }
774
- setTimeout(() => {
775
- onAddBorderSelectedCell(selectedCells.current, id);
776
- showDraggingPoint(selectedCells.current, id);
777
- }, 0);
778
- }, [id, originData, rowsFocus, triggerChangeData]);
779
- const handleDeleteAll = React.useCallback(() => {
780
- triggerChangeData?.([], 'INSERT_BEFORE');
781
- }, [triggerChangeData]);
782
- const onSubmit = formData => {
783
- try {
784
- // const record = (await form.validateFields()) as RecordType;
785
- const row = {
786
- ...formData
787
- };
788
-
789
- // const newData = [...dataSource]
790
- const newData = [...originData];
791
-
792
- // @ts-ignore
793
- const index = flattenData(childrenColumnName, newData).findIndex(item => formData[rowKey] === item[rowKey]);
794
- const rs = updateArrayByKey(newData, row, rowKey);
795
- if (index > -1) {
796
- triggerChangeData?.(rs, 'onChange');
797
- }
798
- } catch (errInfo) {
799
- console.log('Validate Failed:', errInfo);
800
- }
801
- };
802
- const handleCellChange = args => {
803
- const {
804
- record,
805
- type: changeType,
806
- newState,
807
- prevState,
808
- option,
809
- field,
810
- indexCol,
811
- indexRow,
812
- key
813
- } = args;
814
- if (changeType === 'blur') {
815
- const handleChangeCallback = callbackData => {
816
- const callbackRecord = callbackData;
817
- Object.entries(callbackRecord).forEach(([name, value]) => {
818
- setValue(name, value);
819
- });
820
- onSubmit(callbackRecord);
821
- };
822
- if (onCellChange) {
823
- if (onCellChange.length > 1) {
824
- onCellChange({
825
- field,
826
- indexCol,
827
- type: 'onChange',
828
- value: newState,
829
- option,
830
- indexRow,
831
- rowData: record,
832
- rowId: key,
833
- // rowsData: [...dataSource],
834
- rowsData: [...originData],
835
- sumValue: []
836
- }, handleChangeCallback);
837
- } else {
838
- onCellChange({
839
- field,
840
- indexCol,
841
- type: 'onChange',
842
- option,
843
- value: newState,
844
- indexRow,
845
- rowData: record,
846
- rowId: key,
847
- // rowsData: [...dataSource],
848
- rowsData: [...originData],
849
- sumValue: []
850
- }, handleChangeCallback);
851
- onSubmit(record);
852
- }
853
- }
854
- }
855
- if (prevState && newState && prevState !== newState && changeType === 'enter') {
856
- onSubmit(record);
857
- }
858
- };
859
- const handleDeleteContent = () => {
860
- if (selectedCells.current.size > 0) {
861
- const newData = [...dataSource];
862
-
863
- // colIndex => field
864
- const colIndexToField = flatColumns2(visibleCols).map(col => col.field);
865
-
866
- // Duyệt qua mỗi ô cần xóa
867
- for (const cell of selectedCells.current) {
868
- const [rowIndexStr, colIndexStr] = cell.split("-");
869
- const rowIndex = Number(rowIndexStr);
870
- const colIndex = Number(colIndexStr);
871
- const field = colIndexToField[colIndex];
872
- const column = flatColumns2(visibleCols)[colIndex];
873
- const rowData = flattenData(childrenColumnName, dataSource)[rowIndex];
874
- if (newData[rowIndex] && field && field in newData[rowIndex] && isEditable(column, rowData)) {
875
- const rowDta = {
876
- ...newData[rowIndex]
877
- };
878
-
879
- // @ts-ignore
880
- newData[rowIndex][field] = '';
881
- handleCellChange({
882
- key: getRowKey?.(newData[rowIndex], rowIndex),
883
- field: column.field ?? column.dataIndex,
884
- record: newData[rowIndex],
885
- prevState: rowDta[field],
886
- newState: '',
887
- option: '',
888
- indexCol: colIndex,
889
- indexRow: rowIndex,
890
- type: 'blur'
891
- });
892
-
893
- // if (onCellChange)
894
- }
895
- }
896
- const rsFilterData = updateOrInsert(flattenArray([...originData]), newData);
897
- triggerChangeData?.([...rsFilterData], 'DELETE_CONTENT');
898
- }
899
- };
900
- const toolbarItemsBottom = useMemo(() => {
901
- if (!rowsFocus || rowsFocus.length === 0) {
902
- return toolbarItems?.filter(it => it.position === 'Bottom' && it.visible !== false && it.key !== 'DUPLICATE' && it.key !== 'INSERT_BEFORE' && it.key !== 'INSERT_AFTER' && it.key !== 'DELETE_ROWS' && it.key !== 'INSERT_CHILDREN').map(item => {
903
- if (item.key === 'ADD') {
904
- return {
905
- ...item,
906
- template: () => {
907
- return /*#__PURE__*/React.createElement(Fragment, null, item.key === 'ADD' && /*#__PURE__*/React.createElement("div", {
908
- className: classnames(`be-toolbar-item`, item?.className)
909
- }, /*#__PURE__*/React.createElement(Dropdown.Button, {
910
- overlayClassName: 'be-popup-container',
911
- trigger: ['click'],
912
- style: {
913
- color: '#28c76f',
914
- borderColor: '#28c76f'
915
- },
916
- className: 'toolbar-button toolbar-dropdown-button',
917
- menu: {
918
- items: itemsAdd,
919
- onClick: e => handleAddMulti(item, Number(e.key))
920
- }
921
- }, /*#__PURE__*/React.createElement("span", {
922
- style: {
923
- color: '#28c76f'
924
- },
925
- onClick: () => handleAddMulti(item, 1)
926
- }, item.label ? t ? t(item.label) : item.label : t ? t('Add item') : 'Add item'))));
927
- }
928
- };
929
- }
930
- if (item.key === 'DELETE') {
931
- return {
932
- ...item,
933
- template: () => {
934
- return /*#__PURE__*/React.createElement("div", {
935
- className: classnames(`be-toolbar-item`, item?.className)
936
- }, /*#__PURE__*/React.createElement(Button, {
937
- style: {
938
- color: '#eb4619',
939
- borderColor: '#eb4619'
940
- },
941
- variant: 'outlined',
942
- onClick: handleDeleteAll,
943
- className: "d-flex toolbar-button"
944
- }, item.label ? t ? t(item.label) : item.label : t ? t('Delete all item') : 'Delete all item'));
945
- }
946
- };
947
- }
948
- return {
949
- ...item
950
- };
951
- });
952
- }
953
- return toolbarItems?.filter(it => it.position === 'Bottom' && it.visible !== false).map(item => {
954
- if (item.key === 'ADD') {
955
- return {
956
- ...item,
957
- template: () => {
958
- return /*#__PURE__*/React.createElement(Fragment, null, item.key === 'ADD' && /*#__PURE__*/React.createElement("div", {
959
- className: classnames(`be-toolbar-item`, item?.className)
960
- }, /*#__PURE__*/React.createElement(Dropdown.Button, {
961
- overlayClassName: 'be-popup-container',
962
- style: {
963
- color: '#28c76f',
964
- borderColor: '#28c76f'
965
- },
966
- className: 'toolbar-button toolbar-dropdown-button',
967
- menu: {
968
- items: itemsAdd,
969
- onClick: e => handleAddMulti(item, Number(e.key))
970
- }
971
- }, /*#__PURE__*/React.createElement("span", {
972
- style: {
973
- color: '#28c76f'
974
- },
975
- onClick: () => handleAddMulti(item, 1)
976
- }, item.label ? t ? t(item.label) : item.label : t ? t('Add item') : 'Add item'))));
977
- }
978
- };
979
- }
980
- if (item.key === 'DUPLICATE') {
981
- return {
982
- ...item,
983
- template: () => {
984
- return /*#__PURE__*/React.createElement(Fragment, null, item.key === 'DUPLICATE' && item.visible !== false && rowsFocus.length > 0 && /*#__PURE__*/React.createElement("div", {
985
- className: classnames(`be-toolbar-item`, item?.className)
986
- }, /*#__PURE__*/React.createElement(Button, {
987
- style: {
988
- color: '#28c76f',
989
- borderColor: '#28c76f'
990
- },
991
- variant: 'outlined',
992
- onClick: handleDuplicate,
993
- className: "d-flex toolbar-button"
994
- }, item.label ? t ? t(item.label) : item.label : t ? t('Duplicate') : 'Duplicate')));
995
- }
996
- };
997
- }
998
- if (item.key === 'INSERT_BEFORE') {
999
- return {
1000
- ...item,
1001
- template: () => {
1002
- return /*#__PURE__*/React.createElement(Fragment, null, /*#__PURE__*/React.createElement("div", {
1003
- className: classnames(`be-toolbar-item`, item?.className)
1004
- }, /*#__PURE__*/React.createElement(Dropdown.Button, {
1005
- overlayClassName: 'be-popup-container',
1006
- style: {
1007
- color: '#28c76f',
1008
- borderColor: '#28c76f'
1009
- },
1010
- className: 'toolbar-button toolbar-dropdown-button',
1011
- menu: {
1012
- items: itemsAdd,
1013
- onClick: e => handleInsertBefore(item, Number(e.key))
1014
- }
1015
- }, /*#__PURE__*/React.createElement("span", {
1016
- style: {
1017
- color: '#28c76f'
1018
- },
1019
- onClick: () => handleInsertBefore(item, 1)
1020
- }, item.label ? t ? t(item.label) : item.label : t ? t('Insert item before') : 'Insert item before'))));
1021
- }
1022
- };
1023
- }
1024
- if (item.key === 'INSERT_AFTER') {
1025
- return {
1026
- ...item,
1027
- template: () => {
1028
- return /*#__PURE__*/React.createElement(Fragment, null, /*#__PURE__*/React.createElement("div", {
1029
- className: classnames(`be-toolbar-item`, item?.className)
1030
- }, /*#__PURE__*/React.createElement(Dropdown.Button, {
1031
- overlayClassName: 'be-popup-container',
1032
- style: {
1033
- color: '#28c76f',
1034
- borderColor: '#28c76f'
1035
- },
1036
- className: 'toolbar-button toolbar-dropdown-button',
1037
- menu: {
1038
- items: itemsAdd,
1039
- onClick: e => handleInsertAfter(item, Number(e.key))
1040
- }
1041
- }, /*#__PURE__*/React.createElement("span", {
1042
- style: {
1043
- color: '#28c76f'
1044
- },
1045
- onClick: () => handleInsertAfter(item, 1)
1046
- }, item.label ? t ? t(item.label) : item.label : t ? t('Insert item after') : 'Insert item after'))));
1047
- }
1048
- };
1049
- }
1050
- if (item.key === 'INSERT_CHILDREN') {
1051
- return {
1052
- ...item,
1053
- template: () => {
1054
- return /*#__PURE__*/React.createElement(Fragment, null, /*#__PURE__*/React.createElement("div", {
1055
- className: classnames(`be-toolbar-item`, item?.className)
1056
- }, /*#__PURE__*/React.createElement(Button, {
1057
- style: {
1058
- color: '#28c76f',
1059
- borderColor: '#28c76f'
1060
- },
1061
- variant: 'outlined',
1062
- onClick: () => handleInsertChild(item),
1063
- className: "d-flex toolbar-button"
1064
- }, item.label ? t ? t(item.label) : item.label : t ? t('Insert item children') : 'Insert item children')));
1065
- }
1066
- };
1067
- }
1068
- if (item.key === 'DELETE') {
1069
- return {
1070
- ...item,
1071
- template: () => {
1072
- return /*#__PURE__*/React.createElement("div", {
1073
- className: classnames(`be-toolbar-item`, item?.className)
1074
- }, /*#__PURE__*/React.createElement(Button, {
1075
- style: {
1076
- color: '#eb4619',
1077
- borderColor: '#eb4619'
1078
- },
1079
- variant: 'outlined',
1080
- onClick: handleDeleteAll,
1081
- className: "d-flex toolbar-button"
1082
- }, item.label ? t ? t(item.label) : item.label : t ? t('Delete all item') : 'Delete all item'));
1083
- }
1084
- };
1085
- }
1086
- if (item.key === 'DELETE_ROWS') {
1087
- return {
1088
- ...item,
1089
- template: () => {
1090
- return /*#__PURE__*/React.createElement("div", {
1091
- className: classnames(`be-toolbar-item`, item?.className)
1092
- }, /*#__PURE__*/React.createElement(Button, {
1093
- style: {
1094
- color: '#eb4619',
1095
- borderColor: '#eb4619'
1096
- },
1097
- variant: 'outlined',
1098
- onClick: () => handleDeleteRows(item),
1099
- className: "d-flex toolbar-button"
1100
- }, t ? `${t('Delete')} ${rowsFocus.length} ${t('row')}` : `Delete ${rowsFocus.length} item`));
1101
- }
1102
- };
1103
- }
1104
- return {
1105
- ...item
1106
- };
1107
- });
1108
- }, [handleAddMulti, handleDeleteAll, handleDeleteRows, handleDuplicate, handleInsertAfter, handleInsertBefore, handleInsertChild, itemsAdd, rowsFocus, t, toolbarItems]);
1109
-
1110
- // const isEditing = React.useCallback((record: RecordType) => {
1111
- // return record[rowKey as any] === editingKey.current
1112
- // }, [editingKey, rowKey])
1113
-
1114
- React.useEffect(() => {
1115
- const handleClickOutside = event => {
1116
- const element = event.target;
1117
-
1118
- // const tableId = id ? document.getElementById(id) : undefined
1119
- // const tableBodies = document.getElementsByClassName("ui-rc-table-tbody");
1120
- const container = document.querySelector(".be-popup-container");
1121
- const containerContextMenu = document.querySelector(".popup-context-menu");
1122
- const tableBody = document.querySelector(`#${id} .ui-rc-table-tbody .ui-rc-table-tbody-virtual-holder`);
1123
- // const containerHidden = document.querySelector(".be-popup-container.ant-picker-dropdown-hidden")
1124
-
1125
- // const toolbarContainer = document.getElementsByClassName("ui-rc-toolbar");
1126
- const itemContainer = document.querySelector(`#${id} .ui-rc-toolbar-selection-overflow-item`);
1127
- const itemHeader = document.querySelector(`#${id} .ui-rc-table-thead`);
1128
- const isInsideContainer = element.closest(".be-popup-container") && container;
1129
- const isInsideContainerContext = containerContextMenu && element.closest(".popup-context-menu");
1130
- const isInsideToolbar = element.closest(`.ui-rc-toolbar-selection-overflow-item`) && itemContainer;
1131
- const isInsideHeader = itemHeader && itemHeader.contains(event.target);
1132
- if (isInsideContainer || isInsideToolbar || isInsideHeader || isInsideContainerContext) {
1133
- return;
1134
- }
1135
-
1136
- // if (ref.current && !ref.current.contains(event.target)) {
1137
- // if (ref.current && tableId && !tableId.contains(event.target as Node)) {
1138
-
1139
- if (ref.current && tableBody && !tableBody.contains(event.target)) {
1140
- if (editingKey.current) {
1141
- onBlur?.(dataSource);
1142
- }
1143
- setTimeout(() => {
1144
- // setEditingKey('')
1145
- editingKey.current = '';
1146
- });
1147
- isSelecting.current = false;
1148
- startCell.current = null;
1149
- // setSelectedCells(new Set())
1150
- // setRowsSelected(new Set())
1151
-
1152
- onRemoveBgSelectedCell(selectedCells.current, id);
1153
- onRemoveBorderSelectedCell(selectedCells.current, id);
1154
- hideDraggingPoint(selectedCells.current, id);
1155
- rowsSelected.current = new Set();
1156
- selectedCells.current = new Set();
1157
- setRangeCells(new Set());
1158
- }
1159
- };
1160
-
1161
- // document.addEventListener('click', handleClickOutside)
1162
- document.addEventListener('mousedown', handleClickOutside);
1163
- // document.addEventListener('touchstart', handleClickOutside)
1164
-
1165
- return () => {
1166
- // document.removeEventListener('click', handleClickOutside)
1167
- document.removeEventListener('mousedown', handleClickOutside);
1168
- // document.removeEventListener('touchstart', handleClickOutside)
1169
- };
1170
- }, [dataSource, id, onBlur]);
1171
- const triggerDragPaste = (pastesArray, ctrlKey) => {
1172
- const mergedSet = new Set([...selectedCells.current, ...pastesArray]);
1173
- const tmpCols = {
1174
- ...visibleCols
1175
- };
1176
- const rowSelectedFirst = getFirstSelectCell(selectedCells.current).row;
1177
- const rowPasteLast = getLastSelectCell(pasteCells.current).row;
1178
- const selectedArray = Array.from(selectedCells.current).map(key => {
1179
- const [row, col] = key.split("-").map(Number);
1180
- const columnKey = tmpCols[col].field;
1181
-
1182
- // @ts-ignore
1183
- return {
1184
- row,
1185
- col,
1186
- value: flattenData(childrenColumnName, dataSource)[row][columnKey]
1187
- };
1188
- // return { row, col, value: '' };
1189
- });
1190
- const copyRows = selectedArray.map(it => ({
1191
- ...flattenData(childrenColumnName, dataSource)[it.row]
1192
- }));
1193
-
1194
- // Xác định min/max row và col để sắp xếp dữ liệu
1195
- const minRow = Math.min(...selectedArray.map(cell => cell.row));
1196
- const maxRow = Math.max(...selectedArray.map(cell => cell.row));
1197
- const minCol = Math.min(...selectedArray.map(cell => cell.col));
1198
- const maxCol = Math.max(...selectedArray.map(cell => cell.col));
1199
-
1200
- // Tạo dữ liệu dạng bảng (mảng 2D)
1201
- const table = Array.from({
1202
- length: maxRow - minRow + 1
1203
- }, () => Array(maxCol - minCol + 1).fill(""));
1204
-
1205
- // Gán giá trị vào bảng
1206
- selectedArray.forEach(({
1207
- row,
1208
- col,
1209
- value
1210
- }) => {
1211
- table[row - minRow][col - minCol] = value;
1212
- });
1213
- let newRange;
1214
- if (rowPasteLast > rowSelectedFirst) {
1215
- // kéo xuóng
1216
- newRange = ctrlKey ? addRowsDownWithCtrl(table, getRowsPasteIndex(pastesArray).length) : addRowsDown(table, getRowsPasteIndex(pastesArray).length);
1217
- } else {
1218
- // kéo lên
1219
- newRange = ctrlKey ? addRowsUpWithCtrl(table, getRowsPasteIndex(pastesArray).length) : addRowsUp(table, getRowsPasteIndex(pastesArray).length);
1220
- }
1221
-
1222
- // const record = flattenData(childrenColumnName, dataSource)[getFirstSelectCell(pastesArray).row]
1223
-
1224
- // if (!record?.parentId) {
1225
-
1226
- // Cập nhật data mới
1227
- const newData = flattenArray([...dataSource]);
1228
- // const newData = flattenArray([...originData])
1229
-
1230
- // Lấy vị trí bắt đầu
1231
- // const { row: startRow, col: startCol } = selectedCell;
1232
- const startRow = getFirstSelectCell(pastesArray).row;
1233
- const startCol = getFirstSelectCell(selectedCells.current).col;
1234
- const pastedRows = [];
1235
- const pastedColumns = new Set();
1236
- newRange.addedRows.forEach((rowValues, rowIndex) => {
1237
- const targetRow = startRow + rowIndex;
1238
-
1239
- // Nếu vượt quá số dòng hiện có, thêm dòng mới
1240
- if (targetRow >= newData.length) {
1241
- // @ts-ignore
1242
- newData.push({
1243
- id: undefined,
1244
- rowId: newGuid()
1245
- });
1246
- }
1247
- rowValues.forEach((cellValue, colIndex) => {
1248
- const targetCol = startCol + colIndex;
1249
- if (targetCol >= tmpCols.length) {
1250
- // Không vượt quá số cột
1251
- return;
1252
- }
1253
-
1254
- // @ts-ignore
1255
- const columnKey = tmpCols[targetCol].field;
1256
-
1257
- // @ts-ignore
1258
- newData[targetRow] = {
1259
- ...newData[targetRow],
1260
- [columnKey]: typeof cellValue === 'string' ? cellValue.trim() : cellValue
1261
- };
1262
- pastedColumns.add(columnKey);
1263
- });
1264
-
1265
- // Lưu dòng được paste
1266
- pastedRows.push(newData[targetRow]);
1267
- });
1268
- const pastedColumnsArray = Array.from(pastedColumns) ?? [];
1269
-
1270
- // const rsFilterData = updateDataByFilter(flattenArray([...originData]), newData)
1271
- const rsFilterData = updateOrInsert(flattenArray([...originData]), newData);
1272
- // const rsFilterData = mergeWithFilter(flattenArray([...originData]), newData)
1273
- // const rsFilterData = mergeWithFilter2(flattenArray([...originData]), newData)
1274
-
1275
- const rs = unFlattenData(rsFilterData);
1276
- triggerPaste?.(pastedRows, pastedColumnsArray, rs, copyRows);
1277
-
1278
- // }
1279
-
1280
- /// cập nhật cell class
1281
- if (selectedCells.current && selectedCells.current.size > 0) {
1282
- // onRemoveBgSelectedCell(rangeCells, id)
1283
- // onRemoveBorderSelectedCell(rangeCells, id)
1284
- }
1285
-
1286
- // selectedCells.current = sortedSetASC(mergedSet)
1287
- hideDraggingPoint(selectedCells.current, id);
1288
- const newCells = sortedSetASC(mergedSet);
1289
- selectedCells.current = newCells;
1290
- onAddBgCellIndex(newCells, id);
1291
- setRangeCells(newCells);
1292
- onAddBgSelectedCell(newCells, id);
1293
- onAddBorderSelectedCell(newCells, id);
1294
- setTimeout(() => {
1295
- showDraggingPoint(newCells, id);
1296
- }, 50);
1297
-
1298
- // setPasteCells(new Set())
1299
-
1300
- if (pasteCells.current && pasteCells.current.size > 0) {
1301
- removeClassBorderPasteCell(pasteCells.current, 'up', id);
1302
- }
1303
- pasteCells.current = new Set();
1304
- };
1305
- const handlePasted = (record, indexCol, rowNumber, pasteData) => {
1306
- const rows = pasteData.slice(0, onCellPaste?.maxRowsPaste ?? 200);
1307
- if (!record?.parentId) {
1308
- // Cập nhật data mới
1309
- const newData = flattenArray([...dataSource]);
1310
-
1311
- // const indexRows = newData.findIndex((it) => it[rowKey as any] === record[rowKey])
1312
-
1313
- // Lấy vị trí bắt đầu
1314
- // const { row: startRow, col: startCol } = selectedCell;
1315
- const startRow = newData.findIndex(it => it[rowKey] === record[rowKey]);
1316
- const startCol = indexCol;
1317
-
1318
- // const flattData = flattenArray(newData);
1319
-
1320
- const pastedRows = [];
1321
- const pastedColumns = new Set();
1322
- rows.forEach((rowValues, rowIndex) => {
1323
- const targetRow = startRow + rowIndex;
1324
-
1325
- // Nếu vượt quá số dòng hiện có, thêm dòng mới
1326
- if (targetRow >= newData.length) {
1327
- // @ts-ignore
1328
- // newData.push({ id: newGuid()});
1329
- newData.push({
1330
- id: undefined,
1331
- rowId: newGuid()
1332
- });
1333
- }
1334
- rowValues.forEach((cellValue, colIndex) => {
1335
- const targetCol = startCol + colIndex;
1336
- if (targetCol >= visibleCols.length) {
1337
- // Không vượt quá số cột
1338
- return;
1339
- }
1340
- const columnTarget = visibleCols[targetCol];
1341
- const isEdit = typeof columnTarget.editEnable === 'function' ? columnTarget.editEnable(newData[targetRow]) : columnTarget.editEnable;
1342
- if (isEdit) {
1343
- const columnKey = visibleCols[targetCol].field;
1344
- // const isEdit = typeof columnTarget.editEnable === 'function' ? columnTarget.editEnable(newData[targetRow]) : columnTarget.editEnable
1345
-
1346
- if (columnTarget.type === 'number' && isFormattedNumber(cellValue.trim())) {
1347
- const colFormat = typeof columnTarget.format === 'function' ? columnTarget.format(record) : columnTarget.format;
1348
- const valuePasteFormat = detectSeparators(cellValue.trim());
1349
- const cellFormat = getFormat(colFormat, format);
1350
- const thousandSeparator = valuePasteFormat?.thousandSeparator ?? cellFormat?.thousandSeparator;
1351
- const decimalSeparator = valuePasteFormat?.decimalSeparator ?? cellFormat?.decimalSeparator;
1352
- const dec = cellFormat?.decimalScale;
1353
- const numericFormatProps = {
1354
- thousandSeparator: checkThousandSeparator(thousandSeparator, decimalSeparator),
1355
- decimalSeparator: checkDecimalSeparator(thousandSeparator, decimalSeparator),
1356
- allowNegative: cellFormat?.allowNegative ?? true,
1357
- prefix: cellFormat?.prefix,
1358
- suffix: cellFormat?.suffix,
1359
- decimalScale: dec,
1360
- fixedDecimalScale: cellFormat?.fixedDecimalScale ?? false
1361
- };
1362
- const val = removeNumericFormat(cellValue.trim(), undefined, numericFormatProps);
1363
-
1364
- // @ts-ignore
1365
- newData[targetRow] = {
1366
- ...newData[targetRow],
1367
- [columnKey]: Number(val)
1368
- };
1369
- } else {
1370
- // @ts-ignore
1371
- newData[targetRow] = {
1372
- ...newData[targetRow],
1373
- [columnKey]: cellValue.trim()
1374
- };
1375
- }
1376
- pastedColumns.add(columnKey);
1377
- }
1378
- });
1379
-
1380
- // Lưu dòng được paste
1381
- pastedRows.push(newData[targetRow]);
1382
- });
1383
- const pastedColumnsArray = Array.from(pastedColumns) ?? [];
1384
-
1385
- // const rsFilterData = updateDataByFilter(flattenArray([...originData]), newData)
1386
- // const rsFilterData = mergeWithFilter(flattenArray([...originData]), newData)
1387
- const rsFilterData = updateOrInsert(flattenArray([...originData]), newData);
1388
- const rs = unFlattenData(rsFilterData);
1389
- triggerPaste?.(pastedRows, pastedColumnsArray, rs, []);
1390
- } else {
1391
- // Cập nhật data mới
1392
- // const newData = flattenArray([...dataSource])
1393
-
1394
- const parent = findItemByKey(dataSource, rowKey, record.parentId);
1395
-
1396
- // Cập nhật childData mới
1397
- const childData = parent?.children ? [...parent.children] : [];
1398
-
1399
- // Lấy vị trí bắt đầu
1400
- // const { row: startRow, col: startCol } = selectedCell;
1401
- const startRow = childData.findIndex(it => it[rowKey] === record[rowKey]);
1402
- const startCol = indexCol;
1403
- const pastedRows = [];
1404
- const pastedColumns = new Set();
1405
- rows.forEach((rowValues, rowIndex) => {
1406
- const targetRow = startRow + rowIndex;
1407
-
1408
- // Nếu vượt quá số dòng hiện có, thêm dòng mới
1409
- if (targetRow >= childData.length) {
1410
- childData.push({
1411
- id: undefined,
1412
- rowId: newGuid(),
1413
- parentId: parent[rowKey ?? 'id']
1414
- });
1415
- }
1416
- rowValues.forEach((cellValue, colIndex) => {
1417
- const targetCol = startCol + colIndex;
1418
- if (targetCol >= visibleCols.length) {
1419
- // Không vượt quá số cột
1420
- return;
1421
- }
1422
- const columnTarget = visibleCols[targetCol];
1423
- const isEdit = typeof columnTarget.editEnable === 'function' ? columnTarget.editEnable(childData[targetRow]) : columnTarget.editEnable;
1424
- if (isEdit) {
1425
- // @ts-ignore
1426
- const columnKey = visibleCols[targetCol].field;
1427
-
1428
- // @ts-ignore
1429
- childData[targetRow] = {
1430
- ...childData[targetRow],
1431
- [columnKey]: cellValue.trim()
1432
- };
1433
- pastedColumns.add(columnKey);
1434
- }
1435
- });
1436
-
1437
- // Lưu dòng được paste
1438
- pastedRows.push(childData[targetRow]);
1439
- });
1440
- const pastedColumnsArray = Array.from(pastedColumns) ?? [];
1441
- const newRowData = {
1442
- ...parent,
1443
- children: childData
1444
- }; // item đã được filter
1445
-
1446
- // const newDataSource = updateArrayByKey(newData, newRowData, rowKey as string)
1447
- const newDataSource = updateArrayByKey(originData, newRowData, rowKey);
1448
-
1449
- //
1450
- // // const rsFilterData = updateDataByFilter(flattenArray([...originData]), flattenArray(newDataSource))
1451
- // // const rsFilterData = mergeWithFilter(flattenArray([...originData]), flattenArray(newDataSource))
1452
-
1453
- // const rsFilterData1 = updateOrInsert(flattenArray([...originData]), flattenArray([...newDataSource]))
1454
- //
1455
- //
1456
- // // const rs = unFlattenData(rsFilterData)
1457
- // const rs1 = unFlattenData(rsFilterData1)
1458
-
1459
- triggerPaste?.(pastedRows, pastedColumnsArray, newDataSource, []);
1460
- }
1461
- };
1462
- const handlePaste = (record, indexCol, rowNumber, e) => {
1463
- // const clipboard: any = (e.clipboardData || (window && window?.Clipboard)).getData("text")
1464
- const pasteData = e.clipboardData.getData("text/plain");
1465
-
1466
- // Chuyển đổi dữ liệu từ clipboard thành mảng
1467
- const rowsPasted = pasteData.split("\n").filter(row => row !== '').map(row =>
1468
- // const rows = pasteData.split("\n").map((row: any) =>
1469
- row.replace(/\r/g, "").split("\t")
1470
-
1471
- // {
1472
- // return row.replace(/\r/g, "").split("\t")
1473
- // }
1474
- );
1475
- if (rowsPasted.length > (onCellPaste?.maxRowsPaste ?? 200)) {
1476
- // bật popup thông báo
1477
-
1478
- Modal.confirm({
1479
- content: /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement(Paragraph, {
1480
- style: {
1481
- marginBottom: '.25rem',
1482
- fontSize: 14
1483
- }
1484
- }, "D\u1EEF li\u1EC7u sao ch\xE9p v\u01B0\u1EE3t qu\xE1 s\u1ED1 d\xF2ng cho ph\xE9p (500 d\xF2ng).Ph\u1EA7n m\u1EC1n s\u1EBD ch\u1EC9 l\u1EA5y 500 d\xF2ng \u0111\u1EA7u ti\xEAn."), /*#__PURE__*/React.createElement(Title, {
1485
- level: 5,
1486
- style: {
1487
- marginTop: '.75rem'
1488
- }
1489
- }, "B\u1EA1n c\xF3 mu\u1ED1n ti\u1EBFp t\u1EE5c sao ch\xE9p kh\xF4ng?")),
1490
- centered: true,
1491
- className: 'be-popup-container',
1492
- onOk: () => {
1493
- handlePasted(record, indexCol, rowNumber, rowsPasted);
1494
- }
1495
- // footer: (_, { OkBtn, CancelBtn }) => (
1496
- // <>
1497
- // <OkBtn />
1498
- // <CancelBtn />
1499
- // </>
1500
- // ),
1501
- });
1502
- } else {
1503
- handlePasted(record, indexCol, rowNumber, rowsPasted);
1504
- }
1505
- };
1506
- const handlePointDoubleClick = e => {
1507
- // e.preventDefault()
1508
- e.stopPropagation();
1509
- const colStart = getFirstSelectCell(selectedCells.current).col;
1510
- const colEnd = getLastSelectCell(selectedCells.current).col;
1511
- const startPasteRow = getLastSelectCell(selectedCells.current).row;
1512
- const newPasteCells = new Set();
1513
- for (let r = Math.min(startPasteRow, dataSource.length - 1) + 1; r <= Math.max(startPasteRow, dataSource.length - 1); r++) {
1514
- for (let c = Math.min(colStart, colStart); c <= Math.max(colStart, colEnd); c++) {
1515
- newPasteCells.add(`${r}-${c}`);
1516
- }
1517
- }
1518
- hideDraggingPoint(selectedCells.current, id);
1519
- triggerDragPaste(newPasteCells);
1520
- };
1521
- const handleMouseDown = (record, row, col, e) => {
1522
- if (e.button === 2) {
1523
- e.stopPropagation();
1524
- return;
1525
- }
1526
- if (editingKey && editingKey.current === record[rowKey]) {
1527
- return;
1528
- }
1529
- if (record[rowKey] !== editingKey.current && editingKey.current !== '') {
1530
- setTimeout(() => {
1531
- // setEditingKey('')
1532
- editingKey.current = '';
1533
- onBlur?.(dataSource);
1534
- });
1535
- }
1536
-
1537
- // isDragMouse.current = true
1538
- isMouseDown.current = true;
1539
- if (e.ctrlKey) {
1540
- isSelecting.current = true;
1541
- startCell.current = {
1542
- row,
1543
- col
1544
- };
1545
-
1546
- // const cell: any = new Set([`${row}-${col}`])
1547
-
1548
- // setCurrentCtrlCells(cell)
1549
- } else {
1550
- isSelecting.current = true;
1551
- startCell.current = {
1552
- row,
1553
- col
1554
- };
1555
- const target = e.target;
1556
- if (target.closest('.dragging-point')) {
1557
- e.stopPropagation();
1558
- e.preventDefault();
1559
- // Không xử lý gì cả
1560
- } else {
1561
- // setStartSelectedCell({row, col})
1562
-
1563
- startSelectedCells.current = {
1564
- row,
1565
- col
1566
- };
1567
-
1568
- // setSelectedCells(new Set([`${row}-${col}`]));
1569
-
1570
- const cells = new Set([`${row}-${col}`]);
1571
- if (selectedCells.current && selectedCells.current.size > 0) {
1572
- if (!isEqualSet(cells, rangeCells)) {
1573
- // onRemoveBgSelectedCell(rangeCells, id)
1574
- // onRemoveBorderSelectedCell(rangeCells, id)
1575
- hideDraggingPoint(rangeCells, id);
1576
- onRemoveBgCellIndex(selectedCells.current, id);
1577
- }
1578
- }
1579
- if (rowsSelected.current && rowsSelected.current.size > 0) {
1580
- removeClassCellIndexSelected(rowsSelected.current, id);
1581
- }
1582
- if (!isEqualSet(cells, selectedCells.current)) {
1583
- onRemoveBgSelectedCell(selectedCells.current, id);
1584
- hideDraggingPoint(selectedCells.current, id);
1585
- selectedCells.current = cells;
1586
- // setRangeCells(cells)
1587
-
1588
- onAddBgCellIndex(cells, id);
1589
- onAddBorderSelectedCell(cells, id);
1590
- onAddBgSelectedCell(selectedCells.current, id, false);
1591
- showDraggingPoint(selectedCells.current, id);
1592
- }
1593
-
1594
- // setRowsSelected(new Set())
1595
- rowsSelected.current = new Set();
1596
- }
1597
- }
1598
- };
1599
- const handleMouseUp = e => {
1600
- isSelecting.current = false;
1601
- startCell.current = null;
1602
- isSelectingRow.current = false;
1603
- rowStart.current = null;
1604
- isDragMouse.current = false;
1605
- isMouseDown.current = false;
1606
- setIsPasteDragging(false);
1607
- if (e.ctrlKey) {
1608
-
1609
- // setCtrlCells([...ctrlCells, currentCtrlCells])
1610
- }
1611
-
1612
- // nếu ctrlCell length > 0 thì set selectCells
1613
-
1614
- if (pasteCells && pasteCells.current.size > 0) {
1615
- triggerDragPaste(pasteCells.current, e.ctrlKey);
1616
- } else {
1617
- setRangeCells(selectedCells.current);
1618
- const target = e.target;
1619
- if (target.closest('.dragging-point')) {
1620
- e.stopPropagation();
1621
- e.preventDefault();
1622
- return; // Không xử lý gì cả
1623
- }
1624
- if (selectedCells.current && selectedCells.current.size > 1) {
1625
- hideDraggingPoint(selectedCells.current, id);
1626
- onAddBorderSelectedCell(selectedCells.current, id);
1627
-
1628
- // showDraggingPoint(selectedCells.current, id)
1629
- }
1630
- showDraggingPoint(selectedCells.current, id);
1631
- // onAddBorderSelectedCell(selectedCells.current, id)
1632
- }
1633
- };
1634
- const handleMouseEnter = (row, col, e) => {
1635
- if (!isSelecting.current || !startCell.current) {
1636
- return;
1637
- }
1638
- const {
1639
- row: startRow,
1640
- col: startCol
1641
- } = startCell.current;
1642
- if (e.ctrlKey) {
1643
-
1644
- // const newCtrlCells = new Set();
1645
- // for (let r = Math.min(startRow, row); r <= Math.max(startRow, row); r++) {
1646
- // for (let c = Math.min(startCol, col); c <= Math.max(startCol, col); c++) {
1647
- // newCtrlCells.add(`${r}-${c}`)
1648
- // }
1649
- // }
1650
-
1651
- // setCurrentCtrlCells(newCtrlCells)
1652
-
1653
- // return
1654
- }
1655
- if (!isPasteDragging) {
1656
- // chọn vùng copy
1657
-
1658
- // setSelectIsDragging(true)
1659
-
1660
- setIsPasteDragging(false);
1661
- // isPasteDragging.current = false
1662
-
1663
- const newSelectedCells = new Set();
1664
- for (let r = Math.min(startRow, row); r <= Math.max(startRow, row); r++) {
1665
- for (let c = Math.min(startCol, col); c <= Math.max(startCol, col); c++) {
1666
- newSelectedCells.add(`${r}-${c}`);
1667
- }
1668
- }
1669
-
1670
- // setSelectedCells(newSelectedCells)
1671
-
1672
- if (selectedCells.current && selectedCells.current.size > 0) {
1673
- onRemoveBgSelectedCell(selectedCells.current, id);
1674
- }
1675
- selectedCells.current = newSelectedCells;
1676
- onAddBgSelectedCell(newSelectedCells, id);
1677
- } else {
1678
- // chọn vùng paste
1679
-
1680
- // setSelectIsDragging(false)
1681
-
1682
- // setIsPasteDragging(true) ////////
1683
-
1684
- const newSelectedCells = new Set();
1685
- for (let r = Math.min(startRow, row); r <= Math.max(startRow, row); r++) {
1686
- for (let c = Math.min(startCol, col); c <= Math.max(startCol, col); c++) {
1687
- newSelectedCells.add(`${r}-${c}`);
1688
- }
1689
- }
1690
- const colStart = getFirstSelectCell(selectedCells.current).col;
1691
- const colEnd = getLastSelectCell(selectedCells.current).col;
1692
- const rowSelectedEnd = getLastSelectCell(selectedCells.current).row;
1693
- if (row >= rowSelectedEnd) {
1694
- // kéo xuống dưới
1695
-
1696
- const newPasteCells = new Set();
1697
- for (let r = Math.min(startRow, row) + 1; r <= Math.max(startRow, row); r++) {
1698
- for (let c = Math.min(colStart, col); c <= Math.max(colStart, colEnd); c++) {
1699
- newPasteCells.add(`${r}-${c}`);
1700
- }
1701
- }
1702
-
1703
- // setPasteCells(newPasteCells)
1704
-
1705
- if (pasteCells.current && pasteCells.current.size > 0) {
1706
- removeClassBorderPasteCell(pasteCells.current, 'down', id);
1707
- }
1708
- pasteCells.current = newPasteCells;
1709
- addClassBorderPasteCell(newPasteCells, 'down', id);
1710
- }
1711
- if (row < rowSelectedEnd) {
1712
- // kéo lên trên
1713
-
1714
- const rowSelectedStart = getFirstSelectCell(selectedCells.current).row;
1715
- if (row < rowSelectedStart) {
1716
- const newPasteCells = new Set();
1717
- for (let r = Math.min(rowSelectedStart, row); r <= Math.max(rowSelectedStart, row) - 1; r++) {
1718
- for (let c = Math.min(colStart, col); c <= Math.max(colStart, colEnd); c++) {
1719
- newPasteCells.add(`${r}-${c}`);
1720
- }
1721
- }
1722
-
1723
- // setPasteCells(newPasteCells)
1724
-
1725
- if (pasteCells.current && pasteCells.current.size > 0) {
1726
- removeClassBorderPasteCell(pasteCells.current, 'up', id);
1727
- }
1728
- pasteCells.current = newPasteCells;
1729
- addClassBorderPasteCell(newPasteCells, 'up', id);
1730
- }
1731
- }
1732
- if (col > colEnd) {
1733
- // kéo sang phải
1734
- }
1735
- if (row < colStart) {
1736
- // kéo sang trái
1737
- }
1738
- }
1739
- };
1740
- const handleClickColHeader = (column, indexColumn) => {
1741
- const newSelectedCells = new Set();
1742
- for (let r = Math.min(dataSource.length, 0); r <= Math.max(dataSource.length - 1, 0); r++) {
1743
- for (let c = Math.min(indexColumn, indexColumn); c <= Math.max(indexColumn, indexColumn); c++) {
1744
- newSelectedCells.add(`${r}-${c}`);
1745
- }
1746
- }
1747
-
1748
- // setSelectedCells(new Set(newSelectedCells));
1749
-
1750
- if (selectedCells.current && selectedCells.current.size > 0) {
1751
- // onRemoveBgSelectedCell(selectedCells.current, id)
1752
- // onRemoveBorderSelectedCell(selectedCells.current, id)
1753
- }
1754
- if (rowsSelected.current && rowsSelected.current.size > 0) {
1755
- removeClassCellIndexSelected(rowsSelected.current, id);
1756
- }
1757
- selectedCells.current = newSelectedCells;
1758
- onAddBgSelectedCell(newSelectedCells, id);
1759
- onAddBorderSelectedCell(newSelectedCells, id);
1760
- hideDraggingPoint(selectedCells.current, id);
1761
- showDraggingPoint(newSelectedCells, id);
1762
- };
1763
- const handleMouseDownRowHeader = (row, col, column, e) => {
1764
- if (e.button === 2) {
1765
- e.stopPropagation();
1766
- return;
1767
- }
1768
- if (editingKey.current) {
1769
- editingKey.current = '';
1770
- // setEditingKey('')
1771
- }
1772
- isSelectingRow.current = true;
1773
- rowStart.current = {
1774
- row,
1775
- col
1776
- };
1777
- const newSelectedCells = new Set();
1778
- const tCols = editAbleColumns(visibleCols);
1779
- for (let r = Math.min(row, row); r <= Math.max(row, row); r++) {
1780
- for (let c = Math.min(tCols.length, col) + 1; c <= Math.max(tCols.length, col); c++) {
1781
- newSelectedCells.add(`${r}-${c}`);
1782
- }
1783
- }
1784
- if (selectedCells.current && selectedCells.current.size > 0) {
1785
- onRemoveBgCellIndex(selectedCells.current, id);
1786
- onRemoveBgSelectedCell(selectedCells.current, id);
1787
- onRemoveBorderSelectedCell(selectedCells.current, id);
1788
- // onRemoveBorderSelectedCell(selectedCells.current, id)
1789
- }
1790
- if (rowsSelected.current && rowsSelected.current.size > 0) {
1791
- removeClassCellIndexSelected(rowsSelected.current, id);
1792
- }
1793
- hideDraggingPoint(selectedCells.current, id);
1794
- selectedCells.current = newSelectedCells;
1795
- rowsSelected.current = new Set([`${row}-${col}`]);
1796
- onAddBgSelectedCell(newSelectedCells, id, false);
1797
- setTimeout(() => {
1798
- onAddBgSelectedCell(newSelectedCells, id, false);
1799
- }, 10);
1800
- addClassCellIndexSelected(new Set([`${row}-${col}`]), id);
1801
- };
1802
- const handleMouseEnterRowHeader = (row, col, e) => {
1803
- // dừng sự kiện kéo để chọn từ các column khác khi vừa gặp column index
1804
- if (isSelecting) {
1805
- startCell.current = null;
1806
- e.stopPropagation();
1807
- }
1808
- if (!isSelectingRow.current || !rowStart.current) {
1809
- return;
1810
- }
1811
- // const { row: startRow, col: startCol } = rowStart.current;
1812
- const {
1813
- row: startRow,
1814
- col: startCol
1815
- } = rowStart.current;
1816
- const newSelectedRows = new Set();
1817
- for (let r = Math.min(startRow, row); r <= Math.max(startRow, row); r++) {
1818
- for (let c = Math.min(startCol, col); c <= Math.max(startCol, col); c++) {
1819
- newSelectedRows.add(`${r}-${c}`);
1820
- }
1821
- }
1822
- const newSelectedCells = new Set();
1823
- for (let r = Math.min(startRow, row); r <= Math.max(startRow, row); r++) {
1824
- for (let c = Math.min(editAbleColumns(columns).length, col) + 1; c <= Math.max(editAbleColumns(columns).length, col); c++) {
1825
- newSelectedCells.add(`${r}-${c}`);
1826
- }
1827
- }
1828
- if (selectedCells.current && selectedCells.current.size > 0) {
1829
- onRemoveBgSelectedCell(selectedCells.current, id);
1830
- }
1831
- selectedCells.current = newSelectedCells;
1832
- onAddBgSelectedCell(newSelectedCells, id);
1833
- if (rowsSelected.current && rowsSelected.current.size > 0) {
1834
- removeClassCellIndexSelected(rowsSelected.current, id);
1835
- }
1836
- rowsSelected.current = newSelectedRows;
1837
- addClassCellIndexSelected(newSelectedRows, id);
1838
- };
1839
- const handleCellClick = (indexRow, record, column) => {
1840
- const cellClickCallback = newOptions => {
1841
- if (newOptions) {
1842
- const newElem = {
1843
- ...column,
1844
- editSelectSettings: {
1845
- ...(column?.editSelectSettings ? {
1846
- ...column?.editSelectSettings
1847
- } : {}),
1848
- options: newOptions
1849
- }
1850
- };
1851
- const rrr = updateArrayByKey([...columns], newElem, 'field');
1852
- triggerChangeColumns?.(rrr, 'click');
1853
- }
1854
- };
1855
- if (onCellClick) {
1856
- onCellClick({
1857
- index: indexRow,
1858
- rowId: record.rowId,
1859
- cellValue: record[record.field],
1860
- type: "Editing",
1861
- field: column.field,
1862
- rowData: record
1863
- }, cellClickCallback);
1864
- }
1865
- };
1866
- const handleCopy = e => {
1867
- const selectedArray = Array.from(selectedCells.current).map(key => {
1868
- const [row, col] = key.split("-").map(Number);
1869
- // @ts-ignore
1870
- const columnKey = editAbleColumns(columns)[col - 1].field;
1871
-
1872
- // @ts-ignore
1873
- return {
1874
- row,
1875
- col,
1876
- value: flattenData(childrenColumnName, dataSource)[row][columnKey] ?? ''
1877
- };
1878
- // return { row, col, value: '' };
1879
- });
1880
-
1881
- // Xác định min/max row và col để sắp xếp dữ liệu
1882
- const minRow = Math.min(...selectedArray.map(cell => cell.row));
1883
- const maxRow = Math.max(...selectedArray.map(cell => cell.row));
1884
- const minCol = Math.min(...selectedArray.map(cell => cell.col));
1885
- const maxCol = Math.max(...selectedArray.map(cell => cell.col));
1886
-
1887
- // Tạo dữ liệu dạng bảng (mảng 2D)
1888
- const table = Array.from({
1889
- length: maxRow - minRow + 1
1890
- }, () => Array(maxCol - minCol + 1).fill(""));
1891
-
1892
- // Gán giá trị vào bảng
1893
- selectedArray.forEach(({
1894
- row,
1895
- col,
1896
- value
1897
- }) => {
1898
- table[row - minRow][col - minCol] = value;
1899
- });
1900
-
1901
- // Chuyển mảng 2D thành chuỗi định dạng Excel
1902
- const copyText = table.map(row => row.join("\t")).join("\n");
1903
-
1904
- // Copy vào clipboard
1905
- e.preventDefault();
1906
- e.clipboardData.setData("text/plain", copyText);
1907
- Message(t ? t('CopySuccessful') : 'Copy Successful');
1908
- };
1909
- const handleEdit = (record, col, editType, rowIndex, e) => {
1910
- onRemoveBorderSelectedCell(selectedCells.current, id);
1911
-
1912
- // setTooltipContent('')
1913
-
1914
- // @ts-ignore
1915
- // setEditingKey(record[rowKey])
1916
- editingKey.current = record[rowKey];
1917
-
1918
- // setCellEditing({
1919
- // row: record,
1920
- // column: col
1921
- // })
1922
-
1923
- cellEditing.current = {
1924
- row: record,
1925
- column: col
1926
- };
1927
- reset();
1928
-
1929
- // const formattedRecord = { ...record };
1930
-
1931
- if (!isObjEmpty(record)) {
1932
- Object.entries(record).forEach(([name, value]) => {
1933
- setValue(name, value);
1934
-
1935
- // if (listObjectDate.includes(name) && value) {
1936
- // setValue(name, new Date(value))
1937
- // } else {
1938
- // setValue(name, value)
1939
- // }
1940
- });
1941
- }
1942
- if (e.key === 'Enter' || editType === 'date' || e.type === 'dblclick') {} else {
1943
- setValue(col.dataIndex, editType === 'numeric' ? !isNaN(Number(e.key)) ? Number(e.key) : '' : e.key);
1944
- }
1945
- if (editType === 'select') {
1946
- // setSearchValue(e.key)
1947
- // setOpen(true)
1948
- }
1949
- if (startSelectedCells.current && startSelectedCells.current.row !== undefined && startSelectedCells.current.col !== undefined) {
1950
- setTimeout(() => {
1951
- const input = document.querySelector(`.ui-rc-table-row .cell-editing[data-row-index="${startSelectedCells.current.row}"].cell-editing[data-col-index="${startSelectedCells.current.col}"] input`);
1952
- const textarea = document.querySelector(`.ui-rc-table-row .cell-editing[data-row-index="${startSelectedCells.current.row}"].cell-editing[data-col-index="${startSelectedCells.current.col}"] textarea`);
1953
- const select = document.querySelector(`div.cell-editing[tabindex="${startSelectedCells.current.col}"] .ant-select-selection-search input`);
1954
- if (textarea) {
1955
- // input.focus({
1956
- // preventScroll: true,
1957
- // cursor: 'end'
1958
- // })
1959
-
1960
- textarea.focus();
1961
- textarea.setSelectionRange(textarea.value.length, textarea.value.length);
1962
- }
1963
- if (input) {
1964
- input.focus();
1965
- }
1966
- if (select) {
1967
- // @ts-ignore
1968
- select.searchValue = e.key;
1969
- // @ts-ignore
1970
- select.focus();
1971
- }
1972
- }, 20);
1973
- }
1974
- };
1975
-
1976
- // useEffect(() => {
1977
- // const tableBody = document.querySelector(".ui-rc-table-tbody");
1978
- // const tableHeader = document.querySelector(".ui-rc-table-header");
1979
- //
1980
- // if (tableBody && tableHeader) {
1981
- // tableBody.addEventListener("scroll", () => {
1982
- // tableHeader.scrollLeft = tableBody.scrollLeft;
1983
- // });
1984
- // }
1985
- // }, []);
1986
-
1987
- const scrollToCell = (rowIndex, colIndex, cell, scrollType) => {
1988
- const fixedWidth = totalFixedWidth(visibleCols, 'left', selectionSettings);
1989
- if (scrollType === 'horizontal') {
1990
- if (tableRef.current) {
1991
- tableRef.current.scrollTo({
1992
- left: cell.offsetLeft - fixedWidth,
1993
- behavior: "smooth"
1994
- });
1995
-
1996
- // Cuộn header
1997
- // const tableHeader = document?.querySelector(".ui-rc-table-header");
1998
- // if (tableHeader) {
1999
- // tableHeader.scrollLeft = cell.offsetLeft - fixedWidth
2000
- // }
2001
- }
2002
- } else {
2003
- tableRef?.current?.scrollTo({
2004
- index: rowIndex,
2005
- behavior: 'smooth'
2006
- });
2007
- }
2008
- };
2009
- const handleFocusCell = (rowIndex, colIndex, col, scrollType, e, isTimeout) => {
2010
- const isEdit = editingKey.current !== '';
2011
- const cellEdit = document.querySelector(`.ui-rc-table-row .cell-editing[data-row-index="${rowIndex}"].cell-editing[data-col-index="${colIndex}"]`);
2012
- const cell = document.querySelector(`.ui-rc-table-row .cell-editable[data-row-index="${rowIndex}"].cell-editable[data-col-index="${colIndex}"]`);
2013
- const updateSelection = () => {
2014
- // setStartSelectedCell({ row: rowIndex, col: colIndex });
2015
- startSelectedCells.current = {
2016
- row: rowIndex,
2017
- col: colIndex
2018
- };
2019
- // setSelectedCells(new Set([`${rowIndex}-${colIndex}`]));
2020
-
2021
- const cells = new Set([`${rowIndex}-${colIndex}`]);
2022
- if (selectedCells.current && selectedCells.current.size > 0) {
2023
- onRemoveBgSelectedCell(selectedCells.current, id);
2024
- onRemoveBorderSelectedCell(selectedCells.current, id);
2025
- }
2026
- hideDraggingPoint(selectedCells.current, id);
2027
- selectedCells.current = cells;
2028
- setRangeCells(cells);
2029
-
2030
- // setTimeout(() => {
2031
- //
2032
- // // onAddBgSelectedCell(selectedCells.current, id)
2033
- // // onAddBorderSelectedCell(selectedCells.current, id)
2034
- //
2035
- // }, 50)
2036
-
2037
- onAddBgSelectedCell(selectedCells.current, id);
2038
- onAddBorderSelectedCell(selectedCells.current, id);
2039
- showDraggingPoint(cells, id);
2040
- };
2041
- const focusNextCell = (editingCell, cellEditable) => {
2042
- if (isEdit) {
2043
- if (editingCell) {
2044
- updateSelection();
2045
- if (e?.key !== 'Tab') {
2046
- editingCell.focus();
2047
- // editingCell.click()
2048
- }
2049
- }
2050
- if (scrollType === 'horizontal' && editingCell) {
2051
- scrollToCell(rowIndex, colIndex, editingCell, 'horizontal');
2052
- }
2053
- if (scrollType === 'vertical' && cellEditable) {
2054
- // setEditingKey('')
2055
- editingKey.current = '';
2056
- updateSelection();
2057
- scrollToCell(rowIndex, colIndex, cellEdit, 'vertical');
2058
- if (e?.key !== 'Tab') {
2059
- cellEditable.focus();
2060
- onAddBorderSelectedCell(selectedCells.current, id);
2061
- // editingCell.click()
2062
- }
2063
- }
2064
- } else {
2065
- if (cellEditable) {
2066
- updateSelection();
2067
- if (e?.key !== 'Tab') {
2068
- cellEditable.focus();
2069
- onAddBorderSelectedCell(selectedCells.current, id);
2070
- }
2071
- }
2072
- if (cellEditable) {
2073
- scrollToCell(rowIndex, colIndex, cellEditable, scrollType);
2074
- }
2075
- }
2076
- };
2077
- if (isTimeout) {
2078
- let cellEdit1 = undefined;
2079
- let cell1 = undefined;
2080
- setTimeout(() => {
2081
- cellEdit1 = document.querySelector(`.ui-rc-table-row .cell-editing[data-row-index="${rowIndex}"].cell-editing[data-col-index="${colIndex}"]`);
2082
- cell1 = document.querySelector(`.ui-rc-table-row .cell-editable[data-row-index="${rowIndex}"].cell-editable[data-col-index="${colIndex}"]`);
2083
- }, 20);
2084
- setTimeout(() => {
2085
- focusNextCell(cellEdit1, cell1);
2086
- }, 50);
2087
- } else {
2088
- focusNextCell(cellEdit, cell);
2089
- }
2090
- };
2091
- const convertColumns = flatColumns2(columns.filter(it => it.visible !== false)).map((column, colIndex) => {
2092
- if (column === SELECTION_COLUMN) {
2093
- return SELECTION_COLUMN;
2094
- }
2095
- if (column.field === '#') {
2096
- return {
2097
- ...column,
2098
- className: 'rc-ui-cell-editable rc-ui-cell-index',
2099
- onCell: (record, rowIndex) => {
2100
- const rowNumber = getRowNumber(dataSource, record[rowKey], rowKey);
2101
- return {
2102
- 'data-row-index': rowNumber,
2103
- onPaste: event => {
2104
- if (editingKey.current === '') {
2105
- handlePaste(record, colIndex + 1, rowNumber, event);
2106
- event.preventDefault();
2107
- }
2108
- },
2109
- onCopy: e => {
2110
- if (editingKey.current === '') {
2111
- handleCopy(e);
2112
- e.preventDefault();
2113
- }
2114
- },
2115
- // onClick: () => {
2116
- // if (record[rowKey] !== editingKey && (editingKey !== '')) {
2117
- // setEditingKey('')
2118
- // }
2119
- // },
2120
- tabIndex: (rowIndex ?? 0) * visibleCols.length + colIndex
2121
- };
2122
- },
2123
- render: (value, record) => {
2124
- const rowNumber = getRowNumber(dataSource, record[rowKey], rowKey);
2125
- return /*#__PURE__*/React.createElement("div", {
2126
- className: classNames('ui-rc_cell-content ui-rc_cell-content--index', {}),
2127
- onMouseDown: event => handleMouseDownRowHeader(rowNumber, colIndex, column, event),
2128
- onMouseEnter: event => handleMouseEnterRowHeader(rowNumber, colIndex, event),
2129
- onMouseUp: event => handleMouseUp(event)
2130
- }, /*#__PURE__*/React.createElement("div", {
2131
- className: 'ui-rc_content'
2132
- }, findItemPath(dataSource, record, rowKey)));
2133
- }
2134
- };
2135
- }
2136
- if (column.field === 'command') {
2137
- return {
2138
- ...column
2139
- };
2140
- }
2141
- return {
2142
- ...column,
2143
- title: /*#__PURE__*/React.createElement(Fragment, null, /*#__PURE__*/React.createElement(SortableHeaderCell, {
2144
- columnKey: column.field
2145
- }, /*#__PURE__*/React.createElement(HeaderContent, {
2146
- column: {
2147
- ...column
2148
- },
2149
- t: t,
2150
- id: id,
2151
- wrapSettings: wrapSettings,
2152
- onClick: () => {
2153
- handleClickColHeader(column, colIndex);
2154
- },
2155
- onCopy: e => {
2156
- if (editingKey.current === '') {
2157
- handleCopy(e);
2158
- e.preventDefault();
2159
- }
2160
- },
2161
- onPaste: event => {
2162
- if (editingKey.current === '') {
2163
- handlePaste(dataSource[0], colIndex, 0, event);
2164
- event.preventDefault();
2165
- }
2166
- }
2167
- }))),
2168
- onCell: (record, rowIndex) => {
2169
- const rowNumber = getRowNumber(dataSource, record[rowKey], rowKey);
2170
- return {
2171
- ...column?.onCell?.(record, rowIndex),
2172
- onKeyDown: event => {
2173
- const key = getRowKey(record, dataSource.indexOf(record));
2174
- if (event.key === 'Control' && event.ctrlKey) {} else {
2175
- if (event.key.length === 1 && !event.ctrlKey && !event.metaKey || event.key === 'Enter') {
2176
- if (record[rowKey] !== editingKey.current && isEditable(column, record)) {
2177
- // ~~ khi editingKey = ''
2178
- event.preventDefault();
2179
- event.stopPropagation();
2180
- handleEdit(record, column, column.editType, rowNumber, event);
2181
-
2182
- // onRemoveBgSelectedCell(selectedCells.current, id)
2183
- // onRemoveBorderSelectedCell(selectedCells.current, id)
2184
-
2185
- // selectedCells.current = new Set()
2186
-
2187
- handleCellClick(rowNumber, record, column);
2188
- const hasKey = mergedExpandedKeys.has(key);
2189
- if (hasKey) {
2190
- // mergedExpandedKeys.delete(key);
2191
- // newExpandedKeys = [...mergedExpandedKeys];
2192
- } else {
2193
- onTriggerExpand(record);
2194
- }
2195
- } else {
2196
- if (event.shiftKey && event.key === 'Enter') {} else {
2197
- if (event.key === 'Enter') {
2198
- event.preventDefault();
2199
- event.stopPropagation();
2200
- if (editingKey && editingKey.current !== '' && (rowNumber ?? 0) + 1 < flattenArray(dataSource).length && event.key === 'Enter') {
2201
- handleFocusCell((rowNumber ?? 0) + 1, colIndex, column, 'vertical', event);
2202
- } else {
2203
- // // focus cell hiện tại và tắt edit
2204
- // handleFocusCell((rowNumber ?? 0), colIndex, column, 'vertical', event)
2205
- // setEditingKey('')
2206
-
2207
- // thêm dòng mới
2208
-
2209
- handleAddSingle();
2210
- handleFocusCell((rowNumber ?? 0) + 1, colIndex, column, 'vertical', event, true);
2211
- }
2212
- }
2213
- }
2214
- }
2215
- }
2216
- if (event.key === 'Tab') {
2217
- if (editingKey.current) {} else {
2218
- if (colIndex + 1 !== visibleCols.length) {
2219
- handleFocusCell(rowNumber, colIndex + 1, column, 'horizontal', event);
2220
- } else {
2221
- event.stopPropagation();
2222
- event.preventDefault();
2223
- }
2224
- }
2225
- }
2226
- if (event.key === 'ArrowRight' && colIndex + 1 !== visibleCols.length) {
2227
- if (editingKey.current !== '') {} else {
2228
- handleFocusCell(rowNumber, colIndex + 1, column, 'horizontal', event);
2229
- }
2230
- }
2231
- if (event.key === 'ArrowLeft' && colIndex > 0) {
2232
- if (!column.dataIndex && !column.key || column.field === '#' || column.dataIndex === '#') {
2233
- event.stopPropagation();
2234
- event.preventDefault();
2235
- } else {
2236
- if (editingKey.current !== '') {} else {
2237
- handleFocusCell(rowNumber, colIndex - 1, column, 'horizontal', event);
2238
- }
2239
- }
2240
- }
2241
- if (event.key === 'ArrowDown' && (rowNumber ?? 0) + 1 < flattenArray(dataSource).length) {
2242
- // if (isEditing(record) && (
2243
- if (record[rowKey] === editingKey.current && (getEditType(column, record) === 'treeSelect' || getEditType(column, record) === 'select' || getEditType(column, record) === 'selectTable' || getEditType(column, record) === 'asyncSelect')) {
2244
- event.stopPropagation();
2245
- } else {
2246
- handleFocusCell((rowNumber ?? 0) + 1, colIndex, column, 'vertical', event);
2247
- }
2248
- }
2249
- if (event.key === 'ArrowUp' && (rowNumber ?? 0) > 0) {
2250
- if (record[rowKey] === editingKey.current && (getEditType(column, record) === 'asyncSelect' || getEditType(column, record) === 'select' || getEditType(column, record) === 'selectTable' || getEditType(column, record) === 'treeSelect')) {
2251
- event.stopPropagation();
2252
- } else {
2253
- handleFocusCell((rowNumber ?? 0) - 1, colIndex, column, 'vertical', event);
2254
- }
2255
- }
2256
- if (event.key === 'Delete') {
2257
- if (!isEditable(column, record)) {}
2258
- handleDeleteContent();
2259
- }
2260
- if (event.key === 'Escape') {
2261
- // setEditingKey('')
2262
- editingKey.current = '';
2263
- }
2264
- }
2265
- },
2266
- onPaste: event => {
2267
- if (editingKey.current === '') {
2268
- handlePaste(record, colIndex, rowNumber, event);
2269
- event.preventDefault();
2270
- }
2271
- },
2272
- onCopy: e => {
2273
- if (editingKey.current === '') {
2274
- handleCopy(e);
2275
- e.preventDefault();
2276
- }
2277
- },
2278
- onDoubleClick: event => {
2279
- // if (!isEditing(record) && record[rowKey] !== editingKey.current && isEditable(column as any, record)) {
2280
- if (!(record[rowKey] === editingKey.current) && record[rowKey] !== editingKey.current && isEditable(column, record)) {
2281
- handleEdit(record, column, getEditType(column, record), rowNumber, event);
2282
-
2283
- // onRemoveBgSelectedCell(selectedCells.current, id)
2284
- // onRemoveBorderSelectedCell(selectedCells.current, id)
2285
- handleCellClick(rowNumber, record, column);
2286
- }
2287
- },
2288
- onContextMenu: () => {
2289
- // isSelecting.current = true;
2290
- // startCell.current = { row: rowNumber, col: colIndex };
2291
-
2292
- // if (selectedCells.size === 0) {
2293
- // setStartSelectedCell({ row: rowNumber, col: colIndex })
2294
- // setSelectedCells(new Set([`${rowNumber}-${colIndex}`]));
2295
- hideDraggingPoint(selectedCells.current, id);
2296
- startSelectedCells.current = {
2297
- row: rowNumber,
2298
- col: colIndex
2299
- };
2300
- selectedCells.current = new Set([`${rowNumber}-${colIndex}`]);
2301
- rowsSelected.current = new Set();
2302
- onAddBorderSelectedCell(selectedCells.current, id);
2303
- showDraggingPoint(selectedCells.current, id);
2304
- setRangeCells(selectedCells.current);
2305
-
2306
- // }
2307
- },
2308
- onClick: () => {
2309
- if (record[rowKey] !== editingKey.current && editingKey.current !== '') {
2310
- // setEditingKey('')
2311
- } else {
2312
- if (record[rowKey] !== editingKey.current) {
2313
- onAddBorderSelectedCell(selectedCells.current, id);
2314
- }
2315
- if (editingKey.current) {
2316
- handleCellClick(rowNumber, record, column);
2317
- }
2318
- }
2319
- },
2320
- // className: isEditing(record) ? `rc-ui-cell-editable cell-editing ${!isEditable(column as any, record) ? 'disable' : ''}` : `rc-ui-cell-editable cell-editable ${!isEditable(column as any, record) ? 'disable' : ''}`,
2321
- className: classNames('rc-ui-cell-editable', {
2322
- 'cell-editing': record[rowKey] === editingKey.current,
2323
- 'cell-editable': !(record[rowKey] === editingKey.current),
2324
- disable: !isEditable(column, record)
2325
- }),
2326
- record,
2327
- column,
2328
- editType: getEditType(column, record),
2329
- dataIndex: column.dataIndex,
2330
- indexRow: rowNumber,
2331
- indexCol: colIndex,
2332
- title: getValueCell(column, record[column.field], record, rowNumber, colIndex, format),
2333
- 'data-col-index': colIndex,
2334
- 'data-row-index': rowNumber,
2335
- // 'data-tooltip-id': "tooltip-cell-content",
2336
- 'data-tooltip-id': `${id}-tooltip-cell-content`,
2337
- // editing: isEditing(record) && rowEditable?.(record) !== false && isEditable(column as any, record),
2338
- editing: record.rowId === editingKey.current && rowEditable?.(record) !== false && isEditable(column, record),
2339
- cellEditing: cellEditing.current,
2340
- t,
2341
- tabIndex: (rowIndex ?? 0) * visibleCols.length + colIndex,
2342
- style: isPasteDragging ? {
2343
- cursor: "crosshair"
2344
- } : {}
2345
- };
2346
- },
2347
- // onHeaderCell: (data: any, index: any) => {
2348
- //
2349
- // return ({
2350
- // ...column.onHeaderCell ? column.onHeaderCell?.(data, index) : {},
2351
- // // onClick: () => {
2352
- // // handleClickColHeader(column, colIndex)
2353
- // // },
2354
- // // onCopy: (e: any) => {
2355
- // // if (editingKey.current === '') {
2356
- // // handleCopy(e)
2357
- // // e.preventDefault()
2358
- // // }
2359
- // // },
2360
- // //
2361
- // // onPaste: (event: any) => {
2362
- // //
2363
- // // if (editingKey.current === '') {
2364
- // //
2365
- // // handlePaste(dataSource[0], colIndex, 0 as number, event)
2366
- // // event.preventDefault()
2367
- // // }
2368
- // //
2369
- // // },
2370
- // style: {
2371
- // userSelect: 'none'
2372
- // }
2373
- // })
2374
- // },
2375
-
2376
- render: (value, record, rowIndex) => {
2377
- const rowNumber = getRowNumber(dataSource, record[rowKey], rowKey);
2378
- const colFormat = typeof column.format === 'function' ? column.format(record) : column.format;
2379
- const cellFormat = getFormat(colFormat, format);
2380
- const rowError = dataErrors.find(it => it.index === rowNumber);
2381
-
2382
- // const cellError = rowError && column.field && rowError[column.field]?.field === column.field ? rowError[column.field] : null
2383
-
2384
- const handleClick = event => {
2385
- if (!(record[rowKey] === editingKey.current) && record[rowKey] !== editingKey.current && isEditable(column, record)) {
2386
- handleEdit(record, column, getEditType(column, record), rowNumber, event);
2387
-
2388
- // onRemoveBgSelectedCell(selectedCells.current, id)
2389
- // onRemoveBorderSelectedCell(selectedCells.current, id)
2390
- handleCellClick(rowNumber, record, column);
2391
- }
2392
- };
2393
- return /*#__PURE__*/React.createElement("div", {
2394
- className: classNames('ui-rc_cell-content', {
2395
- isValid: column.field && rowError && rowError[column.field]?.field === column?.field
2396
- }),
2397
- onMouseDown: event => handleMouseDown(record, rowNumber, colIndex, event),
2398
- onMouseEnter: event => {
2399
- // setTooltipContent(cellError ? cellError.message : '')
2400
-
2401
- handleMouseEnter(rowNumber, colIndex, event);
2402
-
2403
- // hoveredRow.current = rowNumber
2404
- },
2405
- onMouseUp: handleMouseUp,
2406
- onMouseMove: () => {
2407
- if (selectedCells && selectedCells.current.size > 0 && isMouseDown.current) {
2408
- hideDraggingPoint(selectedCells.current, id);
2409
- isDragMouse.current = true;
2410
- }
2411
- }
2412
- }, /*#__PURE__*/React.createElement("div", {
2413
- className: classNames('ui-rc_content', {
2414
- 'select-cell': ['select', 'selectTable', 'asyncSelect'].includes(getEditType(column, record))
2415
- })
2416
- }, renderContent(column, value, record, rowIndex, colIndex, true, cellFormat, handleClick)), !isDragMouse.current && /*#__PURE__*/React.createElement("div", {
2417
- className: 'dragging-point hidden',
2418
- onMouseDown: e => {
2419
- // e.stopPropagation()
2420
- e.preventDefault();
2421
- if (e.button === 0) {
2422
- setIsPasteDragging(true);
2423
- }
2424
- },
2425
- onDoubleClick: handlePointDoubleClick
2426
- }, /*#__PURE__*/React.createElement("span", {
2427
- className: 'dot-point'
2428
- })));
2429
- }
2430
- };
2431
- });
2432
- // [
2433
- // cellEditing,
2434
- // columns,
2435
- // dataErrors,
2436
- // dataSource,
2437
- // editingKey,
2438
- // format,
2439
- // getRowKey,
2440
- // handleAddSingle,
2441
- // handleCellClick,
2442
- // handleClickColHeader,
2443
- // handleCopy,
2444
- // handleDeleteContent,
2445
- // handleEdit,
2446
- // handleFocusCell,
2447
- // handleMouseDown,
2448
- // handleMouseDownRowHeader,
2449
- // handleMouseEnter,
2450
- // handleMouseEnterRowHeader,
2451
- // handleMouseUp,
2452
- // handlePaste,
2453
- // handlePointDoubleClick,
2454
- // id,
2455
- // isEditing,
2456
- // isPasteDragging,
2457
- // mergedExpandedKeys,
2458
- // onTriggerExpand,
2459
- // rowEditable,
2460
- // rowKey,
2461
- // setTooltipContent,
2462
- // t,
2463
- // visibleCols.length
2464
- // ])
2465
-
2466
- const transformColumns = React.useCallback(cols => {
2467
- // @ts-ignore
2468
- return cols.map(column => {
2469
- const find = convertColumns.find(it => it?.field === column.field);
2470
- if (column === SELECTION_COLUMN) {
2471
- return SELECTION_COLUMN;
2472
- }
2473
-
2474
- // Xử lý đệ quy cho children
2475
- if (column.children?.length) {
2476
- return {
2477
- ...column,
2478
- children: transformColumns(column.children)
2479
- };
2480
- }
2481
- if (find) {
2482
- return {
2483
- ...find
2484
- };
2485
- }
2486
- if (!find) {
2487
- return {
2488
- ...column
2489
- };
2490
- }
2491
- });
2492
- }, [convertColumns]);
2493
- const mergedColumns = React.useMemo(() => transformColumns(columns ?? []), [transformColumns, columns]);
2494
- const bottomToolbar = () => {
2495
- return /*#__PURE__*/React.createElement("div", {
2496
- className: 'ui-rc-toolbar-bottom',
2497
- style: {
2498
- borderBottom: '1px solid #e0e0e0'
2499
- }
2500
- }, /*#__PURE__*/React.createElement(Toolbar, {
2501
- style: {
2502
- width: '100%'
2503
- },
2504
- items: toolbarItemsBottom ?? [],
2505
- mode: 'scroll',
2506
- onClick: ({}) => {
2507
- editingKey.current = '';
2508
- // setEditingKey('')
2509
- }
2510
- }));
2511
- };
2512
- const contextMenuClick = args => {
2513
- if (args.item?.parentKey && args.item.parentKey === 'INSERT_BEFORE') {
2514
- if (args.item.key === 'INSERT_BEFORE_ADV') {
2515
- // mở Modal
2516
-
2517
- setOpenModalAddRow(prev => ({
2518
- ...prev,
2519
- open: true,
2520
- type: 'INSERT_BEFORE'
2521
- }));
2522
- } else {
2523
- handleInsertBefore(args.item, args.item.row);
2524
- }
2525
- return;
2526
- }
2527
- if (args.item?.parentKey && args.item.parentKey === 'INSERT_AFTER') {
2528
- if (args.item.key === 'INSERT_AFTER_ADV') {
2529
- setOpenModalAddRow(prev => ({
2530
- ...prev,
2531
- open: true,
2532
- type: 'INSERT_AFTER'
2533
- }));
2534
- } else {
2535
- handleInsertAfter(args.item, args.item.row);
2536
- }
2537
- return;
2538
- }
2539
- if (args.item.key === 'INSERT_CHILDREN') {
2540
- handleInsertChild(args.item);
2541
- return;
2542
- }
2543
- if (args.item.key === 'DELETE_ROWS') {
2544
- handleDeleteRows(args.item);
2545
- return;
2546
- }
2547
- if (args.item.key === 'DELETE_CONTENT') {
2548
- handleDeleteContent();
2549
- }
2550
- };
2551
- const hideModalAddRow = () => {
2552
- setOpenModalAddRow(prev => ({
2553
- ...prev,
2554
- open: false,
2555
- type: ''
2556
- }));
2557
- setRowsAdd(1);
2558
- };
2559
- const onOkAddRow = () => {
2560
- if (openModalAddRow.type === 'INSERT_AFTER') {
2561
- handleInsertAfter({}, rowsAdd);
2562
- }
2563
- if (openModalAddRow.type === 'INSERT_BEFORE') {
2564
- handleInsertBefore({}, rowsAdd);
2565
- }
2566
- hideModalAddRow();
2567
- };
2568
- const onChangeRows = val => {
2569
- setRowsAdd(val);
2570
- };
2571
- return /*#__PURE__*/React.createElement(Fragment, null, /*#__PURE__*/React.createElement(GridStyle, {
2572
- $heightTable: height,
2573
- $heightScroll: scrollHeight,
2574
- $isFullScreen: isFullScreen,
2575
- style: {
2576
- position: 'relative'
2577
- },
2578
- ref: ref,
2579
- id: id
2580
- }, /*#__PURE__*/React.createElement(TableContext.Provider, {
2581
- value: {
2582
- id: id ?? '',
2583
- rowKey,
2584
- // form,
2585
- format,
2586
- control,
2587
- trigger,
2588
- errors,
2589
- getValues,
2590
- handleCellChange,
2591
- getRowKey
2592
- }
2593
- }, /*#__PURE__*/React.createElement("form", {
2594
- onSubmit: handleSubmit(onSubmit)
2595
- }, /*#__PURE__*/React.createElement(ConfigProvider, {
2596
- theme: {
2597
- components: {
2598
- Table: {
2599
- rowHoverBg: '#eb461912',
2600
- rowSelectedBg: '#eb4619',
2601
- rowSelectedHoverBg: '#eb4619',
2602
- // cellFontSize: 12,
2603
- cellFontSizeSM: 13,
2604
- headerBg: '#ffffff',
2605
- cellPaddingBlockSM: 7
2606
- // cellPaddingBlock: 0,
2607
- // cellPaddingBlockSM: 0,
2608
- // cellPaddingInlineSM: 0,
2609
- // cellPaddingInline: 0
2610
- }
2611
- }
2612
- }
2613
- }, /*#__PURE__*/React.createElement(TableGrid, _extends({}, rest, {
2614
- t: t,
2615
- id: id,
2616
- tableRef: tableRef,
2617
- dataSource: dataSource,
2618
- locale: locale,
2619
- components: {
2620
- ...components,
2621
- body: {
2622
- cell: EditableCell
2623
- // row: RowComponent
2624
- }
2625
- },
2626
- className: classNames(className, 'grid-editable'),
2627
- rowKey: rowKey,
2628
- getRowKey: getRowKey,
2629
- columns: mergedColumns,
2630
- showSorterTooltip: {
2631
- target: 'sorter-icon'
2632
- },
2633
- format: format,
2634
- toolbarItems: toolbarItems
2635
- // selectionSettings={selectionSettings ? {...selectionSettings, checkboxOnly: true} : undefined}
2636
- ,
2637
- selectionSettings: selectionSettings ? {
2638
- ...selectionSettings,
2639
- checkboxOnly: true,
2640
- arrowKey: false
2641
- } : {
2642
- checkboxOnly: true,
2643
- arrowKey: false
2644
- },
2645
- rowHoverable: false,
2646
- bottomToolbar: bottomToolbar,
2647
- expandable: expandable ? {
2648
- expandIconColumnIndex: checkChild(dataSource) ? 3 : undefined,
2649
- ...expandable,
2650
- expandedRowKeys: innerExpandedKeys,
2651
- expandIcon: args => {
2652
- const {
2653
- record,
2654
- expanded
2655
- } = args;
2656
-
2657
- // @ts-ignore
2658
- if (record?.children?.length > 0 || record?.isChildren) {
2659
- return expanded ? /*#__PURE__*/React.createElement("button", {
2660
- onClick: e => {
2661
- e.preventDefault();
2662
- e.stopPropagation();
2663
- onTriggerExpand(record);
2664
- // onExpand(record, e)
2665
- },
2666
- className: 'ui-rc-table-row-expand-icon ui-rc-table-row-expand-icon-expanded'
2667
- }) : /*#__PURE__*/React.createElement("button", {
2668
- onClick: e => {
2669
- e.preventDefault();
2670
- e.stopPropagation();
2671
- onTriggerExpand(record);
2672
- // onExpand(record, e)
2673
- },
2674
- className: 'ui-rc-table-row-expand-icon ui-rc-table-row-expand-icon-collapsed'
2675
- });
2676
- } else {
2677
- return /*#__PURE__*/React.createElement("button", {
2678
- className: 'ui-rc-table-row-expand-icon ui-rc-table-row-expand-icon-spaced'
2679
- });
2680
- }
2681
- }
2682
- } : undefined,
2683
- triggerChangeColumns: triggerChangeColumns,
2684
- clickHeaderToSort: false,
2685
- contextMenuItems: contextMenuItems,
2686
- contextMenuClick: contextMenuClick,
2687
- onScroll: () => {
2688
- if (selectedCells.current && selectedCells.current.size > 0) {
2689
- onAddBgSelectedCell(selectedCells.current, id);
2690
- onAddBorderSelectedCell(selectedCells.current, id);
2691
- showDraggingPoint(selectedCells.current, id);
2692
- }
2693
- if (rowsSelected && rowsSelected.current.size > 0) {
2694
- addClassCellIndexSelected(rowsSelected.current, id);
2695
- }
2696
- },
2697
- isFullScreen: isFullScreen
2698
- })))))), /*#__PURE__*/React.createElement(Toaster, {
2699
- position: toast,
2700
- toastOptions: {
2701
- className: 'react-hot-toast'
2702
- }
2703
- }), /*#__PURE__*/React.createElement(Modal, {
2704
- title: `${t ? t(locale?.add_rows ?? 'Add rows') : 'Add rows'}`,
2705
- open: openModalAddRow.open,
2706
- onOk: onOkAddRow,
2707
- onCancel: hideModalAddRow,
2708
- okText: `${t ? t(locale?.ok_btn ?? 'Ok') : 'Ok'}`,
2709
- cancelText: `${t ? t(locale?.cancel_btn ?? 'Cancel') : 'Cancel'}`,
2710
- className: 'be-popup-container',
2711
- centered: true,
2712
- width: 250,
2713
- closable: false
2714
- }, /*#__PURE__*/React.createElement(InputNumber, {
2715
- style: {
2716
- width: '100%'
2717
- },
2718
- defaultValue: 1,
2719
- value: rowsAdd,
2720
- min: 1,
2721
- max: 1000,
2722
- onChange: onChangeRows,
2723
- changeOnWheel: true
2724
- })));
2725
- };
2726
- export default GridEdit;