es-grid-template 1.2.0 → 1.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (67) hide show
  1. package/assets/index.css +679 -0
  2. package/assets/index.scss +1006 -0
  3. package/es/grid-component/ColumnsChoose.d.ts +1 -0
  4. package/es/grid-component/ColumnsChoose.js +63 -28
  5. package/es/grid-component/ColumnsGroup/ColumnsGroup.d.ts +12 -0
  6. package/es/grid-component/ColumnsGroup/ColumnsGroup.js +223 -0
  7. package/es/grid-component/ColumnsGroup/index.d.ts +1 -0
  8. package/es/grid-component/ColumnsGroup/index.js +1 -0
  9. package/es/grid-component/ConvertColumnTable.d.ts +7 -0
  10. package/es/grid-component/ConvertColumnTable.js +143 -0
  11. package/es/grid-component/EditableCell.js +1 -1
  12. package/es/grid-component/GridStyle.js +1 -1
  13. package/es/grid-component/InternalTable.js +148 -248
  14. package/es/grid-component/TableGrid.d.ts +4 -1
  15. package/es/grid-component/TableGrid.js +29 -58
  16. package/es/grid-component/hooks/{useColumns → columns}/index.d.ts +2 -2
  17. package/es/grid-component/hooks/{useColumns → columns}/index.js +20 -16
  18. package/es/grid-component/hooks/content/HeaderContent.d.ts +11 -0
  19. package/es/grid-component/hooks/content/HeaderContent.js +80 -0
  20. package/es/grid-component/hooks/content/TooltipContent.d.ts +13 -0
  21. package/es/grid-component/hooks/content/TooltipContent.js +74 -0
  22. package/es/grid-component/hooks/useColumns.d.ts +16 -0
  23. package/es/grid-component/hooks/useColumns.js +272 -0
  24. package/es/grid-component/hooks/utils.d.ts +46 -1
  25. package/es/grid-component/hooks/utils.js +740 -2
  26. package/es/grid-component/index.js +3 -1
  27. package/es/grid-component/styles.scss +304 -64
  28. package/es/grid-component/table/Grid.d.ts +2 -0
  29. package/es/grid-component/table/Grid.js +1 -5
  30. package/es/grid-component/table/GridEdit.d.ts +4 -1
  31. package/es/grid-component/table/GridEdit.js +690 -281
  32. package/es/grid-component/table/Group.d.ts +13 -0
  33. package/es/grid-component/table/Group.js +154 -0
  34. package/es/grid-component/type.d.ts +38 -1
  35. package/lib/grid-component/ColumnsChoose.d.ts +1 -0
  36. package/lib/grid-component/ColumnsChoose.js +62 -27
  37. package/lib/grid-component/ColumnsGroup/ColumnsGroup.d.ts +12 -0
  38. package/lib/grid-component/ColumnsGroup/ColumnsGroup.js +234 -0
  39. package/lib/grid-component/ColumnsGroup/index.d.ts +1 -0
  40. package/lib/grid-component/ColumnsGroup/index.js +16 -0
  41. package/lib/grid-component/ConvertColumnTable.d.ts +7 -0
  42. package/lib/grid-component/ConvertColumnTable.js +152 -0
  43. package/lib/grid-component/EditableCell.js +1 -1
  44. package/lib/grid-component/GridStyle.js +1 -1
  45. package/lib/grid-component/InternalTable.js +142 -248
  46. package/lib/grid-component/TableGrid.d.ts +4 -1
  47. package/lib/grid-component/TableGrid.js +23 -56
  48. package/lib/grid-component/hooks/{useColumns → columns}/index.d.ts +2 -2
  49. package/lib/grid-component/hooks/{useColumns → columns}/index.js +20 -16
  50. package/lib/grid-component/hooks/content/HeaderContent.d.ts +11 -0
  51. package/lib/grid-component/hooks/content/HeaderContent.js +87 -0
  52. package/lib/grid-component/hooks/content/TooltipContent.d.ts +13 -0
  53. package/lib/grid-component/hooks/content/TooltipContent.js +81 -0
  54. package/lib/grid-component/hooks/useColumns.d.ts +16 -0
  55. package/lib/grid-component/hooks/useColumns.js +283 -0
  56. package/lib/grid-component/hooks/utils.d.ts +46 -1
  57. package/lib/grid-component/hooks/utils.js +763 -5
  58. package/lib/grid-component/index.js +2 -1
  59. package/lib/grid-component/styles.scss +304 -64
  60. package/lib/grid-component/table/Grid.d.ts +2 -0
  61. package/lib/grid-component/table/Grid.js +1 -5
  62. package/lib/grid-component/table/GridEdit.d.ts +4 -1
  63. package/lib/grid-component/table/GridEdit.js +689 -280
  64. package/lib/grid-component/table/Group.d.ts +13 -0
  65. package/lib/grid-component/table/Group.js +163 -0
  66. package/lib/grid-component/type.d.ts +38 -1
  67. package/package.json +106 -105
@@ -5,7 +5,7 @@ import classNames from "classnames";
5
5
  import { Button, Dropdown, Form } from "antd";
6
6
  import { useForm } from 'react-hook-form';
7
7
  import { Toaster } from "react-hot-toast";
8
- import { flatColumns, renderContent } from "../hooks/useColumns";
8
+ import { flatColumns2, getValueCell, renderContent } from "../hooks/columns";
9
9
  import EditableCell from "../EditableCell";
10
10
  import { GridStyle } from "../GridStyle";
11
11
  import { TableContext } from "../useContext";
@@ -13,13 +13,16 @@ import dayjs from "dayjs";
13
13
  import 'dayjs/locale/es';
14
14
  import 'dayjs/locale/vi';
15
15
  import TableGrid from "../TableGrid";
16
- import { getEditType, getRowNumber, isObjEmpty, totalFixedWidth } from "../hooks";
16
+ import { addRows8, findAllChildrenKeys, findItemByKey, flattenArray, flattenData, getDefaultValue, getEditType, getFirstSelectCell, getLastSelectCell, getRowNumber, getRowsPasteIndex, isObjEmpty, newGuid, totalFixedWidth, updateArrayByKey } from "../hooks";
17
17
  import Message from "../../Message/Message";
18
18
 
19
19
  // import Command from "../Command";
20
20
 
21
21
  import { Toolbar } from "rc-master-ui";
22
22
  import classnames from "classnames";
23
+ import useMergedState from "rc-util/es/hooks/useMergedState";
24
+ // import useLazyKVMap from "rc-master-ui/es/table/hooks/useLazyKVMap";
25
+
23
26
  dayjs.extend(customParseFormat);
24
27
  const toast = 'top-right';
25
28
  const GridEdit = props => {
@@ -34,24 +37,37 @@ const GridEdit = props => {
34
37
  selectionSettings,
35
38
  height,
36
39
  format,
37
- // onDataChange,
38
40
  triggerChangeData,
41
+ triggerChangeColumns,
39
42
  onCellPaste,
40
43
  onCellChange,
44
+ triggerPaste,
41
45
  style,
42
46
  getRowKey,
43
47
  className,
44
48
  toolbarItems,
49
+ defaultValue,
50
+ expandable,
51
+ onCellClick,
45
52
  ...rest
46
53
  } = props;
47
-
48
- // const forceUpdate = useForceUpdate();
49
- // const [updateKey, setUpdateKey] = useState(0);
50
-
54
+ const {
55
+ mode,
56
+ type,
57
+ // checkboxOnly,
58
+ // hideSelectAll,
59
+ columnWidth
60
+ // selectedRowKeys,
61
+ // defaultSelectedRowKeys
62
+ } = selectionSettings || {};
51
63
  const isSelecting = useRef(false);
52
64
  const startCell = useRef(null);
65
+ const childrenColumnName = 'children';
53
66
  const isSelectingRow = useRef(false);
54
67
  const rowStart = useRef(null);
68
+
69
+ // const [getRecordByKey] = useLazyKVMap(dataSource, childrenColumnName, getRowKey);
70
+
55
71
  const itemsAdd = [{
56
72
  key: '10',
57
73
  label: '10 rows'
@@ -65,19 +81,168 @@ const GridEdit = props => {
65
81
  const [form] = Form.useForm();
66
82
  const [editingKey, setEditingKey] = useState('');
67
83
  const [selectedCells, setSelectedCells] = useState(new Set());
84
+ const [pasteCells, setPasteCells] = useState(new Set());
85
+ const [isSelectDragging, setSelectIsDragging] = useState(false);
86
+ const [isPasteDragging, setIsPasteDragging] = useState(false);
87
+
88
+ // const [showDraggingPoint, setShowDraggingPoint] = useState(false);
89
+
68
90
  const [rowsSelected, setRowsSelected] = useState(new Set());
69
- const [selectedCell, setSelectedCell] = useState(null);
70
- const handleAdd = item => {
71
- console.log(item);
91
+ const [startSelectedCells, setStartSelectedCell] = useState(null);
92
+ const [innerExpandedKeys, setInnerExpandedKeys] = React.useState(() => {
93
+ // if (defaultExpandedRowKeys) {
94
+ // return defaultExpandedRowKeys;
95
+ // }
96
+ // if (defaultExpandAllRows) {
97
+ return findAllChildrenKeys(dataSource, getRowKey, childrenColumnName) ?? [];
98
+ // }
99
+ // return [];
100
+ });
101
+ const mergedExpandedKeys = React.useMemo(() => new Set(innerExpandedKeys || []), [innerExpandedKeys]);
102
+ const [mergedSelectedKeys, setMergedSelectedKeys] = useMergedState([], {
103
+ value: []
104
+ });
105
+ const rowsFocus = React.useMemo(() => {
106
+ return [...new Set(Array.from(selectedCells).map(item => parseInt(item.split('-')[0])))] ?? [];
107
+ }, [selectedCells]);
108
+ const onTriggerExpand = React.useCallback(record => {
109
+ const key = getRowKey(record, dataSource.indexOf(record));
110
+ let newExpandedKeys;
111
+ const hasKey = mergedExpandedKeys.has(key);
112
+ if (hasKey) {
113
+ mergedExpandedKeys.delete(key);
114
+ newExpandedKeys = [...mergedExpandedKeys];
115
+ } else {
116
+ newExpandedKeys = [...mergedExpandedKeys, key];
117
+ }
118
+ setInnerExpandedKeys(newExpandedKeys);
119
+ }, [getRowKey, mergedExpandedKeys, dataSource]);
120
+ const handleAddSingle = item => {
121
+ const defaultRowValue = getDefaultValue(defaultValue);
122
+ const rowId = defaultRowValue && defaultRowValue.id ? defaultRowValue.id : newGuid();
72
123
  if (item.onClick) {
73
- console.log('cccccccccccccccc');
124
+ item.onClick({
125
+ toolbar: item
126
+ });
74
127
  } else {
75
- console.log('bbbbbbbbbbbbb');
128
+ const newData = [...dataSource, defaultValue ? {
129
+ ...defaultRowValue,
130
+ id: undefined,
131
+ rowId
132
+ } : {
133
+ id: undefined,
134
+ rowId
135
+ }];
136
+ triggerChangeData?.(newData, 'Add');
137
+ }
138
+ };
139
+ const handleAddMulti = (item, e) => {
140
+ if (item.onClick) {
141
+ item.onClick({
142
+ toolbar: item
143
+ });
144
+ } else {
145
+ const defaultRowValue = getDefaultValue(defaultValue);
146
+ const newRows = Array.from({
147
+ length: Number(e.key)
148
+ }).map(() => defaultRowValue ? {
149
+ ...defaultRowValue,
150
+ id: undefined,
151
+ rowId: newGuid()
152
+ } : {
153
+ id: undefined,
154
+ rowId: newGuid()
155
+ });
156
+ const newData = dataSource.concat(newRows);
157
+ triggerChangeData?.(newData, 'Add');
158
+ }
159
+ };
160
+ const handleDuplicate = () => {
161
+ console.log('rowsFocus', rowsFocus);
162
+ };
163
+ const handleInsertBefore = item => {
164
+ const defaultRowValue = getDefaultValue(defaultValue);
165
+ const rowId = defaultRowValue && defaultRowValue.id ? defaultRowValue.id : newGuid();
166
+ const record = flattenData(childrenColumnName, dataSource)[rowsFocus[rowsFocus.length - 1]];
167
+ if (item.onClick) {
168
+ item.onClick({
169
+ toolbar: item
170
+ });
171
+ } else {
172
+ if (!record.parentId) {
173
+ // Cập nhật data mới
174
+ const newData = [...dataSource];
175
+ const index = newData.findIndex(obj => obj[rowKey] === record[rowKey]);
176
+ newData.splice(index, 0, {
177
+ ...defaultRowValue,
178
+ rowId,
179
+ parentId: null
180
+ });
181
+ triggerChangeData?.(newData, 'INSERT_BEFORE');
182
+ } else {
183
+ const newData = [...dataSource];
184
+ const parent = findItemByKey(newData, rowKey, record.parentId);
185
+
186
+ // Cập nhật childData mới
187
+ const childData = parent?.children ? [...parent.children] : [];
188
+ const index = childData.findIndex(obj => obj[rowKey] === record[rowKey]);
189
+ childData.splice(index, 0, {
190
+ ...defaultRowValue,
191
+ rowId,
192
+ parentId: record.parentId
193
+ });
194
+ const newRowData = {
195
+ ...parent,
196
+ children: childData
197
+ };
198
+ const newDataSource = updateArrayByKey(newData, newRowData, rowKey);
199
+ triggerChangeData?.(newDataSource, 'INSERT_BEFORE');
200
+ }
201
+ }
202
+ };
203
+ const handleInsertAfter = item => {
204
+ const defaultRowValue = getDefaultValue(defaultValue);
205
+ const rowId = defaultRowValue && defaultRowValue.id ? defaultRowValue.id : newGuid();
206
+ const record = flattenData(childrenColumnName, dataSource)[rowsFocus[rowsFocus.length - 1]];
207
+
208
+ // const record = getRecordByKey()
209
+
210
+ if (item.onClick) {
211
+ item.onClick({
212
+ toolbar: item
213
+ });
214
+ } else {
215
+ if (!record.parentId) {
216
+ // Cập nhật data mới
217
+ const newData = [...dataSource];
218
+ const index = newData.findIndex(obj => obj[rowKey] === record[rowKey]);
219
+ newData.splice(index + 1, 0, {
220
+ ...defaultRowValue,
221
+ rowId,
222
+ parentId: null
223
+ });
224
+ triggerChangeData?.(newData, 'INSERT_AFTER');
225
+ } else {
226
+ const newData = [...dataSource];
227
+ const parent = findItemByKey(newData, rowKey, record.parentId);
228
+
229
+ // Cập nhật childData mới
230
+ const childData = parent?.children ? [...parent.children] : [];
231
+ const index = childData.findIndex(obj => obj[rowKey] === record[rowKey]);
232
+ childData.splice(index + 1, 0, {
233
+ ...defaultRowValue,
234
+ rowId,
235
+ parentId: record.parentId
236
+ });
237
+ const newRowData = {
238
+ ...parent,
239
+ children: childData
240
+ };
241
+ const newDataSource = updateArrayByKey(newData, newRowData, rowKey);
242
+ triggerChangeData?.(newDataSource, 'INSERT_BEFORE');
243
+ }
76
244
  }
77
245
  };
78
- const handleDuplicate = () => {};
79
- const handleInsertBefore = () => {};
80
- const handleInsertAfter = () => {};
81
246
  const handleDeleteAll = () => {};
82
247
  const toolbarItemsBottom = useMemo(() => {
83
248
  return toolbarItems?.filter(it => it.position === 'Bottom').map(item => {
@@ -85,51 +250,55 @@ const GridEdit = props => {
85
250
  ...item,
86
251
  template: () => {
87
252
  return /*#__PURE__*/React.createElement(Fragment, null, item.key === 'ADD' && /*#__PURE__*/React.createElement("div", {
88
- className: classnames(`be-toolbar-item ${item.className}`)
253
+ className: classnames(`be-toolbar-item`, item?.className)
89
254
  }, /*#__PURE__*/React.createElement(Dropdown.Button, {
255
+ className: 'toolbar-button',
90
256
  menu: {
91
257
  items: itemsAdd,
92
- onClick: () => handleAdd(item)
258
+ onClick: e => handleAddMulti(item, e)
93
259
  }
94
- }, item.title ? t ? t(item.title) : item.title : t ? t('Add item') : 'Add item')), item.key === 'DUPLICATE' && item.visible !== false && editingKey && /*#__PURE__*/React.createElement("div", {
95
- className: classnames(`be-toolbar-item ${item.className}`)
260
+ }, /*#__PURE__*/React.createElement("span", {
261
+ onClick: () => handleAddSingle(item)
262
+ }, item.title ? t ? t(item.title) : item.title : t ? t('Add item') : 'Add item'))), item.key === 'DUPLICATE' && item.visible !== false && rowsFocus.length > 0 && /*#__PURE__*/React.createElement("div", {
263
+ className: classnames(`be-toolbar-item`, item?.className)
96
264
  }, /*#__PURE__*/React.createElement(Button, {
97
265
  color: "green",
98
266
  variant: 'outlined',
99
267
  onClick: handleDuplicate,
100
- className: "d-flex be-button"
101
- }, item.title ? t ? t(item.title) : item.title : t ? t('Duplicate') : 'Duplicate')), item.key === 'INSERT_BEFORE' && item.visible !== false && editingKey && /*#__PURE__*/React.createElement("div", {
102
- className: classnames(`be-toolbar-item ${item.className}`)
268
+ className: "d-flex toolbar-button"
269
+ }, item.title ? t ? t(item.title) : item.title : t ? t('Duplicate') : 'Duplicate')), item.key === 'INSERT_BEFORE' && item.visible !== false && rowsFocus.length > 0 && /*#__PURE__*/React.createElement("div", {
270
+ className: classnames(`be-toolbar-item`, item?.className)
103
271
  }, /*#__PURE__*/React.createElement(Button, {
104
272
  color: "green",
105
273
  variant: 'outlined',
106
- onClick: handleInsertBefore,
107
- className: "d-flex be-button"
108
- }, item.title ? t ? t(item.title) : item.title : t ? t('Insert item before') : 'Insert item before')), item.key === 'INSERT_AFTER' && item.visible !== false && editingKey && /*#__PURE__*/React.createElement("div", {
109
- className: classnames(`be-toolbar-item ${item.className}`)
274
+ onClick: () => handleInsertBefore(item),
275
+ className: "d-flex toolbar-button"
276
+ }, item.title ? t ? t(item.title) : item.title : t ? t('Insert item before') : 'Insert item before')), item.key === 'INSERT_AFTER' && item.visible !== false && rowsFocus.length > 0 && /*#__PURE__*/React.createElement("div", {
277
+ className: classnames(`be-toolbar-item`, item?.className)
110
278
  }, /*#__PURE__*/React.createElement(Button, {
111
279
  color: "green",
112
280
  variant: 'outlined',
113
- onClick: handleInsertAfter,
114
- className: "d-flex be-button"
281
+ onClick: () => handleInsertAfter(item),
282
+ className: "d-flex toolbar-button"
115
283
  }, item.title ? t ? t(item.title) : item.title : t ? t('Insert item after') : 'Insert item after')), item.key === 'DELETE' && item.visible !== false && /*#__PURE__*/React.createElement("div", {
116
- className: classnames(`be-toolbar-item ${item.className}`)
284
+ className: classnames(`be-toolbar-item`, item?.className)
117
285
  }, /*#__PURE__*/React.createElement(Button, {
118
286
  color: "primary",
119
287
  variant: 'outlined',
120
288
  onClick: handleDeleteAll,
121
- className: "d-flex be-button"
289
+ className: "d-flex toolbar-button"
122
290
  }, item.title ? t ? t(item.title) : item.title : t ? t('Delete all item') : 'Delete all item')));
123
291
  }
124
292
  };
125
293
  });
126
- }, [toolbarItems]);
294
+ }, [handleAddMulti, handleAddSingle, itemsAdd, rowsFocus.length, t, toolbarItems]);
127
295
  const {
128
296
  control,
129
297
  handleSubmit,
130
298
  setValue,
131
299
  trigger,
132
- getValues
300
+ getValues,
301
+ reset
133
302
  // formState: { errors }
134
303
  } = useForm({
135
304
  mode: 'onChange'
@@ -141,13 +310,16 @@ const GridEdit = props => {
141
310
  const isEditing = record => record[rowKey] === editingKey;
142
311
  useEffect(() => {
143
312
  const handleClickOutside = event => {
144
- const tableBodies = document.getElementsByClassName("ui-rc-table-tbody");
145
313
  const element = event.target;
314
+ const tableBodies = document.getElementsByClassName("ui-rc-table-tbody");
146
315
  const container = document.querySelector(".be-popup-container");
147
316
  // const containerHidden = document.querySelector(".be-popup-container.ant-picker-dropdown-hidden")
148
317
 
318
+ // const toolbarContainer = document.getElementsByClassName("ui-rc-toolbar");
319
+ const itemContainer = document.querySelector(".ui-rc-toolbar-selection-overflow-item");
149
320
  const isInsideContainer = element.closest(".be-popup-container") && container;
150
- if (isInsideContainer) {
321
+ const isInsideToolbar = element.closest(".ui-rc-toolbar-selection-overflow-item") && itemContainer;
322
+ if (isInsideContainer || isInsideToolbar) {
151
323
  return;
152
324
  }
153
325
  if (tableBodies.length > 0) {
@@ -167,36 +339,170 @@ const GridEdit = props => {
167
339
  document.removeEventListener("click", handleClickOutside);
168
340
  };
169
341
  }, []);
170
- const handleMouseDown = (row, col, e) => {
342
+ const handleMouseDown = (record, row, col, e) => {
171
343
  if (e.button === 2) {
172
344
  e.stopPropagation();
173
345
  return;
174
346
  }
175
- setSelectedCell({
176
- row,
177
- col
178
- });
347
+ setSelectIsDragging(true);
179
348
  isSelecting.current = true;
180
349
  startCell.current = {
181
350
  row,
182
351
  col
183
352
  };
184
- setSelectedCells(new Set([`${row}-${col}`]));
185
- setRowsSelected(new Set());
353
+ if (!isPasteDragging) {
354
+ setStartSelectedCell({
355
+ row,
356
+ col
357
+ });
358
+ setSelectedCells(new Set([`${row}-${col}`]));
359
+ setRowsSelected(new Set());
360
+ // setShowDraggingPoint(true)
361
+ }
362
+
363
+ // if (record[rowKey] !== editingKey && (editingKey !== '')) {
364
+ // setEditingKey('')
365
+ // }
366
+ };
367
+ const handlePointEnter = e => {
368
+ if (e.button === 2) {
369
+ e.stopPropagation();
370
+ return;
371
+ }
372
+ setIsPasteDragging(true);
373
+ };
374
+ const handlePointLeave = () => {
375
+ if (isPasteDragging && !isSelectDragging) {
376
+ setIsPasteDragging(false);
377
+ }
378
+ };
379
+ const handleMouseUp = () => {
380
+ isSelecting.current = false;
381
+ startCell.current = null;
382
+ isSelectingRow.current = false;
383
+ rowStart.current = null;
384
+ setIsPasteDragging(false);
385
+ setSelectIsDragging(false);
386
+ if (pasteCells.size > 0) {
387
+ console.log('');
388
+ const mergedSet = new Set([...selectedCells, ...pasteCells]);
389
+ setSelectedCells(mergedSet);
390
+ setPasteCells(new Set());
391
+ const selectedArray = Array.from(selectedCells).map(key => {
392
+ const [row, col] = key.split("-").map(Number);
393
+ // @ts-ignore
394
+ const columnKey = columns[col].field;
395
+
396
+ // @ts-ignore
397
+ return {
398
+ row,
399
+ col,
400
+ value: flattenData(childrenColumnName, dataSource)[row][columnKey]
401
+ };
402
+ // return { row, col, value: '' };
403
+ });
404
+
405
+ // Xác định min/max row và col để sắp xếp dữ liệu
406
+ const minRow = Math.min(...selectedArray.map(cell => cell.row));
407
+ const maxRow = Math.max(...selectedArray.map(cell => cell.row));
408
+ const minCol = Math.min(...selectedArray.map(cell => cell.col));
409
+ const maxCol = Math.max(...selectedArray.map(cell => cell.col));
410
+
411
+ // Tạo dữ liệu dạng bảng (mảng 2D)
412
+ const table = Array.from({
413
+ length: maxRow - minRow + 1
414
+ }, () => Array(maxCol - minCol + 1).fill(""));
415
+
416
+ // Gán giá trị vào bảng
417
+ selectedArray.forEach(({
418
+ row,
419
+ col,
420
+ value
421
+ }) => {
422
+ table[row - minRow][col - minCol] = value;
423
+ });
424
+ const aaaa = addRows8(table, getRowsPasteIndex(pasteCells).length);
425
+ const record = flattenData(childrenColumnName, dataSource)[getFirstSelectCell(pasteCells).row];
426
+ if (!record.parentId) {
427
+ // Cập nhật data mới
428
+ const newData = [...dataSource];
429
+
430
+ // Lấy vị trí bắt đầu
431
+ // const { row: startRow, col: startCol } = selectedCell;
432
+ const startRow = getFirstSelectCell(pasteCells).row;
433
+ const startCol = getFirstSelectCell(selectedCells).col;
434
+ const pastedRows = [];
435
+ const pastedColumns = new Set();
436
+ aaaa.addedRows.forEach((rowValues, rowIndex) => {
437
+ const targetRow = startRow + rowIndex;
438
+
439
+ // Nếu vượt quá số dòng hiện có, thêm dòng mới
440
+ if (targetRow >= newData.length) {
441
+ // @ts-ignore
442
+ newData.push({
443
+ id: undefined,
444
+ rowId: newGuid()
445
+ });
446
+ }
447
+ rowValues.forEach((cellValue, colIndex) => {
448
+ const targetCol = startCol + colIndex;
449
+ if (targetCol >= columns.length) {
450
+ // Không vượt quá số cột
451
+ return;
452
+ }
453
+
454
+ // @ts-ignore
455
+ const columnKey = columns[targetCol].field;
456
+
457
+ // @ts-ignore
458
+ newData[targetRow] = {
459
+ ...newData[targetRow],
460
+ [columnKey]: typeof cellValue === 'string' ? cellValue.trim() : cellValue
461
+ };
462
+ pastedColumns.add(columnKey);
463
+ });
464
+
465
+ // Lưu dòng được paste
466
+ pastedRows.push(newData[targetRow]);
467
+ });
468
+ const pastedColumnsArray = Array.from(pastedColumns) ?? [];
469
+ triggerPaste?.(pastedRows, pastedColumnsArray, newData);
470
+ }
471
+ }
186
472
  };
187
473
  const handleMouseEnter = (row, col) => {
188
- if (!isSelecting.current || !startCell.current) return;
474
+ if (!isSelecting.current || !startCell.current) {
475
+ return;
476
+ }
189
477
  const {
190
478
  row: startRow,
191
479
  col: startCol
192
480
  } = startCell.current;
193
- const newSelectedCells = new Set();
194
- for (let r = Math.min(startRow, row); r <= Math.max(startRow, row); r++) {
195
- for (let c = Math.min(startCol, col); c <= Math.max(startCol, col); c++) {
196
- newSelectedCells.add(`${r}-${c}`);
481
+ if (!isPasteDragging) {
482
+ const newSelectedCells = new Set();
483
+ for (let r = Math.min(startRow, row); r <= Math.max(startRow, row); r++) {
484
+ for (let c = Math.min(startCol, col); c <= Math.max(startCol, col); c++) {
485
+ newSelectedCells.add(`${r}-${c}`);
486
+ }
487
+ }
488
+ setSelectedCells(newSelectedCells);
489
+ } else {
490
+ const newSelectedCells = new Set();
491
+ for (let r = Math.min(startRow, row); r <= Math.max(startRow, row); r++) {
492
+ for (let c = Math.min(startCol, col); c <= Math.max(startCol, col); c++) {
493
+ newSelectedCells.add(`${r}-${c}`);
494
+ }
495
+ }
496
+ const colStart = getFirstSelectCell(selectedCells).col;
497
+ const colEnd = getLastSelectCell(selectedCells).col;
498
+ const newPasteCells = new Set();
499
+ for (let r = Math.min(startRow, row) + 1; r <= Math.max(startRow, row); r++) {
500
+ for (let c = Math.min(colStart, col); c <= Math.max(colStart, colEnd); c++) {
501
+ newPasteCells.add(`${r}-${c}`);
502
+ }
197
503
  }
504
+ setPasteCells(newPasteCells);
198
505
  }
199
- setSelectedCells(newSelectedCells);
200
506
  };
201
507
  const handleClickRowHeader = (row, col) => {
202
508
  const newSelectedCells = new Set();
@@ -265,23 +571,46 @@ const GridEdit = props => {
265
571
  setRowsSelected(newSelectedRows);
266
572
  setSelectedCells(newSelectedCells);
267
573
  };
268
- const handleMouseUp = () => {
269
- isSelecting.current = false;
270
- startCell.current = null;
271
- isSelectingRow.current = false;
272
- rowStart.current = null;
574
+ const handleCellClick = (indexRow, record, column) => {
575
+ const cellClickCallback = newOptions => {
576
+ if (newOptions) {
577
+ const newElem = {
578
+ ...column,
579
+ editSelectSettings: {
580
+ ...(column?.editSelectSettings ? {
581
+ ...column?.editSelectSettings
582
+ } : {}),
583
+ options: newOptions
584
+ }
585
+ };
586
+ const rrr = updateArrayByKey([...columns], newElem, 'field');
587
+ triggerChangeColumns?.(rrr, 'click');
588
+ }
589
+ };
590
+ if (onCellClick) {
591
+ onCellClick({
592
+ index: indexRow,
593
+ rowId: record.rowId,
594
+ cellValue: record[record.field],
595
+ type: "Editing",
596
+ field: column.field,
597
+ rowData: record
598
+ }, cellClickCallback);
599
+ }
273
600
  };
274
601
  const handleCopy = e => {
275
602
  const selectedArray = Array.from(selectedCells).map(key => {
276
603
  const [row, col] = key.split("-").map(Number);
277
604
  // @ts-ignore
278
- const columnKey = columns[col].dataIndex;
605
+ const columnKey = columns[col].field;
606
+
279
607
  // @ts-ignore
280
608
  return {
281
609
  row,
282
610
  col,
283
- value: dataSource[row][columnKey]
611
+ value: flattenData(childrenColumnName, dataSource)[row][columnKey]
284
612
  };
613
+ // return { row, col, value: '' };
285
614
  });
286
615
 
287
616
  // Xác định min/max row và col để sắp xếp dữ liệu
@@ -312,133 +641,131 @@ const GridEdit = props => {
312
641
  e.clipboardData.setData("text/plain", copyText);
313
642
  Message(t ? t('CopySuccessful') : 'Copy Successful');
314
643
  };
315
- const handlePaste = (e, indexCol, indexRow) => {
644
+ const handlePaste = (record, indexCol, rowNumber, e) => {
316
645
  // const clipboard: any = (e.clipboardData || (window && window?.Clipboard)).getData("text")
317
646
  const pasteData = e.clipboardData.getData("text/plain").trim();
318
647
 
319
648
  // Chuyển đổi dữ liệu từ clipboard thành mảng
320
649
  const rows = pasteData.split("\n").map(row => row.replace(/\r/g, "").split("\t"));
650
+ if (!record.parentId) {
651
+ // Cập nhật data mới
652
+ const newData = [...dataSource];
321
653
 
322
- // Lấy vị trí bắt đầu
323
- // const { row: startRow, col: startCol } = selectedCell;
324
- const startRow = indexRow;
325
- const startCol = indexCol;
654
+ // @ts-ignore
655
+ const indexRows = newData.findIndex(it => it[rowKey] === record[rowKey]);
326
656
 
327
- // Cập nhật data mới
328
- const newData = [...dataSource];
329
- const pastedRows = [];
330
- const pastedColumns = new Set();
331
- rows.forEach((rowValues, rowIndex) => {
332
- const targetRow = startRow + rowIndex;
657
+ // Lấy vị trí bắt đầu
658
+ // const { row: startRow, col: startCol } = selectedCell;
659
+ const startRow = indexRows;
660
+ const startCol = indexCol;
333
661
 
334
- // Nếu vượt quá số dòng hiện có, thêm dòng mới
335
- if (targetRow >= newData.length) {
336
- // @ts-ignore
337
- // newData.push({ id: newGuid()});
338
- newData.push({
339
- id: newGuid()
662
+ // const flattData = flattenArray(newData);
663
+
664
+ const pastedRows = [];
665
+ const pastedColumns = new Set();
666
+ rows.forEach((rowValues, rowIndex) => {
667
+ const targetRow = startRow + rowIndex;
668
+
669
+ // Nếu vượt quá số dòng hiện có, thêm dòng mới
670
+ if (targetRow >= newData.length) {
671
+ // @ts-ignore
672
+ // newData.push({ id: newGuid()});
673
+ newData.push({
674
+ id: undefined,
675
+ rowId: newGuid()
676
+ });
677
+ }
678
+ rowValues.forEach((cellValue, colIndex) => {
679
+ const targetCol = startCol + colIndex;
680
+ if (targetCol >= columns.length) {
681
+ // Không vượt quá số cột
682
+ return;
683
+ }
684
+
685
+ // @ts-ignore
686
+ const columnKey = columns[targetCol].field;
687
+
688
+ // @ts-ignore
689
+ newData[targetRow] = {
690
+ ...newData[targetRow],
691
+ [columnKey]: cellValue.trim()
692
+ };
693
+ pastedColumns.add(columnKey);
340
694
  });
341
- }
342
- rowValues.forEach((cellValue, colIndex) => {
343
- const targetCol = startCol + colIndex;
344
- if (targetCol >= columns.length) return; // Không vượt quá số cột
345
695
 
346
- // @ts-ignore
347
- const columnKey = columns[targetCol].dataIndex;
348
- // @ts-ignore
349
- newData[targetRow] = {
350
- ...newData[targetRow],
351
- [columnKey]: cellValue.trim()
352
- };
353
- pastedColumns.add(columnKey);
696
+ // Lưu dòng được paste
697
+ pastedRows.push(newData[targetRow]);
354
698
  });
699
+ const pastedColumnsArray = Array.from(pastedColumns) ?? [];
700
+ triggerPaste?.(pastedRows, pastedColumnsArray, newData);
701
+ } else {
702
+ // Cập nhật data mới
703
+ const newData = [...dataSource];
704
+ const parent = findItemByKey(newData, rowKey, record.parentId);
355
705
 
356
- // Lưu dòng được paste
357
- pastedRows.push(newData[targetRow]);
358
- });
359
- const pastedColumnsArray = Array.from(pastedColumns) ?? [];
360
- console.log(pastedColumnsArray);
361
- console.log(pastedRows);
706
+ // Cập nhật childData mới
707
+ const childData = parent?.children ? [...parent.children] : [];
362
708
 
363
- // // trigger DataChange + trigger paste
709
+ // Lấy vị trí bắt đầu
710
+ // const { row: startRow, col: startCol } = selectedCell;
711
+ const startRow = childData.findIndex(it => it[rowKey] === record[rowKey]);
712
+ const startCol = indexCol;
713
+ const pastedRows = [];
714
+ const pastedColumns = new Set();
715
+ rows.forEach((rowValues, rowIndex) => {
716
+ const targetRow = startRow + rowIndex;
364
717
 
365
- // const handlePasteCallback = (callbackData: RecordType[]) => {
366
- //
367
- // const newDataUpdate = updateData(dataSource, callbackData, rowKey as any)
368
- //
369
- // // setData(newDataUpdate)
370
- // // onDataChange?.(newData)
371
- // onCellPaste?.dataChange?.(newDataUpdate)
372
- // }
373
- //
374
- //
375
- // if (onCellPaste && onCellPaste.onPasted) {
376
- //
377
- // if (onCellPaste.onPasted.length > 1) {
378
- // onCellPaste.onPasted({
379
- // pasteData: pastedRows,
380
- // type: 'onPaste',
381
- // data: dataSource,
382
- // pastedColumns: pastedColumnsArray as string[]
383
- // }, handlePasteCallback)
384
- //
385
- // } else {
386
- // onCellPaste.onPasted({
387
- // pasteData: pastedRows,
388
- // type: 'onPaste',
389
- // data: dataSource,
390
- // pastedColumns: ['']
391
- // }, handlePasteCallback)
392
- //
393
- // onCellPaste.dataChange?.(newData)
394
- //
395
- // // setData(newData);
396
- // // onDataChange?.(newData)
397
- // }
398
- //
399
- // }
718
+ // Nếu vượt quá số dòng hiện có, thêm dòng mới
719
+ if (targetRow >= childData.length) {
720
+ childData.push({
721
+ id: undefined,
722
+ rowId: newGuid(),
723
+ parentId: parent[rowKey ?? 'id']
724
+ });
725
+ }
726
+ rowValues.forEach((cellValue, colIndex) => {
727
+ const targetCol = startCol + colIndex;
728
+ if (targetCol >= columns.length) {
729
+ // Không vượt quá số cột
730
+ return;
731
+ }
732
+
733
+ // @ts-ignore
734
+ const columnKey = columns[targetCol].field;
735
+
736
+ // @ts-ignore
737
+ childData[targetRow] = {
738
+ ...childData[targetRow],
739
+ [columnKey]: cellValue.trim()
740
+ };
741
+ pastedColumns.add(columnKey);
742
+ });
743
+
744
+ // Lưu dòng được paste
745
+ pastedRows.push(childData[targetRow]);
746
+ });
747
+ const pastedColumnsArray = Array.from(pastedColumns) ?? [];
748
+ const newRowData = {
749
+ ...parent,
750
+ children: childData
751
+ };
752
+ const newDataSource = updateArrayByKey(newData, newRowData, rowKey);
753
+ triggerPaste?.(pastedRows, pastedColumnsArray, newDataSource);
754
+ }
400
755
  };
401
756
  const onSubmit = formData => {
402
- console.log('onSubmit', formData);
403
757
  try {
404
758
  // const record = (await form.validateFields()) as RecordType;
405
759
  const row = {
406
760
  ...formData
407
761
  };
408
- // const rowData = { ...record };
409
-
410
- // columns.forEach(column => {
411
- //
412
- // // @ts-ignore
413
- // if (column.editType === 'date' && rowData[column.dataIndex]) {
414
- // // @ts-ignore
415
- // rowData[column.dataIndex] = !isEmpty(record[column.dataIndex]) ? moment(row[column.dataIndex]).format() : null
416
- // }
417
- // });
418
-
419
762
  const newData = [...dataSource];
763
+
420
764
  // @ts-ignore
421
765
  const index = newData.findIndex(item => formData[rowKey] === item[rowKey]);
422
-
423
- // setIsManualUpdate(true);
424
-
766
+ const rs = updateArrayByKey(dataSource, row, rowKey);
425
767
  if (index > -1) {
426
- const item = newData[index];
427
- newData.splice(index, 1, {
428
- ...item,
429
- ...row
430
- });
431
- triggerChangeData?.(newData, 'onChange');
432
-
433
- // trigger DataChange
434
- // setData(newData);
435
- // onDataChange?.(newData)
436
- } else {
437
- newData.push(row);
438
- // trigger DataChange
439
-
440
- // setData(newData);
441
- // onDataChange?.(newData)
768
+ triggerChangeData?.(rs, 'onChange');
442
769
  }
443
770
  } catch (errInfo) {
444
771
  console.log('Validate Failed:', errInfo);
@@ -447,29 +774,18 @@ const GridEdit = props => {
447
774
  const handleCellChange = args => {
448
775
  const {
449
776
  record,
450
- type,
777
+ type: changeType,
451
778
  newState,
452
779
  prevState,
453
780
  option,
454
781
  field
455
782
  } = args;
456
783
 
457
- // console.log('newState', newState)
458
- //
459
- // console.log('getValues()', getValues())
460
-
461
784
  // const newRecord = getValues()
462
785
 
463
- if (type === 'enter') {
464
- console.log('aaaaaa enter');
465
- }
466
- if (type === 'blur') {
467
- // onCellChange
468
-
786
+ if (changeType === 'enter') {}
787
+ if (changeType === 'blur') {
469
788
  const handleChangeCallback = callbackData => {
470
- // const newDataUpdate = updateData(data, callbackData, rowKey as any)
471
-
472
- console.log('callbackData', callbackData);
473
789
  const callbackRecord = callbackData;
474
790
  Object.entries(callbackRecord).forEach(([name, value]) => {
475
791
  setValue(name, value);
@@ -478,7 +794,6 @@ const GridEdit = props => {
478
794
  };
479
795
  if (onCellChange) {
480
796
  if (onCellChange.length > 1) {
481
- console.log('onCellChange Callback');
482
797
  onCellChange({
483
798
  field,
484
799
  indexCol: 1,
@@ -492,7 +807,6 @@ const GridEdit = props => {
492
807
  sumValue: []
493
808
  }, handleChangeCallback);
494
809
  } else {
495
- console.log('onCellChange');
496
810
  onCellChange({
497
811
  field,
498
812
  indexCol: 1,
@@ -508,16 +822,15 @@ const GridEdit = props => {
508
822
  onSubmit(record);
509
823
  }
510
824
  }
511
- console.log('aaaaaa blur');
512
825
  }
513
- if (prevState && newState && prevState !== newState && type === 'enter') {
514
- console.log('enter');
826
+ if (prevState && newState && prevState !== newState && changeType === 'enter') {
515
827
  onSubmit(record);
516
828
  }
517
829
  };
518
830
  const handleEdit = (record, col, editType, e) => {
519
831
  // @ts-ignore
520
832
  setEditingKey(record[rowKey]);
833
+ reset();
521
834
 
522
835
  // const formattedRecord = { ...record };
523
836
 
@@ -547,19 +860,20 @@ const GridEdit = props => {
547
860
  // });
548
861
 
549
862
  if (e.key === 'Enter' || editType === 'date' || e.type === 'dblclick') {} else {
550
- setValue(col.dataIndex, e.key);
863
+ setValue(col.dataIndex, editType === 'numeric' ? !isNaN(Number(e.key)) ? Number(e.key) : '' : e.key);
864
+ // setValue(col.dataIndex, e.key)
551
865
  }
552
866
  if (editType === 'select') {
553
867
  // setSearchValue(e.key)
554
868
  // setOpen(true)
555
869
  }
556
- if (selectedCell?.row !== undefined && selectedCell?.col !== undefined) {
870
+ if (startSelectedCells?.row !== undefined && startSelectedCells?.col !== undefined) {
557
871
  setTimeout(() => {
558
872
  // const input = document.querySelector(`.ui-rc-table-row[data-row-key="${selectedCell.row}"] .cell-editing[data-col-index="${selectedCell.col}"] input`) as HTMLInputElement;
559
- const input = document.querySelector(`.ui-rc-table-row .cell-editing[data-row-index="${selectedCell.row}"].cell-editing[data-col-index="${selectedCell.col}"] input`);
873
+ const input = document.querySelector(`.ui-rc-table-row .cell-editing[data-row-index="${startSelectedCells.row}"].cell-editing[data-col-index="${startSelectedCells.col}"] input`);
560
874
  // const input = document.getElementById(`col${selectedCell.col}-record${selectedCell.row}`) as HTMLInputElement;
561
875
 
562
- const select = document.querySelector(`div.cell-editing[tabindex="${selectedCell?.col}"] .ant-select-selection-search input`);
876
+ const select = document.querySelector(`div.cell-editing[tabindex="${startSelectedCells?.col}"] .ant-select-selection-search input`);
563
877
  if (input) {
564
878
  input.focus();
565
879
  }
@@ -572,18 +886,21 @@ const GridEdit = props => {
572
886
  }, 0);
573
887
  }
574
888
  };
575
- useEffect(() => {
576
- const tableBody = document.querySelector(".ui-rc-table-tbody");
577
- const tableHeader = document.querySelector(".ui-rc-table-header");
578
- if (tableBody && tableHeader) {
579
- tableBody.addEventListener("scroll", () => {
580
- tableHeader.scrollLeft = tableBody.scrollLeft;
581
- });
582
- }
583
- }, []);
584
- const scrollToCell = (rowIndex, colIndex, cell, type) => {
889
+
890
+ // useEffect(() => {
891
+ // const tableBody = document.querySelector(".ui-rc-table-tbody");
892
+ // const tableHeader = document.querySelector(".ui-rc-table-header");
893
+ //
894
+ // if (tableBody && tableHeader) {
895
+ // tableBody.addEventListener("scroll", () => {
896
+ // tableHeader.scrollLeft = tableBody.scrollLeft;
897
+ // });
898
+ // }
899
+ // }, []);
900
+
901
+ const scrollToCell = (rowIndex, colIndex, cell, scrollType) => {
585
902
  const fixedWidth = totalFixedWidth(columns, 'left', selectionSettings);
586
- if (type === 'horizontal') {
903
+ if (scrollType === 'horizontal') {
587
904
  if (tableRef.current) {
588
905
  tableRef.current.scrollTo({
589
906
  left: cell.offsetLeft - fixedWidth,
@@ -603,15 +920,12 @@ const GridEdit = props => {
603
920
  });
604
921
  }
605
922
  };
606
- const handleFocusCell = (rowIndex, colIndex, col, type, e) => {
923
+ const handleFocusCell = (rowIndex, colIndex, col, scrollType, e) => {
607
924
  const isEdit = editingKey !== '';
608
- // const cellEdit: any = document.querySelector(`.ui-rc-table-row[data-row-key="${rowIndex}"] .cell-editing[data-col-index="${colIndex}"]`);
609
- // const cell: any = document.querySelector(`.ui-rc-table-row[data-row-key="${rowIndex}"] .cell-editable[data-col-index="${colIndex}"]`);
610
-
611
925
  const cellEdit = document.querySelector(`.ui-rc-table-row .cell-editing[data-row-index="${rowIndex}"].cell-editing[data-col-index="${colIndex}"]`);
612
926
  const cell = document.querySelector(`.ui-rc-table-row .cell-editable[data-row-index="${rowIndex}"].cell-editable[data-col-index="${colIndex}"]`);
613
927
  const updateSelection = () => {
614
- setSelectedCell({
928
+ setStartSelectedCell({
615
929
  row: rowIndex,
616
930
  col: colIndex
617
931
  });
@@ -624,10 +938,10 @@ const GridEdit = props => {
624
938
  cellEdit.focus();
625
939
  }
626
940
  }
627
- if (type === 'horizontal' && cellEdit) {
941
+ if (scrollType === 'horizontal' && cellEdit) {
628
942
  scrollToCell(rowIndex, colIndex, cellEdit, 'horizontal');
629
943
  }
630
- if (type === 'vertical' && cell) {
944
+ if (scrollType === 'vertical' && cell) {
631
945
  setEditingKey('');
632
946
  updateSelection();
633
947
  scrollToCell(rowIndex, colIndex, cellEdit, 'vertical');
@@ -643,11 +957,38 @@ const GridEdit = props => {
643
957
  }
644
958
  }
645
959
  if (cell) {
646
- scrollToCell(rowIndex, colIndex, cell, type);
960
+ scrollToCell(rowIndex, colIndex, cell, scrollType);
647
961
  }
648
962
  }
649
963
  };
650
- const convertColumns = flatColumns(columns).map((column, colIndex) => {
964
+ const getCellClass = (record, rowIndex, colIndex) => {
965
+ const cellKey = `${rowIndex}-${colIndex}`;
966
+ const topCellKey = `${rowIndex + 1}-${colIndex}`;
967
+ const leftCellKey = `${rowIndex}-${colIndex + 1}`;
968
+ const rightCellKey = `${rowIndex}-${colIndex - 1}`;
969
+ const isSelected = selectedCells.has(cellKey);
970
+ const isTopSelected = selectedCells.has(topCellKey);
971
+ const isLeftSelected = selectedCells.has(leftCellKey);
972
+ const isRightSelected = selectedCells.has(rightCellKey);
973
+ const cellClass = isEditing(record) ? 'rc-ui-cell-editable cell-editing' : 'rc-ui-cell-editable cell-editable';
974
+ const prevRecordEditing = flattenData(childrenColumnName, dataSource)[rowIndex + 1];
975
+ const cellStart = getFirstSelectCell(selectedCells);
976
+ const cellEnd = getLastSelectCell(selectedCells);
977
+ if (!isSelected) {
978
+ const isTop = prevRecordEditing && !isEditing(prevRecordEditing) && rowIndex === Math.min(cellStart.row - 1, cellEnd?.row);
979
+ const isLeft = colIndex + 1 === Math.min(cellStart.col, cellEnd?.col);
980
+ const isRight = colIndex - 1 === Math.max(cellStart.col, cellEnd?.col);
981
+ return isTopSelected || isLeftSelected || isRightSelected ? `${cellClass} ${isTop ? `cell-border-top` : ''} ${isLeft ? `cell-border-left` : ''} ${isRight ? `next-cell-border-left` : ''}` : cellClass;
982
+ }
983
+ const isBottom = cellEnd && rowIndex === Math.max(cellStart.row, cellEnd.row);
984
+ const isRight = cellEnd && colIndex === Math.max(cellStart.col, cellEnd.col);
985
+ const isLeft = colIndex === Math.min(cellStart.col, cellEnd?.col);
986
+
987
+ // return `${cellClass} ${isBottom ? `cell-border-bottom` : ''} ${isRight ? `cell-border-right` : '' } ${isBottom && isRight ? `cell-border-end` : '' }
988
+ return `${cellClass} ${isBottom ? `cell-border-bottom` : ''} ${isRight ? `cell-border-right` : ''} ${isLeft ? `fixed-cell-border-left` : ''} ${isBottom && isRight ? `cell-border-end` : ''}
989
+ `;
990
+ };
991
+ const convertColumns = flatColumns2(columns).map((column, colIndex) => {
651
992
  if (!column?.field && !column?.key) {
652
993
  return column;
653
994
  }
@@ -678,83 +1019,96 @@ const GridEdit = props => {
678
1019
  }
679
1020
  return {
680
1021
  ...column,
681
- // editType: getEditType(column, record),
682
- onCell: (record, rowIndex) => ({
683
- onKeyDown: event => {
684
- if (event.key.length === 1 && !event.ctrlKey && !event.metaKey || event.key === 'Enter') {
685
- if (!isEditing(record) && record[rowKey] !== editingKey) {
686
- handleEdit(record, column, column.editType, event);
1022
+ onCell: (record, rowIndex) => {
1023
+ const rowNumber = getRowNumber(dataSource, record[rowKey], rowKey);
1024
+ return {
1025
+ onKeyDown: event => {
1026
+ const key = getRowKey(record, dataSource.indexOf(record));
1027
+ if (event.key.length === 1 && !event.ctrlKey && !event.metaKey || event.key === 'Enter') {
1028
+ if (!isEditing(record) && record[rowKey] !== editingKey) {
1029
+ handleEdit(record, column, column.editType, event);
1030
+ handleCellClick(rowNumber, record, column);
1031
+ const hasKey = mergedExpandedKeys.has(key);
1032
+ if (hasKey) {
1033
+ // mergedExpandedKeys.delete(key);
1034
+ // newExpandedKeys = [...mergedExpandedKeys];
1035
+ } else {
1036
+ onTriggerExpand(record);
1037
+ }
1038
+ }
1039
+ if (editingKey && editingKey !== '' && (rowNumber ?? 0) + 1 < flattenArray(dataSource).length && event.key === 'Enter') {
1040
+ handleFocusCell((rowNumber ?? 0) + 1, colIndex, column, 'vertical', event);
1041
+ }
687
1042
  }
688
- if (editingKey && editingKey !== '' && (rowIndex ?? 0) + 1 < dataSource.length && event.key === 'Enter') {
689
- handleFocusCell((rowIndex ?? 0) + 1, colIndex, column, 'vertical', event);
1043
+ if (event.key === 'Tab') {
1044
+ if (colIndex + 1 !== columns.length) {
1045
+ handleFocusCell(rowNumber, colIndex + 1, column, 'horizontal', event);
1046
+ } else {
1047
+ event.stopPropagation();
1048
+ event.preventDefault();
1049
+ }
690
1050
  }
691
- }
692
- if (event.key === 'Tab') {
693
- if (colIndex + 1 !== columns.length) {
694
- handleFocusCell(rowIndex, colIndex + 1, column, 'horizontal', event);
695
- } else {
696
- event.stopPropagation();
697
- event.preventDefault();
1051
+ if (event.key === 'ArrowRight' && colIndex + 1 !== columns.length) {
1052
+ if (editingKey !== '') {} else {
1053
+ handleFocusCell(rowNumber, colIndex + 1, column, 'horizontal', event);
1054
+ }
698
1055
  }
699
- }
700
- if (event.key === 'ArrowRight' && colIndex + 1 !== columns.length) {
701
- if (editingKey !== '') {} else {
702
- handleFocusCell(rowIndex, colIndex + 1, column, 'horizontal', event);
1056
+ if (event.key === 'ArrowLeft' && colIndex > 0) {
1057
+ if (!column.dataIndex && !column.key || column.field === 'index' || column.field === '#' || column.dataIndex === 'index' || column.dataIndex === '#') {
1058
+ event.stopPropagation();
1059
+ event.preventDefault();
1060
+ } else {
1061
+ if (editingKey !== '') {} else {
1062
+ handleFocusCell(rowNumber, colIndex - 1, column, 'horizontal', event);
1063
+ }
1064
+ }
703
1065
  }
704
- }
705
- if (event.key === 'ArrowLeft' && colIndex > 0) {
706
- if (!column.dataIndex && !column.key || column.field === 'index' || column.field === '#' || column.dataIndex === 'index' || column.dataIndex === '#') {
707
- event.stopPropagation();
1066
+ if (event.key === 'ArrowDown' && (rowNumber ?? 0) + 1 < flattenArray(dataSource).length) {
1067
+ handleFocusCell((rowNumber ?? 0) + 1, colIndex, column, 'vertical', event);
1068
+ }
1069
+ if (event.key === 'ArrowUp' && (rowNumber ?? 0) > 0) {
1070
+ handleFocusCell((rowNumber ?? 0) - 1, colIndex, column, 'vertical', event);
1071
+ }
1072
+ },
1073
+ onPaste: event => {
1074
+ if (editingKey === '') {
1075
+ handlePaste(record, colIndex, rowNumber, event);
708
1076
  event.preventDefault();
709
- } else {
710
- if (editingKey !== '') {} else {
711
- handleFocusCell(rowIndex, colIndex - 1, column, 'horizontal', event);
712
- }
713
1077
  }
714
- }
715
- if (event.key === 'ArrowDown' && (rowIndex ?? 0) + 1 < dataSource.length) {
716
- handleFocusCell((rowIndex ?? 0) + 1, colIndex, column, 'vertical', event);
717
- }
718
- if (event.key === 'ArrowUp' && (rowIndex ?? 0) > 0) {
719
- handleFocusCell((rowIndex ?? 0) - 1, colIndex, column, 'vertical', event);
720
- }
721
- },
722
- onPaste: event => {
723
- if (editingKey === '') {
724
- handlePaste(event, colIndex, rowIndex);
725
- event.preventDefault();
726
- }
727
- },
728
- onCopy: e => {
729
- if (editingKey === '') {
730
- handleCopy(e);
731
- e.preventDefault();
732
- }
733
- },
734
- onDoubleClick: event => {
735
- if (!isEditing(record) && record[rowKey] !== editingKey) {
736
- handleEdit(record, column, getEditType(column, record), event);
737
- }
738
- },
739
- onClick: () => {
740
- if (record[rowKey] !== editingKey && editingKey !== '') {
741
- setEditingKey('');
742
- }
743
- },
744
- className: isEditing(record) ? 'rc-ui-cell-editable cell-editing' : 'rc-ui-cell-editable cell-editable',
745
- record,
746
- column: column,
747
- editType: getEditType(column, record),
748
- dataIndex: column.dataIndex,
749
- title: column.title,
750
- 'data-col-index': colIndex,
751
- 'data-row-index': rowIndex,
752
- // colIndex: colIndex,
753
- indexCol: colIndex,
754
- indexRow: rowIndex,
755
- editing: isEditing(record),
756
- tabIndex: (rowIndex ?? 0) * columns.length + colIndex
757
- }),
1078
+ },
1079
+ onCopy: e => {
1080
+ if (editingKey === '') {
1081
+ handleCopy(e);
1082
+ e.preventDefault();
1083
+ }
1084
+ },
1085
+ onDoubleClick: event => {
1086
+ if (!isEditing(record) && record[rowKey] !== editingKey) {
1087
+ handleEdit(record, column, getEditType(column, record), event);
1088
+ handleCellClick(rowNumber, record, column);
1089
+ }
1090
+ },
1091
+ onClick: () => {
1092
+ if (record[rowKey] !== editingKey && editingKey !== '') {
1093
+ setEditingKey('');
1094
+ }
1095
+ },
1096
+ // className: isEditing(record) ? 'rc-ui-cell-editable cell-editing' : 'rc-ui-cell-editable cell-editable',
1097
+ className: getCellClass(record, rowNumber, colIndex),
1098
+ record,
1099
+ column: column,
1100
+ editType: getEditType(column, record),
1101
+ dataIndex: column.dataIndex,
1102
+ title: getValueCell(column, record[column.field], format),
1103
+ 'data-col-index': colIndex,
1104
+ 'data-row-index': rowNumber,
1105
+ editing: isEditing(record),
1106
+ tabIndex: (rowIndex ?? 0) * columns.length + colIndex,
1107
+ style: isPasteDragging ? {
1108
+ cursor: "crosshair"
1109
+ } : {}
1110
+ };
1111
+ },
758
1112
  render: (value, record, rowIndex) => {
759
1113
  const rowNumber = getRowNumber(dataSource, record[rowKey], rowKey);
760
1114
  return /*#__PURE__*/React.createElement("div", {
@@ -762,13 +1116,21 @@ const GridEdit = props => {
762
1116
  // selected: selectedCells.has(`${record[rowKey]}-${colIndex}`)
763
1117
  selected: selectedCells.has(`${rowNumber}-${colIndex}`)
764
1118
  }),
765
- onMouseDown: event => handleMouseDown(rowNumber, colIndex, event)
766
- // onMouseEnter={() => handleMouseEnter(record[rowKey], colIndex)}
767
- ,
768
- onMouseEnter: () => handleMouseEnter(rowNumber, colIndex)
1119
+ onMouseDown: event => handleMouseDown(record, rowNumber, colIndex, event),
1120
+ onMouseEnter: () => handleMouseEnter(rowNumber, colIndex),
1121
+ onMouseUp: () => handleMouseUp()
769
1122
  }, /*#__PURE__*/React.createElement("div", {
770
1123
  className: 'ui-rc_content'
771
- }, renderContent(column, value, record, rowIndex, format)));
1124
+ }, renderContent(column, value, record, rowIndex, format)), getLastSelectCell(selectedCells).row === rowNumber && getLastSelectCell(selectedCells).col === colIndex && !isSelectDragging &&
1125
+ /*#__PURE__*/
1126
+ // showDraggingPoint &&
1127
+ React.createElement("span", {
1128
+ className: 'dragging-point',
1129
+ onMouseEnter: event => handlePointEnter(event),
1130
+ onMouseLeave: () => handlePointLeave()
1131
+ }, /*#__PURE__*/React.createElement("span", {
1132
+ className: 'dot-point'
1133
+ })));
772
1134
  }
773
1135
  };
774
1136
  });
@@ -796,7 +1158,12 @@ const GridEdit = props => {
796
1158
  }, [convertColumns]);
797
1159
  const mergedColumns = React.useMemo(() => transformColumns(columns ?? []), [transformColumns, columns]);
798
1160
  const bottomToolbar = () => {
799
- return /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement(Toolbar, {
1161
+ return /*#__PURE__*/React.createElement("div", {
1162
+ className: 'ui-rc-toolbar-bottom',
1163
+ style: {
1164
+ borderBottom: '1px solid #e0e0e0'
1165
+ }
1166
+ }, /*#__PURE__*/React.createElement(Toolbar, {
800
1167
  style: {
801
1168
  width: '100%'
802
1169
  },
@@ -807,6 +1174,9 @@ const GridEdit = props => {
807
1174
  // }}
808
1175
  }));
809
1176
  };
1177
+ const onSelectChange = keys => {
1178
+ setMergedSelectedKeys(keys);
1179
+ };
810
1180
  return /*#__PURE__*/React.createElement(Fragment, null, /*#__PURE__*/React.createElement(GridStyle, {
811
1181
  heightTable: height,
812
1182
  style: {
@@ -838,6 +1208,7 @@ const GridEdit = props => {
838
1208
  },
839
1209
  className: classNames(className, 'grid-editable'),
840
1210
  rowKey: rowKey,
1211
+ getRowKey: getRowKey,
841
1212
  columns: mergedColumns,
842
1213
  showSorterTooltip: {
843
1214
  target: 'sorter-icon'
@@ -848,12 +1219,50 @@ const GridEdit = props => {
848
1219
  ...selectionSettings,
849
1220
  checkboxOnly: true
850
1221
  } : undefined,
851
- style: {
852
- ...style,
853
- minHeight: height
854
- },
855
1222
  rowHoverable: false,
856
- bottomToolbar: bottomToolbar
1223
+ bottomToolbar: bottomToolbar,
1224
+ expandable: {
1225
+ ...expandable,
1226
+ expandedRowKeys: innerExpandedKeys,
1227
+ expandIcon: args => {
1228
+ const {
1229
+ record,
1230
+ expanded
1231
+ } = args;
1232
+
1233
+ // @ts-ignore
1234
+ if (record?.children?.length > 0 || record?.isChildren) {
1235
+ return expanded ? /*#__PURE__*/React.createElement("button", {
1236
+ onClick: e => {
1237
+ e.preventDefault();
1238
+ e.stopPropagation();
1239
+ onTriggerExpand(record);
1240
+ // onExpand(record, e)
1241
+ },
1242
+ className: 'ui-rc-table-row-expand-icon ui-rc-table-row-expand-icon-expanded'
1243
+ }) : /*#__PURE__*/React.createElement("button", {
1244
+ onClick: e => {
1245
+ e.preventDefault();
1246
+ e.stopPropagation();
1247
+ onTriggerExpand(record);
1248
+ // onExpand(record, e)
1249
+ },
1250
+ className: 'ui-rc-table-row-expand-icon ui-rc-table-row-expand-icon-collapsed'
1251
+ });
1252
+ } else {
1253
+ return /*#__PURE__*/React.createElement("button", {
1254
+ className: 'ui-rc-table-row-expand-icon ui-rc-table-row-expand-icon-spaced'
1255
+ });
1256
+ }
1257
+ }
1258
+ },
1259
+ rowSelection: columns && columns.length === 0 ? undefined : {
1260
+ type: mode === 'checkbox' || type === 'multiple' ? 'checkbox' : "radio",
1261
+ columnWidth: !mode ? 0.0000001 : columnWidth ?? 50,
1262
+ onChange: onSelectChange,
1263
+ selectedRowKeys: mergedSelectedKeys,
1264
+ preserveSelectedRowKeys: true
1265
+ }
857
1266
  }))))), /*#__PURE__*/React.createElement(Toaster, {
858
1267
  position: toast,
859
1268
  toastOptions: {